如何使用 CheckBox 在 ExpandableListView 中隐藏特定组
How do I hide specific Group in ExpandableListView using CheckBox
在我的 ExpandableListView 中,我有一个行星组列表,我希望其中一个组在主 activity 的 CheckBox 被选中时消失。
不幸的是,这种情况发生了:
这是影响视图可见性的代码。如您所见,我将 1 作为 'groupPosition' 的整数,因此隐藏的视图应该是 Saturn 而不是 Jupiter,无论 'groupPosition' 的值是多少,结果都是相同的。
final MyAdapter myAdapter = new MyAdapter(this, headings, childList);
expandableListView.setAdapter(myAdapter);
checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener()
{
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
{
if(checkBox.isChecked()){
myAdapter.getGroupView(1,false,findViewById(R.id.planet), expandableListView).setVisibility(View.GONE);
myAdapter.notifyDataSetChanged();
}
if(!checkBox.isChecked()){
myAdapter.getGroupView(1,false,findViewById(R.id.planet), expandableListView).setVisibility(View.VISIBLE);
myAdapter.notifyDataSetChanged();
}
}
});
提前致谢。
编辑:这对 Kris 有用,谢谢。现在,我怎样才能有效地将此过滤器应用于此处的其中一个 childView? (children 是 HashMap)例如
public void childFilter(int position, boolean filterCheck) {
planet_child_shown.clear();
String str;
if(!filterCheck) {
for (List<String> l : planet_child.values()) {
for (int i = 0; i < l.size(); i++) {
if (i!=position) {
str = l.get(i);
l.add(str);
}
}
}
}
notifyDataSetChanged();
}
我正在尝试根据字符串在此处的列表<> 中的位置过滤掉一个字符串,然后将其放回自己的名为 planet_child_shown 的 "shown" HashMap> 中。然而,这总是抛出一个 nullPointer,并指向我的 getChildrenCount() 方法,我在你的 getGroupCount():
之后建模
public int getChildrenCount(int groupPosition) {
return planet_child_shown == null ? 0 : planet_child_shown.get(mPlanetShown.get(groupPosition).name)
.size();
}
使用 ListView
s,如果你保持严格的 MVC,你将避免很多问题:
控制器(即onCheckedChanged
)更新模型。
模型由 getView
转换为视图(在您的情况下,getGroupView
)。
您正在尝试直接从控制器更新视图。这总是会引起问题。
你需要做这样的事情:
型号class(已编辑):
public class Planet {
public String name;
public boolean filtered;
private List<String> mChildren;
private List<Boolean> mChildrenFiltered;
private List<String> mChildrenShown;
public Planet(String name, List<String> children) {
this.name = name;
mChildren = children;
mChildrenFiltered = new ArrayList<>();
for (String child : children) {
mChildrenFiltered.add(false);
}
mChildrenShown = new ArrayList<>(children);
}
public int getChildrenCount() {
return mChildrenShown == null ? 0 : mChildrenShown.size();
}
public String getChild(int position) {
return mChildrenShown.get(i);
}
public void filter(String child, boolean filter) {
mChildrenShown.clear();
for (int i = 0; i < mChildren.size(); i++) {
if (mChildren.get(i).equals(child)) {
mChildrenFiltered.set(i, filter);
}
if (! mChildrenFiltered.get(i)) {
mChildrenShown.add(mChildren.get(i));
}
}
}
}
控制器:
final MyAdapter myAdapter = new MyAdapter(this, headings, childList);
expandableListView.setAdapter(myAdapter);
checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
myAdapter.filter("Saturn", isChecked);
}
});
现在在您的适配器中,您将有两个列表:所有行星的列表和将出现在您的 ExpandableListView
中的行星列表。选中该复选框将仅更改显示的行星列表,这是您在创建组视图时将使用的内容。
MyAdapter.java
:(已编辑,添加了子过滤器方法)
public class MyAdapter extends BaseExpandableListAdapter {
private List<Planet> mPlanets;
private List<Planet> mPlanetsShown;
public MyAdapter(List<Planet> planets) {
mPlanets = planets;
mPlanetsShown = new ArrayList<>(mPlanets);
}
@Override
public int getGroupCount() {
return mPlanetsShown == null ? 0 : mPlanetsShown.size();
}
@Override
public Object getGroup(int groupPosition) {
return mPlanetsShown == null ? null : mPlanetsShown.get(groupPosition);
}
@Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
Planet planet = (Planet) getGroup(groupPosition);
// TODO create the view
return null;
}
@Override
public int getChildrenCount(int groupPosition) {
return mPlanetsShown.get(groupPosition).getChildrenCount();
}
@Override
public Object getChild(int groupPosition, int childPosition) {
return mPlanetsShown.get(groupPosition).getChild(childPosition);
}
@Override
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View view, ViewGroup parent) {
String child = mPlanetsShown.get(groupPosition).getChild(childPosition);
// TODO create the view
return null;
}
public void filter(String planetName, boolean filter) {
mPlanetsShown.clear();
for (Planet planet : mPlanets) {
// if this is the planet we are changing, set the flag
if (planet.name.equals(planetName)) {
planet.filtered = filter;
}
// whether this is the planet we are changing or not,
// add this to planets shown if the flag is not set
if (! planet.filtered) {
mPlanetsShown.add(planet);
}
}
notifyDataSetChanged();
}
public void filter(String planetName, String childName, boolean filter) {
for (Planet planet : mPlanets) {
if (planet.name.equals(planetName)) {
planet.filter(childName, filter);
}
}
notifyDataSetChanged();
}
// TODO some code left out here
}
在我的 ExpandableListView 中,我有一个行星组列表,我希望其中一个组在主 activity 的 CheckBox 被选中时消失。 不幸的是,这种情况发生了:
这是影响视图可见性的代码。如您所见,我将 1 作为 'groupPosition' 的整数,因此隐藏的视图应该是 Saturn 而不是 Jupiter,无论 'groupPosition' 的值是多少,结果都是相同的。
final MyAdapter myAdapter = new MyAdapter(this, headings, childList);
expandableListView.setAdapter(myAdapter);
checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener()
{
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
{
if(checkBox.isChecked()){
myAdapter.getGroupView(1,false,findViewById(R.id.planet), expandableListView).setVisibility(View.GONE);
myAdapter.notifyDataSetChanged();
}
if(!checkBox.isChecked()){
myAdapter.getGroupView(1,false,findViewById(R.id.planet), expandableListView).setVisibility(View.VISIBLE);
myAdapter.notifyDataSetChanged();
}
}
});
提前致谢。
编辑:这对 Kris 有用,谢谢。现在,我怎样才能有效地将此过滤器应用于此处的其中一个 childView? (children 是 HashMap)例如
public void childFilter(int position, boolean filterCheck) {
planet_child_shown.clear();
String str;
if(!filterCheck) {
for (List<String> l : planet_child.values()) {
for (int i = 0; i < l.size(); i++) {
if (i!=position) {
str = l.get(i);
l.add(str);
}
}
}
}
notifyDataSetChanged();
}
我正在尝试根据字符串在此处的列表<> 中的位置过滤掉一个字符串,然后将其放回自己的名为 planet_child_shown 的 "shown" HashMap> 中。然而,这总是抛出一个 nullPointer,并指向我的 getChildrenCount() 方法,我在你的 getGroupCount():
之后建模public int getChildrenCount(int groupPosition) {
return planet_child_shown == null ? 0 : planet_child_shown.get(mPlanetShown.get(groupPosition).name)
.size();
}
使用 ListView
s,如果你保持严格的 MVC,你将避免很多问题:
控制器(即
onCheckedChanged
)更新模型。模型由
getView
转换为视图(在您的情况下,getGroupView
)。
您正在尝试直接从控制器更新视图。这总是会引起问题。
你需要做这样的事情:
型号class(已编辑):
public class Planet {
public String name;
public boolean filtered;
private List<String> mChildren;
private List<Boolean> mChildrenFiltered;
private List<String> mChildrenShown;
public Planet(String name, List<String> children) {
this.name = name;
mChildren = children;
mChildrenFiltered = new ArrayList<>();
for (String child : children) {
mChildrenFiltered.add(false);
}
mChildrenShown = new ArrayList<>(children);
}
public int getChildrenCount() {
return mChildrenShown == null ? 0 : mChildrenShown.size();
}
public String getChild(int position) {
return mChildrenShown.get(i);
}
public void filter(String child, boolean filter) {
mChildrenShown.clear();
for (int i = 0; i < mChildren.size(); i++) {
if (mChildren.get(i).equals(child)) {
mChildrenFiltered.set(i, filter);
}
if (! mChildrenFiltered.get(i)) {
mChildrenShown.add(mChildren.get(i));
}
}
}
}
控制器:
final MyAdapter myAdapter = new MyAdapter(this, headings, childList);
expandableListView.setAdapter(myAdapter);
checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
myAdapter.filter("Saturn", isChecked);
}
});
现在在您的适配器中,您将有两个列表:所有行星的列表和将出现在您的 ExpandableListView
中的行星列表。选中该复选框将仅更改显示的行星列表,这是您在创建组视图时将使用的内容。
MyAdapter.java
:(已编辑,添加了子过滤器方法)
public class MyAdapter extends BaseExpandableListAdapter {
private List<Planet> mPlanets;
private List<Planet> mPlanetsShown;
public MyAdapter(List<Planet> planets) {
mPlanets = planets;
mPlanetsShown = new ArrayList<>(mPlanets);
}
@Override
public int getGroupCount() {
return mPlanetsShown == null ? 0 : mPlanetsShown.size();
}
@Override
public Object getGroup(int groupPosition) {
return mPlanetsShown == null ? null : mPlanetsShown.get(groupPosition);
}
@Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
Planet planet = (Planet) getGroup(groupPosition);
// TODO create the view
return null;
}
@Override
public int getChildrenCount(int groupPosition) {
return mPlanetsShown.get(groupPosition).getChildrenCount();
}
@Override
public Object getChild(int groupPosition, int childPosition) {
return mPlanetsShown.get(groupPosition).getChild(childPosition);
}
@Override
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View view, ViewGroup parent) {
String child = mPlanetsShown.get(groupPosition).getChild(childPosition);
// TODO create the view
return null;
}
public void filter(String planetName, boolean filter) {
mPlanetsShown.clear();
for (Planet planet : mPlanets) {
// if this is the planet we are changing, set the flag
if (planet.name.equals(planetName)) {
planet.filtered = filter;
}
// whether this is the planet we are changing or not,
// add this to planets shown if the flag is not set
if (! planet.filtered) {
mPlanetsShown.add(planet);
}
}
notifyDataSetChanged();
}
public void filter(String planetName, String childName, boolean filter) {
for (Planet planet : mPlanets) {
if (planet.name.equals(planetName)) {
planet.filter(childName, filter);
}
}
notifyDataSetChanged();
}
// TODO some code left out here
}