android中实现双列表联动功能

时间:2024-07-17 10:15:20

就是一个数据展示的功能,左边是目录、右边是详情列表。效果图如下:

实现的思路,就是左右一个列表,右边的列表里面嵌套一个列表,一共三个列表。

第一步:先写一个主页面布局文件

<?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"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".Activity.PageEffect.recycleview.doubleList.DoubleListActivity">
    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/rv_left"
        android:layout_width="100dp"
        android:layout_height="wrap_content"/>
    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/rv_right"
        android:layout_toRightOf="@+id/rv_left"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</RelativeLayout>

第二步:写一个左边适配器

public class LeftAdapter extends RecyclerView.Adapter<LeftAdapter.LeftHolder>{
    Context context;
    List<LeftBean> list;
    OnItemClickListener onItemClickListener;
    public LeftAdapter(Context context, List<LeftBean> list){
        this.context=context;
        this.list=list;
    }
    @NonNull
    @Override
    public LeftHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view= LayoutInflater.from(context).inflate(R.layout.item_recycleview_left,parent,false);
        return new LeftHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull LeftHolder holder, @SuppressLint("RecyclerView") int position) {
        holder.typeTv.setText(list.get(position).getType());
        holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (onItemClickListener!=null){
                    onItemClickListener.onItemClick(v,position);
                }
            }
        });
        if (list.get(position).isSelected()){
            holder.leftRl.setBackgroundColor(Color.parseColor("#0000ff"));
            holder.typeTv.setTextColor(Color.parseColor("#00ff00"));
        }else {
            holder.leftRl.setBackgroundColor(Color.parseColor("#00ff00"));
            holder.typeTv.setTextColor(Color.parseColor("#666666"));
        }
    }

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

    public static class LeftHolder extends RecyclerView.ViewHolder {
        RelativeLayout leftRl;
        TextView typeTv;
        public LeftHolder(@NonNull View itemView) {
            super(itemView);
            leftRl=itemView.findViewById(R.id.rl_left);
            typeTv=itemView.findViewById(R.id.tv_type);
        }
    }

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

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

    public void setList(List<LeftBean> list) {
        this.list = list;
    }
}

第三步,写左边列表的布局文件

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/rl_left"
    android:layout_width="100dp"
    android:layout_height="60dp">
    <TextView
        android:id="@+id/tv_type"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:textSize="30sp"
        android:gravity="center"/>
</RelativeLayout>

第四步,写右边列表适配器

public class RightAdapter extends RecyclerView.Adapter<RightAdapter.RightHolder>{
    private Context context;
    private List<RightBean> list;

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

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

    @Override
    public void onBindViewHolder(@NonNull RightHolder holder, int position) {
        holder.typeTv.setText(list.get(position).getType());
        holder.recyclerView.setLayoutManager(new GridLayoutManager(context,2));
        holder.recyclerView.setAdapter(new RightDetailAdapter(context,list.get(position).getDetailList()));
    }

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

    public static class RightHolder extends RecyclerView.ViewHolder {
        TextView typeTv;
        RecyclerView recyclerView;
        public RightHolder(@NonNull View itemView) {
            super(itemView);
            typeTv=itemView.findViewById(R.id.tv_right_type);
            recyclerView=itemView.findViewById(R.id.rv_right_detail);
        }
    }

    public void setList(List<RightBean> list) {
        this.list = list;
    }
}

第五步:写右边列表的布局文件

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
    <TextView
        android:id="@+id/tv_right_type"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:textSize="30sp"
        android:textColor="@color/blue"
        android:gravity="center_vertical"
        android:textStyle="bold"/>
    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/rv_right_detail"
        android:layout_below="@+id/tv_right_type"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

</RelativeLayout>

第六步,写右边列表里面嵌套的详情列表适配器

public class RightDetailAdapter extends RecyclerView.Adapter<RightDetailAdapter.RightDetailHolder>{
    private Context context;
    private List<RightBean.Detail> list;
    public RightDetailAdapter(Context context,List<RightBean.Detail> list){
        this.context=context;
        this.list=list;
    }
    @NonNull
    @Override
    public RightDetailHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view= LayoutInflater.from(context).inflate(R.layout.item_recycleview_right_detail,parent,false);
        return new RightDetailHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull RightDetailHolder holder, int position) {
        holder.nameTv.setText(list.get(position).getName());
    }

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

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

    public void setList(List<RightBean.Detail> list) {
        this.list = list;
    }
}

第七步,写详情列表的布局文件

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="30dp">
    <ImageView
        android:id="@+id/iv_icon"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:src="@mipmap/ic_launcher"/>
    <TextView
        android:id="@+id/tv_name"
        android:layout_below="@id/iv_icon"
        android:layout_width="100dp"
        android:layout_height="50dp"
        android:gravity="center"
        android:textSize="24sp"
        android:textColor="@color/green"/>
</RelativeLayout>

第八步,在主Activity里面写具体的联动方法

public class DoubleListActivity extends AppCompatActivity {
    private RecyclerView leftRv;
    private LeftAdapter leftAdapter;
    private List<LeftBean> leftBeanList=new ArrayList<>();

    private RecyclerView rightRv;
    private RightAdapter rightAdapter;
    private List<RightBean> rightBeanList=new ArrayList<>();

    private int currentPosition = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_double_list);
        initView();
    }
    private void initView(){
        leftRv=findViewById(R.id.rv_left);
        leftBeanList.add(new LeftBean("名酒",false));
        leftBeanList.add(new LeftBean("名烟",false));
        leftBeanList.add(new LeftBean("饮料",false));
        leftBeanList.add(new LeftBean("手机",false));
        leftAdapter=new LeftAdapter(this,leftBeanList);
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
        leftRv.setLayoutManager(linearLayoutManager);
        leftRv.setAdapter(leftAdapter);

        rightRv=findViewById(R.id.rv_right);
        RightBean rightBean=new RightBean();
        rightBean.setType("名酒");
        List<RightBean.Detail> detailList=new ArrayList<>();
        detailList.add(new RightBean.Detail("茅台"));
        detailList.add(new RightBean.Detail("五粮液"));
        detailList.add(new RightBean.Detail("剑南春"));
        detailList.add(new RightBean.Detail("汾酒"));
        detailList.add(new RightBean.Detail("花雕"));
        detailList.add(new RightBean.Detail("红酒"));
        rightBean.setDetailList(detailList);
        rightBeanList.add(rightBean);
        RightBean rightBean2=new RightBean();
        rightBean2.setType("名烟");
        List<RightBean.Detail> detailList2=new ArrayList<>();
        detailList2.add(new RightBean.Detail("中华"));
        detailList2.add(new RightBean.Detail("玉溪"));
        detailList2.add(new RightBean.Detail("双喜"));
        detailList2.add(new RightBean.Detail("小苏"));
        detailList2.add(new RightBean.Detail("黄鹤楼"));
        rightBean2.setDetailList(detailList2);
        rightBeanList.add(rightBean2);
        RightBean rightBean3=new RightBean();
        rightBean3.setType("饮料");
        List<RightBean.Detail> detailList3=new ArrayList<>();
        detailList3.add(new RightBean.Detail("可乐"));
        detailList3.add(new RightBean.Detail("雪碧"));
        detailList3.add(new RightBean.Detail("冰红茶"));
        detailList3.add(new RightBean.Detail("绿茶"));
        detailList3.add(new RightBean.Detail("脉动"));
        detailList3.add(new RightBean.Detail("冰糖雪梨"));
        rightBean3.setDetailList(detailList3);
        rightBeanList.add(rightBean3);
        RightBean rightBean4=new RightBean();
        rightBean4.setType("手机");
        List<RightBean.Detail> detailList4=new ArrayList<>();
        detailList4.add(new RightBean.Detail("华为"));
        detailList4.add(new RightBean.Detail("魅族"));
        detailList4.add(new RightBean.Detail("小米"));
        detailList4.add(new RightBean.Detail("红米"));
        detailList4.add(new RightBean.Detail("三星"));
        detailList4.add(new RightBean.Detail("长虹"));
        rightBean4.setDetailList(detailList4);
        rightBeanList.add(rightBean4);
        rightAdapter=new RightAdapter(this,rightBeanList);
        LinearLayoutManager linearLayoutManager_right = new LinearLayoutManager(this);
        rightRv.setLayoutManager(linearLayoutManager_right);
        rightRv.setAdapter(rightAdapter);

        leftAdapter.setOnItemClickListener(new LeftAdapter.OnItemClickListener() {
            @Override
            public void onItemClick(View v, int position) {
                for(int i=0;i<leftBeanList.size();i++){
                    if (i==position){
                        leftBeanList.get(i).setSelected(true);
                    }else {
                        leftBeanList.get(i).setSelected(false);
                    }
                }
                leftAdapter.setList(leftBeanList);
                leftAdapter.notifyDataSetChanged();
                LinearLayoutManager linearLayoutManager_right= (LinearLayoutManager)rightRv.getLayoutManager();
                if (linearLayoutManager_right!=null){
                    linearLayoutManager_right.scrollToPositionWithOffset(position,0);
                }
            }
        });
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            rightRv.setOnScrollChangeListener(new View.OnScrollChangeListener() {
                @Override
                public void onScrollChange(View v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
                    LinearLayoutManager linearLayoutManager_right= (LinearLayoutManager) rightRv.getLayoutManager();
                    LinearLayoutManager linearLayoutManager_left= (LinearLayoutManager) leftRv.getLayoutManager();
                    if (linearLayoutManager_right!=null&&linearLayoutManager_left!=null){
                        currentPosition=linearLayoutManager_right.findFirstVisibleItemPosition();
                        if (linearLayoutManager_left.findFirstVisibleItemPosition()>currentPosition){
                            linearLayoutManager_left.scrollToPositionWithOffset(currentPosition,0);
                        }else if (linearLayoutManager_left.findFirstVisibleItemPosition()<currentPosition){
                            linearLayoutManager_left.scrollToPositionWithOffset(currentPosition,0);
                        }
                        if (!rightRv.canScrollVertically(1)){
                            currentPosition=leftBeanList.size()-1;
                        }
                        for(int i=0;i<leftBeanList.size();i++){
                            if (i==currentPosition){
                                leftBeanList.get(i).setSelected(true);
                            }else {
                                leftBeanList.get(i).setSelected(false);
                            }
                        }
                        leftAdapter.setList(leftBeanList);
                        leftAdapter.notifyDataSetChanged();
                    }
                }
            });
        }
    }
}

另外两个ben类代码如下

public class LeftBean {
    private String type;
    private boolean selected;

    public LeftBean(String type, boolean selected) {
        this.type = type;
        this.selected = selected;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public boolean isSelected() {
        return selected;
    }

    public void setSelected(boolean selected) {
        this.selected = selected;
    }

    @Override
    public String toString() {
        return "LeftBean{" +
                "type='" + type + '\'' +
                ", selected=" + selected +
                '}';
    }
}
public class RightBean {
    public String type;
    public List<Detail> detailList;

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public List<Detail> getDetailList() {
        return detailList;
    }

    public void setDetailList(List<Detail> detailList) {
        this.detailList = detailList;
    }

    @Override
    public String toString() {
        return "RightBean{" +
                "type='" + type + '\'' +
                ", detailList=" + detailList +
                '}';
    }

    public static class Detail{
        String name;

        public Detail(String name) {
            this.name = name;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        @Override
        public String toString() {
            return "Detail{" +
                    "name='" + name + '\'' +
                    '}';
        }
    }
}