ExpandableListView的自定义布局以及注意事项
来源:互联网 发布:萧山三中网络课程 编辑:程序博客网 时间:2024/06/08 14:32
android开发中常常需要使用到ExpandableListView来对一组数据进行分组, 使用ExpandableListView能够达到类似QQ分组的效果,类似于下面两张效果图:
要达到这种效果其实并不难,因为ExpandableListView跟ListView很相似,如果你对ListView很熟悉的话,很快就能掌握它,如果对ListView不熟悉的话,建议 先看看之前的博文 android学习之ListView的基本使用
首先定义一个主布局:activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity"> <ExpandableListView android:id="@+id/expandableView" android:layout_width="wrap_content" android:layout_height="wrap_content"></ExpandableListView></RelativeLayout>
然后自定义ExpandableListView中的组名显示布局:item_group.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:id="@+id/tv_group_title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_centerInParent="true" android:text="title" android:textSize="30sp" android:layout_marginLeft="30dp" /> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/iv_group_img" android:layout_alignParentRight="true"/></RelativeLayout>
接着定义每个组下子项的布局:item_child.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:id="@+id/tv_child_title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="16dp" android:layout_marginTop="30dp" android:textSize="20sp" android:layout_alignParentLeft="true" android:text="test"/> <TextView android:id="@+id/tv_child_explain" android:layout_width="wrap_content" android:layout_alignLeft="@id/tv_child_title" android:layout_below="@id/tv_child_title" android:layout_height="wrap_content" android:text="explain"/> <ImageView android:id="@+id/iv_child_img" android:layout_alignParentRight="true" android:layout_width="wrap_content" android:layout_height="wrap_content" /></RelativeLayout>
为了方便,可以建立一个类为每个布局的组件创建一个字段,如给子项定义一个Child类:
/** * Created by mhwang on 2015/11/25. */public class Child { /**子项标题*/ private String title; /**子项解释*/ private String explain; public Child(){ title = "title"; explain = "explain"; } public String getTitle() { return title; } public String getExplain() { return explain; } public void setTitle(String title) { this.title = title; } public void setExplain(String explain) { this.explain = explain; }}
如果需要,也可以为群组建立类。
然后到了关键部分,为ExpandableListView创建一个适配器,适配器是连接视图与数据的桥梁。负责将数据送到视图中。这里自定义MyAdapter适配器继承BaseExpandableListAdapter,并重写其所有方法。
/** * Created by mhwang on 2015/11/25. */public class MyAdapter extends BaseExpandableListAdapter { /**群组名*/ private ArrayList<String> groups; /**群组下的子项*/ private ArrayList<ArrayList<Child>> childs; private Context mContext; public MyAdapter(Context context){ mContext = context; init(); } /**为了测试方便,先初始化一些数据*/ public void init(){ groups = new ArrayList<String>(); //添加一些群组 for(int i = 0; i < 10; i++){ groups.add("群组"+i); } childs = new ArrayList<ArrayList<Child>>(); //为每个群组添加一些子项 for(int i = 0; i < groups.size(); i++){ //如果该群组是偶数,为其添加5个子项,奇数添加3项 ArrayList<Child> values = new ArrayList<>(); if(i % 2 == 0 ){ for(int j = 0; j < 5; j++) { Child child = new Child(); child.setTitle("子项"+j); child.setExplain("解释"+j); values.add(child); childs.add(values); } }else{ for(int j = 0; j < 3; j++){ Child child = new Child(); child.setTitle("子项"+j); child.setExplain("解释"+j); values.add(child); childs.add(values); } } } } @Override public int getGroupCount() { return groups.size(); } @Override public int getChildrenCount(int groupPosition) { return childs.get(groupPosition).size(); } @Override public Object getGroup(int groupPosition) { return groups.get(groupPosition); } @Override public Object getChild(int groupPosition, int childPosition) { return childs.get(groupPosition).get(childPosition); } @Override public long getGroupId(int groupPosition) { return groupPosition; } @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) { /**创建view */ View v = LayoutInflater.from(mContext).inflate(R.layout.item_group,null); /**通过创建的view与自定义布局绑定,就要以找到布局里的组件了*/ TextView tvGroupTitle = (TextView)v.findViewById(R.id.tv_group_title); ImageView ivGroupImg = (ImageView)v.findViewById(R.id.iv_group_img); tvGroupTitle.setText(groups.get(groupPosition)); ivGroupImg.setBackgroundResource(R.drawable.m1); return v; } @Override public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) { View v = LayoutInflater.from(mContext).inflate(R.layout.item_child,null); TextView tvChildTitle = (TextView)v.findViewById(R.id.tv_child_title); TextView tvChildExplain = (TextView)v.findViewById(R.id.tv_child_explain); ImageView ivChildImg = (ImageView)v.findViewById(R.id.iv_child_img); tvChildTitle.setText(childs.get(groupPosition).get(childPosition).getTitle()); tvChildExplain.setText(childs.get(groupPosition).get(childPosition).getExplain()); ivChildImg.setBackgroundResource(R.drawable.m2); return v; } @Override public boolean isChildSelectable(int groupPosition, int childPosition) { return true; }}
最后一步,在MainActivity中获取ExpandableListView实例并调用其setAdapter方法将自定义的MyAdapter对象传进去即可。
public class MainActivity extends AppCompatActivity { ExpandableListView expandableListView; MyAdapter adapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); expandableListView = (ExpandableListView)findViewById(R.id.expandableView); adapter = new MyAdapter(this); expandableListView.setAdapter(adapter); }}
这里有几点值得注意:
1、与ListView不同,在ExpandableListView中使用ViewHolder的话会出问题,因为ExpandableListView中的每一个组下子项数目并不是相同的,重用之前的convertView会崩溃。
2、如果是从外部读入数据到列表项中,如数据库等,要特别注意列表项数据为null的情形,否则会有空指针异常并崩溃。
- ExpandableListView的自定义布局以及注意事项
- android ExpandableListView的group是一个自定义的布局,折叠图标覆盖布局上的部分内容
- 自定义dialog的方式,以及需要注意事项
- 自定义surfaceview的步奏以及注意事项
- 自定义ExpandableListView以及实现其分页
- expandableListView 自定义样式以及scrollerView嵌套
- [Android]expandablelistview默认展开以及记录已展开或关闭的子布局
- 垂直的SeekBar以及自定义布局
- android帧布局以及注意事项
- ExpandableListView 好有列表的布局
- ExpandableListView怎么实现不同的布局?
- ExpandableListView怎么实现不同的布局?
- 自定义ExpandableListView
- 自定义ExpandableListView
- 自定义ExpandableListView
- 四大布局的注意事项
- flex布局的注意事项
- ExpandableListView的美化以及出现的问题
- vim编辑器使用技巧
- 第一个特征点提取算法
- 理解长短期记忆网络(LSTM NetWorks)
- 山东理工ACM:2737
- 传智计算器简单界面1等
- ExpandableListView的自定义布局以及注意事项
- Git版本控制工具下载
- [leetcode]Invert Binary Tree
- LeetCode 24:Swap Nodes in Pairs
- MONGODB 检查点和JOURNAL说明
- java相关开发包官网下载地址
- Git的使用
- jQuery对象复制
- 118 系统视频播放