Android RecyclerView 嵌套 RecyclerView 的滑动冲突解决方案

在 Android 开发中,嵌套的 RecyclerView 会导致滑动冲突。这个问题常在一个 RecyclerView 嵌套另一个 RecyclerView 的情况下出现,比如在显示分类信息时。为了让我们的小白开发者能够顺利解决这个问题,以下将详细介绍流程和代码实现。

流程概述

步骤 描述
1 创建外层 RecyclerView。
2 创建内层 RecyclerView 的适配器。
3 设置 RecyclerView 的布局管理器。
4 处理触摸事件,解决滑动冲突。
5 测试与验证。

步骤详解

步骤 1:创建外层 RecyclerView

首先,我们需要在布局文件中添加外部 RecyclerView。

<androidx.recyclerview.widget.RecyclerView
    android:id="@+id/outer_recycler_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

在 Activity 中初始化外部 RecyclerView。

RecyclerView outerRecyclerView = findViewById(R.id.outer_recycler_view);
outerRecyclerView.setLayoutManager(new LinearLayoutManager(this)); // 设置垂直布局
outerRecyclerView.setAdapter(new OuterAdapter(dataList)); // 设置适配器

步骤 2:创建内层 RecyclerView 的适配器

为内层 RecyclerView 创建适配器。

public class InnerAdapter extends RecyclerView.Adapter<InnerAdapter.InnerViewHolder> {
    private List<String> innerDataList;

    public InnerAdapter(List<String> innerDataList) {
        this.innerDataList = innerDataList;
    }

    @Override
    public InnerViewHolder onCreateViewHolder(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(InnerViewHolder holder, int position) {
        holder.textView.setText(innerDataList.get(position)); // 绑定数据
    }

    @Override
    public int getItemCount() {
        return innerDataList.size(); // 返回项数
    }

    static class InnerViewHolder extends RecyclerView.ViewHolder {
        TextView textView;

        public InnerViewHolder(View itemView) {
            super(itemView);
            textView = itemView.findViewById(R.id.text_view);
        }
    }
}

步骤 3:设置 RecyclerView 的布局管理器

在外层适配器中添加内层 RecyclerView,并设置布局管理器。

public class OuterAdapter extends RecyclerView.Adapter<OuterAdapter.OuterViewHolder> {
    private List<List<String>> outerDataList;

    public OuterAdapter(List<List<String>> outerDataList) {
        this.outerDataList = outerDataList;
    }

    @Override
    public OuterViewHolder onCreateViewHolder(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(OuterViewHolder holder, int position) {
        holder.innerRecyclerView.setLayoutManager(new LinearLayoutManager(holder.itemView.getContext())); // 嵌套的布局管理器
        holder.innerRecyclerView.setAdapter(new InnerAdapter(outerDataList.get(position))); // 绑定内层适配器
    }

    @Override
    public int getItemCount() {
        return outerDataList.size(); // 计算外部项数
    }

    static class OuterViewHolder extends RecyclerView.ViewHolder {
        RecyclerView innerRecyclerView;

        public OuterViewHolder(View itemView) {
            super(itemView);
            innerRecyclerView = itemView.findViewById(R.id.inner_recycler_view); // 初始化内层 RecyclerView
        }
    }
}

步骤 4:处理触摸事件解决滑动冲突

为了处理滑动冲突,我们可以自定义内层 RecyclerView 的滑动逻辑:

innerRecyclerView.addOnItemTouchListener(new RecyclerView.OnItemTouchListener() {
    @Override
    public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
        if (e.getAction() == MotionEvent.ACTION_MOVE) {
            rv.getParent().requestDisallowInterceptTouchEvent(true); // 禁止父视图的触摸事件
        }
        return false;
    }

    @Override
    public void onTouchEvent(RecyclerView rv, MotionEvent e) {}

    @Override
    public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {}
});

步骤 5:测试与验证

最后,运行应用,验证是否能在滑动外部 RecyclerView 时,内层 RecyclerView 也能正常滑动,而无滑动冲突。

结尾

以上就是解决 Android 中嵌套 RecyclerView 滑动冲突的方法。通过设置合适的布局管理器、创建适配器及处理触摸事件,我们能够顺利实现目标。希望这篇文章对你有所帮助,祝你在开发过程中不断成长,掌握更多的技能!