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