【问题标题】:Listview containing checkbox and text is getting reset on scrolling包含复选框和文本的列表视图在滚动时被重置
【发布时间】:2015-01-16 19:16:27
【问题描述】:

我已经绘制了一个带有 ListView 和标题的自定义导航抽屉,但是当我滚动列表时,列表中的复选框被取消选中。

其次,当我单击标题部分中的重置按钮时,我希望 Listview 中的所有复选框都应该被取消选中。我一直在尝试使其正常工作,但找不到任何解决方案..

sn-ps 是

public class NavigationDrawer extends Fragment{
   @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        View view = inflater.inflate(R.layout.filter_navigation_drawer, container,false);
        drawerListView= ( ListView ) view.findViewById( R.id.listDrawer );
        drawerListView.setOnItemClickListener(new FilterDrawerItemClickListener());

        dataList.add(new FilterDrawerItem("sample1",true));
        dataList.add(new FilterDrawerItem("sample2",true));
        dataList.add(new FilterDrawerItem("sample3",true));
        dataList.add(new FilterDrawerItem("sample4",true));
        dataList.add(new FilterDrawerItem("sample5",true));
        dataList.add(new FilterDrawerItem("sample2",true));
        dataList.add(new FilterDrawerItem("sample2",true));
        dataList.add(new FilterDrawerItem("sample2",true));
        dataList.add(new FilterDrawerItem("sample2",true));

        adapter = new FilterCustomDrawerAdapter(getActivity(), R.layout.drawer_filter,dataList,drawerStatus);
        drawerListView.setAdapter(adapter);
        adapter.getFilterList();

        resetBtn = (TextView)view.findViewById(R.id.filterby_reset);
        if(resetBtn != null){
            resetBtn.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    application.setFilterStatus("reset");
                    for(int i=0; i<dataList.size(); i++){
                       dataList.get(i).setCheckBoxId(false);
                    }
                    adapter.notifyDataSetChanged();
                    // this.onCreateView();
                }
            });
        }

        return view;
    }
}

FilterCustomDrawerAdapter.java

public class FilterCustomDrawerAdapter extends ArrayAdapter<FilterDrawerItem> {

    Context context;
    List<FilterDrawerItem> drawerItemList;
    int layoutResID;
    int item = 0;
    String status;
    List<Integer> filterList = new ArrayList<Integer>();
    DrawerStatus drawerStatus;
    StataApplication application = StataApplication.getInstance();

    HashMap<Integer, Boolean> checked;   // newly added code

    public FilterCustomDrawerAdapter(Context context, int layoutResourceID,
                                     List<FilterDrawerItem> listItems,DrawerStatus drawerStatus) {
        super(context, layoutResourceID, listItems);
        this.context = context;
        this.drawerItemList = listItems;
        this.layoutResID = layoutResourceID;
        this.drawerStatus = drawerStatus;
        checked = new HashMap<Integer, Boolean>(getCount());
    }

    public FilterCustomDrawerAdapter(Context context, int layoutResourceID,
                                     List<FilterDrawerItem> listItems) {
        super(context, layoutResourceID, listItems);
        this.context = context;
        this.drawerItemList = listItems;
        this.layoutResID = layoutResourceID;
    }

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        // TODO Auto-generated method stub

        final FilterDrawerItemHolder drawerHolder;
        View view = convertView;

        if (view == null) {
            LayoutInflater inflater = ((Activity) context).getLayoutInflater();
            drawerHolder = new FilterDrawerItemHolder();

            view = inflater.inflate(layoutResID, parent, false);
            drawerHolder.ItemName = (TextView) view.findViewById(R.id.drawer_filterName);
            drawerHolder.checkBox = (CheckBox) view.findViewById(R.id.drawer_cbox);

            view.setTag(drawerHolder);
        } else {
            drawerHolder = (FilterDrawerItemHolder) view.getTag();
        }

        FilterDrawerItem dItem = (FilterDrawerItem) this.drawerItemList.get(position);

        drawerHolder.ItemName.setText(dItem.getItemName());
        TextView resetView = (TextView)view.findViewById(R.id.filterby_reset);
        CheckBox checkBox = (CheckBox) view.findViewById(R.id.drawer_cbox);

        // Newly added code
        Boolean isChecked = checked.get(position);
        checkBox.setChecked(isChecked == null ? false : isChecked);

      // if(application.getFilterStatus() != null) {
           if(checkBox.isChecked()){
               drawerHolder.checkBox.setChecked(false);
           }
      // }

        checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView,boolean isChecked) {
                if (isChecked) {
                    filterList.add(new Integer(position));
                    checked.put(position, true);
                } else {
                    filterList.remove(new Integer(position));
                    checked.put(position, false);
                }
            }
        });

        drawerHolder.checkBox.setTag(position);
        Log.d("FILTER_LIST_SIZE",String.valueOf(filterList.size()));

        return view;
    }

    private static class FilterDrawerItemHolder {
        TextView ItemName;
        CheckBox checkBox;
    }

    public List<Integer> getFilterList(){
        return filterList;
    }
}

在下图中,当我滚动列表时,如果我选中复选框 sample1 和 sample 2,它在滚动时将变为未选中。 并且在单击标题中的重置按钮时,我希望取消选中我的所有复选框。 无法让这个工作......

更新 1

 resetBtn.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    List<FilterDrawerItem> adapterDataList = adapter.getDrawerItemList();
                    for(int i=0; i<adapterDataList.size(); i++){  // At this place i am getting the size as 9
                        adapterDataList.get(i).setCheckBoxId(false);
                    }
                    adapter.setDrawerItemList(adapterDataList);
                    adapter.notifyDataSetChanged();
                }
            });

【问题讨论】:

    标签: javascript android android-navigation


    【解决方案1】:

    这是因为 ListView 中视图的循环使用。你应该创建一些 HashMap:

    HashMap<Integer, Boolean> checked;
    

    然后在你的构造函数中这样做:

    checked = new HashMap<Integer, Boolean>(getCount());
    

    在您的复选框上设置 OnCheckedChangeListener 后,在事件方法中执行以下操作:

    checked.put(position, yourCheckBoxCheckedState);
    

    在 getView() 方法中这样做:

    Boolean isChecked = checked.get(position);
    checkBox.setChecked(isChecked == null ? false : isChecked)
    

    试试这个,我觉得应该有帮助

    更新

    resetBtn.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    adapter.deselectAll();
                }
            });
    

    然后在适配器创建方法中:

     public void deselectAll() {
       checked = new HashMap<Integer, Boolean>(getCount());
       notifyDataSetChanged();
     }
    

    【讨论】:

    • 我得到的第一部分复选框现在没有设置,但是如何在重置按钮点击时重置所有复选框
    • 再写一次checked = new HashMap(getCount());
    • 我已经用你的代码编辑了我的答案......你能告诉我如何让这个重置属性工作,以便所有复选框都被取消选中......
    • 对不起,我没能。试试我更新的答案,它应该可以满足您的需求。
    【解决方案2】:

    在您的 FilterDrawerItem 类中,创建一个布尔变量 isChecked

    现在在您的适配器类中,编写如下内容:

    if(dItem.isChecked){
        drawerHolder.checkBox.setChecked(true);
    }
    else{
        drawerHolder.checkBox.setChecked(false);
    }
    

    在你的OnCheckedChangeListener:

    if (isChecked) {
        //your other code
        dItem.setChecked(true);
        notifyDataSetChanged();
    } else {
        //your other code
        dItem.setChecked(false);
        notifyDataSetChanged();
    }
    

    @Orest Savchak 的回答也是正确的,但是跟踪 POJO 类中的复选框将帮助您稍后检索选中的项目,并且还可以更轻松地做其他事情,比如您想在单击“重置”时取消选中所有复选框按钮。为此,在onClick() 的重置按钮上,您只需要这样做:

    for(int i=0; i<FilterDrawerItem.size; i++){
        FilterDrawerItem.get(i).setChecked(false);
    }
    adapterObject.notifyDataSetChanged();
    

    编辑 1:

    在您的适配器中为drawerItemList 创建getter setter,然后在重置按钮的onClick() 中,代替dataList,执行以下操作:

    List<FilterDrawerItem> adapterDataList=adapter.getDataList();
    for(int i=0; i<adapterDataList.size(); i++){
        adapterDataList.get(i).setCheckBoxId(false);
    }
    adapter.setDataList(adapterDataList);
    adapter.notifyDataSetChanged();
    

    【讨论】:

    • 我需要维护复选框的 POJO
    • 重置 Onclick sn-p 是这样的......但我没有得到任何结果。 for(int i=0; i
    • 抱歉,我不明白“没有得到结果”@anand 是什么意思。你能详细说明一下吗?另外,请不要在重置按钮的onClick() 中调用它。
    • 我已经编辑了 OnClick() on reset 按钮的答案。我还调用了适配器,但它没有重置复选框...
    • 我在 UPDATE 1 中用你的代码更新了代码但是复选框仍然没有被重置..@DroidDev
    猜你喜欢
    • 1970-01-01
    • 2012-10-16
    • 2011-11-08
    • 1970-01-01
    • 2016-06-03
    • 1970-01-01
    • 2016-01-19
    • 1970-01-01
    • 2011-08-31
    相关资源
    最近更新 更多