通常我们在外卖或者商城app会看到竖排二级列表的界面,点击左边列表的分类菜单,右边列表则会显示对应分类下的列表内容,这篇博文将对该功能的实现归纳和整理。
首先看下效果图:
在第一个页面选择最多三个标签,将书局塞到数组里返回上一个页面,然后就可以按照需求完成一系列操作。
下面说下实现步骤:
1.首先分析界面,是两个等比宽的列表,推荐使用recyclerview,右上角用来记录选择的标签个数,点击即可把数据返回上一个页面,未选择则返回空数组。
activity_main.xml
<?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:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="40dp">
<TextView
android:id="@+id/main_tv"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:text="确定(0/3)"
android:textSize="16sp"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:paddingRight="10dp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="选择页面"
android:textSize="18sp"
android:layout_centerInParent="true"
/>
</RelativeLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<android.support.v7.widget.RecyclerView
android:id="@+id/main_recyclerviewAll"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" />
<View
android:layout_width="1dp"
android:layout_height="match_parent"
android:background="@color/colorPrimaryDark" />
<android.support.v7.widget.RecyclerView
android:id="@+id/main_recyclerviewDetail"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" />
</LinearLayout>
</LinearLayout>
2.绘制列表item布局,因为就是简单的一个文字,只放一个居中的TextView,由于RecyclerView默认没有分隔线,我们在下面再放条高度为1px的view
item_recyclerview.xml
<?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:orientation="vertical"
android:id="@+id/item_recyclerview_ll">
<TextView
android:id="@+id/item_recyclerview_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="textview"
android:layout_gravity="center_horizontal"
android:layout_marginTop="15dp"
/>
<View
android:layout_width="match_parent"
android:layout_height="1px"
android:background="#e3e3d3"
android:layout_marginTop="15dp"/>
</LinearLayout>
3.新建FirstActivity,界面放个跳转至选择界面MainActivity的Button和用于显示从选择界面返回的标签数组的TextView
activity_first.xml
<?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="match_parent"
android:orientation="vertical">
<Button
android:id="@+id/first_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="去选择界面" />
<TextView
android:id="@+id/first_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
4.在选择界面MainActivity中,首先初始化控件。
tv = findViewById(R.id.main_tv);
recyclerviewAll = findViewById(R.id.main_recyclerviewAll);
recyclerviewDetail = findViewById(R.id.main_recyclerviewDetail);
LinearLayoutManager layout = new LinearLayoutManager(this);
LinearLayoutManager layout1 = new LinearLayoutManager(this);
recyclerviewAll.setLayoutManager(layout);
recyclerviewDetail.setLayoutManager(layout1);
5.设置列表数据bean,isFirst为是否选中的状态boolean值
package com.fantasychong.doublechecklisttest;
import java.io.Serializable;
/*
*Crated by yedona on 2018/9/6
*/
public class ListBean implements Serializable {
private String name;
private boolean isSelect;
public ListBean(String name, boolean isSelect) {
this.name = name;
this.isSelect = isSelect;
}
public boolean isSelect() {
return isSelect;
}
public void setSelect(boolean select) {
isSelect = select;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
5.设置左列表(一级)的数据,因为第一个数据标签默认选中,所以我们设置isSelect为true。
/**
* 设置左列表数据
*/
private void initAllList() {
allList = new ArrayList<>();
AllListBean bean = new AllListBean("英雄联盟", true);
allList.add(bean);
AllListBean bean1 = new AllListBean("仙剑奇侠传", false);
allList.add(bean1);
AllListBean bean2 = new AllListBean("大航海时代", false);
allList.add(bean2);
AllListBean bean3 = new AllListBean("太阁立志传", false);
allList.add(bean3);
AllListBean bean4 = new AllListBean("战国无双", false);
allList.add(bean4);
AllListBean bean5 = new AllListBean("三国志", false);
allList.add(bean5);
AllListBean bean6 = new AllListBean("最终幻想", false);
allList.add(bean6);
AllListBean bean7 = new AllListBean("幻想传说", false);
allList.add(bean7);
}
6.设置左右列表的通用adapter,这里推荐继承BaseQuickApdater,精简易操作。
package com.fantasychong.doublechecklisttest;
import android.content.Context;
import android.graphics.Color;
import android.support.annotation.Nullable;
import android.widget.TabHost;
import com.chad.library.adapter.base.BaseQuickAdapter;
import com.chad.library.adapter.base.BaseViewHolder;
import java.util.List;
/*
*Crated by yedona on 2018/9/6
*/
public class ListAdapter extends BaseQuickAdapter<AllListBean, BaseViewHolder> {
private final Context context;
private final List<AllListBean> data;
public ListAdapter (Context context, @Nullable List<AllListBean> data) {
super(R.layout.item_recyclerview, data);
this.context= context;
this.data= data;
}
@Override
protected void convert(BaseViewHolder helper, AllListBean item) {
helper.setText(R.id.item_recyclerview_tv, item.getName())
.setBackgroundColor(R.id.item_recyclerview_ll, item.isSelect()? Color.WHITE: Color.GRAY);
}
}
在convert方法中设置是否选中后的背景颜色,选中设为白色white,反之设为灰色gray。
7.把数据塞到左recyclerView中,这样左列表可以呈现我们的塞进去的数据。
adapterAll = new ListAdapter (MainActivity.this, allList);
recyclerviewAll.setAdapter(adapterAll);
8.设置左列表的点击事件,当选中时标签会变为白色,并且上个选中标签会设置成未选中状态,即为灰色。注意这里要添加notifyDataSetChanged方法通知adapter刷新。
adapterAll.setOnItemClickListener(new BaseQuickAdapter.OnItemClickListener() {
@Override
public void onItemClick(BaseQuickAdapter adapter, View view, int position) {
if (perPosition != position) {
allList.get(perPosition).setSelect(false);
allList.get(position).setSelect(true);
adapterAll.notifyDataSetChanged();
perPosition = position;
}
}
});
9.这样就完成了左列表显示并选中未选中的功能实现,接下来我们配置右(二级)列表。
我们初衷是进入页面时,左列表直接显示数据,右列表也要显示左列表的第一个分类下的数据,更改左列表标签,右列表的数据也会随之更改。
所以我们先把左列表第一个标签下的内容塞到右列表中让它呈现。
adapterAll.setOnItemClickListener(new BaseQuickAdapter.OnItemClickListener() {
@Override
public void onItemClick(BaseQuickAdapter adapter, View view, int position) {
if (perPosition != position) {
allList.get(perPosition).setSelect(false);
allList.get(position).setSelect(true);
adapterAll.notifyDataSetChanged();
//设置右列表数据
initDetailList(position);
adapterDetail.notifyDataSetChanged();
perPosition = position;
}
}
});
adapterDetail = new ListAdapter(MainActivity.this, detailList);
recyclerviewDetail.setAdapter(adapterDetail);
10.这样进入界面两个列表都会显示数据了,接下来做二级列表的选中和取消选中功能,因为二级列表要多选,所以可设置多个标签同时选中状态,同时把选中标签塞到一个checklist中,用于返回上个页面FirstActivity中,记着实时更新右上角的选中个数文本。
adapterDetail.setOnItemClickListener(new BaseQuickAdapter.OnItemClickListener() {
@Override
public void onItemClick(BaseQuickAdapter adapter, View view, int position) {
if (detailList.get(position).isSelect()){
checkList.remove(detailList.get(position).getName());
}else{
if (checkList.size()== 3) {
Toast.makeText(MainActivity.this, "最多只能选择三个", Toast.LENGTH_SHORT).show();
return;
}
checkList.add(detailList.get(position).getName());
}
detailList.get(position).setSelect(!detailList.get(position).isSelect());
adapterDetail.notifyDataSetChanged();
}
});
11.接下来要做他们的联动,当一级列表点击时,二级列表数据会更新,所以我们先清空二级列表数据list,再把一级列表position对应的数据塞到二级列表数据list,把已选中标签塞到一个checklist中,用于返回上一个页面FirstActivity中。
/**
* 设置右列表数据
*/
private void initDetailList(int position) {
detailList.clear();
switch (position) {
case 0:
ListBean bean = new ListBean("暗夜猎手薇恩", false);
detailList.add(bean);
ListBean bean1 = new ListBean("暴走萝莉金克丝", false);
detailList.add(bean1);
ListBean bean2 = new ListBean("皮城女警凯瑟琳", false);
detailList.add(bean2);
ListBean bean3 = new ListBean("放逐之刃锐雯", false);
detailList.add(bean3);
break;
case 1:
ListBean bean4 = new ListBean("李逍遥", false);
detailList.add(bean4);
ListBean bean5 = new ListBean("赵灵儿", false);
detailList.add(bean5);
ListBean bean6 = new ListBean("林月如", false);
detailList.add(bean6);
ListBean bean7 = new ListBean("阿奴", false);
detailList.add(bean7);
break;
case 2:
ListBean bean8 = new ListBean("拉斐尔卡斯特路", false);
detailList.add(bean8);
ListBean bean9 = new ListBean("丽璐阿歌特", false);
detailList.add(bean9);
ListBean bean10 = new ListBean("李华梅", false);
detailList.add(bean10);
ListBean bean11 = new ListBean("赫德拉姆约阿奇姆柏格斯统", false);
detailList.add(bean11);
ListBean bean12 = new ListBean("蒂雅瓦曼恰斯卡", false);
detailList.add(bean12);
break;
case 3:
ListBean bean13 = new ListBean("丰臣秀吉", false);
detailList.add(bean13);
ListBean bean14 = new ListBean("织田信长", false);
detailList.add(bean14);
ListBean bean15 = new ListBean("真田幸村", false);
detailList.add(bean15);
ListBean bean16 = new ListBean("武田信玄", false);
detailList.add(bean16);
ListBean bean17 = new ListBean("本多忠胜", false);
detailList.add(bean17);
break;
case 4:
ListBean bean18 = new ListBean("上杉谦信", false);
detailList.add(bean18);
break;
case 5:
ListBean bean19 = new ListBean("赵云", false);
detailList.add(bean19);
break;
case 6:
ListBean bean20 = new ListBean("萨菲罗斯", false);
detailList.add(bean20);
break;
case 7:
ListBean bean21 = new ListBean("达尔斯", false);
detailList.add(bean21);
break;
default:
break;
}
}
12.把initDetailList方法放到一级列表的onitemclicklistener中,同时一级列表切换时,清空二级列表的已选中标签数组checklist。
adapterAll.setOnItemClickListener(new BaseQuickAdapter.OnItemClickListener() {
@Override
public void onItemClick(BaseQuickAdapter adapter, View view, int position) {
if (perPosition != position) {
allList.get(perPosition).setSelect(false);
allList.get(position).setSelect(true);
adapterAll.notifyDataSetChanged();
//设置右列表数据
initDetailList(position);
checkList.clear();
tv.setText("确定(0/3)");
adapterDetail.notifyDataSetChanged();
perPosition = position;
}
}
});
13.这下联动已经完成,设置右上角个数文本的点击事件,使用setResult方法传递checklist。
tv.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent= new Intent();
intent.putExtra("list", checkList.toString());
setResult(1, intent);
finish();
}
});
14.在FirstActivity中接受list并显示在textview上,可以根据实际需求做相应操作。
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
if (data== null){
return;
}
if (requestCode== 1){
tv.setText(data.getStringExtra("list"));
Log.d("listlistlist", data.getStringExtra("list"));
}
}
至此全部完成,Demo附上。