public class MainActivity extends AppCompatActivity { private TextView monthText; private TextView yearText; private GridLayout calendarGrid; private LocalDate currentDisplayMonth; private LocalDate tappedSelectedDate; private final Map cellDateMap = new HashMap<>(); private TextView previouslySelectedCellView = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); currentDisplayMonth = LocalDate.now(); setContentView(R.layout.activity_main); monthText = findViewById(R.id.monthText); yearText = findViewById(R.id.yearText); calendarGrid = findViewById(R.id.calendarGrid); Button prevMonthButton = findViewById(R.id.prevMonthButton); Button nextMonthButton = findViewById(R.id.nextMonthButton); if (monthText == null || yearText == null || calendarGrid == null || prevMonthButton == null || nextMonthButton == null) { Log.e("MainActivityLifecycle", "onCreate: One or more views are null!"); return; } updateMonthYearDisplay(); drawCalendar(); prevMonthButton.setOnClickListener(v -> { if (currentDisplayMonth == null) { Log.e("MainActivityLogic", "prevMonthButton: currentDisplayMonth is null!"); currentDisplayMonth = LocalDate.now(); } currentDisplayMonth = currentDisplayMonth.minusMonths(1); clearSelection(); updateMonthYearDisplay(); drawCalendar(); }); ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> { Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars()); v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom); return insets; }); } private void updateMonthYearDisplay() { if (monthText != null && yearText != null && currentDisplayMonth != null) { DateTimeFormatter monthFormatter = DateTimeFormatter.ofPattern("MMMM", Locale.getDefault()); monthText.setText(currentDisplayMonth.format(monthFormatter)); DateTimeFormatter yearFormatter = DateTimeFormatter.ofPattern("yyyy", Locale.getDefault()); yearText.setText(currentDisplayMonth.format(yearFormatter)); } else { if (monthText == null) System.err.println("Error: monthText TextView not found!"); if (yearText == null) System.err.println("Error: yearText TextView not found!"); } } private void clearSelection() { tappedSelectedDate = null; if (previouslySelectedCellView != null) { removeSelectionStyle(previouslySelectedCellView); previouslySelectedCellView = null; } } private void drawCalendar() { if (currentDisplayMonth == null) { Log.e("CalendarError", "drawCalendar() called but currentDisplayMonth is null! Initializing to now."); currentDisplayMonth = LocalDate.now(); // Fallback, but points to a deeper issue } Log.d("CalendarLifecycle", "drawCalendar() called for month: " + currentDisplayMonth.toString()); // New Log calendarGrid.removeAllViews(); cellDateMap.clear(); } YearMonth yearMonth = YearMonth.from(currentDisplayMonth); int daysInMonth = yearMonth.lengthOfMonth(); LocalDate firstOfMonth = currentDisplayMonth.withDayOfMonth(1); DayOfWeek firstDayOfWeekEnum = firstOfMonth.getDayOfWeek(); int dayOfWeekOfFirst = (firstDayOfWeekEnum == DayOfWeek.SUNDAY) ? 0 : firstDayOfWeekEnum.getValue(); { // Add empty cells for days before the first of the month for (int i = 0; i < dayOfWeekOfFirst; i++) { addCellToGrid(null, false, null); } // Add cells for each day of the month for (int day = 1; day <= daysInMonth; day++) { LocalDate cellDate = currentDisplayMonth.withDayOfMonth(day); Log.d("CalendarLifecycle", "drawCalendar() - about to call addCellToGrid for: " + cellDate); addCellToGrid(String.valueOf(day), true, cellDate); } // Optional: Fill remaining cells int cellsInTypicalGrid = 42; // 7 columns * 6 rows if (calendarGrid.getColumnCount() > 0 && calendarGrid.getRowCount() > 0) { cellsInTypicalGrid = calendarGrid.getColumnCount() * calendarGrid.getRowCount(); } int currentCellCount = calendarGrid.getChildCount(); for (int i = currentCellCount; i < cellsInTypicalGrid; i++) { addCellToGrid(null, false, null); } } private void addCellToGrid(final String text, boolean isDayCell, final LocalDate cellDate) { final TextView cell = new TextView(this); GridLayout.LayoutParams params = new GridLayout.LayoutParams( GridLayout.spec(GridLayout.UNDEFINED, 1f), GridLayout.spec(GridLayout.UNDEFINED, 1f) ); params.width = 0; params.height = 0; // Consider setting margins in dp via XML styles or programmatically converting dp to pixels params.setMargins(2, 2, 2, 2); cell.setLayoutParams(params); cell.setGravity(Gravity.CENTER); cell.setPadding(10, 10, 10, 10); cell.setTextSize(15f); // Use TypedValue.COMPLEX_UNIT_SP for sp units if (isDayCell && cellDate != null) { cell.setText(text); cellDateMap.put(cell, cellDate); // Style for TODAY'S DATE // if (cellDate.equals(LocalDate.now())) { cell.setBackground(ContextCompat.getDrawable(this, R.drawable.date_circle_bg)); // White circle cell.setTextColor(ContextCompat.getColor(this, R.color.date_text_today_circled)); // Black text cell.setTypeface(null, Typeface.NORMAL); // Make today's date bold } LocalDate today = LocalDate.now(); if (cellDate.equals(today)) { cell.setTextColor(ContextCompat.getColor(this, R.color.my_app_primary_color)); cell.setTypeface(null, Typeface.BOLD); } else { cell.setTextColor(Color.BLACK); cell.setTypeface(null, Typeface.NORMAL); } if (cellDate.equals(tappedSelectedDate)) { applySelectionStyle(cell); previouslySelectedCellView = cell; } else { removeSelectionStyle(cell); } cell.setOnClickListener(v -> { if (previouslySelectedCellView != null) { removeSelectionStyle(previouslySelectedCellView); } tappedSelectedDate = cellDateMap.get(cell); applySelectionStyle(cell); previouslySelectedCellView = cell; }); } else { cell.setText(""); cell.setClickable(false); cell.setBackground(null); } calendarGrid.addView(cell); } private void applySelectionStyle(TextView cell) { try { Drawable selectedBg = ContextCompat.getDrawable(this, R.drawable.selected_day_background); if (selectedBg != null) { cell.setBackground(selectedBg); } else { cell.setBackgroundColor(Color.LTGRAY); } // cell.setTextColor(Color.WHITE); // Optional } catch (Exception e) { cell.setBackgroundColor(Color.LTGRAY); System.err.println("Error applying selection style: " + e.getMessage()); } } private void removeSelectionStyle(TextView cell) { cell.setBackground(null); LocalDate cellDate = cellDateMap.get(cell); if (cellDate != null) { if (cellDate.equals(LocalDate.now())) { cell.setTextColor(ContextCompat.getColor(this, R.color.my_app_primary_color)); cell.setTypeface(null, Typeface.BOLD); } else { cell.setTextColor(Color.WHITE); cell.setTypeface(null, Typeface.NORMAL); } } else { cell.setTextColor(Color.WHITE); cell.setTypeface(null, Typeface.NORMAL); } } }