Multi-level Android 中带有复选框的 ExpandableListView
Multi-level ExpandableListView with CheckBoxes in Android
我正在尝试在 Android 中实现 3 级 ExpandableListView
。
看起来像这样:
- 1 级
- 2 级
- 2级
- 3 级
- 2 级
- 1 级
- 2 级
- 2 级
2 级和 3 级应该有 CheckBox
-es。 And when CheckBox
in Level 2 is selected, all his children in Level 3 are selected as well.
我已经完成了 2 个适配器 - 都扩展了 BaseExpandableListAdapter
。所以最后我插入了 2 个 ExpandableListView
-s - 一个用于 1 级 - 2 级,另一个用于 2 级 - 3 级。
我还有 2 个单独的布局 - 一个用于级别 1,一个用于级别 2-3(因为它们是相同的)。它s just a
TextViewwith id inside
RelativeView`.
题目:
当我将 TextView
更改为 CheckBox
es 并将文本设置为它们时,我无法将列表扩展到第三级。我不明白为什么会发生这种情况以及如何处理它,有人可以帮助我吗?
如何在没有 children 的 2 级项目中隐藏指标(那些箭头显示 expanded/collapsed 状态)?
我不明白为什么我的 ExpandableListView
不想垂直放满所有屏幕,它只占用了它的 1/4。我尝试更改 CustomExpandableListView
中的一些参数,但没有成功。
这里是一些截图:
截图一:
截图二:
如您所见,当我展开亚洲列表时,欧洲列表会自动隐藏。
这是级别 1 的代码:
public class RegionsAdapter extends BaseExpandableListAdapter {
private List<Object> objects;
private Activity activity;
private LayoutInflater inflater;
public RegionsAdapter(Activity activity, List<Object> objects) {
this.objects = objects;
this.activity = activity;
this.inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public Object getChild(int groupPosition, int childPosition) {
return objects.get(groupPosition).getObjects().get(childPosition);
}
@Override
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
@Override
public View getChildView(int groupPosition, int childPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
Object object = (Object) getChild(groupPosition, childPosition);
CustomExpandableListView subObjects = (CustomExpandableListView) convertView;
if (convertView == null) {
subObjects = new CustomExpandableListView(activity);
}
CountriesAdapter adapter = new CountriesAdapter(activity, object);
subObjects.setAdapter(adapter);
return subObjects;
}
@Override
public int getChildrenCount(int groupPosition) {
return objects.get(groupPosition).getObjects().size();
}
@Override
public Object getGroup(int groupPosition) {
return objects.get(groupPosition);
}
@Override
public int getGroupCount() {
return objects.size();
}
@Override
public long getGroupId(int groupPosition) {
return groupPosition;
}
@Override
public View getGroupView(int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
Object object = (Object) getGroup(groupPosition);
if (convertView == null) {
convertView = inflater.inflate(R.layout.layout_region_item, null);
}
TextView name = (TextView) convertView.findViewById(R.id.name);
name.setText(object.getName());
return convertView;
}
@Override
public boolean hasStableIds() {
return true;
}
@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
}
2-3级代码:
public class CountriesAdapter extends BaseExpandableListAdapter {
private Object object;
private LayoutInflater inflater;
private Activity activity;
public CountriesAdapter(Activity activity, Object object) {
this.activity = activity;
this.object = object;
this.inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public Object getChild(int groupPosition, int childPosition) {
return object.getObjects().get(childPosition);
}
@Override
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
@Override
public View getChildView(int groupPosition, int childPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
Object object = (Object) getChild(0, childPosition);
if (convertView == null) {
convertView = inflater.inflate(R.layout.layout_country_item, null);
Resources r = activity.getResources();
float px40 = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 40, r.getDisplayMetrics());
convertView.setPadding(
convertView.getPaddingLeft() + (int) px40,
convertView.getPaddingTop(),
convertView.getPaddingRight(),
convertView.getPaddingBottom());
}
TextView name = (TextView) convertView.findViewById(R.id.name);
name.setText(object.getName());
return convertView;
}
@Override
public int getChildrenCount(int groupPosition) {
if (object.getObjects() == null) {
return 0;
}
return object.getObjects().size();
}
@Override
public Object getGroup(int groupPosition) {
return object;
}
@Override
public int getGroupCount() {
return 1;
}
@Override
public long getGroupId(int groupPosition) {
return groupPosition;
}
@Override
public View getGroupView(int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = inflater.inflate(R.layout.layout_country_item, null);
Resources r = activity.getResources();
float px20 = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 20, r.getDisplayMetrics());
convertView.setPadding(
convertView.getPaddingLeft() + (int) px20,
convertView.getPaddingTop(),
convertView.getPaddingRight(),
convertView.getPaddingBottom());
}
TextView name = (TextView) convertView.findViewById(R.id.name);
name.setText(object.getName());
return convertView;
}
@Override
public boolean hasStableIds() {
return true;
}
@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
}
我还有一些自定义的 ExpandableListView:
public class CustomExpandableListView extends ExpandableListView {
public CustomExpandableListView(Context context) {
super(context);
}
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
widthMeasureSpec = MeasureSpec.makeMeasureSpec(960, MeasureSpec.AT_MOST);
heightMeasureSpec = MeasureSpec.makeMeasureSpec(600, MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
而我的 MainActivity 代码:
public class MainActivity extends AppCompatActivity {
public static CustomExpandableListView list;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
List<Item> objectsLvl1 = new ArrayList<Item>();
List<Item> objectsAsia = new ArrayList<Item>();
List<Item> objectsEurope = new ArrayList<Item>();
List<Item> objectsChina = new ArrayList<Item>();
List<Item> objectsGermany = new ArrayList<Item>();
objectsLvl1.add(new Item("Asia", objectsAsia));
objectsLvl1.add(new Item("Europe", objectsEurope));
objectsAsia.add(new Item("China", objectsChina));
objectsAsia.add(new Item("Japan"));
objectsChina.add(new Item("Central", null));
objectsChina.add(new Item("North", null));
objectsChina.add(new Item("South", null));
RelativeLayout parent = (RelativeLayout) findViewById(R.id.parent);
list = new CustomExpandableListView(this);
RegionsAdapter regionsAdapter = new RegionsAdapter(this, objectsLvl1);
list.setAdapter(regionsAdapter);
if (parent != null) {
parent.addView(list);
}
}
}
最后我想通了。这就是答案。
- 用复选框扩展列表:
这个很简单。我在 getGroupView
方法中将 OnClickListener
添加到 TextView
:
View.OnClickListener clickListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
if (!isExpanded) {
expandableListView.expandGroup(groupPosition);
} else {
expandableListView.collapseGroup(groupPosition);
}
}
};
holder.childName.setOnClickListener(clickListener);
holder.childIndicator.setOnClickListener(clickListener);
- 隐藏指标:
替换标准指标和添加我自己的指标更容易。然后,在 getGroupView
中使用它。
首先,将默认的groupIndicator
设置为null
:
expandableListView.setGroupIndicator(null);
然后,使用自定义图像:
holder.childIndicator = (ImageView) convertView.findViewById(R.id.imgChildIndicator);
if (getChildrenCount(groupPosition) == 0) {
holder.childIndicator.setAlpha(0);
} else {
holder.childIndicator.setImageResource(isExpanded ? R.drawable.expanded : R.drawable.collapsed);
}
最后,隐藏我所有 3 级物品的 groupIndicator
:
holder.childIndicator.setAlpha(0);
对 1 级项目进行了相同的更改。
- 在屏幕上适配 ExpandableListView:
我把 ExpandableListView
放在 activity_main
中的 RelativeLayout
里。
并且在MainActivity:
里面改变了实现
ExpandableListView list = (ExpandableListView) findViewById(R.id.expandableListView_Parent);
if (list != null) {
ParentAdapter adapter = new ParentAdapter(this, objectsLvl1);
list.setAdapter(adapter);
}
这解决了我的问题,现在我有了全屏 ExpandableList
。
我正在尝试在 Android 中实现 3 级 ExpandableListView
。
看起来像这样:
- 1 级
- 2 级
- 2级
- 3 级
- 2 级
- 1 级
- 2 级
- 2 级
2 级和 3 级应该有 CheckBox
-es。 And when CheckBox
in Level 2 is selected, all his children in Level 3 are selected as well.
我已经完成了 2 个适配器 - 都扩展了 BaseExpandableListAdapter
。所以最后我插入了 2 个 ExpandableListView
-s - 一个用于 1 级 - 2 级,另一个用于 2 级 - 3 级。
我还有 2 个单独的布局 - 一个用于级别 1,一个用于级别 2-3(因为它们是相同的)。它s just a
TextViewwith id inside
RelativeView`.
题目:
当我将
TextView
更改为CheckBox
es 并将文本设置为它们时,我无法将列表扩展到第三级。我不明白为什么会发生这种情况以及如何处理它,有人可以帮助我吗?如何在没有 children 的 2 级项目中隐藏指标(那些箭头显示 expanded/collapsed 状态)?
我不明白为什么我的
ExpandableListView
不想垂直放满所有屏幕,它只占用了它的 1/4。我尝试更改CustomExpandableListView
中的一些参数,但没有成功。
这里是一些截图:
截图一:
截图二:
如您所见,当我展开亚洲列表时,欧洲列表会自动隐藏。
这是级别 1 的代码:
public class RegionsAdapter extends BaseExpandableListAdapter {
private List<Object> objects;
private Activity activity;
private LayoutInflater inflater;
public RegionsAdapter(Activity activity, List<Object> objects) {
this.objects = objects;
this.activity = activity;
this.inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public Object getChild(int groupPosition, int childPosition) {
return objects.get(groupPosition).getObjects().get(childPosition);
}
@Override
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
@Override
public View getChildView(int groupPosition, int childPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
Object object = (Object) getChild(groupPosition, childPosition);
CustomExpandableListView subObjects = (CustomExpandableListView) convertView;
if (convertView == null) {
subObjects = new CustomExpandableListView(activity);
}
CountriesAdapter adapter = new CountriesAdapter(activity, object);
subObjects.setAdapter(adapter);
return subObjects;
}
@Override
public int getChildrenCount(int groupPosition) {
return objects.get(groupPosition).getObjects().size();
}
@Override
public Object getGroup(int groupPosition) {
return objects.get(groupPosition);
}
@Override
public int getGroupCount() {
return objects.size();
}
@Override
public long getGroupId(int groupPosition) {
return groupPosition;
}
@Override
public View getGroupView(int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
Object object = (Object) getGroup(groupPosition);
if (convertView == null) {
convertView = inflater.inflate(R.layout.layout_region_item, null);
}
TextView name = (TextView) convertView.findViewById(R.id.name);
name.setText(object.getName());
return convertView;
}
@Override
public boolean hasStableIds() {
return true;
}
@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
}
2-3级代码:
public class CountriesAdapter extends BaseExpandableListAdapter {
private Object object;
private LayoutInflater inflater;
private Activity activity;
public CountriesAdapter(Activity activity, Object object) {
this.activity = activity;
this.object = object;
this.inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public Object getChild(int groupPosition, int childPosition) {
return object.getObjects().get(childPosition);
}
@Override
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
@Override
public View getChildView(int groupPosition, int childPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
Object object = (Object) getChild(0, childPosition);
if (convertView == null) {
convertView = inflater.inflate(R.layout.layout_country_item, null);
Resources r = activity.getResources();
float px40 = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 40, r.getDisplayMetrics());
convertView.setPadding(
convertView.getPaddingLeft() + (int) px40,
convertView.getPaddingTop(),
convertView.getPaddingRight(),
convertView.getPaddingBottom());
}
TextView name = (TextView) convertView.findViewById(R.id.name);
name.setText(object.getName());
return convertView;
}
@Override
public int getChildrenCount(int groupPosition) {
if (object.getObjects() == null) {
return 0;
}
return object.getObjects().size();
}
@Override
public Object getGroup(int groupPosition) {
return object;
}
@Override
public int getGroupCount() {
return 1;
}
@Override
public long getGroupId(int groupPosition) {
return groupPosition;
}
@Override
public View getGroupView(int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = inflater.inflate(R.layout.layout_country_item, null);
Resources r = activity.getResources();
float px20 = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 20, r.getDisplayMetrics());
convertView.setPadding(
convertView.getPaddingLeft() + (int) px20,
convertView.getPaddingTop(),
convertView.getPaddingRight(),
convertView.getPaddingBottom());
}
TextView name = (TextView) convertView.findViewById(R.id.name);
name.setText(object.getName());
return convertView;
}
@Override
public boolean hasStableIds() {
return true;
}
@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
}
我还有一些自定义的 ExpandableListView:
public class CustomExpandableListView extends ExpandableListView {
public CustomExpandableListView(Context context) {
super(context);
}
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
widthMeasureSpec = MeasureSpec.makeMeasureSpec(960, MeasureSpec.AT_MOST);
heightMeasureSpec = MeasureSpec.makeMeasureSpec(600, MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
而我的 MainActivity 代码:
public class MainActivity extends AppCompatActivity {
public static CustomExpandableListView list;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
List<Item> objectsLvl1 = new ArrayList<Item>();
List<Item> objectsAsia = new ArrayList<Item>();
List<Item> objectsEurope = new ArrayList<Item>();
List<Item> objectsChina = new ArrayList<Item>();
List<Item> objectsGermany = new ArrayList<Item>();
objectsLvl1.add(new Item("Asia", objectsAsia));
objectsLvl1.add(new Item("Europe", objectsEurope));
objectsAsia.add(new Item("China", objectsChina));
objectsAsia.add(new Item("Japan"));
objectsChina.add(new Item("Central", null));
objectsChina.add(new Item("North", null));
objectsChina.add(new Item("South", null));
RelativeLayout parent = (RelativeLayout) findViewById(R.id.parent);
list = new CustomExpandableListView(this);
RegionsAdapter regionsAdapter = new RegionsAdapter(this, objectsLvl1);
list.setAdapter(regionsAdapter);
if (parent != null) {
parent.addView(list);
}
}
}
最后我想通了。这就是答案。
- 用复选框扩展列表:
这个很简单。我在 getGroupView
方法中将 OnClickListener
添加到 TextView
:
View.OnClickListener clickListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
if (!isExpanded) {
expandableListView.expandGroup(groupPosition);
} else {
expandableListView.collapseGroup(groupPosition);
}
}
};
holder.childName.setOnClickListener(clickListener);
holder.childIndicator.setOnClickListener(clickListener);
- 隐藏指标:
替换标准指标和添加我自己的指标更容易。然后,在 getGroupView
中使用它。
首先,将默认的groupIndicator
设置为null
:
expandableListView.setGroupIndicator(null);
然后,使用自定义图像:
holder.childIndicator = (ImageView) convertView.findViewById(R.id.imgChildIndicator);
if (getChildrenCount(groupPosition) == 0) {
holder.childIndicator.setAlpha(0);
} else {
holder.childIndicator.setImageResource(isExpanded ? R.drawable.expanded : R.drawable.collapsed);
}
最后,隐藏我所有 3 级物品的 groupIndicator
:
holder.childIndicator.setAlpha(0);
对 1 级项目进行了相同的更改。
- 在屏幕上适配 ExpandableListView:
我把 ExpandableListView
放在 activity_main
中的 RelativeLayout
里。
并且在MainActivity:
里面改变了实现ExpandableListView list = (ExpandableListView) findViewById(R.id.expandableListView_Parent);
if (list != null) {
ParentAdapter adapter = new ParentAdapter(this, objectsLvl1);
list.setAdapter(adapter);
}
这解决了我的问题,现在我有了全屏 ExpandableList
。