CalendarView选中状态丢失:点击日期时currentSelection置空求助
解决方案:将选中状态移至Activity全局管理
问题核心是每个DayViewContainer实例都持有独立的选中状态变量,导致点击日期时状态无法共享,出现currentSelection被置为null的问题。通过将选中状态迁移到Activity作为全局变量,统一管理状态和点击逻辑即可解决。
步骤1:在Activity中声明全局选中日期变量
// 在你的Activity类中添加全局变量 private LocalDate selectedDate = null;
步骤2:修改DayViewContainer,移除局部状态并添加点击回调
移除容器内的selectedDate和currentSelection变量,通过回调将点击事件传递给Activity处理:
public class DayViewContainer extends ViewContainer { public TextView textView; public CalendarDay day; public CalendarView calendarView; private final OnDayClickListener listener; // 定义日期点击回调接口 public interface OnDayClickListener { void onDayClicked(CalendarDay day); } public DayViewContainer(View view, OnDayClickListener listener) { super(view); this.listener = listener; textView = view.findViewById(R.id.calendarDayText); CalendarDayLayoutBinding binding = CalendarDayLayoutBinding.bind(view); textView = binding.calendarDayText; // 点击事件转发给Activity处理 textView.setOnClickListener(v -> { if (day != null && day.getPosition() == DayPosition.MonthDate) { listener.onDayClicked(day); } }); } }
步骤3:修改Activity中的DayBinder逻辑
在create方法中传入回调处理点击,在bind方法中使用全局selectedDate判断日期选中状态:
calendarView.setDayBinder(new MonthDayBinder<DayViewContainer>() { @NonNull @Override public DayViewContainer create(@NonNull View view) { // 传入点击回调,统一在Activity中处理选中逻辑 return new DayViewContainer(view, day -> { LocalDate clickedDate = day.getDate(); if (selectedDate != null && selectedDate.equals(clickedDate)) { // 点击已选中日期,取消选中 LocalDate oldSelected = selectedDate; selectedDate = null; calendarView.notifyDateChanged(oldSelected); } else { // 选中新日期,刷新旧日期和新日期的UI LocalDate oldSelected = selectedDate; selectedDate = clickedDate; if (oldSelected != null) { calendarView.notifyDateChanged(oldSelected); } calendarView.notifyDateChanged(selectedDate); } }); } @RequiresApi(api = Build.VERSION_CODES.O) @Override public void bind(@NonNull DayViewContainer container, CalendarDay data) { container.day = data; container.calendarView = calendarView; TextView textView = container.textView; textView.setText(String.valueOf(data.getDate().getDayOfMonth())); if (data.getPosition() == DayPosition.MonthDate) { textView.setVisibility(View.VISIBLE); LocalDate date = data.getDate(); // 使用Activity全局的selectedDate判断选中状态 if (selectedDate != null && selectedDate.equals(date)) { textView.setTextColor(Color.WHITE); textView.setBackgroundColor(Color.rgb(98,0,238)); } else { textView.setTextColor(Color.BLACK); textView.setBackgroundColor(Color.TRANSPARENT); } } else { textView.setVisibility(View.INVISIBLE); } } });
关键说明
- 全局状态确保所有日期容器共享同一选中状态,避免了每个实例各自持有状态导致的不一致问题
- 点击逻辑统一在Activity中处理,简化了容器的职责,只负责UI绑定和事件转发
- 通过
notifyDateChanged方法精准刷新旧选中日期和新选中日期的UI,提升性能
内容的提问来源于stack exchange,提问作者Jeremy Vidaurri
相关产品推荐
相关产品推荐

