Android: haga clic largo en las vistas secundarias de un ExpandableListView?

ExpandableListView tiene un método setOnChildClickListener, pero carece del método setOnChild Long ClickListener .

Cuando agregué setOnLongClickListener() en child view en getChildView() , toda la sublicencia se volvió completamente unclickable (a pesar de parentView.setOnChildClickListener() presente y trabajando antes).

¿Cómo puedo habilitar clics largos en vistas de niños?

5 Solutions collect form web for “Android: haga clic largo en las vistas secundarias de un ExpandableListView?”

Conseguí conseguir los tecleos largos que trabajaban en un artículo infantil de ExpandableListView , usando el siguiente:

 getExpandableListView().setOnItemLongClickListener(new OnItemLongClickListener() { @Override public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) { if (ExpandableListView.getPackedPositionType(id) == ExpandableListView.PACKED_POSITION_TYPE_CHILD) { int groupPosition = ExpandableListView.getPackedPositionGroup(id); int childPosition = ExpandableListView.getPackedPositionChild(id); // You now have everything that you would as if this was an OnChildClickListener() // Add your logic here. // Return true as we are handling the event. return true; } return false; } }); 

Tomó siglos para averiguar que el argumento id en onItemLongClick era el argumento packedPosition requerido por los métodos getPackedPosition *, ciertamente no está claro en la documentación.

Nota: Para que esta solución funcione, debe reemplazar los getGroupId y getChildId() en su adaptador

  @Override public long getGroupId(int groupPosition) { return groupPosition; } @Override public long getChildId(int groupPosition, int childPosition) { return childPosition; } 

He encontrado una respuesta en el blog de Steve Oliver aquí: http://steveoliverc.wordpress.com/2009/10/16/context-menus-for-expandable-lists/

Debe utilizar onCreateContextMenu() lugar de buscar setOnChildLongClickListener() . Aquí está la información de Steve:

Una lista expandible admite menús contextuales de la misma manera que una lista estándar: añade un listener para el menú contextual (cuando el usuario ha presionado durante mucho tiempo en un elemento de lista). Sin embargo, a diferencia de una vista de lista estándar, es probable que desee saber si el usuario ha seleccionado un elemento de grupo (elemento expandible) o un elemento de lista secundario (sub-elemento).

Además, es posible que no quiera hacer nada si el usuario intenta abrir un menú contextual en un elemento de grupo. Puede haber casos en los que desearía hacer algo a todos los niños bajo un grupo, pero en mi aplicación de Librarium, quería ignorar los elementos del grupo y presentar el menú contextual sólo para los niños.

En primer lugar, debe saber cuándo se va a crear el menú contextual para que pueda identificar si el usuario presionó en un grupo o un niño. Si oprimieron un grupo, cancelen el menú contextual. Esto también nos da la oportunidad de obtener el texto del elemento hijo, para que podamos ponerlo en el encabezado del menú contextual.

 public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { super.onCreateContextMenu(menu, v, menuInfo); ExpandableListView.ExpandableListContextMenuInfo info = (ExpandableListView.ExpandableListContextMenuInfo) menuInfo; int type = ExpandableListView.getPackedPositionType(info.packedPosition); int group = ExpandableListView.getPackedPositionGroup(info.packedPosition); int child = ExpandableListView.getPackedPositionChild(info.packedPosition); // Only create a context menu for child items if (type == ExpandableListView.PACKED_POSITION_TYPE_CHILD) { // Array created earlier when we built the expandable list String page =mListStringArray[group][child]; menu.setHeaderTitle(page); menu.add(0, MENU_READ, 0, “Read page”); menu.add(0, MENU_EDIT, 0, “Edit page”); menu.add(0, MENU_FAVORITE, 0, “Add page to favorites”); menu.add(0, MENU_EXPORT, 0, “Export page to file”); menu.add(0, MENU_DELETE, 1, “Delete page”); } } 

En segundo lugar, crear el menú contextual:

 public boolean onContextItemSelected(MenuItem menuItem) { ExpandableListContextMenuInfo info = (ExpandableListContextMenuInfo) menuItem.getMenuInfo(); int groupPos = 0, childPos = 0; int type = ExpandableListView.getPackedPositionType(info.packedPosition); if (type == ExpandableListView.PACKED_POSITION_TYPE_CHILD) { groupPos = ExpandableListView.getPackedPositionGroup(info.packedPosition); childPos = ExpandableListView.getPackedPositionChild(info.packedPosition); } // Pull values from the array we built when we created the list String author = mListStringArray[groupPos][0]; String page = mListStringArray[groupPos][childPos * 3 + 1]; rowId = Integer.parseInt(mListStringArray[groupPos][childPos * 3 + 3]); switch (menuItem.getItemId()) { case MENU_READ: readNote(rowId); return true; case MENU_EDIT: editNote(rowId); return true; // etc.. default: return super.onContextItemSelected(menuItem); } } 

Eso es. Ahora los usuarios pueden presionar largo tiempo en un elemento de una lista expandible, y obtener el menú contextual si es un elemento secundario.

Sé que esta respuesta puede no ser necesario, pero tengo una situación similar y no de estas respuestas resolver mi problema. Así que publico la mía en caso de que alguien pueda necesitarla. Espero que todos ustedes no les importa.

 @Override public boolean onItemLongClick(AdapterView<?> parent, View childView, int flatPos, long id) { if (ExpandableListView.getPackedPositionType(id) == ExpandableListView.PACKED_POSITION_TYPE_CHILD) { final ExpandableListAdapter adapter = ((ExpandableListView) parent).getExpandableListAdapter(); long packedPos = ((ExpandableListView) parent).getExpandableListPosition(flatPos); int groupPosition = ExpandableListView.getPackedPositionGroup(packedPos); int childPosition = ExpandableListView.getPackedPositionChild(packedPos); // do whatever you want with groupPos and childPos here - I used these to get my object from list adapter. return false; } 

Editar Esta solución para Listview fue hace mucho tiempo. Recomiendo encarecidamente que trasladarse a RecyclerView ahora.

Estaba buscando esta respuesta, pero no aquí dio resultados correctos.

La respuesta marcada de tomash sugiere manera completamente diferente. La respuesta de Nicholas es parcialmente correcta, pero usar 'id' es incorrecto.

Correcto, el trabajo, la respuesta es: convertir el parámetro de position a packedPosition y ENTONCES! Utilizando este nuevo valor packedPosition para obtener ID de grupo e hijo. Verifique el código a continuación

  getExpandableListView().setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() { @Override public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) { long packedPosition = getExpandableListView().getExpandableListPosition(position); if (ExpandableListView.getPackedPositionType(packedPosition) == ExpandableListView.PACKED_POSITION_TYPE_CHILD) { // get item ID's int groupPosition = ExpandableListView.getPackedPositionGroup(packedPosition); int childPosition = ExpandableListView.getPackedPositionChild(packedPosition); // handle data ... // return true as we are handling the event. return true; } return false; } }); 

EDIT : Ahora veo que autobot tiene solución casi correcta, excepto probar getPackedPositionType en id y no en packetPosition

Me encargo de su problema. Sólo tiene que establecer una etiqueta ur artículo y utilizarlo, como este:

 adapter = new ExpandableListAdapter() { private String[] groups = { "Biceps", "Deltoids", "Hamstrings", "Lower Back","Quadriceps","Triceps","Wrist" }; private String[][] children = { { "Konsantra Dumbell curl", "Hammer curl", "Barbell Biceps Curl", "Prone Curl" }, { "Arnold Press", "Lateral Raise", "Dumbell Upright row", "Bar Military Press" }, { "Dead Lift", "Hack Squat","Zercher Squat","Seated Leg Flexion" }, { "Back Raise", "Superman" }, { "Back Squat", "Bulgarian Split Squat","Dumbell Lunge" }, { "Bench Dip", "French Press","Triceps Extension" }, { "Dumbell Wrist Curl "," Reverse Writst Curl"} }; public void unregisterDataSetObserver(DataSetObserver observer) { // TODO Auto-generated method stub } public void registerDataSetObserver(DataSetObserver observer) { // TODO Auto-generated method stub } public void onGroupExpanded(int groupPosition) { // TODO Auto-generated method stub } public void onGroupCollapsed(int groupPosition) { // TODO Auto-generated method stub } public boolean isEmpty() { // TODO Auto-generated method stub return false; } public boolean isChildSelectable(int groupPosition, int childPosition) { // TODO Auto-generated method stub return true; } public boolean hasStableIds() { // TODO Auto-generated method stub return true; } public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) { TextView textView = getGenericView(); textView.setText(getGroup(groupPosition).toString()); textView.setTag((Object)getGroup(groupPosition).toString()+"G"); return textView; } public long getGroupId(int groupPosition) { // TODO Auto-generated method stub return groupPosition; } public int getGroupCount() { // TODO Auto-generated method stub return groups.length; } public Object getGroup(int groupPosition) { // TODO Auto-generated method stub return groups[groupPosition]; } public long getCombinedGroupId(long groupId) { // TODO Auto-generated method stub return 0; } public long getCombinedChildId(long groupId, long childId) { // TODO Auto-generated method stub return 0; } public int getChildrenCount(int groupPosition) { // TODO Auto-generated method stub return children[groupPosition].length; } public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) { TextView textView = getGenericView(); textView.setText(getChild(groupPosition, childPosition).toString()); textView.setTag((Object)getChild(groupPosition, childPosition).toString()+"C"); return textView; } public long getChildId(int groupPosition, int childPosition) { // TODO Auto-generated method stub return childPosition; } public Object getChild(int groupPosition, int childPosition) { // TODO Auto-generated method stub return children[groupPosition][childPosition]; } public boolean areAllItemsEnabled() { // TODO Auto-generated method stub return false; } public TextView getGenericView() { // Layout parameters for the ExpandableListView AbsListView.LayoutParams lp = new AbsListView.LayoutParams( ViewGroup.LayoutParams.FILL_PARENT, 64); TextView textView = new TextView(expandXml.this); textView.setLayoutParams(lp); // Center the text vertically textView.setGravity(Gravity.CENTER_VERTICAL | Gravity.LEFT); // Set the text starting position textView.setPadding(36, 0, 0, 0); return textView; } }; 

Y luego setOnItemLongClickListener para Expandable ListView.

 listView.setOnItemLongClickListener(new OnItemLongClickListener() { public boolean onItemLongClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) { // TODO Auto-generated method stub String s=null; int childPosition =ExpandableListView.getPackedPositionChild(arg3); if(arg1.getTag()!=null){ Object o= arg1.getTag(); s = o.toString(); } Toast.makeText(expandXml.this ,s , Toast.LENGTH_SHORT).show(); return false; } }); 

Aquí vamos.

FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.