先上图:
页面布局
布局很简单,就一个ExpandableListView ,直接上布局截图,相信各位能看懂
由于其控件会默认自带箭头,我们可以通过XML中在ExpandableListView控件加上
android:groupIndicator="@null"
取消掉其自带的指示器箭头,当然除了在xml上,也可通过在代码中,当绑定完控件后调用代码也可实现取消效果
expandableListView.setGroupIndicator(null);
接下来是我们重点要研究的适配器FoodinfoExpandableAdapter,继承并重写了BaseExpandableListAdapter这个类的相关函数,其中注释我已经详细写在代码中,若是不懂或者写错,希望各位可以交流或指出,大家一起加深对其认识。
public class FoodinfoExpandableAdapter extends BaseExpandableListAdapter {
private final Context context;
private List<Foodinfo> data;
public FoodinfoExpandableAdapter(Context context, List<Foodinfo> data) {
this.context = context;
this.data = data;
}
/**
* 获取组的数目
*
* @return 返回一级列表组的数量
*/
@Override
public int getGroupCount() {
return data == null ? 0 : data.size();
}
/**
* 获取指定组中的子节点数量
*
* @param groupPosition 子元素组所在的位置
* @return 返回指定组中的子数量
*/
@Override
public int getChildrenCount(int groupPosition) {
return data.get(groupPosition).getFoodinfoChildrenList().size();
}
/**
* 获取与给定组相关联的对象
*
* @param groupPosition 子元素组所在的位置
* @return 返回指定组的子数据
*/
@Override
public Object getGroup(int groupPosition) {
return data.get(groupPosition).getFoodType();
}
/**
* 获取与给定组中的给定子元素关联的数据
*
* @param groupPosition 子元素组所在的位置
* @param childPosition 子元素的位置
* @return 返回子元素的对象
*/
@Override
public Object getChild(int groupPosition, int childPosition) {
return data.get(groupPosition).getFoodinfoChildrenList().get(childPosition);
}
/**
* 获取组在给定位置的ID(唯一的)
*
* @param groupPosition 子元素组所在的位置
* @return 返回关联组ID
*/
@Override
public long getGroupId(int groupPosition) {
return groupPosition;
}
/**
* 获取给定组中给定子元素的ID(唯一的)
*
* @param groupPosition 子元素组所在的位置
* @param childPosition 子元素的位置
* @return 返回子元素关联的ID
*/
@Override
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
/**
* @return 确定id 是否总是指向同一个对象
*/
@Override
public boolean hasStableIds() {
return true;
}
/**
* @return 返回指定组的对应的视图 (一级列表样式)
*/
@Override
public View getGroupView(final int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
ParentHolder parentHolder;
if (convertView == null) {
convertView = LayoutInflater.from(context).inflate(R.layout.level_item, null);
parentHolder = new ParentHolder();
parentHolder.tvParent = convertView.findViewById(R.id.tv_parent);
parentHolder.img_left = convertView.findViewById(R.id.img_left);
parentHolder.img_right = convertView.findViewById(R.id.img_right);
convertView.setTag(parentHolder);
} else {
parentHolder = (ParentHolder) convertView.getTag();
}
parentHolder.tvParent.setText(data.get(groupPosition).getFoodType());
parentHolder.img_left.setImageResource(data.get(groupPosition).getFoodTypeImg());
//共用一个右箭头,如果展开则顺时针旋转90°选择,否则不旋转
if (isExpanded) parentHolder.img_right.setRotation(90F);
else parentHolder.img_right.setRotation(0F);
return convertView;
}
/**
* @return 返回指定位置对应子视图的视图
*/
@Override
public View getChildView(final int groupPosition, final int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
final ChildrenHolder childrenHolder;
if (convertView == null) {
convertView = LayoutInflater.from(context).inflate(R.layout.level2_item, null);
childrenHolder = new ChildrenHolder();
childrenHolder.tvChild = convertView.findViewById(R.id.tv_child);
childrenHolder.imageView = convertView.findViewById(R.id.child_img);
convertView.setTag(childrenHolder);
} else {
childrenHolder = (ChildrenHolder) convertView.getTag();
}
childrenHolder.tvChild.setText(data.get(groupPosition).getFoodinfoChildrenList().get(childPosition).getName());
childrenHolder.imageView.setImageResource(data.get(groupPosition).getFoodinfoChildrenList().get(childPosition).getFoodinfoChildrenImg());
return convertView;
}
/**
* 指定位置的子元素是否可选
*
* @param groupPosition 子元素组所在的位置
* @param childPosition 子元素的位置
* @return 返回是否可选
*/
@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
class ParentHolder {
TextView tvParent;
ImageView img_left, img_right;
}
class ChildrenHolder {
TextView tvChild;
ImageView imageView;
}
}
父布局使用的xml:
子布局使用的xml:
注意在getGroupView中getGroupView的控件不能设置一些抢占焦点的事件或属性,如点击事件或者在代码布局里设置了focusable属性为true,都会导致无法展开子列表。
实体类Foodinfo代码如下:
public class Foodinfo {
private String foodType;
private int foodTypeImg;
private List<FoodinfoChildren> foodinfoChildrenList;
public Foodinfo(String foodType, int foodTypeImg, List<FoodinfoChildren> foodinfoChildrenList) {
this.foodType = foodType;
this.foodTypeImg = foodTypeImg;
this.foodinfoChildrenList = foodinfoChildrenList;
}
public String getFoodType() {
return foodType;
}
public void setFoodType(String foodType) {
this.foodType = foodType;
}
public int getFoodTypeImg() {
return foodTypeImg;
}
public void setFoodTypeImg(int foodTypeImg) {
this.foodTypeImg = foodTypeImg;
}
public List<FoodinfoChildren> getFoodinfoChildrenList() {
return foodinfoChildrenList;
}
public void setFoodinfoChildrenList(List<FoodinfoChildren> foodinfoChildrenList) {
this.foodinfoChildrenList = foodinfoChildrenList;
}
}
最后是在我们的主界面中实现代码
public class Food_information_Activity extends AppCompatActivity {
private static List<Foodinfo> foodinfoList;
private static FoodinfoExpandableAdapter foodinfoExpandableAdapter;
private ExpandableListView listView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_food_information);
getSupportActionBar().hide();
TextView title = findViewById(R.id.title_layout);
title.setText("食物分类");
listView = findViewById(R.id.food_info_list);
initData();
initAdapter();
}
private final String[] foodTypes = {"鱼肉海鲜", "肉类", "蔬菜豆类", "水果"};
private final int[] foodTypeImg = {R.drawable.type1, R.drawable.type2, R.drawable.type3, R.drawable.type4};
private final String[] yl = {"草鱼", "鲤鱼", "鲫鱼", "鱿鱼"};
private final int[] ylImg = {R.drawable.yl1, R.drawable.yl2, R.drawable.yl3, R.drawable.yl4};
private final String[] rl = {"牛肉", "猪肉", "羊肉", "鸡肉"};
private final int[] rlImg = {R.drawable.rl1, R.drawable.rl2, R.drawable.rl3, R.drawable.rl4};
private final String[] sd = {"豌豆", "胡萝卜", "生菜", "空心菜"};
private final int[] sdImg = {R.drawable.sd1, R.drawable.sd2, R.drawable.sd3, R.drawable.sd4};
private final String[] sg = {"橘子", "哈密瓜", "苹果", "黄桃"};
private final int[] sgImg = {R.drawable.sg1, R.drawable.sg2, R.drawable.sg3, R.drawable.sg4};
private void initData() {
foodinfoList = new ArrayList<>();
List<FoodinfoChildren> ylFood = new ArrayList<>();
for (int j = 0; j < 4; j++) {
ylFood.add(new FoodinfoChildren(yl[j], ylImg[j]));
}
List<FoodinfoChildren> rlFood = new ArrayList<>();
for (int j = 0; j < 4; j++) {
rlFood.add(new FoodinfoChildren(rl[j], rlImg[j]));
}
List<FoodinfoChildren> sdFood = new ArrayList<>();
for (int j = 0; j < 4; j++) {
sdFood.add(new FoodinfoChildren(sd[j], sdImg[j]));
}
List<FoodinfoChildren> sgFood = new ArrayList<>();
for (int j = 0; j < 4; j++) {
sgFood.add(new FoodinfoChildren(sg[j], sgImg[j]));
}
foodinfoList.add(new Foodinfo(foodTypes[0], foodTypeImg[0], ylFood));
foodinfoList.add(new Foodinfo(foodTypes[1], foodTypeImg[1], rlFood));
foodinfoList.add(new Foodinfo(foodTypes[2], foodTypeImg[2], sdFood));
foodinfoList.add(new Foodinfo(foodTypes[3], foodTypeImg[3], sgFood));
}
private void initAdapter() {
foodinfoExpandableAdapter = new FoodinfoExpandableAdapter(this, foodinfoList);
listView.setAdapter(foodinfoExpandableAdapter);
/**
* 默认展开某个item
* */
//expandableListView.expandGroup(1);
}
}