可扩展列表视图回收问题

Posted

技术标签:

【中文标题】可扩展列表视图回收问题【英文标题】:Expandable listview recycling issue 【发布时间】:2019-05-08 10:09:55 【问题描述】:

朋友们,我正在使用可扩展列表视图来显示各种类别及其子项。我使用复选框来选择子项,以便可以从各种类别中选择多个子项。但是由于观点的回收,我在这里面临一个问题。当我展开类别并勾选其中子项的复选框时,然后当我单击另一个类别时,已经选中了一些复选框。我认为这是由于视图的回收而发生的。我想解决这个问题。我也遇到了与 recyclerview 类似的问题。请指导我。先感谢您。 我正在粘贴我的适配器代码以供参考 -

 public class DayBookAdapter extends BaseExpandableListAdapter 

    private Context _context;
    private List<DayBookData> listDataHeader;
    String msubItem,mcategory;
    ArrayList<String>  selecteditems;
    ArrayList<String>  selectedcategories;
    public DayBookAdapter(Context context, List<DayBookData> listDataHeader, ArrayList<String> selectedItems,ArrayList<String> selectedcategories) 
        this._context = context;
        this.listDataHeader = listDataHeader;
        this.selecteditems = selectedItems;
        this.selectedcategories = selectedcategories;
    

    @Override
    public ArrayList<DayBookDetailsData> getChild(int groupPosition, int childPosititon) 
        return this.listDataHeader.get(groupPosition).getCh_list();
    

    @Override
    public long getChildId(int groupPosition, int childPosition) 
        return childPosition;
    

    @SuppressLint("InflateParams")
    @Override
    public View getChildView(final int groupPosition, final int childPosition, boolean isLastChild, View convertView, ViewGroup parent) 

        final DayBookDetailsData childText = listDataHeader.get(groupPosition).getCh_list().get(childPosition);
        Boolean checkstatus = childText.isIschecked();
        Log.d("checkstatus", "getChildView: "+checkstatus);
        if (convertView == null) 
            LayoutInflater infalInflater = (LayoutInflater) this._context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = infalInflater.inflate(R.layout.day_book_details_data_item, null);
        

        TextView item_txt_sub_cat_id = convertView.findViewById(R.id.item_id);
        item_txt_sub_cat_id.setText(childText.getItem_id());

        CheckBox item_txt_sub_cat_name = convertView.findViewById(R.id.item_name);
        item_txt_sub_cat_name.setText(childText.getItem_name());

        item_txt_sub_cat_name.setOnClickListener(new View.OnClickListener() 


            public void onClick(View v) 
                final CheckBox cb = (CheckBox) v;


                msubItem = listDataHeader.get(groupPosition).getCh_list().get(childPosition).getItem_id();
                mcategory = listDataHeader.get(groupPosition).getCategory_id();
                if (cb.isChecked()) 

                    childText.setIschecked(true);
                    selecteditems.add(msubItem);
                    selectedcategories.add(mcategory);
                    Log.d("itemschecked", "items -"+selecteditems+"categories-"+selectedcategories);
                 else 
                    childText.setIschecked(false);
                    selecteditems.remove(msubItem);
                    selectedcategories.remove(mcategory);
                    Log.d("itemschecked", "items -"+selecteditems+"categories-"+selectedcategories);
                
            
        );
        return convertView;
    

    @Override
    public int getChildrenCount(int groupPosition) 
        return this.listDataHeader.get(groupPosition).getCh_list().size();
    

    @Override
    public DayBookData getGroup(int groupPosition) 
        return this.listDataHeader.get(groupPosition);
    

    @Override
    public int getGroupCount() 
        return this.listDataHeader.size();
    

    @Override
    public long getGroupId(int groupPosition) 
        return groupPosition;
    

    @SuppressLint("InflateParams")
    @Override
    public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) 
        DayBookData headerTitle = getGroup(groupPosition);
        if (convertView == null) 
            LayoutInflater infalInflater = (LayoutInflater) this._context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = infalInflater.inflate(R.layout.day_book_data_item, null);
        
        TextView item_txt_category_id = convertView.findViewById(R.id.category_id);
        TextView item_txt_category_name = convertView.findViewById(R.id.category_name);
        item_txt_category_id.setText(headerTitle.getCategory_id());
        item_txt_category_name.setText(headerTitle.getCategory_name());
        return convertView;
    
    @Override
    public boolean hasStableIds() 
        return false;
    
    @Override
    public boolean isChildSelectable(int groupPosition, int childPosition) 
        return true;
    

如果您还需要什么,请告诉我。 谢谢。

已编辑 - 这是我的子项 pojo 文件,谁能告诉我要进行哪些更改?

public class DayBookDetailsData 

    private String item_name;
    private String item_id;

    public boolean isIschecked() 
        return ischecked;
    

    public void setIschecked(boolean ischecked) 
        this.ischecked = ischecked;
    

    boolean ischecked;

    public DayBookDetailsData(String item_name, String item_id,boolean ischecked) 
        this.item_name = item_name;
        this.item_id = item_id;
        this.ischecked = ischecked;
    

    public String getItem_name() 
        return item_name;
    

    public String getItem_id() 
        return item_id;
    



这是我的 JSON 解析代码,我在其中设置布尔值-

  bData.setCategory_id(jObjIn.getString("cat_id"));
                bData.setCategory_name(jObjIn.getString("c_name"));

                JSONArray jArrItemData = new JSONArray(jObjIn.getString("itemdata"));

                for (int j = 0; j < jArrItemData.length(); j++) 

                    JSONObject jObjItem = new JSONObject(jArrItemData.getString(j));

                    try 

                        String item_id = jObjItem.getString("id");
                        String item_name = jObjItem.getString("item");
                        Boolean checkstatus = false;
                        bData.getCh_list().add(new DayBookDetailsData(item_name, item_id,checkstatus));
                     catch (JSONException e) 
                        e.printStackTrace();
                    
                

                listData.add(bData);
            

            exp_listview.setAdapter(new DayBookAdapter(getActivity(), listData,selectedItems,selectedcategory));

我已根据您的建议更新了文件,但对我没有帮助。请告诉我我的代码有什么问题。

【问题讨论】:

获取子视图中是否勾选复选框需要设置 @Cruces 已经更新了代码,但无论如何都没有帮助我,你能告诉我我需要在哪里进行更改 【参考方案1】:

在每个子模型对象中保留一个“isChecked”布尔值,并在您选中/取消选中项目时更新它。然后在获取视图时显式设置复选框的选中状态。

当回收视图时,您最安全的选择是假设回收视图中的每个项目都处于不需要的状态,因此应该明确设置。

例如:

getChildView(...)

  checkbox.setChecked(getChild(groupPosition, childPosition).getCheckedStatus());


onChildClick()
getChild(groupPosition, childPosition).setCheckedStatus(...)

【讨论】:

我已经尝试过你要求我做的事情。我还发布了更新的代码。但它没有做对。请您指导我完成它。

以上是关于可扩展列表视图回收问题的主要内容,如果未能解决你的问题,请参考以下文章

一个可扩展列表视图中有 2 个不同的列表视图

多级可扩展列表视图

如何使可扩展列表视图的项目选中/不可选中

我已经有一个列表视图,我想将其转换为可扩展的列表视图

如果在 Android Studio 上突出显示至少一个子视图,则突出显示可扩展列表视图的标题视图

如何将可扩展列表视图的选定子视图数据从片段发送到父活动?