【问题标题】:How do I hide specific Group in ExpandableListView using CheckBox如何使用 CheckBox 在 ExpandableListView 中隐藏特定组
【发布时间】:2016-05-15 17:51:10
【问题描述】:

在我的 ExpandableListView 中,我有一个作为组的行星列表,我希望在选中主要活动中的 CheckBox 时其中一个组消失。 不幸的是,这种情况发生了:

Filter Unchecked

Filter Checked

这是影响视图可见性的代码。如您所见,我将 1 作为 'groupPosition' 的 int,因此被隐藏的视图应该是土星而不是木星,无论 '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();
            }
        }
    });

提前谢谢你。

编辑:这对克里斯很有效,谢谢。现在,我怎样才能有效地将此过滤器应用于此处的其中一个子视图? (孩子是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();
}

我试图根据它在 List 中的位置过滤掉一个字符串,并将其放回名为planet_child_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();
}

【问题讨论】:

    标签: java android android-studio expandablelistview expandablelistadapter


    【解决方案1】:

    使用ListViews,如果你保持严格的MVC,你会避免很多问题:

    • 控制器(即onCheckedChanged)更新模型。

    • 模型由getView(在您的情况下为getGroupView)转换为视图。

    您正在尝试直接从控制器更新视图。这总会导致问题。

    你需要做这样的事情:

    模型类(已编辑):

    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
    }
    

    【讨论】:

    • @Andrej 如果您愿意用您的适配器代码和模型(行星)代码更新您的问题,我会更新我的答案。它总是回到 MVC。该模型需要包含可扩展列表在任何给定时间点的状态。适配器应该具有更改模型的方法,其中 notifyDataSetChanged() 在最后被调用。
    • 是的,我在这里意外留下了评论,但我的问题已被编辑,谢谢 :)
    • 更新了我的答案。简而言之,适配器负责跟踪过滤后的组,组模型(Planet)被赋予了跟踪过滤后的孩子的职责。
    猜你喜欢
    • 1970-01-01
    • 2014-06-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-16
    • 1970-01-01
    • 2023-03-06
    • 1970-01-01
    相关资源
    最近更新 更多