上一篇已经介绍了利用ExpanableListView组件做简单的二级树形列表,上次说过要把二级树形列表封装成一个通用的树形列表,不用每次用都要建,要做到每次用只要传入参数就行了。
首先新建一个借口类LayerAdapterInterface,为什么要建这个借口,后面就会明白:
package com.example.appview.Common.TwoTree; import android.view.View; import android.view.ViewGroup; public interface LayerAdapterInterface { /** * * @param groupPosition 第一层位置 * @param convertView 第一层视图 * @return */ public View getGroupView(int groupPosition, View convertView); /** * * @param groupPosition 第一层组位置 * @param childPosition 第二层view位置 * @param convertView 第二层视图 * @return */ public View getChildView(int groupPosition, int childPosition, View convertView); }
新建一个类LayerAdapterHelper 继承BaseExpandableListAdapter基类
package com.example.appview.Common.TwoTree; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseExpandableListAdapter; import java.util.List; public class LayerAdapterHelper<T1,T2,TControl extends LayerAdapterInterface> extends BaseExpandableListAdapter { public List<T1> oneTree; //二级列表第一层 public List<List<T2>> twoTree;//二级列表第二层 private TControl tControl; //这个是我们初始化控件用的类,这个是每一个Activity页面独有的,因为每个布局里面的内容可能不一样。 private int RoneTree;//这个是二级列表第一层的页面布局 R.layout.布局页面 private int RtwoTree;//这个是二级列表第二层的页面布局 R.layout.布局页面 private Context context; LayoutInflater layoutInflater; public LayerAdapterHelper(Context context,List<T1> oneTree, List<List<T2>> twoTree,TControl tControl,int RoneTree,int RtwoTree){ this.context=context; this.oneTree=oneTree; this.twoTree=twoTree; this.tControl=tControl; this.RoneTree=RoneTree; this.RtwoTree=RtwoTree; layoutInflater = LayoutInflater.from(context); } //组数量 @Override public int getGroupCount() { return oneTree.size(); } //子View数量 @Override public int getChildrenCount(int groupPosition) { return twoTree.get(groupPosition).size(); } //获取组对象 @Override public Object getGroup(int groupPosition) { return oneTree.get(groupPosition); } //获取子View对象 @Override public Object getChild(int groupPosition, int childPosition) { return twoTree.get(groupPosition).get(childPosition); } // 组View下标 @Override public long getGroupId(int groupPosition) { return groupPosition; } //子View下标 @Override public long getChildId(int groupPosition, int childPosition) { return childPosition; } @Override public boolean hasStableIds() { return false; } //取得用于显示给定分组的视图. 这个方法仅返回分组的视图对象 @Override public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) { convertView= layoutInflater.inflate(RoneTree, null); return tControl.getGroupView(groupPosition,convertView); } //取得显示给定分组给定子位置的数据用的视图 @Override public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) { convertView= layoutInflater.inflate(RtwoTree, null); return tControl.getChildView(groupPosition,childPosition,convertView); } @Override public boolean isChildSelectable(int groupPosition, int childPosition) { return false; } }
Activity:
package com.example.appview; import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.ExpandableListView; import android.widget.LinearLayout; import android.widget.TextView; import android.widget.Toast; import com.example.appview.Common.ThreeTree.MyExpanableListAdapterHelper; import com.example.appview.Common.TwoTree.LayerAdapterHelper; import com.example.appview.Common.TwoTree.LayerAdapterInterface; import com.example.appview.mian_page.Frament.Preject_Tance_Frament.ItemA_Model.JiLou; import com.example.appview.mian_page.Frament.Preject_Tance_Frament.ItemA_Model.JiLouModel; import com.example.appview.mian_page.Frament.Preject_Tance_Frament.ItemA_Model.SheiBeiModel; import com.example.appview.mian_page.Frament.Preject_Tance_Frament.ItemA_Model.ThreeTreeModel; import com.example.appview.mian_page.Frament.Preject_Tance_Frament.ItemA_Model.Tree.ExpandableListViewInterface; import com.example.appview.mian_page.Frament.Preject_Tance_Frament.ItemA_Model.Tree.ParentAdapterHelper; import java.util.ArrayList; import java.util.Date; import java.util.List; public class Demo extends AppCompatActivity { private ExpandableListView expandableListView; private List<JiLouModel> jiLou=new ArrayList<>(); private List<SheiBeiModel> sheiBei; private List<List<SheiBeiModel>> sheiBeiModels=new ArrayList<>(); private LayerAdapterHelper<JiLouModel,SheiBeiModel,myControl> adapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_demo); expandableListView = findViewById(R.id.expandable_listView); initdata(); adapter=new LayerAdapterHelper<>(Demo.this,jiLou,sheiBeiModels,new myControl(),R.layout.preject_item_addcaiji_onetree,R.layout.preject_item_addcaiji_twotree); expandableListView .setAdapter(adapter); } //创造数据 public void initdata(){ jiLou.add(new JiLouModel(1,"机楼1","",new Date(System.currentTimeMillis()))); jiLou.add(new JiLouModel(1,"机楼2","",new Date(System.currentTimeMillis()))); jiLou.add(new JiLouModel(1,"机楼3","",new Date(System.currentTimeMillis()))); sheiBei=new ArrayList<>(); sheiBei.add(new SheiBeiModel(1,"设备1","")); sheiBei.add(new SheiBeiModel(1,"设备2","")); sheiBei.add(new SheiBeiModel(1,"设备3","")); sheiBeiModels.add(sheiBei); sheiBei=new ArrayList<>(); sheiBei.add(new SheiBeiModel(1,"设备4","")); sheiBei.add(new SheiBeiModel(1,"设备5","")); sheiBei.add(new SheiBeiModel(1,"设备6","")); sheiBeiModels.add(sheiBei); sheiBei=new ArrayList<>(); sheiBei.add(new SheiBeiModel(1,"设备7","")); sheiBei.add(new SheiBeiModel(1,"设备8","")); sheiBei.add(new SheiBeiModel(1,"设备9","")); sheiBeiModels.add(sheiBei); } class myControl implements LayerAdapterInterface{ @Override public View getGroupView(int groupPosition, View convertView) { TextView textView = convertView.findViewById(R.id.preject_item_caijiqi_onetree); textView.setText(adapter.oneTree.get(groupPosition).getJiLouName()); return convertView; } @Override public View getChildView(int groupPosition, int childPosition, View convertView) { convertView.setPadding(50,5,0,5); TextView textView = convertView.findViewById(R.id.preject_item_dianbiao); textView.setText(adapter.twoTree.get(groupPosition).get(childPosition).getSheBeiName()); return convertView; } } }
preject_item_addcaiji_onetree 布局:
<?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="@color/white" android:orientation="horizontal"> <LinearLayout android:layout_width="match_parent" android:layout_height="50dp" android:descendantFocusability="blocksDescendants" android:background="@drawable/mainpage_gridview" android:elevation="10dp" android:orientation="horizontal"> <LinearLayout android:id="@+id/preject_item_layout_onetree" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1"> <ImageView android:layout_width="40dp" android:layout_marginLeft="10dp" android:layout_gravity="center" android:background="@mipmap/preject_item_caijiqi" android:layout_height="40dp"/> </LinearLayout> <TextView android:id="@+id/preject_item_caijiqi_onetree" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center" android:text="采集器编号" android:textColor="@color/black"/> <TextView android:id="@+id/preject_item_addtime_onetree" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="2" android:text="2021-08-12 11:19:00" android:textColor="@color/black" android:gravity="center" /> <LinearLayout android:layout_width="0dp" android:id="@+id/preject_item_imagecaiji_onetree" android:layout_height="match_parent" android:focusable="false" android:clickable="true" android:layout_weight="1"> <ImageView android:id="@+id/preject_item_caijiqi" android:layout_width="30dp" android:layout_height="30dp" android:background="@mipmap/preject_item_caozuo" android:layout_gravity="center" android:layout_marginLeft="20dp"/> </LinearLayout> </LinearLayout> </LinearLayout>
preject_item_addcaiji_twotree 布局:
<?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="@color/white" android:orientation="horizontal"> <LinearLayout android:layout_width="match_parent" android:layout_height="50dp" android:background="@drawable/mainpage_gridview" android:elevation="10dp" android:descendantFocusability="blocksDescendants" android:orientation="horizontal"> <LinearLayout android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1"> <ImageView android:id="@+id/preject_item_jztype" android:layout_width="40dp" android:layout_marginLeft="10dp" android:layout_gravity="center" android:background="@mipmap/preject_item_dianbiao" android:layout_height="40dp"/> </LinearLayout> <TextView android:id="@+id/preject_item_dianbiao" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center" android:text="电表表号" android:textColor="@color/black"/> <TextView android:id="@+id/preject_item_dianbiao_address" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:text="通信地址" android:textColor="@color/black" android:gravity="center" /> <TextView android:id="@+id/preject_item_addtime_twotree" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="2" android:text="2021-08-12 11:19:00" android:textColor="@color/black" android:gravity="center"/> <LinearLayout android:layout_width="0dp" android:id="@+id/preject_item_layoutcaozuo_twotree" android:focusable="false" android:clickable="true" android:layout_height="match_parent" android:layout_weight="1"> <ImageView android:id="@+id/preject_item_dianbiao_caozuo" android:layout_width="30dp" android:layout_height="30dp" android:layout_gravity="center" android:background="@mipmap/preject_item_caozuo" android:layout_marginLeft="20dp" /> </LinearLayout> </LinearLayout> </LinearLayout>
效果图:
上面实现二级树形列表封装的过程,主要利用泛型来实现的,上面用到了一个借口,我们在通用中传入的TControl这个组件初始化的类。这个类被泛型约束它必须要实现LayerAdapterInterface 借口,这个是实现的核心。
到这里二级树形列表的简单实现和最后封装都已经实现了。下次我会在二级的基础上介绍一下三级树形列表的实现和最后的通用封装。