【问题标题】:Checkbox on Expandable ListView GroupView auto-checking and unchecking when scrolling in android在Android中滚动时可扩展ListView GroupView上的复选框自动选中和取消选中
【发布时间】:2014-08-05 09:55:27
【问题描述】:

之前没有注意到这一点我觉得很愚蠢,但是当我在我的应用程序中上下滚动时,复选框会随机选中和取消选中。复选框位于 GroupView 而不是 Expandable ListView 的子元素上。我对此进行了大量研究,并意识到问题在于回收视图以及与 onCheckedChangeListener 有关。我也知道(某种程度上)我必须做些什么来解决这个问题。问题是,我不确定如何实现它。这是因为所有研究都导致人们使用复选框 ListView 的修复或可扩展 ListView 的 ChildView 中的复选框的修复

Here是我用于Expandable ListView的教程

以下是我发现的与我的问题相关的其他链接,排序。他们都没有特别的帮助:

Android ListView with Checkbox: automatically unchecks

Android, Checkboxes Randomly Checked/Unchecked in Expandable List

checkbox unchecked when i scroll listview in android

ListView with CheckBox Scrolling Issue

Expandable listview with selectall checkbox : group itemclick and scrolling bug

下面是一些代码,希望能对一些事情有所启发:

ExpandableListAdapter.java现在根据第一个答案更新

public class ExpandableListAdapter extends BaseExpandableListAdapter {

private Context _context;
private List<String> _listDataHeader; // header titles
// child data in format of header title, child title
private HashMap<String, List<String>> _listDataChild;

boolean checkAll_flag = false;
boolean checkItem_flag = false;

public ExpandableListAdapter(Context context, List<String> listDataHeader,
        HashMap<String, List<String>> listChildData) {
    this._context = context;
    this._listDataHeader = listDataHeader;
    this._listDataChild = listChildData;
}

@Override
public Object getChild(int groupPosition, int childPosititon) {
    return this._listDataChild.get(this._listDataHeader.get(groupPosition))
            .get(childPosititon);
}

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

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

    final String childText = (String) getChild(groupPosition, childPosition);

    if (convertView == null) {
        LayoutInflater infalInflater = (LayoutInflater) this._context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        convertView = infalInflater.inflate(R.layout.suikoden_list_item1, null);
    }

    TextView txtListChild = (TextView) convertView
            .findViewById(R.id.lblListItem);

    txtListChild.setText(childText);
    return convertView;
}

@Override
public int getChildrenCount(int groupPosition) {
    return this._listDataChild.get(this._listDataHeader.get(groupPosition))
            .size();
}

@Override
public Object getGroup(int groupPosition) {
    return this._listDataHeader.get(groupPosition);
}

@Override
public int getGroupCount() {
    return this._listDataHeader.size();
}

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

class ExpanableValue
{
  String title;
  boolean isChecked;


  // setter and getter

}

@Override
public View getGroupView(int groupPosition, boolean isExpanded,
        View convertView, ViewGroup parent) {


    if (convertView == null) {
        LayoutInflater infalInflater = (LayoutInflater) this._context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        convertView = infalInflater.inflate(R.layout.suikoden_list_group1, null);
        //convertView.setTag(gholder);

    //}else{
        //gholder = (GroupViewHolder)convertView.getTag();
    }

    /////////////////////

    CheckBox cb = (CheckBox)convertView
            .findViewById(R.id.checkboxTick);
    cb.setTag(groupPosition);
    cb.setOnClickListener(this);
    cb.setCheck(groupList.get(groupPosition).isChecked());
    ////////////////////

    TextView lblListHeader = (TextView) convertView
            .findViewById(R.id.lblListHeader);
    lblListHeader.setTypeface(null, Typeface.BOLD);
    lblListHeader.setText(groupList.get(groupPosition).getTitle());

    return convertView;
}

public void onClick(View v) {

     switch(v.getId())
    {
      case R.id.checkboxTick:
        int pos = (Integer) arg0.findViewById(R.id.checkboxTick).getTag();
            groupList.get(pos).setChecked((CheckBox)v.isChecked());
            break;
    }
}

@Override
public boolean hasStableIds() {
    return false;
}

@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
    return true;
}

}

SuikodenFragment.java中的复选框:

@Override
public void onCheckedChanged(CompoundButton buttonView,boolean isChecked) {
    CheckBox checkBox = (CheckBox) expListView.findViewById(R.id.checkboxTick);
    checkBox.setOnCheckedChangeListener(null);
    if (isChecked)
        // Add the tick to the box
        //Log.d(TAG, "Tick the box");
        checked = true;
     else
        // Remove the tick in the box
        //Log.d(TAG, "Untick the box");
         checked = false;
}

如果有人可以提出修复建议,或提供示例代码或任何其他帮助,那就太好了!提前致谢!

【问题讨论】:

  • 您需要保存复选框的状态,然后在 getChild 视图方法中阅读,如果您不明白,请发ExpandableListAdapter的邮政编码
  • @shayanpourvatan 感谢您的回复,我已更新代码以包含所有 ExpandableListAdapter 代码。但是该复选框不在 ChildView 中(下拉菜单),它在 GroupView 中。例如,我的列表是 CheckBox - Character Name > 然后下拉到字符信息。所以 CheckBox 在 GroupView 中。谢谢!
  • GroupView 中初始化它的位置?我没看到
  • @shayanpourvatan 我的复选框在不同的片段中实现,代码在我的第一篇文章中。虽然我在一些解决方案中看到 onCheckedChanged 方法应该放在 ExpandableListView 中

标签: android listview checkbox expandablelistview expandablelistadapter


【解决方案1】:

创建一个类,如:

class ExpanableValue
{
  String title;
  boolean isChecked;


  // setter and getter

}

而不是List&lt;String&gt; 传递一个ExpanableValue 列表(或者你想要的任何名称)。

然后在getGroupView:

@Override
public View getGroupView(int groupPosition, boolean isExpanded,
        View convertView, ViewGroup parent) {


    if (convertView == null) {
        LayoutInflater infalInflater = (LayoutInflater) this._context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        convertView = infalInflater.inflate(R.layout.suikoden_list_group1, null);
        //convertView.setTag(gholder);

    //}else{
        //gholder = (GroupViewHolder)convertView.getTag();
    }

    /////////////////////

    CheckBox cb = (CheckBox)convertView
            .findViewById(R.id.checkBoxID);
    cb.setTag(groupPosition);
    cb.setOnClickListener(this);
    cb.setCheck(groupList.get(groupPosition).isChecked());
    ////////////////////

    TextView lblListHeader = (TextView) convertView
            .findViewById(R.id.lblListHeader);
    lblListHeader.setTypeface(null, Typeface.BOLD);
    lblListHeader.setText(groupList.get(groupPosition).getTitle());

    return convertView;
}

然后在onClick方法中:

@Override
public void onClick(View v) {

     switch(v.getId())
    {
      case R.id.checkBoxID:
        int pos = (Integer) v.findViewById(R.id.checkBoxID).getTag();
            groupList.get(pos).setChecked((CheckBox)v.isChecked());
            break;
    }
}

在getGroupView中最好使用ViewHolder,

【讨论】:

  • 感谢您的支持,我会尽快实施。只是一个简单的问题,我是否将所有这些新代码都放在 ExpandableListView 中?
  • 是的,使用我的getGroupView,但您需要更改更多内容,我在我的帖子中说过,如果没有,请添加 onClick,您需要实现onClickListener 并按照我说的创建一个类跨度>
  • 非常感谢您的帮助。我是初学者,所以很抱歉我一直在问问题。我目前遇到几个错误。每次它说“groupList”时,我都会收到一个无法解决的错误。 onClick 中的“arg0”给出了同样的错误。最后两个错误在 onClick 中的“cb.setOnClickListener”和“v.isChecked()”上。我已经更新了代码,谢谢
  • arg0改为v,你必须将groupList发送给构造函数,而不是listDataHeader
猜你喜欢
  • 2018-04-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-14
  • 1970-01-01
  • 1970-01-01
  • 2012-06-29
  • 1970-01-01
相关资源
最近更新 更多