最近学习了ExpandableList的用法,并用之实现子项布局不同
实现目标如下:1、主界面由两个list组成2、这两个list均可以展开,即有自己的子布局3、子布局的布局不同
下面看效果图:
实现思路:
1、首先是构建布局,我们需要用到的布局有三个,分别是承载ExpandableList的布局、父布局、子布局,因为子布局界面不同,所以我们写了两种不同的子布局,具体如何使用,在下面讲解
2、建立ParentData和ChildrenData实体类 用于存储我们输入的数据,在ChildrenData中,我们加入了type这个属性,这个属性就是控制加载哪种子布局
3、建立ExpandableList适配器,在适配器中我们要重点实现getGroupView和getChildView,其中在getChildView中实现加载不同的子布局,重点说一下getChildView是如何加载不同的子布局的
可以看到是用一个switch开关,通过得到父元素的位置得到子元素,然后通过子元素的位置获得其对应的type,然后我们就可以根据type的种类来决定该加载哪一种布局
4、将ExpandableListView和数据通过适配器进行连接
下面是代码:
ExpandableListView布局
父布局
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="match_parent"> <ImageView android:id="@+id/image" android:layout_width="50dp" android:layout_height="50dp" android:src="@drawable/head" /> <LinearLayout android:layout_marginTop="5dp" android:layout_toRightOf="@id/image" android:layout_marginLeft="10dp" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:id="@+id/tv_top" android:textSize="20sp" android:gravity="center_vertical|left" android:text="上方的标题" android:layout_width="match_parent" android:layout_height="wrap_content" /> <TextView android:id="@+id/tv_bottom" android:gravity="center_vertical|left" android:text="下方的标题" android:layout_width="match_parent" android:layout_height="wrap_content" /> LinearLayout> RelativeLayout>
效果图:
第一种子布局:
xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:background="#D0D0D0" android:layout_height="match_parent"> <LinearLayout android:layout_marginTop="1dp" android:orientation="horizontal" android:background="#D0D0D0" android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:layout_marginRight="0.5dp" android:background="#FCFCFC" android:gravity="center" android:id="@+id/type1_b1" android:textSize="14sp" android:text="泵车" android:layout_weight="1" android:layout_width="0dp" android:layout_height="wrap_content" /> <TextView android:layout_marginLeft="0.5dp" android:background="#FCFCFC" android:gravity="center" android:id="@+id/type1_b2" android:text="混凝土搅拌车" android:layout_weight="1" android:layout_width="0dp" android:textSize="14sp" android:layout_height="wrap_content" /> LinearLayout> <LinearLayout android:layout_marginTop="1dp" android:orientation="horizontal" android:background="#D0D0D0" android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:layout_marginRight="0.5dp" android:background="#FCFCFC" android:gravity="center" android:id="@+id/type1_b3" android:textSize="14sp" android:text="拖泵" android:layout_weight="1" android:layout_width="0dp" android:layout_height="wrap_content" /> <TextView android:layout_marginLeft="0.5dp" android:background="#FCFCFC" android:gravity="center" android:id="@+id/type1_b4" android:text="车载泵" android:layout_weight="1" android:layout_width="0dp" android:textSize="14sp" android:layout_height="wrap_content" /> LinearLayout> <LinearLayout android:layout_marginTop="1dp" android:orientation="horizontal" android:background="#D0D0D0" android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:layout_marginRight="0.5dp" android:background="#FCFCFC" android:gravity="center" android:id="@+id/type1_b5" android:textSize="14sp" android:text="混凝土搅拌站" android:layout_weight="1" android:layout_width="0dp" android:layout_height="wrap_content" /> <TextView android:layout_marginLeft="0.5dp" android:background="#FCFCFC" android:gravity="center" android:id="@+id/type1_b6" android:text="混凝土搅拌机" android:layout_weight="1" android:layout_width="0dp" android:textSize="14sp" android:layout_height="wrap_content" /> LinearLayout> LinearLayout>
效果图:
第二种子布局:
xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:background="#D0D0D0" android:layout_height="match_parent"> <LinearLayout android:layout_marginTop="1dp" android:orientation="horizontal" android:background="#D0D0D0" android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:layout_marginRight="0.5dp" android:background="#FCFCFC" android:gravity="center" android:id="@+id/type2_b1" android:textSize="14sp" android:text="半挂牵引车" android:layout_weight="1" android:layout_width="0dp" android:layout_height="wrap_content" /> <TextView android:layout_marginLeft="0.5dp" android:background="#FCFCFC" android:gravity="center" android:id="@+id/type2_b2" android:text="全牵引车" android:layout_weight="1" android:layout_width="0dp" android:textSize="14sp" android:layout_height="wrap_content" /> LinearLayout> <LinearLayout android:layout_marginTop="1dp" android:orientation="horizontal" android:background="#D0D0D0" android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:layout_marginRight="0.5dp" android:background="#FCFCFC" android:gravity="center" android:id="@+id/type2_b3" android:textSize="14sp" android:text="牵引特殊挂车" android:layout_weight="1" android:layout_width="0dp" android:layout_height="wrap_content" /> <TextView android:layout_marginLeft="0.5dp" android:background="#FCFCFC" android:gravity="center" android:id="@+id/type2_b4" android:text="旋挖钻机" android:layout_weight="1" android:layout_width="0dp" android:textSize="14sp" android:layout_height="wrap_content" /> LinearLayout> LinearLayout>
效果图:
ParentData:
package com.example.count.count; import java.util.List; /** * Created by wei on 2017/10/11. */ public class ParentData { //父选项下面的子选项的集合 private ListChildrenData:childrenDataList; //图片 private int image; //上方文本 private String top; //下方文本 private String bottom; //外界调用时需要将数据都传入(在这里是因为数据是预先准备好的,所以需要直接填入) public ParentData(List childrenDataList,int image,String top,String bottom ) { this.childrenDataList=childrenDataList; this.image=image; this.top=top; this.bottom=bottom; } public List getChildrenDataList() { return childrenDataList; } public void setChildrenDataList(List childrenDataList) { this.childrenDataList = childrenDataList; } public int getImage() { return image; } public void setImage(int image) { this.image = image; } public String getTop() { return top; } public void setTop(String top) { this.top = top; } public String getBottom() { return bottom; } public void setBottom(String bottom) { this.bottom = bottom; } }
package com.example.count.count; /** * Created by wei on 2017/10/11. */ public class ChildrenData { //将子布局可能出现的数据均写在这里 private String data1; private String data2; private String data3; private String data4; private String data5; private String data6; //用于判断当前该加载哪一种布局 private int type; public ChildrenData(String data1,String data2,String data3,String data4,String data5,String data6,int type) { this.data1=data1; this.data2=data2; this.data3=data3; this.data4=data4; this.data5=data5; this.data6=data6; this.type=type; } public String getData1() { return data1; } public void setData1(String data1) { this.data1 = data1; } public String getData2() { return data2; } public void setData2(String data2) { this.data2 = data2; } public String getData3() { return data3; } public void setData3(String data3) { this.data3 = data3; } public String getData4() { return data4; } public void setData4(String data4) { this.data4 = data4; } public String getData5() { return data5; } public void setData5(String data5) { this.data5 = data5; } public String getData6() { return data6; } public void setData6(String data6) { this.data6 = data6; } public int getType() { return type; } public void setType(int type) { this.type = type; } }
适配器
package com.example.count.count; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseExpandableListAdapter; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.RelativeLayout; import android.widget.TextView; import java.util.List; /** * Created by wei on 2017/10/11. */ //自定义的可扩展下拉列表 public class MyExpandableListView extends BaseExpandableListAdapter { //这是父项的布局 private RelativeLayout layout; //这是子项种类一布局 private LinearLayout linearLayout1; //这是子项种类二布局 private LinearLayout linearLayout2; //这个集合包含了父项和子项 ListMainActivity:parentDataList; //得到上下文对象 private Context mContext; //构造时传入数据和上下文对象 public MyExpandableListView(List parentDataList,Context mContext) { this.parentDataList=parentDataList; this.mContext=mContext; } //获得父项的数量 @Override public int getGroupCount() { return parentDataList.size(); } //获得子项的数量 @Override public int getChildrenCount(int groupPosition) { //先获得当前的父项 然后得到父项的子项集合的长度 即是子项的数量 return parentDataList.get(groupPosition).getChildrenDataList().size(); } //获得某个父项 @Override public Object getGroup(int groupPosition) { return parentDataList.get(groupPosition); } //获得某个子项 @Override public Object getChild(int groupPosition, int childPosition) { return parentDataList.get(groupPosition).getChildrenDataList().get(childPosition); } //获得某个父项id @Override public long getGroupId(int groupPosition) { return groupPosition; } //获得某个子项id @Override public long getChildId(int groupPosition, int childPosition) { return childPosition; } // 按函数的名字来理解应该是是否具有稳定的id,这个方法目前一直都是返回false,没有去改动过 @Override public boolean hasStableIds() { return false; } // 获得父项显示的view @Override public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) { LayoutInflater inflater=LayoutInflater.from(mContext); layout= (RelativeLayout) inflater.inflate(R.layout.other_34_parent,null); //将父布局中需要填充的元素进行填充 ImageView image= (ImageView) layout.findViewById(R.id.image); TextView tv_top= (TextView) layout.findViewById(R.id.tv_top); TextView tv_bottom= (TextView) layout.findViewById(R.id.tv_bottom); image.setImageResource(parentDataList.get(groupPosition).getImage()); tv_top.setText(parentDataList.get(groupPosition).getTop()); tv_bottom.setText(parentDataList.get(groupPosition).getBottom()); return layout; } // 获得子项显示的view @Override public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) { LayoutInflater inflater = LayoutInflater.from(mContext); //从子项中获得自带的布局种类 根据布局种类加载不同的布局 从而填充不同的数据 switch (parentDataList.get(groupPosition).getChildrenDataList().get(childPosition).getType()) { case 1: //将布局1中需要填充的内容进行填充 linearLayout1= (LinearLayout) inflater.inflate(R.layout.other_34_type1,null); TextView type1_b1= (TextView) linearLayout1.findViewById(R.id.type1_b1); TextView type1_b2= (TextView) linearLayout1.findViewById(R.id.type1_b2); TextView type1_b3= (TextView) linearLayout1.findViewById(R.id.type1_b3); TextView type1_b4= (TextView) linearLayout1.findViewById(R.id.type1_b4); TextView type1_b5= (TextView) linearLayout1.findViewById(R.id.type1_b5); TextView type1_b6= (TextView) linearLayout1.findViewById(R.id.type1_b6); type1_b1.setText(parentDataList.get(groupPosition).getChildrenDataList().get(childPosition).getData1()); type1_b2.setText(parentDataList.get(groupPosition).getChildrenDataList().get(childPosition).getData2()); type1_b3.setText(parentDataList.get(groupPosition).getChildrenDataList().get(childPosition).getData3()); type1_b4.setText(parentDataList.get(groupPosition).getChildrenDataList().get(childPosition).getData4()); type1_b5.setText(parentDataList.get(groupPosition).getChildrenDataList().get(childPosition).getData5()); type1_b6.setText(parentDataList.get(groupPosition).getChildrenDataList().get(childPosition).getData6()); return linearLayout1; case 2: //将布局二中的内容进行填充 linearLayout2= (LinearLayout) inflater.inflate(R.layout.other_34_type2,null); TextView type2_b1= (TextView) linearLayout2.findViewById(R.id.type2_b1); TextView type2_b2= (TextView) linearLayout2.findViewById(R.id.type2_b2); TextView type2_b3= (TextView) linearLayout2.findViewById(R.id.type2_b3); TextView type2_b4= (TextView) linearLayout2.findViewById(R.id.type2_b4); type2_b1.setText(parentDataList.get(groupPosition).getChildrenDataList().get(childPosition).getData1()); type2_b2.setText(parentDataList.get(groupPosition).getChildrenDataList().get(childPosition).getData2()); type2_b3.setText(parentDataList.get(groupPosition).getChildrenDataList().get(childPosition).getData3()); type2_b4.setText(parentDataList.get(groupPosition).getChildrenDataList().get(childPosition).getData4()); return linearLayout2; } return null; } // 子项是否可选中,如果需要设置子项的点击事件,需要返回true @Override public boolean isChildSelectable(int groupPosition, int childPosition) { return true; } }
package com.example.count.count; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.widget.ExpandableListView; import java.util.ArrayList; import java.util.List; public class Other_34 extends AppCompatActivity { //获取expandableListView布局 private ExpandableListView el; //创建list集合存放数据 private ListparentDataList; //expandableListView布局适配器 private MyExpandableListView myExpandableListView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_other_34); //向list中初始数据 InitData(); //获得expandableListView的实例 el= (ExpandableListView) findViewById(R.id.el); myExpandableListView=new MyExpandableListView(parentDataList,this); //将适配器与布局进行连接 el.setAdapter(myExpandableListView); } public void InitData() { //数据采用预存入的方式 //初始化parentDataList parentDataList=new ArrayList (); //先向ChildrenData中放入数据 List list=new ArrayList (); ChildrenData childrenData=new ChildrenData("我","秦始皇","兵马俑","掉漆","重修","打钱",1); list.add(childrenData); //再向parentData中放入数据 ParentData parentData=new ParentData(list,R.drawable.head,"阿伟","强无敌"); parentDataList.add(parentData); //第二条数据参考第一条数据存入方式 但是值得注意的是 第二天数据中的data5和data6是不存在的 List list1=new ArrayList (); ChildrenData childrenData2=new ChildrenData("你","武则天","女皇","拜见",null,null,2); list1.add(childrenData2); ParentData parentData2=new ParentData(list1,R.drawable.head,"你啊","无敌强"); parentDataList.add(parentData2); } }
反思与总结:
1、在实现过程中,因为有部分代码相同,所以直接复制时忘了更改一些字段,导致程序出错,做一个CV战士,更要做一个细心的CV战士
2、在这里实现了父布局相同,子布局不同,同理我们也可以个ParentData加一个type,这样就可以实现父布局不同,子布局也不同
3、我们还没有对程序进行优化,一直重复加载布局,会使程序的效率变低,下一篇文章会讲
写在后面
1、本人学习安卓时间并不长,难免受到技术上的限制出现错误,请各位嘴下留情,如果你看了这篇文章觉得很生气,你可以选择右上角的x,或者直接砸了了手中的电脑或者手机
2、三人行必有吾师,愿与各位共进步,我会一直更新我在安卓上学习到的知识的