You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何实现含三个RecyclerView的联动日历并填充年月数据?

实现三联动日历RecyclerView:数据填充与交互指南

Hey there! 我来一步步帮你搞定这三个RecyclerView的数据源设置和联动逻辑,其实核心就是固定年份/月份列表 + 动态生成日期列表,再配合选中事件的刷新就行。


一、先搞定基础数据源

1. 年份列表

你可以自定义年份范围,比如最近15年或者用户需要的区间,直接用循环生成就行:

// Java 示例:生成2010-2025的年份列表
List<Integer> yearList = new ArrayList<>();
for (int year = 2010; year <= 2025; year++) {
    yearList.add(year);
}
// Kotlin 示例
val yearList = (2010..2025).toList()

把这个列表传给年份RecyclerView的Adapter就OK了。

2. 月份列表

月份可以是数字(1-12)或者带文字的("1月"到"12月"),按需选择:

// Java:中文月份列表
List<String> monthList = Arrays.asList("1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月");
// 或者数字月份
List<Integer> monthNumList = IntStream.rangeClosed(1, 12).boxed().collect(Collectors.toList());
// Kotlin:中文月份列表
val monthList = listOf("1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月")
// 数字月份
val monthNumList = (1..12).toList()

同样把这个列表绑定给月份RecyclerView的Adapter。

3. 日期列表(联动核心)

日期是依赖选中的年份和月份的,不能提前固定,得动态计算当月的天数来生成列表。推荐用Java 8+的LocalDate(或者AndroidX的ThreeTenABP兼容低版本),比传统Calendar好用太多:

动态生成日期的工具方法

// Java:传入选中的年、月,返回当月的日期列表(1到当月天数)
public List<Integer> generateDayList(int selectedYear, int selectedMonth) {
    List<Integer> dayList = new ArrayList<>();
    // LocalDate的月份是1-based,和我们的数字月份对应
    LocalDate monthStart = LocalDate.of(selectedYear, selectedMonth, 1);
    int totalDays = monthStart.lengthOfMonth();
    for (int day = 1; day <= totalDays; day++) {
        dayList.add(day);
    }
    return dayList;
}
// Kotlin 版本
fun generateDayList(selectedYear: Int, selectedMonth: Int): List<Int> {
    val monthStart = LocalDate.of(selectedYear, selectedMonth, 1)
    val totalDays = monthStart.lengthOfMonth()
    return (1..totalDays).toList()
}

二、实现联动逻辑

现在要让年份/月份的选中事件触发日期列表的刷新,核心就是监听RecyclerView的item点击,更新选中的年月,然后重新生成日期列表并刷新日期RecyclerView。

1. 年份RecyclerView的点击监听

在年份Adapter的onBindViewHolder里给item设置点击事件:

// Java 示例
yearViewHolder.itemView.setOnClickListener(v -> {
    // 获取选中的年份
    int currentSelectedYear = yearList.get(position);
    // 保存全局选中年份(比如在Activity/Fragment里定义变量)
    mSelectedYear = currentSelectedYear;
    // 重新生成日期列表,用当前选中的月份(默认可以设为1,或者之前选中的月份)
    List<Integer> newDayList = generateDayList(mSelectedYear, mSelectedMonth);
    // 刷新日期Adapter
    mDayAdapter.submitList(newDayList); // 如果用ListAdapter的话用submitList,否则用notifyDataSetChanged
});

2. 月份RecyclerView的点击监听

和年份逻辑类似,注意如果用的是中文月份,要先转成数字:

// Java 示例:如果是中文月份列表
monthViewHolder.itemView.setOnClickListener(v -> {
    String monthStr = monthList.get(position);
    // 把"1月"转成数字1
    int currentSelectedMonth = Integer.parseInt(monthStr.replace("月", ""));
    mSelectedMonth = currentSelectedMonth;
    // 生成新日期列表
    List<Integer> newDayList = generateDayList(mSelectedYear, mSelectedMonth);
    mDayAdapter.submitList(newDayList);
});

三、初始化与细节优化

  • 初始状态:打开页面时默认选中当前年月,生成对应的日期列表:
// Java 初始化示例
LocalDate now = LocalDate.now();
mSelectedYear = now.getYear();
mSelectedMonth = now.getMonthValue();
List<Integer> initialDayList = generateDayList(mSelectedYear, mSelectedMonth);
mDayAdapter.submitList(initialDayList);
  • 选中高亮:记得在每个Adapter里维护选中位置的变量,在onBindViewHolder里更新item的UI(比如改变背景色、文字颜色),让用户知道当前选中的是哪一项。
  • 性能优化:用ListAdapter配合DiffUtil来刷新日期列表,比直接调用notifyDataSetChanged更高效,避免不必要的视图重绘。

这样一套下来,三个RecyclerView的数据源填充和联动就完全搞定啦~

内容的提问来源于stack exchange,提问作者DevMobApp

火山引擎 最新活动