Domanda Android: clic lungo sulle visualizzazioni figlio di ExpandableListView?


ExpandableListView ha un metodo setOnChildClickListener, ma privo di setOnChildLungoclickListener metodo.

Quando ho aggiunto setOnLongClickListener() a vista bambino in getChildView(), l'intera sottolista è diventata completamente invalicabile (nonostante parentView.setOnChildClickListener() presente e funzionante prima).

Come posso abilitare i clic lunghi sulle viste secondarie?


47
2018-02-28 23:11


origine


risposte:


Sono riuscito a ottenere lunghi clic lavorando su un ExpandableListView elemento figlio, usando il seguente:

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;
    }
});

Ci sono voluti anni per capire che l'argomento id su onItemLongClick era il packedPosition argomento richiesto da getPackedPosition* metodi, certamente non chiari dalla documentazione.

Nota: Per far funzionare questa soluzione è necessario scavalcare il getGroupId e getChildId() metodi nell'adattatore

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

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

83
2017-11-30 01:37



Ho trovato una risposta sul blog di Steve Oliver qui: http://steveoliverc.wordpress.com/2009/10/16/context-menus-for-expandable-lists/

Dovresti usare onCreateContextMenu() invece di cercare setOnChildLongClickListener(). Ecco le informazioni di Steve:

Un elenco espandibile supporta i menu di scelta rapida praticamente nello stesso modo di un elenco standard: aggiungi un listener per il menu di scelta rapida (quando l'utente ha premuto a lungo su un elemento della lista). A differenza di una visualizzazione elenco standard, tuttavia, probabilmente si desidera sapere se l'utente ha selezionato un elemento di gruppo (elemento espandibile) o un elemento secondario (elemento secondario).

Inoltre, potresti non voler fare nulla se l'utente cerca di aprire un menu di scelta rapida su un elemento del gruppo. Potrebbero esserci casi in cui si vorrebbe fare qualcosa a tutti i bambini di un gruppo, ma nella mia applicazione Librarium, volevo ignorare le voci di gruppo e presentare il menu di scelta rapida solo per i bambini.

Innanzitutto, è necessario sapere quando verrà creato il menu di scelta rapida in modo da poter identificare se l'utente ha premuto su un gruppo o un bambino. Se hanno premuto su un gruppo, quindi annullare il menu di scelta rapida. Questo ci dà anche la possibilità di ottenere il testo dell'elemento figlio, in modo che possiamo inserirlo nell'intestazione del menu di scelta rapida.

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”);
  }
}

In secondo luogo, crea il menu di scelta rapida:

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);
  }
}

Questo è tutto. Ora gli utenti possono premere a lungo su un elemento in un elenco espandibile e ottenere il menu di scelta rapida se si tratta di un elemento figlio.


40
2018-03-01 08:33



So che questa risposta potrebbe non essere necessaria, ma ho una situazione simile e nessuna di queste risposte risolve il mio problema. Quindi inserisco il mio nel caso qualcuno ne abbia bisogno. Spero a tutti voi ragazzi non 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;
                }

modificare Questa soluzione per Listview è stata molto tempo fa. Consiglio vivamente di trasferirmi RecyclerView adesso.


30
2018-05-08 08:46



Stavo cercando questa risposta, ma qui non ha dato risultati corretti.

Risposta contrassegnata da Tomash suggerire un modo completamente diverso. Risposta da Nicholas è parzialmente corretto, ma l'uso di "id" non è corretto.

Corretto, funzionante, la risposta è: convert position parametro a packedPosition e poi! usando questo nuovo packedPosition valore per ottenere ID di gruppo e figlio. Controlla il codice qui sotto

    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;
        }
    });

MODIFICARE: Ora lo vedo Autobot ha una soluzione quasi corretta, eccetto test getPackedPositionType sopra id e non via packetPosition


12
2017-08-31 12:02



Gestisco il tuo problema. basta impostare un tag ur item e usarlo, in questo modo:

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;
        }

    };

E quindi setOnItemLongClickListener per ListView espandibile.

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;
        }
    });

Eccoci qui.


1
2018-05-22 21:35