Newer
Older
CitrusClient / app / src / main / java / com / example / citrusclient / views / CalendarFragment.java
t-watanabe on 8 Oct 21 KB カレンダーの機能修正
  1. package com.example.citrusclient.views;
  2.  
  3. import android.app.Activity;
  4. import android.graphics.Color;
  5. import android.os.Bundle;
  6.  
  7. import androidx.annotation.NonNull;
  8. import androidx.annotation.Nullable;
  9. import androidx.fragment.app.Fragment;
  10. import androidx.lifecycle.Observer;
  11. import androidx.lifecycle.ViewModelProvider;
  12. import androidx.recyclerview.widget.LinearLayoutManager;
  13. import androidx.recyclerview.widget.RecyclerView;
  14.  
  15. import android.view.LayoutInflater;
  16. import android.view.View;
  17. import android.view.ViewGroup;
  18. import android.view.ViewTreeObserver;
  19. import android.widget.Button;
  20. import android.widget.LinearLayout;
  21. import android.widget.RadioGroup;
  22. import android.widget.TableLayout;
  23. import android.widget.TableRow;
  24. import android.widget.TextView;
  25.  
  26. import com.example.citrusclient.Citrus;
  27. import com.example.citrusclient.R;
  28. import com.example.citrusclient.models.Book;
  29. import com.example.citrusclient.models.Schedule;
  30. import com.example.citrusclient.models.Task;
  31. import com.example.citrusclient.models.Todo;
  32. import com.example.citrusclient.viewmodels.BooksViewModel;
  33. import com.example.citrusclient.viewmodels.ScheduleViewModel;
  34. import com.example.citrusclient.viewmodels.TodosViewModel;
  35. import com.google.android.material.floatingactionbutton.FloatingActionButton;
  36.  
  37. import java.time.DayOfWeek;
  38. import java.time.LocalDate;
  39. import java.time.YearMonth;
  40. import java.util.ArrayList;
  41. import java.util.Calendar;
  42. import java.util.HashMap;
  43. import java.util.List;
  44.  
  45. /**
  46. * A simple {@link Fragment} subclass.
  47. * Use the {@link CalendarFragment#newInstance} factory method to
  48. * create an instance of this fragment.
  49. */
  50. public class CalendarFragment extends Fragment {
  51.  
  52. // TODO: Rename parameter arguments, choose names that match
  53. // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
  54. private static final String ARG_PARAM1 = "param1";
  55. private static final String ARG_PARAM2 = "param2";
  56.  
  57. // TODO: Rename and change types of parameters
  58. private String mParam1;
  59. private String mParam2;
  60.  
  61.  
  62. private TableLayout tableLayout;
  63. private TableRow[] tableRows = new TableRow[6];
  64. private TextView curMonth;
  65.  
  66. public CalendarFragment() {
  67. Calendar calendar = Calendar.getInstance();
  68. year = calendar.get(Calendar.YEAR); //現在の年
  69. month = calendar.get(Calendar.MONTH) + 1; //現在の月
  70. }
  71.  
  72. public CalendarFragment(int year, int month) {
  73. this.year = year;
  74. this.month = month;
  75. }
  76.  
  77. /**
  78. * Use this factory method to create a new instance of
  79. * this fragment using the provided parameters.
  80. *
  81. * @param param1 Parameter 1.
  82. * @param param2 Parameter 2.
  83. * @return A new instance of fragment ScheduleFragment.
  84. */
  85. // TODO: Rename and change types and number of parameters
  86. public static CalendarFragment newInstance(String param1, String param2) {
  87. CalendarFragment fragment = new CalendarFragment();
  88. Bundle args = new Bundle();
  89. args.putString(ARG_PARAM1, param1);
  90. args.putString(ARG_PARAM2, param2);
  91. fragment.setArguments(args);
  92. return fragment;
  93. }
  94.  
  95. @Override
  96. public void onCreate(Bundle savedInstanceState) {
  97. super.onCreate(savedInstanceState);
  98. if (getArguments() != null) {
  99. mParam1 = getArguments().getString(ARG_PARAM1);
  100. mParam2 = getArguments().getString(ARG_PARAM2);
  101. }
  102.  
  103. scheduleViewModel = new ViewModelProvider(this).get(ScheduleViewModel.class);
  104. booksViewModel = new ViewModelProvider(this).get(BooksViewModel.class);
  105. todosViewModel = new ViewModelProvider(this).get(TodosViewModel.class);
  106.  
  107. schedules = new HashMap<>();
  108. }
  109.  
  110. @Override
  111. public View onCreateView(LayoutInflater inflater, ViewGroup container,
  112. Bundle savedInstanceState) {
  113. // Inflate the layout for this fragment
  114. return inflater.inflate(R.layout.fragment_calendar, container, false);
  115. }
  116.  
  117.  
  118. BooksViewModel booksViewModel;
  119. private List<Schedule> scheduleList;
  120. ScheduleViewModel scheduleViewModel;
  121. TodosViewModel todosViewModel;
  122. private HashMap<Integer, Book> integerBookHashMap;
  123.  
  124. int year;
  125. int month;
  126. int day;
  127.  
  128. HashMap<Integer, Book> books;
  129.  
  130. HashMap<Integer, HashMap<Integer, Schedule>> schedules;
  131. HashMap<Integer, HashMap<Integer, Todo>> todos;
  132.  
  133. public TextView[][] calendar(int firstDayOfWeek, int prevMonthDay, int lastDay) {
  134. int curDay = 1;
  135. int d = 1;
  136. int prevDay = prevMonthDay - firstDayOfWeek;
  137. TextView textViews[][] = new TextView[6][7];
  138. if(firstDayOfWeek == 7) firstDayOfWeek = 0;
  139. for(int i = 0; i < 6; i++) {
  140. for(int j = 0; j < 7; j++){
  141. if(firstDayOfWeek > 0) {
  142. prevDay++;
  143. textViews[i][j] = new TextView(requireContext());
  144. textViews[i][j].setTextColor(Color.GRAY);
  145. textViews[i][j].setText("" + prevDay);
  146. firstDayOfWeek--;
  147. } else if(firstDayOfWeek <= 0 && curDay <= lastDay) {
  148. textViews[i][j] = new TextView(requireContext());
  149. textViews[i][j].setText("" + curDay);
  150. curDay++;
  151. } else if (curDay > lastDay && d <= 43-curDay) {
  152. textViews[i][j] = new TextView(requireContext());
  153. textViews[i][j].setTextColor(Color.GRAY);
  154. textViews[i][j].setText("" + d);
  155. d++;
  156. }
  157. }
  158. }
  159. return textViews;
  160. }
  161.  
  162. public String[][] calendarString(int firstDayOfWeek, int prevMonthDay, int lastDay) {
  163. int curDay = 1;
  164. int d = 1;
  165. int prevDay = prevMonthDay - firstDayOfWeek;
  166. String[][] textViews = new String[6][7];
  167. if(firstDayOfWeek == 7) firstDayOfWeek = 0;
  168. for(int i = 0; i < 6; i++) {
  169. for(int j = 0; j < 7; j++){
  170. if(firstDayOfWeek > 0) {
  171. prevDay++;
  172. textViews[i][j] = ("" + prevDay);
  173. firstDayOfWeek--;
  174. } else if(firstDayOfWeek <= 0 && curDay <= lastDay) {
  175. textViews[i][j] = ("" + curDay);
  176. curDay++;
  177. } else if (curDay > lastDay && d <= 43-curDay) {
  178. textViews[i][j] = ("" + d);
  179. d++;
  180. }
  181. }
  182. }
  183. return textViews;
  184. }
  185.  
  186. @Override
  187. public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
  188. super.onViewCreated(view, savedInstanceState);
  189.  
  190. Citrus citrus = (Citrus)(getActivity().getApplication());
  191. String token = citrus.getToken();
  192. String accountId = citrus.getAccountId();
  193.  
  194. todos = new HashMap<>();
  195. schedules = new HashMap<>();
  196.  
  197. scheduleViewModel.getSchedulesByMonth().observe(getViewLifecycleOwner(), new Observer<HashMap<Integer, HashMap<Integer, Schedule>>>() {
  198. @Override
  199. public void onChanged(HashMap<Integer, HashMap<Integer, Schedule>> integerHashMapHashMap) {
  200. TextView curMonth = view.findViewById(R.id.Month);
  201. schedules = integerHashMapHashMap;
  202. updateCalendar(curMonth);
  203. }
  204. });
  205.  
  206. booksViewModel.getBookLiveData().observe(getViewLifecycleOwner(), new Observer<HashMap<Integer, Book>>() {
  207. @Override
  208. public void onChanged(HashMap<Integer, Book> integerBookHashMap) {
  209. books = integerBookHashMap;
  210. if(books != null) {
  211. TextView curMonth = view.findViewById(R.id.Month);
  212. if(todos != null) {
  213. todos.clear();
  214. } else {
  215. todos = new HashMap<>();
  216. }
  217.  
  218. for(int bookId:books.keySet()){
  219. todosViewModel.loadTodosByMonth(accountId, bookId, year, month, token);
  220. }
  221.  
  222. updateCalendar(curMonth);
  223. }
  224. }
  225. });
  226.  
  227. todosViewModel.getTodosByMonthLiveData().observe(getViewLifecycleOwner(), new Observer<HashMap<Integer, HashMap<Integer, Todo>>>() {
  228. @Override
  229. public void onChanged(HashMap<Integer, HashMap<Integer, Todo>> integerHashMapHashMap) {
  230. TextView curMonth = view.findViewById(R.id.Month);
  231. if(integerHashMapHashMap != null && !integerHashMapHashMap.isEmpty()) {
  232. for (int day : integerHashMapHashMap.keySet()) {
  233. if (todos.get(day) == null) {
  234. todos.put(day, new HashMap<>());
  235. }
  236. for (int todoId : integerHashMapHashMap.get(day).keySet()) {
  237. todos.get(day).put(todoId, integerHashMapHashMap.get(day).get(todoId));
  238. }
  239. }
  240. }
  241. updateCalendar(curMonth);
  242. }
  243. });
  244.  
  245. booksViewModel.loadBooks(accountId, token);
  246.  
  247. tableLayout = view.findViewById(R.id.calendarlayout);
  248. // Calendar calendar = Calendar.getInstance();
  249. // year = calendar.get(Calendar.YEAR); //現在の年
  250. // month = calendar.get(Calendar.MONTH) + 1; //現在の月
  251.  
  252. scheduleViewModel.updateSchedulesByMonth(accountId, year, month, token);
  253.  
  254. //現在の月の最後の日付を取得
  255. YearMonth yearMonth = YearMonth.of(year, month);
  256. LocalDate CurLastDay = yearMonth.atEndOfMonth();
  257. int lastDay = CurLastDay.getDayOfMonth();
  258.  
  259. //前の月の最後の日付を取得
  260. LocalDate lastDate = LocalDate.of(year, month, 1);
  261. LocalDate lastDayPrevMonth = lastDate.minusDays(1);
  262. int prevMonthDay = lastDayPrevMonth.getDayOfMonth();
  263.  
  264. //指定した年月の一日の曜日を取得
  265. LocalDate firstDay = LocalDate.of(year, month, 1);
  266. DayOfWeek dayOfWeek = firstDay.getDayOfWeek();
  267. int firstDayOfWeek = dayOfWeek.getValue();
  268.  
  269. Button nextMonth = view.findViewById(R.id.NextMonth);
  270. Button prevMonth = view.findViewById(R.id.PrevMonth);
  271. FloatingActionButton createBook = view.findViewById(R.id.floatingActionButton);
  272. TextView curMonth = view.findViewById(R.id.Month);
  273. curMonth.setText(year + "年" + month + "月");
  274.  
  275. createBook.setOnClickListener(new View.OnClickListener() {
  276. @Override
  277. public void onClick(View view) {
  278. ((MainActivity) getActivity()).showFragment(new CreateScheduleFragment(year, month, day));
  279. }
  280. });
  281.  
  282. //カレンダーの次の月を表示
  283. nextMonth.setOnClickListener(new View.OnClickListener() {
  284. @Override
  285. public void onClick(View view) {
  286. month++;
  287. if(month > 12){
  288. month = 1;
  289. year++;
  290. }
  291. scheduleViewModel.updateSchedulesByMonth(accountId, year, month, token);
  292. }
  293. });
  294.  
  295. //カレンダーの前の月を表示
  296. prevMonth.setOnClickListener(new View.OnClickListener() {
  297. @Override
  298. public void onClick(View view) {
  299. month--;
  300. if(month < 1) {
  301. month = 12;
  302. year--;
  303. }
  304. scheduleViewModel.updateSchedulesByMonth(accountId, year, month, token);
  305. }
  306. });
  307.  
  308. view.findViewById(R.id.rbTodo).setOnClickListener(view1 -> {
  309. updateCalendar(curMonth);
  310. });
  311. view.findViewById(R.id.rbSchedule).setOnClickListener(view1 -> {
  312. updateCalendar(curMonth);
  313. });
  314. view.findViewById(R.id.rbBoth).setOnClickListener(view1 -> {
  315. updateCalendar(curMonth);
  316. });
  317.  
  318. //カレンダーの初期表示
  319. TableLayout tableLayout = view.findViewById(R.id.calendarlayout);
  320. TextView[][] days = calendar(firstDayOfWeek, prevMonthDay, lastDay);
  321. for(int i = 0; i < 6; i++) {
  322. TableRow tableRow = (TableRow) tableLayout.getChildAt(i);
  323. for(int j = 0; j < 7; j++) {
  324. LinearLayout layout = new LinearLayout(requireContext());
  325. layout.setOrientation(LinearLayout.VERTICAL);
  326. layout.setLayoutParams(new TableRow.LayoutParams(0, TableRow.LayoutParams.MATCH_PARENT));
  327. TableRow.LayoutParams p2 = (TableRow.LayoutParams) layout.getLayoutParams();
  328. p2.weight = 1;
  329. tableRow.addView(layout);
  330. layout.addView(days[i][j]);
  331. final int ii = i;
  332. final int jj = j;
  333. layout.setOnClickListener(new View.OnClickListener() {
  334. @Override
  335. public void onClick(View view) {
  336. citrus.setCurMonth(month);
  337. citrus.setCurYear(year);
  338. //指定した年月の一日の曜日を取得
  339. LocalDate firstDay = LocalDate.of(year, month, 1);
  340. DayOfWeek dayOfWeek = firstDay.getDayOfWeek();
  341. int firstDayOfWeek = dayOfWeek.getValue();
  342. //前の月の最後の日付を取得
  343. LocalDate lastDate = LocalDate.of(year, month, 1);
  344. LocalDate lastDayPrevMonth = lastDate.minusDays(1);
  345. int prevMonthDay = lastDayPrevMonth.getDayOfMonth();
  346. //現在の月の最後の日付を取得
  347. YearMonth yearMonth = YearMonth.of(year, month);
  348. LocalDate CurLastDay = yearMonth.atEndOfMonth();
  349. int lastDay = CurLastDay.getDayOfMonth();
  350.  
  351. String[][] daysString = calendarString(firstDayOfWeek, prevMonthDay, lastDay);
  352. citrus.setCurDay(Integer.parseInt(daysString[ii][jj]));
  353. if(ii == 0 && Integer.parseInt(daysString[ii][jj]) > 8) {
  354. if(month == 1) {
  355. month = 13;
  356. citrus.setCurMonth(month - 1);
  357. }
  358. } else if (ii >= 4 && Integer.parseInt(daysString[ii][jj]) < 25) {
  359. if(month == 12) {
  360. month = 0;
  361. citrus.setCurMonth(month + 1);
  362. }
  363. }
  364. ((MainActivity) getActivity()).showFragment(new HomeFragment());
  365. }
  366. });
  367. RecyclerView recyclerView = new RecyclerView(requireContext());
  368. RecyclerView.LayoutManager layoutmanager = new LinearLayoutManager(requireContext());
  369. recyclerView.setLayoutManager(layoutmanager);
  370.  
  371. List<Task> schedules = new ArrayList<>();
  372.  
  373. recyclerView.setAdapter(new MyScheduleAdapter(schedules, books));
  374. layout.addView(recyclerView);
  375. layout.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
  376. @Override
  377. public void onGlobalLayout() {
  378. LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
  379. LinearLayout.LayoutParams.MATCH_PARENT,
  380. layout.getHeight()
  381. );
  382. layout.getChildAt(1).setLayoutParams(layoutParams);
  383. layout.getViewTreeObserver().removeOnGlobalLayoutListener(this);
  384. }
  385. });
  386.  
  387. }
  388. }
  389. }
  390.  
  391. //カレンダーの更新
  392. private void updateCalendar(TextView curMonth){
  393. curMonth.setText(year + "年" + month + "月");
  394. //指定した年月の一日の曜日を取得
  395. LocalDate firstDay = LocalDate.of(year, month, 1);
  396. DayOfWeek dayOfWeek = firstDay.getDayOfWeek();
  397. int firstDayOfWeek = dayOfWeek.getValue();
  398. //前の月の最後の日付を取得
  399. LocalDate lastDate = LocalDate.of(year, month, 1);
  400. LocalDate lastDayPrevMonth = lastDate.minusDays(1);
  401. int prevMonthDay = lastDayPrevMonth.getDayOfMonth();
  402. //現在の月の最後の日付を取得
  403. YearMonth yearMonth = YearMonth.of(year, month);
  404. LocalDate CurLastDay = yearMonth.atEndOfMonth();
  405. int lastDay = CurLastDay.getDayOfMonth();
  406.  
  407. String[][] days = calendarString(firstDayOfWeek, prevMonthDay, lastDay);
  408. int one = 0;
  409. RadioGroup selectButton = getView().findViewById(R.id.SelectButton);
  410.  
  411. for(int i = 0; i < 6; i++) {
  412. TableRow tableRow = (TableRow) tableLayout.getChildAt(i);
  413. for(int j = 0; j < 7; j++) {
  414. LinearLayout layout = (LinearLayout) tableRow.getChildAt(j);
  415. RecyclerView recyclerView = (RecyclerView) layout.getChildAt(1);
  416. List<Task> schedules = new ArrayList<>();
  417. if(days[i][j].equals("1")){
  418. one++;
  419. }
  420. if(this.schedules != null && one == 1) {
  421.  
  422. int select = selectButton.getCheckedRadioButtonId();
  423. if(select != -1){
  424. if(select == R.id.rbTodo){
  425. if (this.todos.get(Integer.parseInt(days[i][j])) != null) {
  426. for (Todo schedule : this.todos.get(Integer.parseInt(days[i][j])).values()) {
  427. schedules.add(schedule);
  428. }
  429. }
  430. } else if(select == R.id.rbSchedule){
  431. if (this.schedules.get(Integer.parseInt(days[i][j])) != null) {
  432. for (Schedule schedule : this.schedules.get(Integer.parseInt(days[i][j])).values()) {
  433. schedules.add(schedule);
  434. }
  435. }
  436. } else {
  437. if (this.todos.get(Integer.parseInt(days[i][j])) != null) {
  438. for (Todo schedule : this.todos.get(Integer.parseInt(days[i][j])).values()) {
  439. schedules.add(schedule);
  440. }
  441. }
  442. if (this.schedules.get(Integer.parseInt(days[i][j])) != null) {
  443. for (Schedule schedule : this.schedules.get(Integer.parseInt(days[i][j])).values()) {
  444. schedules.add(schedule);
  445. }
  446. }
  447. }
  448.  
  449.  
  450. }
  451. }
  452.  
  453. ((MyScheduleAdapter) recyclerView.getAdapter()).setSchedules(schedules, books);
  454. ((TextView) layout.getChildAt(0)).setText(days[i][j]);
  455. }
  456. }
  457. }
  458. }
  459.  
  460. class MyScheduleAdapter extends RecyclerView.Adapter<MyScheduleAdapter.MyScheduleViewHolder> {
  461.  
  462. private List<Task> scheduleList;
  463. private HashMap<Integer, Book> integerBookHashMap;
  464.  
  465. MyScheduleAdapter(List<Task> schedules, HashMap<Integer, Book> integerBookHashMap) {
  466. this.scheduleList = schedules;
  467. if(integerBookHashMap != null) {
  468. this.integerBookHashMap = new HashMap<>(integerBookHashMap);
  469. } else {
  470. this.integerBookHashMap = new HashMap<>();
  471. }
  472. }
  473.  
  474. public void setSchedules(List<Task> schedules, HashMap<Integer, Book> integerBookHashMap) {
  475. scheduleList = schedules;
  476. if(integerBookHashMap != null) {
  477. this.integerBookHashMap = new HashMap<>(integerBookHashMap);
  478. } else {
  479. this.integerBookHashMap = new HashMap<>();
  480. }
  481. notifyDataSetChanged();
  482. }
  483. @NonNull
  484. @Override
  485. public MyScheduleViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
  486. View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.other_calendar_schedule, parent, false);
  487. return new MyScheduleViewHolder(view);
  488. }
  489.  
  490. @Override
  491. public void onBindViewHolder(@NonNull MyScheduleViewHolder holder, int position) {
  492. int red = 169;
  493. int green = 169;
  494. int blue = 169;
  495. Task scheduleData = this.scheduleList.get(position);
  496. holder.scheduleText.setText(scheduleData.getTitle());
  497. Book book = integerBookHashMap.get(scheduleData.getBookId());
  498. if(book != null) {
  499. red = Integer.parseInt(book.getColor().substring(1, 3), 16);
  500. green = Integer.parseInt(book.getColor().substring(3, 5), 16);
  501. blue = Integer.parseInt(book.getColor().substring(5, 7), 16);
  502. }
  503. holder.scheduleText.setBackgroundColor(Color.rgb(red, green, blue));
  504. holder.scheduleText.setTextColor(Color.rgb(255-red, 255-green, 255-blue));
  505. }
  506.  
  507. @Override
  508. public int getItemCount() {
  509. return scheduleList.size();
  510. }
  511.  
  512. static class MyScheduleViewHolder extends RecyclerView.ViewHolder {
  513. TextView scheduleText;
  514. public MyScheduleViewHolder(@NonNull View itemView) {
  515. super(itemView);
  516. scheduleText = itemView.findViewById(R.id.schedule_text);
  517. }
  518. }
  519. }
  520.