在我的可扩展列表中,我试图实现以下功能,当用户单击子项目时,它应该为该项目着色,以便人们可以看到它已被选中,并且当用户再次单击它时,它会返回到默认颜色。这工作正常,问题是它还为列表中前面的其他子项目着色,并且它有一个模式,它以 10 个项目为间隔为子项目着色。我认为这是由于视图被回收,但我不知道如何解决这个问题。 任何帮助将不胜感激:)
我将发布最相关的代码:
**public class ExpandableListAdapter extends BaseExpandableListAdapter** {
private Context context;
private List<String> headers;
private Map<String, List<String>> items;
public ExpandableListAdapter(Context context, List<String> headers, Map<String, List<String>> items) {
this.context = context;
this.headers = headers;
this.items = items;
}
@Override
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = LayoutInflater.from(context).inflate(R.layout.list_item, parent, false);
}
TextView childItemTextView = convertView.findViewById(R.id.childItemTextView);
String item = items.get(headers.get(groupPosition)).get(childPosition);
childItemTextView.setText(item);
return convertView;
}
**public class ComplexSearchActivity extends AppCompatActivity implements ComplexSearchContract.View** {
expandableListView.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
@Override
public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) {
String selectedItem = items.get(headers.get(groupPosition)).get(childPosition);
Log.d("Debug", "Clicked View Details: " + v.toString());
Log.d("Debug", "Selected Item: " + selectedItem);
presenter.onChildItemClick(selectedItem, v);
return true;
}
});
@Override
**public void updateItemSelection(View clickedView, boolean isSelected)** {
TextView textView = clickedView.findViewById(R.id.childItemTextView);
textView.setSelected(isSelected);
}
}
**public class ComplexSearchPresenter implements ComplexSearchContract.Presenter** {
public void onChildItemClick(String clickedItem, View clickedView) {
if (selectedItems.contains(clickedItem)) {
selectedItems.remove(clickedItem);
Log.d("Debug", "Removed from selectedItems: " + clickedItem);
} else {
selectedItems.add(clickedItem);
Log.d("Debug", "Added to selectedItems: " + clickedItem);
}
view.updateItemSelection(clickedView, selectedItems.contains(clickedItem));
}
}
TextView childItemTextView 包含一个选择器,当布尔值 isSelected 为 true 或 false 时,该选择器指示项目的颜色:
textView.setSelected(isSelected);
xml 代码如下:
布局资源-list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/childItemTextView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingLeft="?android:attr/expandableListPreferredChildPaddingLeft"
android:paddingTop="10dp"
android:paddingBottom="10dp"
android:background="@drawable/item_selector">
</TextView>
</LinearLayout>
可绘制资源- item_selector.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_selected="true"
android:drawable="@drawable/selected_state"
/>
<item
android:drawable="@drawable/default_state"
/>
</selector>
尝试将 selectedItems 传递到适配器中,因此更改适配器的构造函数:
private List<String> selectedItems; // Add this.
public ExpandableListAdapter(Context context,List<String> headers,Map<String, List<String>>items, List<String>selectedItems){
this.context=context;
this.headers=headers;
this.items=items;
this.selectedItems=selectedItems; // Add this.
}
然后更改getChildView():
@Override
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent){
if(convertView==null){
convertView= LayoutInflater.from(context).inflate(R.layout.list_item,parent,false);
}
TextView childItemTextView=convertView.findViewById(R.id.childItemTextView);
String item=items.get(headers.get(groupPosition)).get(childPosition);
childItemTextView.setText(item);
childItemTextView.setSelected(selectedItems.contains(item)); // Add this.
return convertView;
}
在activity中,根据适配器的构造函数来改变适配器的创建。
附加注释:现在只有子项的字符串保存到 selectItems 列表中。这仅适用于所有子项目都是不同的字符串。如果子项可以具有相同的字符串,则选择多个子项。对于这种情况,将组和子项字符串合并为一个并保存到 selectItems 列表中, getChildView() 需要相应更改。