检查文本视图在检查检查文本视图后滚动时被随机选中和取消选中



我为子项目设计了一个CheckedTextView ExpandableListView,一切都很好,但是
当我随机检查CheckedTextViewCheckedTextView随机
地在另一组中检查这个ExpandableListView让我发疯。这是我的代码

   public class ExpandableListAdapter extends BaseExpandableListAdapter {
private Context context;
private List<String> expandableListTitle;
private HashMap<String, List<String>> expandableListDetail;   
public int lastExpandedGroupPosition;    
public ExpandableListAdapter(Context context, List<String> expandableListTitle,
        HashMap<String, List<String>> expandableListDetail) {
    this.context = context;
    this.expandableListTitle = expandableListTitle;
    this.expandableListDetail = expandableListDetail;      
}
@Override
//counts the number of group/parent items so the list knows how many times calls getGroupView() method
public int getGroupCount() {
     return this.expandableListTitle.size();
}
@Override
//counts the number of children items so the list knows how many times calls getChildView() 
method
public int getChildrenCount(int listPosition) {
    return this.expandableListDetail.get(this.expandableListTitle.get(listPosition))
            .size();     
}
@Override
//gets the title of each parent/group
public Object getGroup(int listPosition) {      
     return this.expandableListTitle.get(listPosition);
}
@Override
//gets the name of each item
public Object getChild(int listPosition, int expandedListPosition) {
    return this.expandableListDetail.get(this.expandableListTitle.get(listPosition))
            .get(expandedListPosition);    
}
@Override
public long getGroupId(int listPosition) {
    return listPosition;
}
@Override
public long getChildId(int listPosition, int expandedListPosition) {
    return expandedListPosition;
}
@Override
public boolean hasStableIds() {
    return true;
}
@Override
//in this method you must set the text to see the parent/group on the list
public View getGroupView(int listPosition, boolean isExpanded, View convertView, ViewGroup 
parent) {
 String listTitle = (String) getGroup(listPosition);
    if (convertView == null) {
        LayoutInflater layoutInflater = (LayoutInflater) this.context.
                getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        convertView = layoutInflater.inflate(R.layout.list_group, null);
    }
    // set category name as tag so view can be found view later
    convertView.setTag(getGroup(listPosition).toString());
    TextView textView = (TextView) convertView.findViewById(R.id.listTitle);
    //"i" is the position of the parent/group in the list
    textView.setText(getGroup(listPosition).toString());
    TextView sub = (TextView) convertView.findViewById(R.id.list_item_text_subscriptions);      

    return convertView;
}

 @Override
 //in this method you must set the text to see the children on the list
 public View getChildView(int listPosition, int expandedListPosition, boolean isLastChild, View
 convertView, ViewGroup parent) {
     final String expandedListText = (String) getChild(listPosition, expandedListPosition);
     if (convertView == null) {
         LayoutInflater layoutInflater = (LayoutInflater) this.context
                 .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
         convertView = layoutInflater.inflate(R.layout.list_item, null);
     }
    CheckedTextView textView = (CheckedTextView)
   convertView.findViewById(R.id.list_item_text_child);       
    textView.setText(expandedListText);  
    return convertView;
}
@Override
public boolean isChildSelectable(int listPosition, int expandedListPosition) {
    return true;
}
}

这是来自 json 响应的数据

public class ExpandableListDataPump {
public static HashMap<String, List<String>> getData() {
    ServiceHandler sh = new ServiceHandler();
    String url = "http://****/**/fetch_details/services/news_keywords.json";
    // Making a request to url and getting response
    String jsonStr = sh.makeServiceCall(url, ServiceHandler.POST);
    ArrayList<HashMap<String, String>> dataHashMap = new ArrayList<HashMap<String, String>>();
    try {
        JSONArray jsonArray = new JSONArray(jsonStr);
        for (int i = 0; i < jsonArray.length(); i++) {
            JSONObject c = jsonArray.getJSONObject(i);
            HashMap<String, String> dataArray = new HashMap<String, String>();
            if(!c.isNull("name")){                  
            String region = c.getString("name");
            String state = c.getString("ank_name");
            dataArray.put("name", region);
            dataArray.put("ank_name", state);               
            dataHashMap.add(dataArray);
            }
        }
    } catch (JSONException e) {
        e.printStackTrace();
    }
    HashMap<String, List<String>> expandableListDetail = new HashMap<String, List<String>>();
    Set<String> regionsList = new HashSet<String>();
    for (HashMap<String, String> map : dataHashMap) {
        for (Entry<String, String> mapEntry : map.entrySet()) {
            String key = mapEntry.getKey();
            String value = mapEntry.getValue();
            if (key.equalsIgnoreCase("name")) {
                regionsList.add(value);
            }
        }
    }
    try {
        JSONArray jsonArray = new JSONArray(jsonStr);
        for (String regionName : regionsList) {
            Log.e("Keywords list", regionName);
            List<String> name = new ArrayList<String>();
            for (int i = 0; i < jsonArray.length(); i++) {
                JSONObject c = jsonArray.getJSONObject(i);
                String regionTemp = c.getString("name");
                String nameTemp = c.getString("ank_name");
                if (regionTemp.equalsIgnoreCase(regionName)) {
                    name.add(nameTemp);
                }
            }
            expandableListDetail.put(regionName, name);
        }
    } catch (JSONException e) {
        e.printStackTrace();
    }
    return expandableListDetail;
  }
 }  

是的,这是list_group.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
    android:id="@+id/listTitle"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:paddingLeft="?android:attr/expandableListPreferredItemPaddingLeft"
    android:textColor="#A4C739"
    android:paddingTop="10dp"
    android:paddingBottom="10dp" />
</LinearLayout>

这是list_item.xml

 <?xml version="1.0" encoding="utf-8"?>
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:orientation="vertical" android:layout_width="match_parent"
 android:layout_height="wrap_content">
  <CheckedTextView
    android:id="@+id/list_item_text_child"
    android:layout_width="match_parent"
    android:layout_height="?android:attr/listPreferredItemHeightSmall"
    android:textAppearance="?android:attr/textAppearanceListItemSmall"
    android:gravity="center_vertical"
    android:textSize="15sp"
    android:checkMark="?android:attr/textCheckMark"
    android:paddingStart="?android:attr/listPreferredItemPaddingStart"
    android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
   />
 </LinearLayout>

每当滚动 ListView/ExpandableListView 时,它会在运行时滚动时调用相应适配器的"getView"函数。假设您在 ListView 中有 10 个项目,其中前 5 个当前显示在屏幕上。此时,ListView 仅对当前显示的那些项调用了"getView"。现在,当您向上滚动列表时,它将开始为第 6、7、8 个接一个地调用适配器的"getView"......项目。

另一方面,CheckedTextView 将其检查状态设置为默认值(如果未在布局 XML 中设置,则为 FALSE(。因此,每当 ListView 调用适配器的"getView"时,它都会为该项创建一个新布局,并且根据新布局,CheckedTextView 的检查状态将恢复为 DEFAULT。

要处理此问题,您必须保存每个检查文本视图的检查状态,并将此值设置为检查文本视图,同时从适配器的"getView"返回视图。

编辑:

在 ExpandableListAdapter 的构造函数中,用默认的检查状态值填充以下数组列表...

ArrayList<ArrayList<Boolean>> checkStates = new ArrayList<ArrayList<Boolean>>();
public void MyExpendableListAdapter()
{
       checkStates = new ArrayList<ArrayList<Boolean>>();
       //
       for(int i=0; i<numberOfGroups; i++) // Number of total groups or headers
       {
              ArrayList<Boolean> childrenCheckedStates = new ArrayList<Boolean>();
              for(int j=0; j<groups.get(i).size(); j++) // saving checked state for each children in each group
              {
                     childrenCheckedStates.add(defaultCheckState); // true or false
              }
              checkStates.add(childrenCheckedStates);
       }
}

现在在getChildView...

public View getChildView(final int listPosition, final int expandedListPosition,
        boolean isLastChild, View convertView, ViewGroup parent) {
    final String expandedListText = (String) getChild(listPosition,
            expandedListPosition);
    if (convertView == null) {
        LayoutInflater layoutInflater = (LayoutInflater) this.context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        convertView = layoutInflater.inflate(R.layout.list_item, null);
    }
    CheckedTextView textView = (CheckedTextView) convertView
            .findViewById(R.id.list_item_text_child);
    textView.setText(expandedListText);
    textView.setChecked(checkStates.get(listPosition).get(expandedListPosition));
    textView.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            CheckedTextView tv = (CheckedTextView)v;
            checkStates.get(listPosition).set(expandedListPosition, tv.isChecked());
        }
    });
    return convertView;
}

祝你好运。:)

我遇到了这个问题。实际上我们必须管理它。

我使用了以下方法

将选中的子索引添加到列表中

在getchildView中,如果选中,请检查选中的文本视图。

((CheckedTextView) convertView).setChecked(getClicked(
                        groupPosition, childPosition));

下面的函数将返回一个布尔值,无论是否选中给定的孩子

public boolean getClicked(int groupPosition, int childPosition) {
    if (checkedPositions.get(groupPosition) != null) {
        boolean isChecked = checkedPositions.get(groupPosition).get(
                childPosition);
        return isChecked;
    }
    return false;
}

您可以使用这样的函数为选中的项目编制索引

public void setClicked(int groupPosition, int childPosition) {
SparseBooleanArray checkedChildPositionsSingle = checkedPositions
        .get(groupPosition);
if (checkedChildPositionsSingle == null) {
    checkedChildPositionsSingle = new SparseBooleanArray();
    checkedChildPositionsSingle.put(childPosition, true);
    checkedPositions.put(groupPosition, checkedChildPositionsSingle);
} else {
    boolean oldState = checkedChildPositionsSingle.get(childPosition);
    if (!oldState) {
        checkedChildPositionsSingle.clear();
        checkedChildPositionsSingle.put(childPosition, !oldState);
    }
}
notifyDataSetChanged();

}

添加:

 @Override
 //in this method you must set the text to see the children on the list
 public View getChildView(int listPosition, int expandedListPosition, boolean isLastChild, View
 convertView, ViewGroup parent) {
     final String expandedListText = (String) getChild(listPosition, expandedListPosition);
     if (convertView == null) {
         LayoutInflater layoutInflater = (LayoutInflater) this.context
                 .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
         convertView = layoutInflater.inflate(R.layout.list_item, null);
     }
    CheckedTextView textView = (CheckedTextView)
   convertView.findViewById(R.id.list_item_text_child);       
    textView.setText(expandedListText);  
((CheckedTextView) convertView).setChecked(getClicked(
                            groupPosition, childPosition)); //Added
    return convertView;
}

在创建适配器的类中创建 onChildClickListener

expandableListView.setOnChildClickListener(new OnChildClickListener() {
                        @Override
                        public boolean onChildClick(ExpandableListView parent,
                                View clickedView, int groupPosition,
                                int childPosition, long id) {
                    expandableListAdapter.setClicked(groupPosition,childPosition);
            }
        }

注意:checkedPosition是一个稀疏布尔数组数组

SparseArray<SparseBooleanArray> checkedPositions;

最新更新