如何实现RecyclerView嵌套及点击项跳转至带指定数据的RecyclerView(Java)
问题1:RecyclerView嵌套及选中行数据获取方案
嘿,这个需求其实挺常见的,咱们一步步来实现:
1. 准备布局文件
首先,外层RecyclerView的每个item布局(比如item_outer.xml)里要嵌套内层RecyclerView:
<!-- item_outer.xml --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:padding="16dp"> <TextView android:id="@+id/tv_outer_title" android:layout_width="match_parent" android:layout_height="wrap_content" android:textSize="18sp" android:textStyle="bold"/> <androidx.recyclerview.widget.RecyclerView android:id="@+id/inner_recycler" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="8dp"/> </LinearLayout>
2. 编写内层RecyclerView的Adapter(带点击回调)
内层Adapter需要定义点击接口,把选中的数据传递出去:
public class InnerAdapter extends RecyclerView.Adapter<InnerAdapter.InnerViewHolder> { private List<String> innerDataList; private OnInnerItemClickListener listener; // 定义点击回调接口 public interface OnInnerItemClickListener { void onInnerItemClick(String data); } public InnerAdapter(List<String> innerDataList, OnInnerItemClickListener listener) { this.innerDataList = innerDataList; this.listener = listener; } @NonNull @Override public InnerViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_inner, parent, false); return new InnerViewHolder(view); } @Override public void onBindViewHolder(@NonNull InnerViewHolder holder, int position) { String data = innerDataList.get(position); holder.tvInnerText.setText(data); // 设置点击事件 holder.itemView.setOnClickListener(v -> { if (listener != null) { listener.onInnerItemClick(data); } }); } @Override public int getItemCount() { return innerDataList.size(); } static class InnerViewHolder extends RecyclerView.ViewHolder { TextView tvInnerText; public InnerViewHolder(@NonNull View itemView) { super(itemView); tvInnerText = itemView.findViewById(R.id.tv_inner_text); } } }
3. 编写外层RecyclerView的Adapter
外层Adapter需要初始化内层RecyclerView,并处理内层的点击回调,再传递给上层组件:
public class OuterAdapter extends RecyclerView.Adapter<OuterAdapter.OuterViewHolder> { private List<OuterItem> outerDataList; private OnInnerItemClickListener innerClickListener; // 外层数据实体类,包含标题和内层数据列表 public static class OuterItem { public String title; public List<String> innerData; public OuterItem(String title, List<String> innerData) { this.title = title; this.innerData = innerData; } } // 对外暴露内层点击的回调 public interface OnInnerItemClickListener { void onInnerItemClick(String data); } public OuterAdapter(List<OuterItem> outerDataList, OnInnerItemClickListener innerClickListener) { this.outerDataList = outerDataList; this.innerClickListener = innerClickListener; } @NonNull @Override public OuterViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_outer, parent, false); return new OuterViewHolder(view); } @Override public void onBindViewHolder(@NonNull OuterViewHolder holder, int position) { OuterItem item = outerDataList.get(position); holder.tvOuterTitle.setText(item.title); // 初始化内层RecyclerView InnerAdapter innerAdapter = new InnerAdapter(item.innerData, innerClickListener); holder.innerRecycler.setLayoutManager(new LinearLayoutManager(holder.itemView.getContext())); holder.innerRecycler.setAdapter(innerAdapter); } @Override public int getItemCount() { return outerDataList.size(); } static class OuterViewHolder extends RecyclerView.ViewHolder { TextView tvOuterTitle; RecyclerView innerRecycler; public OuterViewHolder(@NonNull View itemView) { super(itemView); tvOuterTitle = itemView.findViewById(R.id.tv_outer_title); innerRecycler = itemView.findViewById(R.id.inner_recycler); } } }
4. 在Activity/Fragment中使用并获取选中数据
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); RecyclerView outerRecycler = findViewById(R.id.outer_recycler); outerRecycler.setLayoutManager(new LinearLayoutManager(this)); // 构造测试数据 List<OuterAdapter.OuterItem> outerData = new ArrayList<>(); outerData.add(new OuterAdapter.OuterItem("分组1", Arrays.asList("子项1-1", "子项1-2", "子项1-3"))); outerData.add(new OuterAdapter.OuterItem("分组2", Arrays.asList("子项2-1", "子项2-2"))); // 设置外层Adapter,监听内层点击事件 OuterAdapter outerAdapter = new OuterAdapter(outerData, data -> { // 这里就是你拿到的内层选中行的数据,可以做后续处理 Toast.makeText(MainActivity.this, "选中了:" + data, Toast.LENGTH_SHORT).show(); }); outerRecycler.setAdapter(outerAdapter); } }
问题2:点击RecyclerView项跳转并加载对应数据的实现
这个需求也很清晰,咱们按以下步骤来:
1. 准备两个页面及布局
- 主页面(
MainActivity)布局包含第一个RecyclerView; - 详情页面(
DetailActivity)布局包含第二个RecyclerView。
2. 第一个RecyclerView的Adapter(带点击回调)
public class MainAdapter extends RecyclerView.Adapter<MainAdapter.MainViewHolder> { private List<MainItem> mainDataList; private OnItemClickListener listener; // 主页面数据实体,包含标题和对应详情页的数据集 public static class MainItem { public String title; public List<String> detailData; public MainItem(String title, List<String> detailData) { this.title = title; this.detailData = detailData; } } public interface OnItemClickListener { void onItemClick(MainItem item); } public MainAdapter(List<MainItem> mainDataList, OnItemClickListener listener) { this.mainDataList = mainDataList; this.listener = listener; } @NonNull @Override public MainViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_main, parent, false); return new MainViewHolder(view); } @Override public void onBindViewHolder(@NonNull MainViewHolder holder, int position) { MainItem item = mainDataList.get(position); holder.tvTitle.setText(item.title); // 设置item点击事件 holder.itemView.setOnClickListener(v -> { if (listener != null) { listener.onItemClick(item); } }); } @Override public int getItemCount() { return mainDataList.size(); } static class MainViewHolder extends RecyclerView.ViewHolder { TextView tvTitle; public MainViewHolder(@NonNull View itemView) { super(itemView); tvTitle = itemView.findViewById(R.id.tv_main_title); } } }
3. 主页面处理点击跳转,传递数据
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); RecyclerView mainRecycler = findViewById(R.id.main_recycler); mainRecycler.setLayoutManager(new LinearLayoutManager(this)); // 构造预设数据,每个主项对应一组详情数据 List<MainAdapter.MainItem> mainData = new ArrayList<>(); mainData.add(new MainAdapter.MainItem("商品分类1", Arrays.asList("商品A", "商品B", "商品C"))); mainData.add(new MainAdapter.MainItem("商品分类2", Arrays.asList("商品D", "商品E"))); MainAdapter adapter = new MainAdapter(mainData, item -> { // 跳转到详情页面,传递选中项的详情数据 Intent intent = new Intent(MainActivity.this, DetailActivity.class); // 这里把数据序列化传递,自定义实体类建议实现Parcelable效率更高 intent.putExtra("DETAIL_DATA", (Serializable) item.detailData); startActivity(intent); }); mainRecycler.setAdapter(adapter); } }
4. 详情页面接收数据并加载RecyclerView
public class DetailActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_detail); RecyclerView detailRecycler = findViewById(R.id.detail_recycler); detailRecycler.setLayoutManager(new LinearLayoutManager(this)); // 接收传递过来的数据 List<String> detailData = (List<String>) getIntent().getSerializableExtra("DETAIL_DATA"); // 设置详情页的Adapter,加载对应数据 DetailAdapter detailAdapter = new DetailAdapter(detailData); detailRecycler.setAdapter(detailAdapter); } // 详情页的RecyclerView Adapter static class DetailAdapter extends RecyclerView.Adapter<DetailAdapter.DetailViewHolder> { private List<String> detailDataList; public DetailAdapter(List<String> detailDataList) { this.detailDataList = detailDataList; } @NonNull @Override public DetailViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_detail, parent, false); return new DetailViewHolder(view); } @Override public void onBindViewHolder(@NonNull DetailViewHolder holder, int position) { holder.tvDetail.setText(detailDataList.get(position)); } @Override public int getItemCount() { return detailDataList.size(); } static class DetailViewHolder extends RecyclerView.ViewHolder { TextView tvDetail; public DetailViewHolder(@NonNull View itemView) { super(itemView); tvDetail = itemView.findViewById(R.id.tv_detail_text); } } } }
内容的提问来源于stack exchange,提问作者MossXD
相关产品推荐
相关产品推荐

