这段时间在项目中遇到了二级标签列表的实现,可是项目中的代码用的是人家第三方的,所以我决定用ExpandableListView来实现二级标签列表(这个demo上周就写好了,因为上周找房子没更博,难受啊,贵的房子租不起,便宜的房子要不然太小,要不然环境差…努力提高自己吧,等工资提上来了,一切都好说)扯远了,让我们上一下效果图:
首先说一下什么是ExpandableListView,ExpandableListView继承ListView,一种比较常见的一个比较简单的实现二级标签列表的控件。为了实现上面的效果图,我们所要做的如下:
一:创建数据源类(我按照一般后台接口返回的数据格式建类)
public class BeanFirstItemBase {
private String name;
private List<BeanSecondItem> beanSecondItem;
public List<BeanSecondItem> getBeanSecondItem() {
return beanSecondItem;
}
public void setBeanSecondItem(List<BeanSecondItem> beanSecondItem) {
this.beanSecondItem = beanSecondItem;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
static class BeanSecondItem {//二级标签类
private String name;
public BeanSecondItem(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
}
二.布局文件
1.activity_expand_view(activity布局文件)
<?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=".activity.expandlistview.ExpandListViewActivity">
<ExpandableListView
android:id="@+id/el_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</LinearLayout>
2.item_first_label(一级标签列表布局)
大家看这个布局文件LinearLayout里面又包了一层LinearLayout,可能认为多余,其实不是这样,要想自定义一级标签列表的宽度,必须里面在包一层布局,这是什么原因,当时我也问了几个人,他们也没回答出来,这个如果有人知道可以告诉我一下~~,下面二级标签列表布局也一样(其中icon_huanzhe_xiala1图片我没给出来,这就是表示以及标签列表是展开还是关闭的图片显示,大家可以网上找一下)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tool="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="60dp"
android:gravity="center_vertical"
android:orientation="horizontal">
<TextView
android:id="@+id/tv_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
android:layout_weight="1"
android:gravity="center_vertical"
android:textSize="18sp"
tool:text="333" />
<ImageView
android:id="@+id/iv_state"
android:layout_width="15dp"
android:layout_height="15dp"
android:layout_marginRight="25dp"
android:src="@mipmap/icon_huanzhe_xiala1" />
</LinearLayout>
</LinearLayout>
3.item_second_label(二级标签布局)
<?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:gravity="center_vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="40dp"
android:gravity="center_vertical"
android:orientation="horizontal">
<TextView
android:id="@+id/tv_child_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
android:gravity="center_vertical"
android:text="333"
android:textColor="#008577"
android:textSize="18sp" />
</LinearLayout>
</LinearLayout>
三.自定义适配器ExpandListViewAdapter
public class ExpandListViewAdapter extends BaseExpandableListAdapter {
private List<BeanFirstItemBase> mFirstItemList;//从Activity传过来的数据源
private Context mContext;
public ExpandListViewAdapter(List<BeanFirstItemBase> mFirstItemList, Context mContext) {
this.mFirstItemList = mFirstItemList;
this.mContext = mContext;
}
//返回的是一级标签的数量
@Override
public int getGroupCount() {
return mFirstItemList.size();
}
//返回的是子标签的数量
@Override
public int getChildrenCount(int groupPosition) {
return mFirstItemList.get(groupPosition).getBeanSecondItem().size();
}
//获得某个一级标签的内容
@Override
public Object getGroup(int groupPosition) {
return mFirstItemList.get(groupPosition);
}
//获得某个一级标签下的子标签
@Override
public Object getChild(int groupPosition, int childPosition) {
return mFirstItemList.get(groupPosition).getBeanSecondItem().get(childPosition);
}
//一级标签列表的Id
@Override
public long getGroupId(int groupPosition) {
return groupPosition;
}
//二级标签列表的Id
@Override
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
//具体啥作用,真不清楚~~
@Override
public boolean hasStableIds() {
return true;
}
//显示一级标签列表
@Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
FirstViewHolder firstViewHolder;
if (convertView == null) {//第一次展示View 没有被创建
convertView = LayoutInflater.from(mContext).inflate(R.layout.item_first_label, null);
firstViewHolder = new FirstViewHolder(convertView);
convertView.setTag(firstViewHolder);//创建之后,将firstViewHolder存到视图中
} else {
firstViewHolder = (FirstViewHolder) convertView.getTag();//将firstViewHolder 拿出来
}
firstViewHolder.tvName.setText(mFirstItemList.get(groupPosition).getName());//赋值
if (isExpanded) {//表明此时已经展开
firstViewHolder.ivState.setImageDrawable(mContext.getResources().getDrawable(R.mipmap.icon_huanzhe_xiala3));
//这个图我没有给,就是表示一级标签列表展开的图标,因为不好发图,网上找一下就行了,具体可以看动图,下面也是
} else {//表明此时已经关闭
firstViewHolder.ivState.setImageDrawable(mContext.getResources().getDrawable(R.mipmap.icon_huanzhe_xiala1));
}
return convertView;
}
//显示二级标签列表
@Override
public View getChildView(final int groupPosition, final int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
SecondViewHolder secondViewHolder;
if (convertView == null) {//第一次展示View 没有被创建
convertView = LayoutInflater.from(mContext).inflate(R.layout.item_second_label, null);
secondViewHolder = new SecondViewHolder(convertView);
convertView.setTag(secondViewHolder);//创建之后,将firstViewHolder存到View中
} else {
secondViewHolder = (SecondViewHolder) convertView.getTag();//将firstViewHolder从View拿出来
}
secondViewHolder.tvChildName.setText(mFirstItemList.get(groupPosition).getBeanSecondItem().get(childPosition).getName());
return convertView;
}
//指定位置上的child能否被选中
@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
/* 下面我注释掉方法的表示当二级标签名为张三 不响应点击事件 有兴趣可以试一下
if (mFirstItemList.get(groupPosition).getBeanSecondItem().get(childPosition).getName().equals("张三")) {
return false;
} else {
return true;
}*/
return true;
}
static class FirstViewHolder {
TextView tvName;
ImageView ivState;
FirstViewHolder(View view) {
tvName = view.findViewById(R.id.tv_name);
ivState = view.findViewById(R.id.iv_state);
}
}
static class SecondViewHolder {
TextView tvChildName;
SecondViewHolder(View view) {
tvChildName = view.findViewById(R.id.tv_child_name);
}
}
}
四:ExpandListViewActivity的书写
public class ExpandListViewActivity extends AppCompatActivity {
@BindView(R.id.el_list)
ExpandableListView mElList;
private List<BeanFirstItemBase> mBeanFirstItemBases = new ArrayList<>();//数据源
private ExpandableListAdapter mAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_expand_view);
ButterKnife.bind(this);
initView();
}
private void initView() {
//初始化数据
BeanFirstItemBase beanFirstItemBase1 = new BeanFirstItemBase();
beanFirstItemBase1.setName("第一组");
List<BeanFirstItemBase.BeanSecondItem> beanSecondItems1 = new ArrayList<>();
//BeanFirstItemBase.BeanSecondItem b=new BeanFirstItemBase.BeanSecondItem("张三");
beanSecondItems1.add(new BeanFirstItemBase.BeanSecondItem("张三"));
beanSecondItems1.add(new BeanFirstItemBase.BeanSecondItem("李四"));
beanSecondItems1.add(new BeanFirstItemBase.BeanSecondItem("王五"));
beanFirstItemBase1.setBeanSecondItem(beanSecondItems1);
BeanFirstItemBase beanFirstItemBase2 = new BeanFirstItemBase();
beanFirstItemBase2.setName("第二组");
List<BeanFirstItemBase.BeanSecondItem> beanSecondItems2 = new ArrayList<>();
beanSecondItems2.add(new BeanFirstItemBase.BeanSecondItem("赵六"));
beanSecondItems2.add(new BeanFirstItemBase.BeanSecondItem("孙七"));
beanSecondItems2.add(new BeanFirstItemBase.BeanSecondItem("周八"));
beanFirstItemBase2.setBeanSecondItem(beanSecondItems2);
BeanFirstItemBase beanFirstItemBase3 = new BeanFirstItemBase();
beanFirstItemBase3.setName("第三组");
List<BeanFirstItemBase.BeanSecondItem> beanSecondItems3 = new ArrayList<>();
beanSecondItems3.add(new BeanFirstItemBase.BeanSecondItem("吴九"));
beanSecondItems3.add(new BeanFirstItemBase.BeanSecondItem("郑十"));
beanFirstItemBase3.setBeanSecondItem(beanSecondItems3);
mBeanFirstItemBases.add(beanFirstItemBase1);
mBeanFirstItemBases.add(beanFirstItemBase2);
mBeanFirstItemBases.add(beanFirstItemBase3);
//上面一系列都是为了获得数据源 都是为了获得数据源
mAdapter = new ExpandListViewAdapter(mBeanFirstItemBases, ExpandListViewActivity.this);//将数据源传到Adapter中
mElList.setGroupIndicator(null);//去掉默认左边的图标
mElList.setAdapter(mAdapter);
//二级标签列表的点击事件
mElList.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
@Override
public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) {
Toast.makeText(ExpandListViewActivity.this, mBeanFirstItemBases.get(groupPosition).getBeanSecondItem().get(childPosition).getName(), Toast.LENGTH_SHORT).show();
return true;
}
});
}
}
总结:代码看着有点多,其实很简单,自己写个小demo就清楚了。