Join FlipAndroid.COM Telegram Group: https://t.me/joinchat/F_aqThGkhwcLzmI49vKAiw


Resaltar para el elemento seleccionado en la lista expandible

Tengo una disposición donde tengo una lista extensible en un fragmento a la izquierda y un fragmento de los detalles a la derecha. Todo esto funciona bien.

Ahora quisiera indicar qué artículo a la izquierda está teniendo los detalles demostrados a la derecha y aquí estoy teniendo un problema.

En una vista de lista normal, he logrado esto estableciendo el modo de elección para la vista de lista como único y luego utilizando un estado dibujable basado en el estado "activado". Cuando hago clic en el elemento, el fondo se establece en el color seleccionado y se mantiene así hasta que seleccione otro elemento de la lista.

Intenté aplicar esto a mi lista extensible y era / es un fracaso lamentable. No hubo errores, pero el elemento seleccionado no mantuvo su estado de color. No estoy seguro de si no estoy configurando el modo de elección correctamente (lo he probado en el archivo de diseño, así como programaticamente, no parece hacer una diferencia), o señalar a la cosa equivocada (No estoy seguro de cómo podría ser, pero …)

Cualquier ayuda / punteros apreciados (incluso si está en una dirección completamente diferente).

Mayor fallo actual:

Código de vista de lista expandible

private void fillData(String group, String child) { ExpandableListView lv; mGroupsCursor = mDbHelper.fetchGroup(group); getActivity().startManagingCursor(mGroupsCursor); mGroupsCursor.moveToFirst(); lv = (ExpandableListView) getActivity().findViewById(R.id.explist); lv.setChoiceMode(ExpandableListView.CHOICE_MODE_SINGLE); mAdapter = new MyExpandableListAdapter(mGroupsCursor, getActivity(), R.layout.explistlayout, R.layout.explistlayout, new String[] { "_id" }, new int[] { android.R.id.text1 }, new String[] { child }, new int[] { android.R.id.text1 }); lv.setAdapter(mAdapter); registerForContextMenu(lv); lv.setOnChildClickListener(new ExpandableListView.OnChildClickListener() { @Override public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) { mRowId = id; EventDisplayFragment eventdisplay = new EventDisplayFragment(); getFragmentManager().beginTransaction().replace(R.id.rightpane, eventdisplay).commit(); return true; } }); } public class MyExpandableListAdapter extends SimpleCursorTreeAdapter { public MyExpandableListAdapter(Cursor cursor, Context context, int groupLayout, int childLayout, String[] groupFrom, int[] groupTo, String[] childrenFrom, int[] childrenTo) { super(context, cursor, groupLayout, groupFrom, groupTo, childLayout, childrenFrom, childrenTo); } @Override protected Cursor getChildrenCursor(Cursor groupCursor) { Cursor childCursor = mDbHelper.fetchChildren(mGroup, groupCursor .getString(groupCursor .getColumnIndex(AttendanceDB.EVENT_ROWID))); getActivity().startManagingCursor(childCursor); childCursor.moveToFirst(); return childCursor; } } 

Item_selector.xml

 <?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_pressed="true" android:drawable="@color/green" /> <item android:state_selected="true" android:drawable="@color/blue" /> <item android:state_focused="true" android:drawable="@color/violet" /> <item android:state_activated="true" android:drawable="@color/blue" /> </selector> 

9 Solutions collect form web for “Resaltar para el elemento seleccionado en la lista expandible”

Haga lo siguiente en ExpandableListView:

Paso 1. Establecer el modo de elección a solo (Puede hacerse en xml como android: choiceMode = "singleChoice" )

Paso 2. Utilice un selector xml como fondo ( android: listSelector = "@ drawable / selector_list_item" )

 <?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android" android:exitFadeDuration="@android:integer/config_mediumAnimTime"> <item android:drawable="@android:color/holo_blue_bright" android:state_pressed="true"/> <item android:drawable="@android:color/holo_blue_light" android:state_selected="true"/> <item android:drawable="@android:color/holo_blue_dark" android:state_activated="true"/> </selector> 

Paso 3. Llame a expandableListView.setItemChecked (index, true) en onChildClick () callback.

Índice es un índice basado en 0 del elemento secundario calculado como sigue

Grupo 1 [índice = 0]

  • Artículo infantil 1
  • Artículo infantil 2
  • Artículo 3 del niño [índice = 3]

Grupo 2 [índice = 4]

  • Artículo infantil 1
  • Artículo infantil 2
  • Artículo 3 del niño [índice = 7]

Grupo 3 [índice = 8]

  • Artículo infantil 1
  • Artículo infantil 2
  • Artículo 3 del niño [índice = 11]

Si tenemos encabezados de lista también, también contabilizarán valores de índice.

He aquí un ejemplo de trabajo:

 @Override public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) { ... int index = parent.getFlatListPosition(ExpandableListView.getPackedPositionForChild(groupPosition, childPosition)); parent.setItemChecked(index, true); return true; } 

Después de pasar 3-4 horas se hace su tan simple no hay necesidad de crear archivos XML adicionales sólo comprobar si el elemento de grupo se expande si sí, a continuación, seleccione el color y en la declaración de hacerlos como lo son ….

 @Override //in this method you must set the text to see the parent/group on the list public View getGroupView(final int i, boolean b, View view, ViewGroup viewGroup) { if (view == null) { view = inflater.inflate(R.layout.list_item_parent, viewGroup,false); } if(b){ view.setBackgroundResource(R.color.waterblue); }else{ view.setBackgroundColor(color.transparent); } //return the entire view return view; } 

Finalmente me di cuenta de cómo hacer que este trabajo (para mí). Parece un poco del hack, pero es la única cosa que he manejado conseguir trabajar para esto.

Básicamente, creo una matriz bidimensional para mantener el estado seleccionado de los niños, lo inicializo en el constructor del adaptador, luego hago referencia a eso en mi método getChildView (en caso de que el niño seleccionado se onChildClick fuera de la vista) y mi método onChildClick (para cambiar La selección actual y apague la antigua).

 private selectedStatus[][]; // array to hold selected state private View oldView; // view to hold so we can set background back to normal after selection of another view 

Constructor inicializar la matriz

  public MyExpandableListAdapter(Cursor cursor, Context context, int groupLayout, int childLayout, String[] groupFrom, int[] groupTo, String[] childrenFrom, int[] childrenTo) { super(context, cursor, groupLayout, groupFrom, groupTo, childLayout, childrenFrom, childrenTo); selectedStatus = new boolean[cursor.getCount()][]; for (int i = 0; i < cursor.getCount(); i++) { cursor.moveToPosition(i); Cursor childCheckCursor = mDbHelper.fetchChildren(mGroup, cursor.getString(cursor .getColumnIndex(AttendanceDB.EVENT_ROWID))); getActivity().startManagingCursor(childCheckCursor); selectedStatus[i] = new boolean[childCheckCursor.getCount()]; for (int j = 0; j < childCheckCursor.getCount(); j++) { selectedStatus[i][j] = false; } } } 

GetChildView necesario para cuando el niño se desplaza fuera de la vista

  @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] == true){ v.setBackgroundResource(R.color.blue); } else { v.setBackgroundResource(R.color.black); } return v; } 

OnChildClick cambiar el elemento seleccionado

  lv.setOnChildClickListener(new ExpandableListView.OnChildClickListener() { @Override public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) { mRowId = id; EventDisplayFragment eventdisplay = new EventDisplayFragment(); getFragmentManager().beginTransaction() .replace(R.id.rightpane, eventdisplay).commit(); if(oldView != null){ oldView.setBackgroundResource(R.color.black); // change the background of the old selected item back to default black } oldView = v; // set oldView to current view so we have a reference to change back on next selection for (int i = 0; i < selectedStatus.length; i++) { for (int j = 0; j < checkedStatus[i].length; j++) { if(i == groupPosition && j == childPosition){ // set the current view to true and all others to false selectedStatus[i][j] = true; } else { selectedStatus[i][j] = false; } } } v.setBackgroundResource(R.color.blue); return true; } }); 

Estaba teniendo el mismo problema que lo arreglé añadiendo

 v.setSelected(true); 

Aquí hay una muestra de mi código:

 expandableListDetailsLevel.setChoiceMode(ExpandableListView.CHOICE_MODE_SINGLE); expandableListDetailsLevel .setOnGroupExpandListener(new OnGroupExpandListener() { public void onGroupExpand(int groupPosition) { if(groupPosition!=1){ expandableIsThere = false; } for (int i = 0; i < len; i++) { if (i != groupPosition) { expandableListDetailsLevel.collapseGroup(i); } } } }); expandableListDetailsLevel .setOnChildClickListener(new OnChildClickListener() { @Override public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) { v.setSelected(true); } 

Mi artículo 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="horizontal" android:background="@drawable/selector" > <TextView android:id="@+id/TVChild" android:layout_width="fill_parent" android:layout_height="match_parent" android:textColor="#000" android:textSize="12dp"/> </LinearLayout> 

Atributo android:drawSelectorOnTop="true" en el elemento ExpandableListView en el archivo xml (no el elemento hijo o grupo) de la siguiente manera:

 <ExpandableListView android:id="@+id/expandableViewDetailsBriefing" android:layout_width="fill_parent" android:layout_height="match_parent" android:background="#fff" android:drawSelectorOnTop="true" android:dividerHeight="1px" android:childDivider="@color/Gris" android:indicatorRight="690dp" android:textFilterEnabled="true" > </ExpandableListView> 

La siguiente solución le ayudará a hacer selector de lista diferente para grupo y niño.

En primer lugar, necesita desactivar el selector de lista para ExpendableListView:

... <ExpandableListView ... android:listSelector="@android:color/transparent" ... /> ...
... <ExpandableListView ... android:listSelector="@android:color/transparent" ... /> ... 

Después, necesita copiar una lista vacíaSelector. Puedes hacer que te guste esto

... private Drawable empty; ... // binding view here. Name of ExpandableListView will be elv empty = elv.getSelector();
... private Drawable empty; ... // binding view here. Name of ExpandableListView will be elv empty = elv.getSelector(); 

Ahora, necesitamos saber cuándo habilitaremos el selector de listas o desactivaremos. Debería agregar los siguientes cambios a su adaptador para eso:

my adapter here { ... @Override public View getGroupView(int groupPosition, boolean isExpanded, View view, ViewGroup parent) { ... // after, we've got view of goup view.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { elv.setSelector(empty); return false; } }); ... } ... @Override public View getChildView(final int groupPosition, final int childPosition, boolean isLastChild, View convertView, final ViewGroup parent) { ... // after, we've got view of child view.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { elv.setSelector(R.drawable.my_custom_list_selector); return false; } }); ... } ... }
my adapter here { ... @Override public View getGroupView(int groupPosition, boolean isExpanded, View view, ViewGroup parent) { ... // after, we've got view of goup view.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { elv.setSelector(empty); return false; } }); ... } ... @Override public View getChildView(final int groupPosition, final int childPosition, boolean isLastChild, View convertView, final ViewGroup parent) { ... // after, we've got view of child view.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { elv.setSelector(R.drawable.my_custom_list_selector); return false; } }); ... } ... } 

Eso es todo. Espero que esta solución conserve su tiempo.

En caso de que necesite sólo cambiar el color del elemento secundario que en el método onchildclick , establezca el color de fondo en la vista v.

 @Override public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) { // TODO Auto-generated method stub v.setBackgroundColor(Color.RED); } 

Para ello, establezca isChildSelectable en true en el adaptador.

Puede guardar la vista actual y cambiar el color de fondo de la vista en los oyentes de clics:

 View currentView; ExpandableListView elv; elv.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener() { @Override public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition, long id) { if(currentView != null) { currentView.setBackgroundColor(Color.parseColor("#FFFFFF")); } v.setBackgroundColor(Color.parseColor("#EEEEEE")); currentDrawerView = view; //do something return false; } }); elv.setOnChildClickListener(new ExpandableListView.OnChildClickListener() { @Override public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) { if(currentView != null) { currentView.setBackgroundColor(Color.parseColor("#FFFFFF")); } v.setBackgroundColor(Color.parseColor("#EEEEEE")); currentDrawerView = view; //do something return false; } }); 

Esta solución simple me ha ayudado cuando me encontré con la misma pregunta que el autor

Tengo una disposición donde tengo una lista extensible en un fragmento a la izquierda y un fragmento de los detalles a la derecha. Todo esto funciona bien. Ahora quisiera indicar qué artículo a la izquierda está teniendo los detalles demostrados a la derecha y aquí estoy teniendo un problema.

Para indicar qué elemento de la lista expandible está seleccionado, vaya a las propiedades de ExpandableListView (en el diseño) y elija color para listSelector.

Solo usa el siguiente

  <ExpandableListView android:id="@+id/expandable_list" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="start" android:childDivider="#474043" android:groupIndicator="@null" android:listSelector = "@drawable/item_selector" android:background="#555" android:drawSelectorOnTop="true" android:textFilterEnabled="true" /> 

Y su item_selector.xml como sigue

 <?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@color/selection_color_for_ex_list" android:state_pressed="true"/> <item android:drawable="@color/selection_color_for_ex_list" android:state_selected="true"/> <item android:drawable="@color/selection_color_for_ex_list" android:state_focused="true"/> </selector> 
FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.