本文介绍: 二级分类双列表联动Demo

先上图:
在这里插入图片描述

Demo解释

demo使用的是双列表展示(准确的说是三个,二级分类那里嵌套了一个),点击左边的条目,右边的列表会跳转相应的条目,滑动右边的列表,左边的列表也会相应的滑动。

代码

主页面布局

这个很简单,就是两个RecyclerView

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/one"
        android:layout_weight="7"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/two"
        android:layout_weight="3"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</LinearLayout>

适配器

因为有三个列表RecyclerView,所以有三个适配器:
OneTypeAdapter

public class OneTypeAdapter extends RecyclerView.Adapter<OneTypeAdapter.OneTypeHolder> {
    private final Context context;
    private final List<String> list;
    public int selectedPosition = 0;//当前选择的下标
    private OnItemClickListener onItemClickListener;

    public OneTypeAdapter(Context context, List<String> list) {
        this.context = context;
        this.list = list;
    }

    @NonNull
    @Override
    public OneTypeHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view= LayoutInflater.from(context).inflate(R.layout.item_main_left,parent,false);
        return new OneTypeHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull OneTypeHolder holder, @SuppressLint("RecyclerView") int position) {

        holder.type.setText(list.get(position));
        holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (onItemClickListener!=null){
                    onItemClickListener.onItemClickListener(v,position);
                }
            }
        });
        if (position==selectedPosition){
            holder.itemView.setBackgroundColor(context.getColor(R.color.white));
            holder.type.setTextColor(context.getColor(R.color.colorAccent));
            holder.type.setTextSize(32);
        }
        else {
            holder.itemView.setBackgroundColor(context.getColor(R.color.flow));
            holder.type.setTextColor(context.getColor(R.color.black));
            holder.type.setTextSize(24);
        }
    }

    @Override
    public int getItemCount() {
        return list.size();
    }

    public static class OneTypeHolder extends RecyclerView.ViewHolder{
        TextView type;
        public OneTypeHolder(@NonNull View itemView) {
            super(itemView);
            type = itemView.findViewById(R.id.type);
        }
    }

    public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
        this.onItemClickListener = onItemClickListener;
    }

    public interface OnItemClickListener {
        void onItemClickListener(View v, int position);
    }
}

TwoTypeAdapter

public class TwoTypeAdapter extends RecyclerView.Adapter<TwoTypeAdapter.TwoTypeHolder> {
    private Context context;
    private List<String> name;
    private List<String> detail;

    public TwoTypeAdapter(Context context, List<String> name, List<String> detail) {
        this.context = context;
        this.name = name;
        this.detail = detail;
    }

    @NonNull
    @Override
    public TwoTypeHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view= LayoutInflater.from(context).inflate(R.layout.item_main_right,parent,false);
        return new TwoTypeHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull TwoTypeHolder holder, int position) {
        holder.type.setText(name.get(position));
        holder.more.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Toast.makeText(context, "更多", Toast.LENGTH_SHORT).show();
            }
        });
        holder.recyclerView.setAdapter(new DetailAdapter(context, detail));
        holder.recyclerView.setLayoutManager(new GridLayoutManager(context,3));
    }

    @Override
    public int getItemCount() {
        return name.size();
    }

    public static class TwoTypeHolder extends RecyclerView.ViewHolder{
        TextView type,more;
        RecyclerView recyclerView;
        public TwoTypeHolder(@NonNull View itemView) {
            super(itemView);
            type = itemView.findViewById(R.id.type);
            more = itemView.findViewById(R.id.more);
            recyclerView = itemView.findViewById(R.id.right_recycle);
        }
    }
}

DetailAdapter

public class DetailAdapter extends RecyclerView.Adapter<DetailAdapter.ThreeTYpeHolder> {
    private final Context context;
    private final List<String> list;

    public DetailAdapter(Context context, List<String> list) {
        this.context = context;
        this.list = list;
    }

    @NonNull
    @Override
    public ThreeTYpeHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view= LayoutInflater.from(context).inflate(R.layout.item_main_details,parent,false);
        return new ThreeTYpeHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull ThreeTYpeHolder holder, int position) {
        holder.type.setText(list.get(position));
        holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Toast.makeText(context, list.get(position), Toast.LENGTH_SHORT).show();
            }
        });
    }

    @Override
    public int getItemCount() {
        return list.size();
    }

    public static class ThreeTYpeHolder extends RecyclerView.ViewHolder{
        TextView type;
        ImageView icon;
        public ThreeTYpeHolder(@NonNull View itemView) {
            super(itemView);
            type = itemView.findViewById(R.id.type);
            icon = itemView.findViewById(R.id.icon);
        }
    }
}

条目布局

item_main_left

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/item_main_left_layout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center"
    android:orientation="horizontal"
    android:padding="5dp">
    <TextView
        android:id="@+id/type"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="18sp"
        android:layout_marginVertical="15dp" />
</LinearLayout>

item_main_right

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="#fff"
    android:padding="10dp">

    <TextView
        android:id="@+id/type"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="#333"
        android:textSize="18sp" />
    <TextView
        android:id="@+id/more"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="查看更多 >"
        android:layout_alignParentEnd="true"
        android:textColor="#999"
        android:textSize="14sp" />

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/right_recycle"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/type"/>

</RelativeLayout>

item_main_details

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="#ffffff"
    android:gravity="center"
    android:orientation="vertical">

    <ImageView
        android:id="@+id/icon"
        android:layout_width="70dp"
        android:layout_height="70dp" />

    <TextView
        android:id="@+id/type"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="5dp" />
</LinearLayout>

主页面代码

左边条目点击事件回调

oneTypeAdapter.setOnItemClickListener(new OneTypeAdapter.OnItemClickListener() {
            @Override
            public void onItemClickListener(View v, int position) {
                LinearLayoutManager twoRecyclerLayoutManager = ((LinearLayoutManager) twoRecycler.getLayoutManager());
                if (twoRecyclerLayoutManager!=null){
                    /**
                     这里有个问题,可能因为字号等问题,左边最后n个条目可能出现点击了但是颜色没渲染上的问题,不知道啥原因
                     然后我就是最后n个点击事件手动处理,比如我这就是最后3个点击有问题
                     */
                    if (position>= oneList.size()-3){
                        oneTypeAdapter.selectedPosition=position;
                        oneTypeAdapter.notifyDataSetChanged();
                        twoRecyclerLayoutManager.scrollToPositionWithOffset(position,0);
                    }
                    else {
                        twoRecyclerLayoutManager.scrollToPositionWithOffset(position,0);
                    }
                }
            }
        });

右边列表滑动监听

twoRecycler.setOnScrollChangeListener(new View.OnScrollChangeListener() {
            @Override
            public void onScrollChange(View v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
                LinearLayoutManager twoRecyclerLayoutManager = (LinearLayoutManager) twoRecycler.getLayoutManager();
                LinearLayoutManager oneRecyclerLayoutManager = ((LinearLayoutManager) oneRecycler.getLayoutManager());

                if (twoRecyclerLayoutManager!=null&&oneRecyclerLayoutManager!=null){
                    /**
                     获取第一个可见的item的position
                     */
                    currentPosition = twoRecyclerLayoutManager.findFirstVisibleItemPosition();
                    Log.e("TAG", "onScrollChange: "+currentPosition );
                    /**
                     这地方需要进行判断,如果右边的Recycle在移动的时候,左边的RecyclerView也是需要进行移动的
                     左边的recyclerview有可能会不可见,这时候,我们必须去判断一下,左边最后的一个item是不是
                     小于右边滑动的位置,或左边第一个item是不是大于右边滑动的位置
                     */
                    if (oneRecyclerLayoutManager.findFirstVisibleItemPosition() > currentPosition) {
                        oneRecyclerLayoutManager.scrollToPositionWithOffset(currentPosition, 0);
                    } else if (oneRecyclerLayoutManager.findFirstVisibleItemPosition() < currentPosition) {
                        oneRecyclerLayoutManager.scrollToPositionWithOffset(currentPosition, 0);
                    }

                    /**
                     判断右边是否滑动到最后一个item,是的话,也将左边移动到最后一个item
                     canScrollVertically(1)表示是否能向上滚动,false表示已经滚动到底部
                     */
                    if (!twoRecycler.canScrollVertically(1)) {
                        currentPosition = oneList.size() - 1;
                    }
                    oneTypeAdapter.selectedPosition=currentPosition;
                    oneTypeAdapter.notifyDataSetChanged();
                }
            }
        });

完整代码

public class MainActivity extends AppCompatActivity {
    private RecyclerView oneRecycler;
    private RecyclerView twoRecycler;

    private OneTypeAdapter oneTypeAdapter;
    private TwoTypeAdapter twoTypeAdapter;
    private List<String> oneList = new ArrayList<>();

    private List<String> twoList = new ArrayList<>();
    private int currentPosition = 0;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        initData();

        oneRecycler = findViewById(R.id.one);
        twoRecycler = findViewById(R.id.two);
        oneRecycler.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
        twoRecycler.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));

        oneTypeAdapter=new OneTypeAdapter(this, oneList);
        twoTypeAdapter=new TwoTypeAdapter(this, oneList,twoList);

        oneRecycler.setAdapter(oneTypeAdapter);
        twoRecycler.setAdapter(twoTypeAdapter);

        oneTypeAdapter.setOnItemClickListener(new OneTypeAdapter.OnItemClickListener() {
            @Override
            public void onItemClickListener(View v, int position) {
                LinearLayoutManager twoRecyclerLayoutManager = ((LinearLayoutManager) twoRecycler.getLayoutManager());
                if (twoRecyclerLayoutManager!=null){
                    /**
                     这里有个问题,可能因为字号等问题,左边最后n个条目可能出现点击了但是颜色没渲染上的问题,不知道啥原因
                     然后我就是最后n个点击事件手动处理,比如我这就是最后3个点击有问题
                     */
                    if (position>= oneList.size()-3){
                        oneTypeAdapter.selectedPosition=position;
                        oneTypeAdapter.notifyDataSetChanged();
                        twoRecyclerLayoutManager.scrollToPositionWithOffset(position,0);
                    }
                    else {
                        twoRecyclerLayoutManager.scrollToPositionWithOffset(position,0);
                    }
                }
            }
        });


        twoRecycler.setOnScrollChangeListener(new View.OnScrollChangeListener() {
            @Override
            public void onScrollChange(View v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
                LinearLayoutManager twoRecyclerLayoutManager = (LinearLayoutManager) twoRecycler.getLayoutManager();
                LinearLayoutManager oneRecyclerLayoutManager = ((LinearLayoutManager) oneRecycler.getLayoutManager());

                if (twoRecyclerLayoutManager!=null&&oneRecyclerLayoutManager!=null){
                    /**
                     获取第一个可见的item的position
                     */
                    currentPosition = twoRecyclerLayoutManager.findFirstVisibleItemPosition();
                    Log.e("TAG", "onScrollChange: "+currentPosition );
                    /**
                     这地方需要进行判断,如果右边的Recycle在移动的时候,左边的RecyclerView也是需要进行移动的
                     左边的recyclerview有可能会不可见,这时候,我们必须去判断一下,左边最后的一个item是不是
                     小于右边滑动的位置,或左边第一个item是不是大于右边滑动的位置
                     */
                    if (oneRecyclerLayoutManager.findFirstVisibleItemPosition() > currentPosition) {
                        oneRecyclerLayoutManager.scrollToPositionWithOffset(currentPosition, 0);
                    } else if (oneRecyclerLayoutManager.findFirstVisibleItemPosition() < currentPosition) {
                        oneRecyclerLayoutManager.scrollToPositionWithOffset(currentPosition, 0);
                    }

                    /**
                     判断右边是否滑动到最后一个item,是的话,也将左边移动到最后一个item
                     canScrollVertically(1)表示是否能向上滚动,false表示已经滚动到底部
                     */
                    if (!twoRecycler.canScrollVertically(1)) {
                        currentPosition = oneList.size() - 1;
                    }
                    oneTypeAdapter.selectedPosition=currentPosition;
                    oneTypeAdapter.notifyDataSetChanged();
                }
            }
        });
    }

    private void initData() {
        for (int i = 0; i < 20; i++) {
            oneList.add("一级类型"+i);
        }
        for (int i=0;i<10;i++){
            twoList.add("二级类型"+i);
        }
    }
}

源码地址:
github:Categorydemo
gitee:Categorydemo

原文地址:https://blog.csdn.net/butterfly_new/article/details/135945931

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。

如若转载,请注明出处:http://www.7code.cn/show_64145.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除!

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注