目录
二,ExpandableListView 、BaseExpandableListAdapter的使用
ExpandableListAcitviy、BaseExpandableListAdapter配和,与 ExpandableListView BaseExpandableListAdapter配和实现一样的可折叠的ListView;
一,ExpandableListAcitviy,BaseExpandableListAdapter的使用
简介:ExpandableListActivity有一个默认布局,该布局由单个全屏居中的可展开列表组成。但是,如果需要自定义屏幕布局,可以通过在onCreate()中使用setContentView()设置自己的视图布局。自己的布局必须包含一个ID为“@android:id/list”的ExpandableListView对象。ExpandableListAcitviy的用法与ExpandableListView的用法基本相似,只要为该Activity传入一个ExpandableListAdapter对象即可,接下来ExpandableListAcitviy将会生成一个显示可展开列表的窗口。
可折叠的ListView
1,ExpandableListAcitviy的代码:
public class ExpandableListActivityTest extends ExpandableListActivity {
String[] armTypes = { "阿里", "百度", "腾讯" };
String[][] arms = { { "支付宝", "淘宝", "天猫","阿里云" }, { "搜索", "百度外卖", "百度钱包" }, { "QQ", "微信", "王者荣耀" } };
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
BaseExpandableListAdapter adapter = new MyExpandableListAdapter(this);
setListAdapter(adapter);
}
public class MyExpandableListAdapter extends BaseExpandableListAdapter{
private Context context;
private TextView getTextView() {
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, 70);
TextView textView = new TextView(ExpandableListActivityTest.this);
textView.setLayoutParams(lp);
textView.setGravity(Gravity.CENTER_VERTICAL | Gravity.LEFT);
textView.setPadding(36, 0, 0, 0);
textView.setTextSize(20);
return textView;
}
public MyExpandableListAdapter(Context context) {
this.context = context;
}
@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
@Override
public boolean hasStableIds() {
return true;
}
// 该方法决定每个组选项的UI显示
@Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
View view = null;
if(convertView==null)
view = View.inflate(context,R.layout.expandable_list_item,null);
else{
view= convertView;
}
TextView textView = view.findViewById(R.id.tv_expandable_content);
//设置textView的显示样式
textView.setTextSize(30);
textView.setPadding(50,5,0,5);
//向textView设置数据
String s = armTypes[groupPosition];
textView.setText(s);
return view;
}
@Override
public long getGroupId(int groupPosition) {
return groupPosition;
}
@Override
public int getGroupCount() {//组的数量
return armTypes.length;
}
@Override
public Object getGroup(int groupPosition) {
return armTypes[groupPosition];
}
@Override
public int getChildrenCount(int groupPosition) {//每组子项的数量
return arms[groupPosition].length;
}
// 该方法决定每个子选项的UI显示
@Override
public View getChildView(final int groupPosition, final int childPosition, boolean isLastChild, View convertView,
ViewGroup parent) {
TextView textView = getTextView();
textView.setText(getChild(groupPosition, childPosition).toString());
textView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(ExpandableListActivityTest.this,getChild(groupPosition, childPosition).toString(),Toast.LENGTH_LONG).show();
}
});
return textView;
}
@Override
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
@Override
public Object getChild(int groupPosition, int childPosition) {
return arms[groupPosition][childPosition];
}
}
}
2,每个组的子项布局(也就是二级目录的布局):expandable_list_item.xml
<?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="match_parent">
<TextView
android:id="@+id/tv_expandable_content"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
1.3,效果图,注意下图中自带一个上下的箭头,当点击打开二级目录时,箭头变成向上的;具体如下图;
二,ExpandableListView 、BaseExpandableListAdapter的使用
ExpandableListView 、BaseExpandableListAdapter配合使用就像ListView和BaseAdapter配合使用一样;这里ExpandableListActivity不再是必须的,可以在ExpandableListActivity使用,也可以在普通Activity中使用;以下以普通的activity为例进行介绍;
ExpandableListView 常用属性:
1. android:childDivider 指定各组内子类表项之间的分隔条,
2. android:childIndicator 显示在子列表旁边的Drawable对象
3. android:childIndicatorLeft 子列表项指示符的左边约束位置
4. android:childIndicatorRight 子列表项指示符的右边约束位置
5. android:groupIndicator 显示在组列表旁边的Drawable对象
6. android:indicatorLeft 组列表项指示器的左边约束位置
7. android:indicatorRight 组列表项指示器的右边约束位置
1,Activity的activity_expandable_list_view.xml 布局文件:
<LinearLayout 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"
tools:context=".ui.activity.ExpandableListViewActivity">
<ExpandableListView
android:id="@+id/elv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layoutDirection="rtl"/>
</LinearLayout>
2,group(一级目录)的布局group_itme.xml:
<?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="match_parent"
android:gravity="left"
android:layoutDirection="ltr">
<TextView
android:id="@+id/tv_expandable_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</LinearLayout>
3,每个group组的二级目录布局在代码中动态添加
//在MyBaseExpandableListAdapter中动态给二级目录添加布局
private TextView getTextView() {
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 70);
TextView textView = new TextView(context);
textView.setLayoutParams(lp);
textView.setGravity(Gravity.CENTER);
textView.setPadding(36, 0, 0, 0);
textView.setTextSize(20);
return textView;
}
4,继承BaseExpandableListAdapter的代码实现:
public class MyBaseExpandableListAdapter extends BaseExpandableListAdapter {
private Context context;
String[] armTypes = {"阿里", "百度", "腾讯"};
String[][] arms = {{"支付宝", "淘宝", "天猫", "阿里云"}, {"搜索", "百度外卖", "百度钱包"}, {"QQ", "微信", "王者荣耀"}};
private TextView getTextView() {
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 70);
TextView textView = new TextView(context);
textView.setLayoutParams(lp);
textView.setGravity(Gravity.CENTER);
textView.setPadding(36, 0, 0, 0);
textView.setTextSize(20);
return textView;
}
public MyBaseExpandableListAdapter(Context context) {
this.context = context;
}
@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
@Override
public boolean hasStableIds() {
return true;
}
// 该方法决定每个组选项的UI显示
@Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
GroupHolder groupHolder;
if (convertView == null) {
convertView = View.inflate(context, R.layout.expandable_group_item, null);
groupHolder = new GroupHolder();
groupHolder.groupTitle = convertView.findViewById(R.id.tv_expandable_content);
convertView.setTag(groupHolder);
} else {
groupHolder = (GroupHolder) convertView.getTag();
}
//设置textView的显示样式
groupHolder.groupTitle.setTextSize(28);
groupHolder.groupTitle.setPadding(70, 5, 0, 5);
//向textView设置数据
String s = armTypes[groupPosition];
groupHolder.groupTitle.setText(s);
return convertView;
}
@Override
public long getGroupId(int groupPosition) {
return groupPosition;
}
@Override
public int getGroupCount() {//组的数量
return armTypes.length;
}
@Override
public Object getGroup(int groupPosition) {
return armTypes[groupPosition];
}
@Override
public int getChildrenCount(int groupPosition) {//每组子项的数量
return arms[groupPosition].length;
}
// 该方法决定每个子选项的UI显示
@Override
public View getChildView(final int groupPosition, final int childPosition, boolean isLastChild, View convertView,
ViewGroup parent) {
TextView textView = getTextView();
textView.setText(getChild(groupPosition, childPosition).toString());
textView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(context, getChild(groupPosition, childPosition).toString(), Toast.LENGTH_LONG).show();
}
});
return textView;
}
@Override
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
@Override
public Object getChild(int groupPosition, int childPosition) {
return arms[groupPosition][childPosition];
}
class GroupHolder {
TextView groupTitle;
}
}
Activity的代码实现:
public class ExpandableListViewActivity extends AppCompatActivity {
private ExpandableListView elv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_expandable_list_view);
elv = findViewById(R.id.elv);
//用于是否显示group的图标
// elv.setGroupIndicator(null);
elv.setAdapter(new MyBaseExpandableListAdapter(this));
elv.setOnGroupExpandListener(new ExpandableListView.OnGroupExpandListener() {//只能打开一个group
@Override
public void onGroupExpand(int groupPosition) {
int count = new MyBaseExpandableListAdapter(ExpandableListViewActivity.this).getGroupCount();
for (int i = 0; i < count; i++) {
if (i != groupPosition) {
elv.collapseGroup(i);
}
}
}
});
}
}
注意:此种方式把自带的上下箭头的图标,设置到右边了;
效果图:
自定义Group类替换Adapter中的二维数组和一位数组,其实相当于List<String> groupList 和List<List<String>> itemList的组合实现替换一维数组和二维数组;
Group类:
public class Group {
//分组名
public String groupName;
//有很多User
public List<String> list;
public Group(String groupName) {
this.groupName = groupName;
list = new ArrayList<String>();
}
//添加User
public void addUser(String user) {
list.add(user);
}
//获取某个分组中User的数量
public int getChildCount() {
return list.size();
}
//获取某个分组中User在线的数量
// public int getOnlineCount() {
// int sum = 0;
// for (String user : list) {
// if (user.isOnline()) {
// sum++;
// }
// }
// return sum;
// }
//获取分组中的某个孩子
public String getChild(int childPosition) {
return list.get(childPosition);
}
}
ExpandableListViewActivity 代码:
public class ExpandableListViewActivity extends AppCompatActivity {
private ExpandableListView elv;
private List<Group> groupList = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_expandable_list_view);
elv = findViewById(R.id.elv);
//用于是否显示group的图标
// elv.setGroupIndicator(null);
initDate();
elv.setAdapter(new MyBaseExpandableListAdapter(this,groupList));
elv.setOnGroupExpandListener(new ExpandableListView.OnGroupExpandListener() {//只能打开一个group
@Override
public void onGroupExpand(int groupPosition) {
int count = new MyBaseExpandableListAdapter(ExpandableListViewActivity.this,groupList).getGroupCount();
for (int i = 0; i < count; i++) {
if (i != groupPosition) {
elv.collapseGroup(i);
}
}
}
});
}
private void initDate() {
Group group1 = new Group("阿里");
group1.addUser("支付宝");
group1.addUser("淘宝");
group1.addUser("天猫");
group1.addUser("阿里云");
group1.addUser("达摩院");
Group group2 = new Group("百度");
group2.addUser("搜索引擎");
group2.addUser("百度外卖");
group2.addUser("百度钱包");
group2.addUser("百度网盘");
Group group3 = new Group("腾讯");
group3.addUser("QQ");
group3.addUser("微信");
group3.addUser("王者荣耀");
group3.addUser("qq邮箱");
groupList.add(group1);
groupList.add(group2);
groupList.add(group3);
}
}
MyBaseExpandableListAdapter中的代码:
public class MyBaseExpandableListAdapter extends BaseExpandableListAdapter {
private Context context;
private List<Group> groupList = new ArrayList<>();
String[] armTypes = {"阿里", "百度", "腾讯"};
String[][] arms = {{"支付宝", "淘宝", "天猫", "阿里云"}, {"搜索", "百度外卖", "百度钱包"}, {"QQ", "微信", "王者荣耀"}};
private TextView getTextView() {
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 70);
TextView textView = new TextView(context);
textView.setLayoutParams(lp);
textView.setGravity(Gravity.CENTER);
textView.setPadding(36, 0, 0, 0);
textView.setTextSize(20);
return textView;
}
public MyBaseExpandableListAdapter(Context context) {
this.context = context;
}
public MyBaseExpandableListAdapter(Context context, List<Group> groupList) {
this.context = context;
this.groupList = groupList;
}
@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
@Override
public boolean hasStableIds() {
return true;
}
// 该方法决定每个组选项的UI显示
@Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
GroupHolder groupHolder;
if (convertView == null) {
convertView = View.inflate(context, R.layout.expandable_group_item, null);
groupHolder = new GroupHolder();
groupHolder.groupTitle = convertView.findViewById(R.id.tv_expandable_content);
convertView.setTag(groupHolder);
} else {
groupHolder = (GroupHolder) convertView.getTag();
}
//设置textView的显示样式
groupHolder.groupTitle.setTextSize(28);
groupHolder.groupTitle.setPadding(70, 5, 0, 5);
//向textView设置数据
String s = getGroup(groupPosition).groupName;
groupHolder.groupTitle.setText(s);
return convertView;
}
// 该方法决定每个子选项的UI显示
@Override
public View getChildView(final int groupPosition, final int childPosition, boolean isLastChild, View convertView,
ViewGroup parent) {
TextView textView = getTextView();
// textView.setText(getGroup(groupPosition).getChild(childPosition));
textView.setText(getChild(groupPosition,childPosition));
textView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(context, getChild(groupPosition, childPosition).toString(), Toast.LENGTH_LONG).show();
}
});
return textView;
}
@Override
public int getGroupCount() {//组的数量
return groupList.size();
}
@Override
public Group getGroup(int groupPosition) {
return groupList.get(groupPosition);
}
@Override
public int getChildrenCount(int groupPosition) {//每组子项的数量
return groupList.get(groupPosition).getChildCount();
}
@Override
public String getChild(int groupPosition, int childPosition) {
return groupList.get(groupPosition).getChild(childPosition);
}
@Override
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
@Override
public long getGroupId(int groupPosition) {
return groupPosition;
}
class GroupHolder {
TextView groupTitle;
}
}