【问题标题】:How avoid refresh checkbox while expand list in android在android中展开列表时如何避免刷新复选框
【发布时间】:2017-04-04 05:13:31
【问题描述】:

我正在使用列表视图制作 NLevel 可扩展列表。我在列表视图中仅添加了复选框的最后一级数据。我陷入了以下情况。

如果我选中复选框,那么当我展开列表视图时,意味着复选框会自动取消选中。我不希望它是那样的。如果我选中复选框,它应该保持选中状态,直到我手动取消选中。

请任何人帮助我!我在这里卡了两天了。

这是我的代码:

MainActivity.java

public class MainActivity extends Activity {

    List<NLevelItem> list;
    ListView listView;
    Context context;
    Button checkButton;
    ArrayList<String>tempList;

    CheckBox selected = null; //Make only one selection at a time
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        listView = (ListView) findViewById(R.id.listView1);
        list = new ArrayList<NLevelItem>();
        context = this;
        checkButton = (Button)findViewById(R.id.buttons);
        tempList = new ArrayList<String>();
        //here we create 5 grandparent (top level) NLevelItems
        //then foreach grandparent create a random number of parent (second level) NLevelItems
        //then foreach parent create a random number of children (third level) NLevelItems

        //we pass in an anonymous instance of NLevelView to the NLevelItem, this NLevelView is
        //what supplies the NLevelAdapter with a View for this NLevelItem
        Random rng = new Random();
        final LayoutInflater inflater = LayoutInflater.from(this);
        for (int i = 0; i < 5; i++) {
            final NLevelItem grandParent = new NLevelItem(new SomeObject("GrandParent "+i),null, new NLevelView() {

                @Override
                public View getView(NLevelItem item) {
                    View view = inflater.inflate(R.layout.list_item, null);
                    TextView tv = (TextView) view.findViewById(R.id.textView);
                    //tv.setBackgroundColor(Color.GREEN);
                    String name = (String) ((SomeObject) item.getWrappedObject()).getName();
                    tv.setText(name);
                    return view;
                }
            });
            list.add(grandParent);

            int numChildren = rng.nextInt(4) + 1;
            for (int j = 0; j < numChildren; j++) {
                NLevelItem parent = new NLevelItem(new SomeObject("Parent "+j),grandParent, new NLevelView() {

                    @Override
                    public View getView(NLevelItem item) {
                        View view = inflater.inflate(R.layout.list_item, null);
                        TextView tv = (TextView) view.findViewById(R.id.textView);
                        //tv.setBackgroundColor(Color.YELLOW);
                        String name = (String) ((SomeObject) item.getWrappedObject()).getName();
                        tv.setText(name);
                        return view;
                    }
                });
                list.add(parent);

                int children = rng.nextInt(3)+1;
                for(int x=0; x<children;x++){
                    final NLevelItem childs = new NLevelItem(new SomeObject("Parent1 "+x),parent, new NLevelView() {

                        @Override
                        public View getView(NLevelItem item) {
                            View view = inflater.inflate(R.layout.list_item, null);
                            TextView tv = (TextView) view.findViewById(R.id.textView);
                            //tv.setBackgroundColor(Color.BLUE);
                            String name = (String) ((SomeObject) item.getWrappedObject()).getName();
                            tv.setText(name);
                            return view;
                        }
                    });
                    list.add(childs);

                    int grandChildren = rng.nextInt(5)+1;
                    for( int k = 0; k < grandChildren; k++) {
                        NLevelItem child = new NLevelItem(new SomeObject("child "+k),childs, new NLevelView() {

                            @Override
                            public View getView(NLevelItem item) {
                                View view = inflater.inflate(R.layout.check_list, null);
                                TextView tv = (TextView) view.findViewById(R.id.checktextView);
                                final String name = (String) ((SomeObject) item.getWrappedObject()).getName();
                                final CheckBox checkBox = (CheckBox)view.findViewById(R.id.check);
                                checkBox.setOnClickListener(new View.OnClickListener() {
                                    @Override
                                    public void onClick(View v) {
                                        if(selected != null){  //Edit
                                             selected.setChecked(false);
                                            }
                                            selected = checkBox; //Edit
                                        if(checkBox.isChecked()){

                                            tempList.add((String) ((SomeObject)childs.getWrappedObject()).getName()+"+"+name);
                                        }
                                        else {
                                            tempList.remove((String) ((SomeObject)childs.getWrappedObject()).getName()+"+"+name);
                                        }
                                    }
                                });
                                //tv.setBackgroundColor(Color.GRAY);

                                tv.setText(name);
                                return view;
                            }
                        });
                        list.add(child);
                    }
                }

            }
        }

        NLevelAdapter adapter = new NLevelAdapter(list);
        listView.setAdapter(adapter);
        listView.setOnItemClickListener(new OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
                    long arg3) {
                ((NLevelAdapter)listView.getAdapter()).toggle(arg2);
                ((NLevelAdapter)listView.getAdapter()).getFilter().filter();

            }
        });

        checkButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                for (int i=0;i<tempList.size();i++){
                    Toast.makeText(context,tempList.get(i),Toast.LENGTH_LONG).show();
                }
            }
        });


    }   

    class SomeObject {
        public String name;

        public SomeObject(String name) {
            this.name = name;
        }
        public String getName() {
            return name;
        }
    }

}

NLevelAdapter.java

public class NLevelAdapter extends BaseAdapter {

        List<NLevelItem> list;
        List<NLevelListItem> filtered;
        public void setFiltered(ArrayList<NLevelListItem> filtered) {
                this.filtered = filtered;

        }

        public NLevelAdapter(List<NLevelItem> list) {
                this.list = list;
                this.filtered = filterItems();
        }

        @Override
        public int getCount() {
                return filtered.size();
        }

        @Override
        public NLevelListItem getItem(int arg0) {
                return filtered.get(arg0);
        }

        @Override
        public long getItemId(int arg0) {
                return 0;
        }

        @Override
        public View getView(int arg0, View arg1, ViewGroup arg2) {
                return getItem(arg0).getView();
        }

        public NLevelFilter getFilter() {
                return new NLevelFilter();
        }


        class NLevelFilter {

                public void filter() {
                        new AsyncFilter().execute();
                }

                class AsyncFilter extends AsyncTask<Void, Void, ArrayList<NLevelListItem> > {

                        @Override
                        protected ArrayList<NLevelListItem> doInBackground(Void...arg0) {
                                return (ArrayList<NLevelListItem>)filterItems();
                        }

                        @Override
                        protected void onPostExecute(ArrayList<NLevelListItem> result) {
                                setFiltered(result);
                                NLevelAdapter.this.notifyDataSetChanged();
                        }
                }


        }

        public List<NLevelListItem> filterItems() {

            List<NLevelListItem> tempfiltered = new ArrayList<NLevelListItem>();
            OUTER: for (NLevelListItem item : list) {
                        //add expanded items and top level items
                        //if parent is null then its a top level item
                        if(item.getParent() == null) {
                                tempfiltered.add(item);
                        } else {
                                //go through each ancestor to make sure they are all expanded
                                NLevelListItem parent = item;
                                while ((parent = parent.getParent())!= null) {
                                        if (!parent.isExpanded()) {
                                                    //one parent was not expanded
                                                    //skip the rest and continue the OUTER for loop
                                                    continue OUTER;
                                        }
                                }
                                tempfiltered.add(item);
                      }
                }

                return tempfiltered;    
        }

        public void toggle(int arg2) {
                    filtered.get(arg2).toggle();
        }
}

提前致谢!!

【问题讨论】:

    标签: java android


    【解决方案1】:

    我认为您需要将复选框状态存储在 boolean(已选中)中,并在调用 getView() 时将其反映在视图上。

    1- 将布尔检查添加到 NLevelItem :

    private boolean checked = false;
    //add setter: setChecked(boolean)
    //add getter isChecked()
    

    2- 在getView() 中使用该布尔值(添加复选框的最后一个)

    @Override
    public View getView(final NLevelItem item) {
    // .......
    
        final CheckBox checkBox = (CheckBox)view.findViewById(R.id.check);
        checkBox.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
    
                //store checkbox state, note that NLevelItem item might need to be defined with 'final'
                item.setChecked(checkBox.isChecked());
    
                if(checkBox.isChecked()){
                    tempList.add((String) ((SomeObject)childs.getWrappedObject()).getName()+"+"+name);
                }
                else {
                    tempList.remove((String) ((SomeObject)childs.getWrappedObject()).getName()+"+"+name);
                }
            }//onClick()
        }//setOnClickListener()
    
        //update checkbox state from the corresponding NLevelItem
        checkBox.setChecked(item.isChecked());
    
        //.......
    }//getView()
    

    -编辑:

    要选择1个项目,你需要迭代所有项目,设置checked = false,但是1 我不确定你是否必须这样做:

    List<NLevelItem> list;
    

    List<NLevelListItem> filtered;
    

    在适配器类中

    private void selectOnly(int position){
        for(int a=0;a<list.size();a++){
            if(a == position){
                list.get(a).setChecked(true);
                continue;
            }
            list.get(a).setChecked(false);
        }//for loop
        notifyDataSetChanged(); // to update views (checkbox state)
    }
    

    用法:selectOnly(15);

    【讨论】:

    • 还有一个疑问..如何一次只做一个选择
    • @appu 我已经更新了这个问题,它未经测试,不确定它是否会起作用,但这是逻辑。
    • 我在我的问题中做了一些编辑。它一次只做一个选择,但当我展开列表视图时,再次表示复选框被自动取消选中。
    • @appu 我建议您使用您正在使用的最新代码添加一个新问题,并询问您想要的新问题。
    • 好的,您是否检查了建议的答案(显示在重复标题旁边的那个)?
    【解决方案2】:

    使用 ViewHolder 类来设置和获取 Tag,如下所示:

    public class ListAdapter extends BaseAdapter {
    
        private Context con;
        private List<String> dataLt;
        private static LayoutInflater inflater = null;
    
        public ListAdapter(Context context, List<String> dataList){
            con         = context;
            dataLt      = dataList;
            inflater    = (LayoutInflater)con.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        }
    
        @Override
        public int getCount() {
            return dataLt.size();
        }
    
        @Override
        public Object getItem(int position) {
            return position;
        }
    
        @Override
        public long getItemId(int position) {
            return position;
        }
    
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            View vi = convertView;
            ViewHolder holder;
    
            if(convertView==null){
    
                /****** Inflate tabitem.xml file for each row ( Defined below ) *******/
                vi = inflater.inflate(R.layout.list_item_search, null);
                /****** View Holder Object to contain tabitem.xml file elements ******/
                holder = new ViewHolder();
                holder.textView           = (TextView)    vi.findViewById(R.id.textView);
                /************  Set holder with LayoutInflater ************/
                vi.setTag( holder );
            }
            else
                holder=(ViewHolder)vi.getTag();
    
            return vi;
        }
    
        public static class ViewHolder{
            TextView textView;
        }
    }
    

    希望这会有所帮助。

    【讨论】:

    • 我认为这会产生新问题,其中复选框状态 (isChecked) 将根据回收视图维护,而不是每个项目本身,即当滚动时,您可能会看到一些不应该选中复选框的项目待查。
    猜你喜欢
    • 1970-01-01
    • 2017-12-03
    • 2020-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-21
    • 1970-01-01
    • 2014-09-11
    相关资源
    最近更新 更多