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.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. citrus.setCurMonth(month - 1);
  359. } else if (ii >= 4 && Integer.parseInt(daysString[ii][jj]) < 25) {
  360. if(month == 12) {
  361. month = 0;
  362. citrus.setCurMonth(month + 1);
  363. }
  364. citrus.setCurMonth(month + 1);
  365. }
  366. ((MainActivity) getActivity()).showFragment(new HomeFragment());
  367. }
  368. });
  369. RecyclerView recyclerView = new RecyclerView(requireContext());
  370. RecyclerView.LayoutManager layoutmanager = new LinearLayoutManager(requireContext());
  371. recyclerView.setLayoutManager(layoutmanager);
  372.  
  373. List<Task> schedules = new ArrayList<>();
  374.  
  375. recyclerView.setAdapter(new MyScheduleAdapter(schedules, books));
  376. layout.addView(recyclerView);
  377. layout.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
  378. @Override
  379. public void onGlobalLayout() {
  380. LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
  381. LinearLayout.LayoutParams.MATCH_PARENT,
  382. layout.getHeight()
  383. );
  384. layout.getChildAt(1).setLayoutParams(layoutParams);
  385. layout.getViewTreeObserver().removeOnGlobalLayoutListener(this);
  386. }
  387. });
  388.  
  389. }
  390. }
  391. }
  392.  
  393. //カレンダーの更新
  394. private void updateCalendar(TextView curMonth){
  395. curMonth.setText(year + "年" + month + "月");
  396. //指定した年月の一日の曜日を取得
  397. LocalDate firstDay = LocalDate.of(year, month, 1);
  398. DayOfWeek dayOfWeek = firstDay.getDayOfWeek();
  399. int firstDayOfWeek = dayOfWeek.getValue();
  400. //前の月の最後の日付を取得
  401. LocalDate lastDate = LocalDate.of(year, month, 1);
  402. LocalDate lastDayPrevMonth = lastDate.minusDays(1);
  403. int prevMonthDay = lastDayPrevMonth.getDayOfMonth();
  404. //現在の月の最後の日付を取得
  405. YearMonth yearMonth = YearMonth.of(year, month);
  406. LocalDate CurLastDay = yearMonth.atEndOfMonth();
  407. int lastDay = CurLastDay.getDayOfMonth();
  408.  
  409. String[][] days = calendarString(firstDayOfWeek, prevMonthDay, lastDay);
  410. int one = 0;
  411. RadioGroup selectButton = getView().findViewById(R.id.SelectButton);
  412.  
  413. for(int i = 0; i < 6; i++) {
  414. TableRow tableRow = (TableRow) tableLayout.getChildAt(i);
  415. for(int j = 0; j < 7; j++) {
  416. LinearLayout layout = (LinearLayout) tableRow.getChildAt(j);
  417. RecyclerView recyclerView = (RecyclerView) layout.getChildAt(1);
  418. List<Task> schedules = new ArrayList<>();
  419. if(days[i][j].equals("1")){
  420. one++;
  421. }
  422. if(this.schedules != null && one == 1) {
  423.  
  424. int select = selectButton.getCheckedRadioButtonId();
  425. if(select != -1){
  426. if(select == R.id.rbTodo){
  427. if (this.todos.get(Integer.parseInt(days[i][j])) != null) {
  428. for (Todo schedule : this.todos.get(Integer.parseInt(days[i][j])).values()) {
  429. schedules.add(schedule);
  430. }
  431. }
  432. } else if(select == R.id.rbSchedule){
  433. if (this.schedules.get(Integer.parseInt(days[i][j])) != null) {
  434. for (Schedule schedule : this.schedules.get(Integer.parseInt(days[i][j])).values()) {
  435. schedules.add(schedule);
  436. }
  437. }
  438. } else {
  439. if (this.todos.get(Integer.parseInt(days[i][j])) != null) {
  440. for (Todo schedule : this.todos.get(Integer.parseInt(days[i][j])).values()) {
  441. schedules.add(schedule);
  442. }
  443. }
  444. if (this.schedules.get(Integer.parseInt(days[i][j])) != null) {
  445. for (Schedule schedule : this.schedules.get(Integer.parseInt(days[i][j])).values()) {
  446. schedules.add(schedule);
  447. }
  448. }
  449. }
  450.  
  451.  
  452. }
  453. }
  454.  
  455. ((MyScheduleAdapter) recyclerView.getAdapter()).setSchedules(schedules, books);
  456. ((TextView) layout.getChildAt(0)).setText(days[i][j]);
  457. }
  458. }
  459. }
  460. }
  461.  
  462. class MyScheduleAdapter extends RecyclerView.Adapter<MyScheduleAdapter.MyScheduleViewHolder> {
  463.  
  464. private List<Task> scheduleList;
  465. private HashMap<Integer, Book> integerBookHashMap;
  466.  
  467. MyScheduleAdapter(List<Task> schedules, HashMap<Integer, Book> integerBookHashMap) {
  468. this.scheduleList = schedules;
  469. if(integerBookHashMap != null) {
  470. this.integerBookHashMap = new HashMap<>(integerBookHashMap);
  471. } else {
  472. this.integerBookHashMap = new HashMap<>();
  473. }
  474. }
  475.  
  476. public void setSchedules(List<Task> schedules, HashMap<Integer, Book> integerBookHashMap) {
  477. scheduleList = schedules;
  478. if(integerBookHashMap != null) {
  479. this.integerBookHashMap = new HashMap<>(integerBookHashMap);
  480. } else {
  481. this.integerBookHashMap = new HashMap<>();
  482. }
  483. notifyDataSetChanged();
  484. }
  485. @NonNull
  486. @Override
  487. public MyScheduleViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
  488. View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.a_calendar_schedule, parent, false);
  489. return new MyScheduleViewHolder(view);
  490. }
  491.  
  492. @Override
  493. public void onBindViewHolder(@NonNull MyScheduleViewHolder holder, int position) {
  494. int red = 169;
  495. int green = 169;
  496. int blue = 169;
  497. Task scheduleData = this.scheduleList.get(position);
  498. holder.scheduleText.setText(scheduleData.getTitle());
  499. Book book = integerBookHashMap.get(scheduleData.getBookId());
  500. if(book != null) {
  501. red = Integer.parseInt(book.getColor().substring(1, 3), 16);
  502. green = Integer.parseInt(book.getColor().substring(3, 5), 16);
  503. blue = Integer.parseInt(book.getColor().substring(5, 7), 16);
  504. }
  505. holder.scheduleText.setBackgroundColor(Color.rgb(red, green, blue));
  506. holder.scheduleText.setTextColor(Color.rgb(255-red, 255-green, 255-blue));
  507. }
  508.  
  509. @Override
  510. public int getItemCount() {
  511. return scheduleList.size();
  512. }
  513.  
  514. static class MyScheduleViewHolder extends RecyclerView.ViewHolder {
  515. TextView scheduleText;
  516. public MyScheduleViewHolder(@NonNull View itemView) {
  517. super(itemView);
  518. scheduleText = itemView.findViewById(R.id.schedule_text);
  519. }
  520. }
  521. }
  522.