Question:
Given : ExpandableListView with its own adapter that inherits from BaseExpandableListAdapter. The list is given the groupClickListener and childClickListener listeners. In both, on click on the element, I do this:
mDrawerList.setSelectedChild(groupPosition, childPosition, true);
As a result, the list displays the selected element (group or child), highlighting it with "@< selector/>".
The list itself is used as a pull-down menu in the NavigationDrawer.
Issue : The highlight is only shown after the list has been scrolled. Those. First I click on the list element – nothing happens externally, but the element is marked (selected) programmatically. Next, I pull the list and the element is painted with the color specified in the selector.
Tried :
expListView.notifyDataSetChanged(); //не помогает.
Possible solution : I am absolutely sure that the problem can be solved by changing the color of the element in the methods of the adapter that renders them:
@Override
public View getChildView(final int groupPosition, final int childPosition, boolean isLastChild, View convertView,
ViewGroup parent)
{
//получаем groupPosition и childPosition выбранного элемента
//тут меняем цвет выбранного элемента, сравнивая groupPosition и childPosition выбранного элемента с текущим
}
I'm sure, because this method is called every time the list slides off the edge of the screen.
The whole question is how to get the groupPosition and childPosition of the selected element.
I spent hours rummaging through the docks and methods of the adapter and the list, but did not understand anything. Methods that should return data on the selected element always return the same values, which is not clear where to shove.
I'm ready to give up and write groupPosition and childPosition to the activity variables when clicking on the element and take them from there in the adapter. But I have a lot of activities with the same list – a lot of extra code and variables.
Question : how to get the groupPosition and childPosition of the selected element from the list/adapter?
Update 0
When clicked, everything displays correctly through this code:
@Override
public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id)
{
//test
final long groupChildFlatPosition=ExpandableListView.getPackedPositionForChild(groupPosition, childPosition);
final int groupPos1 = ExpandableListView.getPackedPositionGroup(groupChildFlatPosition);//(groupChildFlatPosition);
final int childPos1 = ExpandableListView.getPackedPositionChild(groupChildFlatPosition);
System.out.println("onChildClick_groupPos1: " + groupPos1 + "/ childPos1: "+childPos1);
}
@Override
public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition, long id)
{
//test
final long packedPosition = parent.getExpandableListPosition(groupPosition);
final int groupPosition1 = ExpandableListView.getPackedPositionGroup(packedPosition);
System.out.println("onGroupClick_groupPosition1: "+groupPosition1);
}
In the adapter, here is the code (in getChildView() ):
final long groupChildPositionSelected=((ExpandableListView)parent).getSelectedPosition();
switch(ExpandableListView.getPackedPositionType(groupChildPositionSelected)) {
case ExpandableListView.PACKED_POSITION_TYPE_CHILD:
System.out.println("position type: child");
break;
case ExpandableListView.PACKED_POSITION_TYPE_GROUP:
System.out.println("position type: group");
break;
case ExpandableListView.PACKED_POSITION_TYPE_NULL:
System.out.println("position type: null");
break;
}
final int groupPos1 = ExpandableListView.getPackedPositionGroup(groupChildPositionSelected);//(groupChildFlatPosition);
final int childPos1 = ExpandableListView.getPackedPositionChild(groupChildPositionSelected);
System.out.println("FROM_ADAPTER_groupPos1: " + groupPos1 + "/ childPos1: "+childPos1);
Outputs:
position type: null
FROM_ADAPTER_groupPos1: -1 / childPos1: -1
Those. the adapter fails to get any data about the selected item from the list.
Answer:
Perhaps this hack will help you –
a two-dimensional array to store the state of child and group items
private selectedStatus[][];
initialize the default state in the constructor
public MyExpandableListAdapter(Context context, int groupCount, int childCount) {
selectedStatus = new boolean[groupCount][];
for (int i = 0; i < groupCount); i++) {
selectedStatus[i] = new boolean[childCheckCursor.getCount()];
for (int j = 0; j < childCount; j++) {
selectedStatus[i][j] = false;
}
}
}
set the background based on the status
@Override
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
final View v = super.getChildView(groupPosition, childPosition, isLastChild, convertView, parent);
if(selectedStatus[groupPosition][childPosition]){
v.setBackgroundResource(R.color.blue);
} else {
v.setBackgroundResource(R.color.black);
}
return v;
}
add a method that allows you to change the previous state and set the new one to the adapter
setSelectedStatus (int groupPosition, int childPosition) {
for (int i = 0; i < selectedStatus.length; i++) {
for (int j = 0; j < checkedStatus[i].length; j++) {
if(i == groupPosition && j == childPosition) {
selectedStatus[i][j] = true;
} else {
selectedStatus[i][j] = false;
}
}
}
}
use in listener
lv.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
@Override
public boolean onChildClick(ExpandableListView parent, View v,
int groupPosition, int childPosition, long id) {
YuorListAdapter adapter = (YuorListAdapter) parent.getAdapter; // само собой это ваш адаптер
adapter.setSelectedStatus(groupPosition, childPosition);
return true;
}
});