RecyclerView无法显示全部条目求助(附Adapter代码片段)
问题根源
你的RecyclerView只显示单个条目,核心原因是当前Adapter的数据源是ChildModal对象列表,而这个列表里只有1个ChildModal实例。每个ChildModal里的appsList虽然包含多个应用,但Adapter的getItemCount()返回的是ChildModal的数量(也就是1),所以RecyclerView只会创建1个条目,onBindViewHolder只执行一次(position=0),自然只显示keyset.get(0)对应的Telegram。
两种修复方案
方案1:把每个应用单独作为RecyclerView条目(推荐)
这种方式符合RecyclerView的设计逻辑,方便后续给单个应用加点击、长按等交互:
- 定义单个应用的实体类
public class AppUsage { private String packageName; private long usageTime; public AppUsage(String packageName, long usageTime) { this.packageName = packageName; this.usageTime = usageTime; } public String getPackageName() { return packageName; } public long getUsageTime() { return usageTime; } }
- 修改Adapter的数据源和泛型
把Adapter的数据源改成List<AppUsage>,调整泛型后重写核心方法:
public class ParentStatsAdapter extends RecyclerView.Adapter<ParentStatsViewHolder> { private List<AppUsage> appUsageList; public ParentStatsAdapter(List<AppUsage> appUsageList) { this.appUsageList = appUsageList; } @Override public int getItemCount() { return appUsageList != null ? appUsageList.size() : 0; } @Override public void onBindViewHolder(@NonNull ParentStatsViewHolder holder, int position) { AppUsage appUsage = appUsageList.get(position); holder.pkgName.setText(appUsage.getPackageName()); holder.usageTime.setText(DateUtils.formatElapsedTime(appUsage.getUsageTime() / 1000)); Log.d("Positionofsdsd", String.valueOf(position)); } // onCreateViewHolder方法保持原有实现即可 }
- 转换数据源并初始化Adapter
在设置RecyclerView的地方,把ChildModal中的应用数据转换成List<AppUsage>:
// 假设已获取到目标ChildModal对象 ChildModal childModal = ...; Map<String, Long> appsMap = childModal.getAppsList(); List<AppUsage> appUsageList = new ArrayList<>(); for (Map.Entry<String, Long> entry : appsMap.entrySet()) { appUsageList.add(new AppUsage(entry.getKey(), entry.getValue())); } // 绑定Adapter到RecyclerView ParentStatsAdapter adapter = new ParentStatsAdapter(appUsageList); recyclerView.setAdapter(adapter);
方案2:在单个RecyclerView条目中嵌套显示所有应用
如果不需要给单个应用加交互,只是想在一个条目中展示所有应用,可以用这种方式:
- 修改Item布局,添加应用容器
在原有item布局中新增一个垂直LinearLayout作为应用条目容器:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <!-- 保留原有视图 --> <LinearLayout android:id="@+id/apps_container" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"/> </LinearLayout>
- 更新ViewHolder,添加容器引用
public class ParentStatsViewHolder extends RecyclerView.ViewHolder { TextView pkgName; TextView usageTime; LinearLayout appsContainer; // 新增容器引用 public ParentStatsViewHolder(@NonNull View itemView) { super(itemView); pkgName = itemView.findViewById(R.id.pkg_name); usageTime = itemView.findViewById(R.id.usage_time); appsContainer = itemView.findViewById(R.id.apps_container); } }
- 在onBindViewHolder中动态加载应用条目
先清空容器,再遍历应用数据创建并添加视图:
@Override protected void onBindViewHolder(@NonNull ParentStatsViewHolder holder, int position, @NonNull ChildModal model) { Map<String, Long> mapFromFirebase = model.getAppsList(); holder.appsContainer.removeAllViews(); // 清空旧视图 // 遍历所有应用,动态生成条目 for (Map.Entry<String, Long> entry : mapFromFirebase.entrySet()) { View appItem = LayoutInflater.from(holder.itemView.getContext()) .inflate(R.layout.item_single_app, holder.appsContainer, false); TextView appNameTv = appItem.findViewById(R.id.tv_app_name); TextView appTimeTv = appItem.findViewById(R.id.tv_app_time); appNameTv.setText(entry.getKey()); appTimeTv.setText(DateUtils.formatElapsedTime(entry.getValue() / 1000)); holder.appsContainer.addView(appItem); } }
注意:需要提前创建item_single_app.xml布局,包含显示应用名称和使用时间的TextView。
重点检查
不管用哪种方案,一定要确认getItemCount()的返回值:
- 方案1中,返回
appUsageList.size(),RecyclerView会创建对应数量的条目; - 方案2中,返回原
ChildModal列表的大小(如果只有1个,就显示1个条目,但里面包含所有应用)。
内容的提问来源于stack exchange,提问作者Mr Learning
相关产品推荐
相关产品推荐

