在特定场景中单击 ExpandableListView.onGroupClick 上的子项后检查视图
Checking a view after clicking child on ExpandableListView.onGroupClick in a specific scenario
我有一个包含 6 个项目的扩展列表,当第 3 个可以扩展到另一个包含 12 个项目的列表时。
一切都很好,展开,折叠,打开片段...我的问题是我无法设置选中的项目(更改其背景)只有在非常特殊的情况下:当我选择一个子项目(从第三个扩展列表),不关闭扩展列表,并选择扩展列表下方的项目(大于2)。
例如:我选择项目 2,列表展开,然后我向下滚动并从第一个(组)列表中选择最后一个项目 - 它有效但它是检查(更改背景)第 3 个项目代替的第 6 个!
我猜它有回收视图,但我想不通。我在谷歌上搜索了很多,但没有找到一个有效的例子。有可能吗?
请帮忙。发送
mMenuAdapter = new ExpandableListAdapter (this, listDataHeader, listDataChild, expandableList);
expandableList.setAdapter (mMenuAdapter);
expandableList.setOnGroupClickListener (new ExpandableListView.OnGroupClickListener () {
@Override
public boolean onGroupClick (ExpandableListView expandableListView, View view, int i, long l) {
if (currentView != null)
currentView.setBackgroundColor (getResources ().getColor (R.color.transparent));
if (expandableListView.isGroupExpanded (2))
expandableListView.collapseGroup (2);
if (i != 2) {
currentView = view;
currentView.setBackgroundColor (getResources ().getColor (R.color.veryLightBg));
} else {
currentView = null;
return false;
}
mainMenuClicked (i); // opens the right fragment
return true;
}
});
expandableList.setOnChildClickListener (new ExpandableListView.OnChildClickListener () {
@Override
public boolean onChildClick (ExpandableListView expandableListView, View view, int i, int i1, long l) {
if (currentView != null)
currentView.setBackgroundColor (getResources ().getColor (R.color.transparent));
currentView = view;
currentView.setBackgroundColor (getResources ().getColor (R.color.veryLightBg));
childMenuClicked (i1);
return false;
}
});
适配器:
public class ExpandableListAdapter extends BaseExpandableListAdapter {
private Context mContext;
private List<ExpandedMenuItem> mListDataHeader;
private HashMap<ExpandedMenuItem, List<String>> mListDataChild;
ExpandableListView expandList;
public ExpandableListAdapter(Context context, List<ExpandedMenuItem> listDataHeader, HashMap<ExpandedMenuItem, List<String>> listChildData, ExpandableListView mView) {
this.mContext = context;
this.mListDataHeader = listDataHeader;
this.mListDataChild = listChildData;
this.expandList = mView;
}
@Override
public int getGroupCount() {
return this.mListDataHeader.size();
}
public int getChildrenCount(int groupPosition) {
int childCount = 0;
if (groupPosition == 2)
childCount = this.mListDataChild.get(this.mListDataHeader.get(groupPosition)).size();
return childCount;
}
@Override
public Object getGroup(int groupPosition) {
return this.mListDataHeader.get(groupPosition);
}
@Override
public Object getChild(int groupPosition, int childPosition) {
return this.mListDataChild.get(this.mListDataHeader.get(groupPosition)).get(childPosition);
}
@Override
public long getGroupId(int groupPosition) {
return groupPosition;
}
@Override
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
@Override
public boolean hasStableIds() {
return false;
}
@Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
ExpandedMenuItem headerTitle = (ExpandedMenuItem) getGroup(groupPosition);
if (convertView == null) {
LayoutInflater infalInflater = (LayoutInflater) this.mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = infalInflater.inflate(R.layout.main_list, null);
}
TextView lblListHeader = convertView.findViewById(R.id.single_menu);
if (groupPosition == 2) {
if (!isExpanded)
lblListHeader.setText (mContext.getString (R.string.products_category));
else
lblListHeader.setText (mContext.getString (R.string.expand_products_category));
} else {
lblListHeader.setText (headerTitle.getName ());
}
return convertView;
}
@Override
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
final String childText = (String) getChild (groupPosition, childPosition);
if (convertView == null) {
LayoutInflater infalInflater = (LayoutInflater) this.mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = infalInflater.inflate(R.layout.sub_list, null);
}
TextView txtListChild = convertView.findViewById(R.id.single_menu);
txtListChild.setText(childText);
return convertView;
}
@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
}
经过多次搜索,我得出了完整的答案。
首先,我为列表视图添加了一个checkableRowLayout
class(如answer建议的那样),因此可以检查:
public class checkableRowLayout extends ConstraintLayout implements Checkable {
private boolean isChecked = false;
public checkableRowLayout(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public boolean isChecked() {
return isChecked;
}
public void setChecked(boolean isChecked) {
this.isChecked = isChecked;
changeColor(isChecked);
}
public void toggle() {
this.isChecked = !this.isChecked;
changeColor(this.isChecked);
}
private void changeColor(boolean isChecked){
if (isChecked) {
setBackgroundColor(getResources().getColor(R.color.veryveryLightGrey));
} else {
setBackgroundColor(getResources().getColor(android.R.color.transparent));
}
}
}
接下来,我在列表行的 xml
源文件中设置这个 class(而不是“LinearLayout”作为根视图),如果你有,请注意对两个视图都这样做主列表项和子项的不同视图:
<?xml version="1.0" encoding="utf-8"?>
<com.myapp.togo.checkableRowLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="20sp"
android:textColor="@color/blue"
android:textSize="20sp"
android:id="@+id/title"
android:paddingBottom="15sp"
android:paddingTop="15sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
</com.myapp.togo.checkableRowLayout>
我在 click listeners
中为组和子列表项添加了 2 行:
expandableList.setOnChildClickListener (new ExpandableListView.OnChildClickListener () {
@Override
public boolean onChildClick (ExpandableListView expandableListView, View view, int i, int i1, long l) {
expandableList.setItemChecked(i+i1+1, true); // this is the new line
expandableList.setSelection(i+i1+1); // this is the new line
childMenuClicked (i1);
return false;
}
});
expandableList.setOnGroupClickListener (new ExpandableListView.OnGroupClickListener () {
@Override
public boolean onGroupClick (ExpandableListView expandableListView, View view, int i, long l) {
if (expandableListView.isGroupExpanded (2))
expandableListView.collapseGroup (2);
expandableList.setItemChecked(i, true); // this is the new line
expandableList.setSelection(i); // this is the new line
if (i == 2)
return false;
mainMenuClicked (i);
return true;
}
});
现在可以了。希望对您有所帮助!
我有一个包含 6 个项目的扩展列表,当第 3 个可以扩展到另一个包含 12 个项目的列表时。
一切都很好,展开,折叠,打开片段...我的问题是我无法设置选中的项目(更改其背景)只有在非常特殊的情况下:当我选择一个子项目(从第三个扩展列表),不关闭扩展列表,并选择扩展列表下方的项目(大于2)。
例如:我选择项目 2,列表展开,然后我向下滚动并从第一个(组)列表中选择最后一个项目 - 它有效但它是检查(更改背景)第 3 个项目代替的第 6 个!
我猜它有回收视图,但我想不通。我在谷歌上搜索了很多,但没有找到一个有效的例子。有可能吗?
请帮忙。发送
mMenuAdapter = new ExpandableListAdapter (this, listDataHeader, listDataChild, expandableList);
expandableList.setAdapter (mMenuAdapter);
expandableList.setOnGroupClickListener (new ExpandableListView.OnGroupClickListener () {
@Override
public boolean onGroupClick (ExpandableListView expandableListView, View view, int i, long l) {
if (currentView != null)
currentView.setBackgroundColor (getResources ().getColor (R.color.transparent));
if (expandableListView.isGroupExpanded (2))
expandableListView.collapseGroup (2);
if (i != 2) {
currentView = view;
currentView.setBackgroundColor (getResources ().getColor (R.color.veryLightBg));
} else {
currentView = null;
return false;
}
mainMenuClicked (i); // opens the right fragment
return true;
}
});
expandableList.setOnChildClickListener (new ExpandableListView.OnChildClickListener () {
@Override
public boolean onChildClick (ExpandableListView expandableListView, View view, int i, int i1, long l) {
if (currentView != null)
currentView.setBackgroundColor (getResources ().getColor (R.color.transparent));
currentView = view;
currentView.setBackgroundColor (getResources ().getColor (R.color.veryLightBg));
childMenuClicked (i1);
return false;
}
});
适配器:
public class ExpandableListAdapter extends BaseExpandableListAdapter {
private Context mContext;
private List<ExpandedMenuItem> mListDataHeader;
private HashMap<ExpandedMenuItem, List<String>> mListDataChild;
ExpandableListView expandList;
public ExpandableListAdapter(Context context, List<ExpandedMenuItem> listDataHeader, HashMap<ExpandedMenuItem, List<String>> listChildData, ExpandableListView mView) {
this.mContext = context;
this.mListDataHeader = listDataHeader;
this.mListDataChild = listChildData;
this.expandList = mView;
}
@Override
public int getGroupCount() {
return this.mListDataHeader.size();
}
public int getChildrenCount(int groupPosition) {
int childCount = 0;
if (groupPosition == 2)
childCount = this.mListDataChild.get(this.mListDataHeader.get(groupPosition)).size();
return childCount;
}
@Override
public Object getGroup(int groupPosition) {
return this.mListDataHeader.get(groupPosition);
}
@Override
public Object getChild(int groupPosition, int childPosition) {
return this.mListDataChild.get(this.mListDataHeader.get(groupPosition)).get(childPosition);
}
@Override
public long getGroupId(int groupPosition) {
return groupPosition;
}
@Override
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
@Override
public boolean hasStableIds() {
return false;
}
@Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
ExpandedMenuItem headerTitle = (ExpandedMenuItem) getGroup(groupPosition);
if (convertView == null) {
LayoutInflater infalInflater = (LayoutInflater) this.mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = infalInflater.inflate(R.layout.main_list, null);
}
TextView lblListHeader = convertView.findViewById(R.id.single_menu);
if (groupPosition == 2) {
if (!isExpanded)
lblListHeader.setText (mContext.getString (R.string.products_category));
else
lblListHeader.setText (mContext.getString (R.string.expand_products_category));
} else {
lblListHeader.setText (headerTitle.getName ());
}
return convertView;
}
@Override
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
final String childText = (String) getChild (groupPosition, childPosition);
if (convertView == null) {
LayoutInflater infalInflater = (LayoutInflater) this.mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = infalInflater.inflate(R.layout.sub_list, null);
}
TextView txtListChild = convertView.findViewById(R.id.single_menu);
txtListChild.setText(childText);
return convertView;
}
@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
}
经过多次搜索,我得出了完整的答案。
首先,我为列表视图添加了一个checkableRowLayout
class(如answer建议的那样),因此可以检查:
public class checkableRowLayout extends ConstraintLayout implements Checkable {
private boolean isChecked = false;
public checkableRowLayout(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public boolean isChecked() {
return isChecked;
}
public void setChecked(boolean isChecked) {
this.isChecked = isChecked;
changeColor(isChecked);
}
public void toggle() {
this.isChecked = !this.isChecked;
changeColor(this.isChecked);
}
private void changeColor(boolean isChecked){
if (isChecked) {
setBackgroundColor(getResources().getColor(R.color.veryveryLightGrey));
} else {
setBackgroundColor(getResources().getColor(android.R.color.transparent));
}
}
}
接下来,我在列表行的 xml
源文件中设置这个 class(而不是“LinearLayout”作为根视图),如果你有,请注意对两个视图都这样做主列表项和子项的不同视图:
<?xml version="1.0" encoding="utf-8"?>
<com.myapp.togo.checkableRowLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="20sp"
android:textColor="@color/blue"
android:textSize="20sp"
android:id="@+id/title"
android:paddingBottom="15sp"
android:paddingTop="15sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
</com.myapp.togo.checkableRowLayout>
我在 click listeners
中为组和子列表项添加了 2 行:
expandableList.setOnChildClickListener (new ExpandableListView.OnChildClickListener () {
@Override
public boolean onChildClick (ExpandableListView expandableListView, View view, int i, int i1, long l) {
expandableList.setItemChecked(i+i1+1, true); // this is the new line
expandableList.setSelection(i+i1+1); // this is the new line
childMenuClicked (i1);
return false;
}
});
expandableList.setOnGroupClickListener (new ExpandableListView.OnGroupClickListener () {
@Override
public boolean onGroupClick (ExpandableListView expandableListView, View view, int i, long l) {
if (expandableListView.isGroupExpanded (2))
expandableListView.collapseGroup (2);
expandableList.setItemChecked(i, true); // this is the new line
expandableList.setSelection(i); // this is the new line
if (i == 2)
return false;
mainMenuClicked (i);
return true;
}
});
现在可以了。希望对您有所帮助!