前言:感觉自己在大学里学习android已经到了一个瓶颈,总觉得无法突破,思来想去觉得还是基础打的不够牢固,所以我决定在博客中把我学过的知识和新学的知识做一个总结,我将会好好地研究我写出的每一行代码,打牢自己的基础。
最近在完善自己程序的时候发现一个新的组件,用于列表的开合,例如qq好友的列表。今天在这做一个总结。话不多说直接开始!
先做我们的布局文件
- main布局文件中写入组件
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
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"
tools:context="Learn_Tedu.UI.ExpandableListText">
<ExpandableListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/expandablelist_1"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
- 父布局xml文件,这个是用来展现一级列表,负责点击展开与隐藏,这里可以根据自己需求自定义布局,包括下面要讲到的子布局xml文件
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/able_expandable_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="父布局测试"
android:textSize="30sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
- 子布局xml文件,用于二级列表:展开的列表;可根据自己需求自定义
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/able_expandable_child_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="子布局测试"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
ok,开始我们的代码部分
- 创建资源
public class ExpandableListText extends AppCompatActivity {
// 列表框
ExpandableListView listView;
// 父布局资源
String[] parentValues = {"第一个父列表","第二个父列表","第三个父列表"};
// 子布局资源
String[][] childValues = {
{"第一列表中的第一子列表","第一列表中的第二子列表","第一列表中的第三子列表"},
{"第二列表中的第一子列表","第二列表中的第二子列表"},
{"第三列表中的第一子列表"}};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_expandable_list_text);
setView();
}
/**
* 初始化布局文件
*/
private void setView() {
listView = findViewById(R.id.expandablelist_1);
// 设置适配器
listView.setAdapter(new MyAdapter());
}
}
- 构造适配器
/**
/**
* ExpandablelistView专用适配器
*/
class MyAdapter extends BaseExpandableListAdapter {
/**
* 获取父列表大小
* @return 大小
*/
@Override
public int getGroupCount() {
return parentValues.length;
}
/**
* 指定父布局下的子布局大小
* @param groupPosition 父布局下标
* @return 子布局大小
*/
@Override
public int getChildrenCount(int groupPosition) {
return childValues[groupPosition].length;
}
/**
* 加载父布局资源
* @param groupPosition 父布局下标
* @return 要设置的资源
*/
@Override
public Object getGroup(int groupPosition) {
return parentValues[groupPosition];
}
/**
* 加载子布局资源
* @param groupPosition 父布局下标
* @param childPosition 子布局下标
* @return 要设置的资源
*/
@Override
public Object getChild(int groupPosition, int childPosition) {
return childValues[groupPosition][childPosition];
}
/**
* 获取父布局的id
* @param groupPosition 父布局下标
* @return 父布局id
*/
@Override
public long getGroupId(int groupPosition) {
return groupPosition;
}
/**
* 获取子布局的id
* @param groupPosition 父布局id
* @param childPosition 子布局id
* @return 子布局id
*/
@Override
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
/**
* //分组和子选项是否持有稳定的ID,
* @return 是否稳定
*/
@Override
public boolean hasStableIds() {
return true;
}
/**
* 加载父布局视图
* @param groupPosition 父布局下标
* @param isExpanded 是否是展开状态
* @param convertView 重用已有的视图对象
* @param parent 视图组
* @return 父布局界面
*/
@Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
MyGroupHolder groupHolder;
if (convertView == null){
convertView = LayoutInflater.from(ExpandableListText.this).inflate(R.layout.able_expandable_parent,parent,
false);
groupHolder = new MyGroupHolder(convertView);
convertView.setTag(groupHolder);
} else {
groupHolder = (MyGroupHolder) convertView.getTag();
}
groupHolder.textView.setText(parentValues[groupPosition]);
return convertView;
}
/**
* 加载子布局文件
* @param groupPosition 父布局下标
* @param childPosition 子布局下标
* @param isLastChild 该子项是否为组中的最后一个子项
* @param convertView 重用已有的视图对象
* @param parent 视图组
* @return 子布局文件
*/
@Override
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
MyChildHolder childHolder;
if (convertView == null){
convertView = LayoutInflater.from(ExpandableListText.this).inflate(
R.layout.able_expandable_child,parent,false);
childHolder = new MyChildHolder(convertView);
convertView.setTag(childHolder);
}else{
childHolder = (MyChildHolder) convertView.getTag();
}
childHolder.textView.setText(childValues[groupPosition][childPosition]);
return convertView;
}
/**
* 指定的子列表是否可点击
* @param groupPosition 父布局下标
* @param childPosition 子布局下标
* @return 是否可点击
*/
@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
}
static class MyGroupHolder {
TextView textView;
MyGroupHolder(View view){
textView = view.findViewById(R.id.able_expandable_text);
};
}
static class MyChildHolder{
TextView textView;
MyChildHolder(View view){
textView = view.findViewById(R.id.able_expandable_child_text);
}
}
- 设置列表及监听事件
/**
* 设置展开列表
*/
private void setExpandable() {
// 默认打开或关闭所有列表
for (int i = 0; i < parentValues.length; i++){
listView.expandGroup(i);//打开指定列表
listView.collapseGroup(i);//关闭指定列表
}
//父列表点击事件
listView.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener() {
/**
*
* @param parent 点击的父组件
* @param v 点击的视图
* @param groupPosition 坐标
* @param id id
* @return 是否拦截
*/
@Override
public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition, long id) {
Log.d(TAG, "onGroupClick: 父列表被点击");
return false;
}
});
//父列表展开
listView.setOnGroupExpandListener(new ExpandableListView.OnGroupExpandListener() {
@Override
public void onGroupExpand(int groupPosition) {
Log.d(TAG, "onGroupExpand: 父列表展开" + groupPosition);
}
});
//父列表关闭
listView.setOnGroupCollapseListener(new ExpandableListView.OnGroupCollapseListener() {
@Override
public void onGroupCollapse(int groupPosition) {
Log.d(TAG, "onGroupCollapse: 父列表关闭" + groupPosition);
}
});
//子列表点击
listView.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
@Override
public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) {
Log.d(TAG, "onChildClick: 字列表点击");
return false;
}
});
}
对于ExpandableListview大概的功能就介绍到这里了,这些都是作者亲自实验过的,有什么问题和错误可以到评论区补充