javaandroidcalendarview

Retaining selection for CalendarView


I am utilizing this library to set up a custom calendar but it appears that on each date click, currentSelection gets set to null. I have the following daybinder set.

calendarView.setDayBinder(new MonthDayBinder<DayViewContainer>() {
            // Called only when a new container is needed.
            @NonNull
            @Override
            public DayViewContainer create(@NonNull View view) {
                return new DayViewContainer(view);
            }

            // Called every time we need to reuse a container.
            @RequiresApi(api = Build.VERSION_CODES.O)
            @Override
            public void bind(@NonNull DayViewContainer container, CalendarDay data) {
                container.day = data;
                CalendarDay day = data;
                selectedDate = container.selectedDate;
                container.calendarView = calendarView;
                Log.d(TAG, "bind: "+ container.day);
                TextView textView = container.textView;
                textView.setText(String.valueOf(data.getDate().getDayOfMonth()));

                if (day.getPosition() == DayPosition.MonthDate) {

                    textView.setVisibility(View.VISIBLE);
                    LocalDate date = day.getDate();
                    // If user selects same date, clear highlight
                    if (date.equals(selectedDate)) {
                        // New date was selected.
                        textView.setTextColor(Color.WHITE);
                        textView.setBackgroundColor(Color.rgb(98,0,238));
                    } else {
                        textView.setVisibility(View.VISIBLE);
                        textView.setTextColor(Color.BLACK);
                        textView.setBackgroundColor(Color.TRANSPARENT);

                    }
                } else {
                    textView.setVisibility(View.INVISIBLE);
                }
            }
        });

        calendarView.setMonthHeaderBinder(new MonthHeaderFooterBinder<MonthViewContainer>() {
            @NonNull
            @Override
            public MonthViewContainer create(@NonNull View view) {
                return new MonthViewContainer(view);
            }

            @Override
            public void bind(@NonNull MonthViewContainer container, @NonNull CalendarMonth data) {
                if (container.getTitlesContainer().getTag() == null) {
                    container.getTitlesContainer().setTag(data.getYearMonth());

                    TextView textView = container.getTitlesContainer();
                    String title = String.valueOf(data.getYearMonth());
                    textView.setText(title);
                }
            }
            });

and the related DayViewContainer class:

public class DayViewContainer extends ViewContainer {

    public TextView textView;
    @SuppressLint("NewApi")
    public CalendarDay day;
    public LocalDate selectedDate;
    public LocalDate currentSelection;
    public CalendarView calendarView;

    public DayViewContainer(View view) {

        super(view);
        textView = view.findViewById(R.id.calendarDayText);
        // With ViewBinding
        CalendarDayLayoutBinding binding = CalendarDayLayoutBinding.bind(view);
        textView = binding.calendarDayText;


        textView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                if (day.getPosition() == DayPosition.MonthDate) {
                    currentSelection = selectedDate;
                    Log.d(TAG, "onClick: Clicked inDate");
                    // If user selects same date, clear eventContainer
                    if (currentSelection != null && currentSelection.equals(day.getDate())) {
                        selectedDate = null;
                        textView.post(() -> calendarView.notifyDateChanged(currentSelection));
                        Log.d(TAG, "onClick: Clicked the same date that was selected");
                    } else {

                        selectedDate = day.getDate();

                        if (currentSelection != null){
                            textView.post(() -> calendarView.notifyDateChanged(currentSelection));
                            Log.d(TAG, "onClick: Updating old date");
                        }
                        textView.post(() -> calendarView.notifyDateChanged(selectedDate));
                        Log.d(TAG, "onClick: Updating new date");
                    }
                }
            }
        });
    }
}

If I'm understanding correctly, each date has its own dayviewcontainer which has selectedDate. I believe storing it in my activity would probably resolve this issue but I am unsure how to do so.


Solution

  • In order to store something so that you can retrieve later, you can consider using SharedPreferences.

    First, you can have a simple SharedPreferencesUtil class as follow:

    public class SharedPreferencesUtil {
        // You can define a key here
        public static final String KEY_DATE = "KEY_DATE";
    
        public static boolean setLocalDate(Context context, String key, LocalDate value) {
            SharedPreferences sp = context.getPreferences(Context.MODE_PRIVATE);
            Editor editor = sp.edit();
            // You can convert your LocalDate to Long and store into SharedPreferences
            return editor.putLong(key, value.toEpochDay()).commit();
        }
    
        public static LocalDate getLocalDate(Context context, String key) {
            SharedPreferences sp = context.getPreferences(Context.MODE_PRIVATE);
            Long numberOfDays = sp.getLong(key, -1);
            if (numberOfDays == -1)
                return null;
            return LocalDate.ofEpochDay(numberOfDays);
        }
    }
    

    Then you can easily update and retrieve the value in your Activity like this:

    // Store the LocalDate for later retrieval
    SharedPreferencesUtil.setLocalDate(getActivity(), SharedPreferencesUtil.KEY_DATE, LocalDate that you want to store);
    
    // Retrieve the previous stored LocalDate
    LocalDate storedDate = SharedPreferencesUtil.getLocalDate(getActivity(), SharedPreferencesUtil.KEY_DATE);
    if (storedDate == null) {
        // You have not saved LocalDate yet
    } else {
        // You should be able to retrieve the previous stored LocalDate
    }