OnItemCLickListener non funziona nella visualizzazione elenco


243

Activity codice classe:

conversationList = (ListView)findViewById(android.R.id.list);
ConversationArrayAdapter conversationArrayAdapter=new  ConversationArrayAdapter(this, R.layout.conversation_list_item_format_left, conversationDetails);
conversationList.setAdapter(conversationArrayAdapter);
conversationList.setOnItemClickListener(new AdapterView.OnItemClickListener(){ 
    @Override
    public void onItemClick(AdapterView<?> arg0, View arg1, int position, long arg3) {
        Log.d("test","clicked");
    }
});

La getViewfunzione nella Adapterclasse:

if (v == null) {                                
    LayoutInflater vi = (LayoutInflater)ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    if(leftSideMessageNumber.equals(m.getTo())) {
        v = vi.inflate(R.layout.conversation_list_item_format_left, null);
    } else {
        v = vi.inflate(R.layout.conversation_list_item_format_right, null);
    }
}

C'è un problema con l'uso di due xmls mentre si gonfia?


4
@hiei Il mio problema era che stavo usando i pulsanti immagine nelle mie celle di layout. Anche dopo aver aggiunto "android: descendantFocusability" il mio listener di clic non rispondeva. Quello che ho fatto è stato, ho cambiato tutti i ImaegButtons in ImageViews. Ciò ha risolto il mio problema.
Ajith Memana,

Risposte:


731

Ho appena trovato una soluzione da qui, ma facendo un clic profondo.

Se un qualsiasi elemento dell'elenco di righe contiene una vista attivabile o cliccabile, allora OnItemClickListenernon funzionerà.

L'elemento riga deve avere un parametro simile android:descendantFocusability = "blocksDescendants".

Qui puoi vedere un esempio di come dovrebbe apparire la tua lista. L'elemento xml dell'elenco dovrebbe essere ... row_item.xml( your_xml_file.xml)

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:baselineAligned="false"
    android:descendantFocusability="blocksDescendants"
    android:gravity="center_vertical" >

    // your other widgets here

</LinearLayout>

non funziona per me. Chiunque può dare un'occhiata a [ stackoverflow.com/questions/21692209/...
suitianshi

3
Puoi anche impostarlo programmaticamente con listView.setDescendantFocusability(int focus);dove si focustrova uno dei ViewGroup.FOCUS_BEFORE_DESCENDANTS, ViewGroup.FOCUS_AFTER_DESCENDANTSoppureViewGroup.FOCUS_BLOCK_DESCENDANTS
Max Worg

Penso che sia divertente che come 20 persone ti abbiano ringraziato in un commento. Ho riscontrato questo problema nelle ultime 8 ore, quindi molte grazie per questo.
sparticvs,

1
La mia domanda è: si tratta di un bug Android o è di progettazione?
fangzhzh,

Sono stato bloccato su questo per 6 ore e ho davvero bisogno di aiuto. stackoverflow.com/questions/35108940/why-cant-i-remove-an-item/…
Ruchir Baronia

89

Il problema è che i layout contengono elementi attivabili o selezionabili. Se una vista contiene elementi selezionabili o selezionabili, OnItemCLickListener non verrà chiamato.

Clicca qui per maggiori informazioni.

Per favore pubblica uno dei tuoi xmls di layout se non è così.


2
Questa era la soluzione per me, stavo dichiarando la mia vista cliccabile. Grazie!
Kingraam,

1
Grazie! Ho cambiato i miei 2 EditTexts in TextViews, e mi è CheckBoxstato permesso di rimanere (e rimanere attivabile) con android:descendantFocusability="blocksDescendants"aggiunto al mio LinearLayout.
Azurespot

Sì! Avevo android:focusableInTouchMode="true"per la fila, una volta rimosso ha iniziato a funzionare finalmente! :-)
SharpC

58

Per i miei elenchi, le mie righe hanno altre cose che possono essere cliccate, come i pulsanti, quindi fare una coperta blocksDescendantsnon funziona. Invece ho aggiunto una riga nell'xml del pulsante:

android:focusable="false"

Ciò impedisce ai pulsanti di bloccare i clic sulle righe, ma consente comunque ai pulsanti di eseguire i clic.


@ user1840899 Questa è una risposta comune e una da cui ho imparato, quindi l'ho trasmessa. Sono informazioni corrette, non degne di voto negativo.
Janene Pappas,

Questo funziona per me su una casella di controllo nella elementi ListView (senza blocksDescendants)
thpitsch

Questo risolve il bug mantenendo i pulsanti (ToggleButton per me) cliccabili
Mohsen Afshin

L'unico modo per ottenere GridView con RadioButtons funzionante era applicare Android: descendantFocusability = "blocksDescendants" su LinearLayout contenente RadioButton e impostando android: clickable = "false" in RadioButton stesso.
Stephen McCormick,

Sono stato bloccato su questo per 6 ore e ho davvero bisogno di aiuto. stackoverflow.com/questions/35108940/why-cant-i-remove-an-item/…
Ruchir Baronia

34

devi fare 2 passaggi nel tuo listview_item.xml

  1. imposta il layout di root con: android:descendantFocusability="blocksDescendants"
  2. imposta qualsiasi vista focalizzabile o cliccabile in questo oggetto con:
    android:clickable="false"
    android:focusable="false"
    android:focusableInTouchMode="false"

Ecco un esempio: listview_item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_marginBottom="10dp"
    android:layout_marginTop="10dp"
    android:paddingLeft="10dp"
    android:paddingRight="10dp"
    android:gravity="center_vertical"
    android:orientation="vertical"
    android:descendantFocusability="blocksDescendants">

    <RadioButton
        android:id="@+id/script_name_radio_btn"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:textStyle="bold"
        android:textColor="#000"
        android:padding="5dp"
        android:clickable="false"
        android:focusable="false"
        android:focusableInTouchMode="false"
        />

</LinearLayout>

L'impostazione clickable="truenella vista dell'elemento renderà il onItemClicknon essere chiamato. Quindi fai attenzione ad aggiungere anche clickable="false"sulla vista radice dell'articolo, in questo caso è ilLinearLayout
vovahost il

Impostare android: descendantFocusability = "blocksDescendants" mi aiuta. Grazie!
LLIAJLbHOu,

21/12/16, e dopo ore di ricerche, QUESTO ha funzionato, grazie amico!
Tanner Summers,

Se hai lo stesso layout del paesaggio, ecc. Assicurati di farlo anche lì.
Immy l'

19

utilizzare il codice seguente all'interno del tag pulsante nel layout di riga personalizzato di listview

 android:focusable="false"
 android:clickable="false"

Grande uomo è stato davvero utile !!
divyansh ingle

questo ha funzionato qui !! Ho molte caselle di controllo in questa vista e provo a android:descendantFocusability="blocksDescendants"bloccare queste caselle per clic
Armando Marques Sobrinho

17

Ho avuto lo stesso problema e ho appena visto che avevo impostato accidentalmente:

@Override
public boolean isEnabled(int position)
{
    return false;
}

sulla mia classe CustomListViewAdapter.

Modificandolo in:

return true;

Sono riuscito a risolvere il problema. Nel caso in cui qualcuno abbia fatto lo stesso errore ...


7
Anch'io ho avuto un@Override public void onApplicationStart { ExplodeThisDevice(); }
Léon Pelletier

17

Usa android: descendantFocusability

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="80dip"
    android:background="@color/light_green"
    android:descendantFocusability="blocksDescendants" >

Aggiungi sopra nel layout di root


2
L'aggiunta di dettagli potrebbe rendere questa una risposta migliore e +1.
Killer,

Questo ha funzionato per me e il mio pulsante nell'elemento elenco continuava a funzionare come previsto.
Gustav Eriksson,


10

se hai visualizzazioni di testo, pulsanti o stg selezionabili o selezionabili solo nella visualizzazione riga

android:descendantFocusability="blocksDescendants"

non è abbastanza. Devi impostare

android:textIsSelectable="false"

alle tue visualizzazioni di testo e

android:focusable="false"

ai tuoi pulsanti e altri elementi focalizzabili.


L'ho imparato a mie spese. android: textIsSelectable = "false"
Stai attento a

10

Anche se stavo avendo lo stesso problema, ho la casella di controllo, ho fatto quanto segue per far funzionare mascher itemClickListener,

Aggiunte le seguenti proprietà alla casella di controllo,

android:focusable="false"
android:focusableInTouchMode="false"
android:clickable="false"

e ItemClickListner hanno iniziato a funzionare.

Per un esempio dettagliato puoi consultare il link,

http://knowledge-cess.com/android-itemclicklistner-with-checkbox-or-radiobutton/

Spero che aiuti Saluti !!


5

Ho avuto lo stesso problema e ho provato tutte le soluzioni menzionate senza risultati. attraverso i test ho scoperto che rendere il testo selezionabile impediva di chiamare l'ascoltatore. Quindi, cambiandolo in false o rimuovendolo, il mio ascoltatore è stato chiamato di nuovo.

android:textIsSelectable="false"

spero che questo aiuti qualcuno che era bloccato come me.


4
  1. Aggiungi questo nel layout principale

    android:descendantFocusability="blocksDescendants"
  2. Scrivi questo codice in ogni pulsante, Textview, ImageView ecc. Che hanno onClick

    android:focusable="false"
    
    android:clickable="false"

Spero che funzioni.


3

Due soluzioni fantastiche erano queste, se il tuo ListFragment esteso da un frammento, sai che mListView.setOnItemClickListenernon verrà chiamato prima che la tua attività venga creata, questo assicura che sia impostato quando l'attività è stata creata

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    mListView.setOnItemClickListener(new OnItemClickListener() {

        @Override
        public void onItemClick(AdapterView<?> adapterView, View view, int position, long rowId) {
            // Do the onItemClick action

            Log.d("ROWSELECT", "" + rowId);
        }
    });
}

Mentre guardavo il codice sorgente per ListFragment, mi sono imbattuto in questo

public class ListFragment extends Fragment {
    ...........................................
    ................................................

    final private AdapterView.OnItemClickListener mOnClickListener
                = new AdapterView.OnItemClickListener() {
        public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
            onListItemClick((ListView)parent, v, position, id);
        }
    };

    ................................................................
    ................................................................

    public void onListItemClick(ListView l, View v, int position, long id) {
    }
}

Un onItemClickListeneroggetto è collegato e chiama onListItemClick() Come tale l'altra soluzione simile, che funziona esattamente allo stesso modo è quella di eseguire l'overrideonListItemClick()

@Override
public void onListItemClick(ListView l, View v, int position, long rowId) {
    super.onListItemClick(l, v, position, id);
   // Do the onItemClick action

   Log.d("ROWSELECT", "" + rowId);
} 

3

nel mio caso nessuna delle proprietà del layout xml non è stata utile.

Aggiungo solo una singola riga di codice come questa: convertView.setClickable (false);

@NonNull
@Override
public View getView(final int position, View convertView, @NonNull ViewGroup parent) {
    ViewHolder viewHolder;
    if (convertView == null || convertView.getTag() == null) {
        LayoutInflater inflater = LayoutInflater.from(context);
        convertView = inflater.inflate(R.layout.my_layout_id, parent, false);
        viewHolder = new ViewHolder(convertView);
        convertView.setTag(viewHolder);
    } else {
        viewHolder = (ViewHolder) convertView.getTag();
    }
    ...
    convertView.setClickable(false);
    return convertView;
}

quindi fondamentalmente fa la stessa cosa come impostare proprietà nel layout xml ma era l'unica cosa che funziona nel mio caso.

Non è un tempismo perfetto, ma forse aiuterà qualcuno Happy coding


1

Ho provato tutto quanto sopra e NIENTE ha funzionato.

Ho risolto il problema come segue:

Per prima cosa definisco un pulsante personalizzato chiamato ListButton

public class ListButton extends android.widget.Button
{

private ButtonClickedListener clickListener;

public ListButton(Context context)
{
    this(context, null);
}

public ListButton(Context context, AttributeSet attrs)
{
    this(context, attrs, 0);
}

public ListButton(Context context, AttributeSet attrs, int defStyle)
{
    super(context, attrs, defStyle);
}

public void setClickListener(ButtonClickedListener listener) {
    this.clickListener = listener;
}

@Override
public boolean isInTouchMode() {
    return true;
}

@Override
public boolean onTouchEvent(MotionEvent event) {

    return false;
}

@Override
public boolean dispatchTouchEvent(MotionEvent event) {

    switch (event.getAction()) 
      {
          case MotionEvent.ACTION_DOWN:
              break;
          case MotionEvent.ACTION_UP:

              eventClicked();

              break;
          case MotionEvent.ACTION_CANCEL:
              break;
          case MotionEvent.ACTION_MOVE:
              break;
          default :

      }
    return true;
}

private void eventClicked() {
    if (this.clickListener!=null) {
        this.clickListener.ButtonClicked();
    }
}

}

L'XML è simile a:

<dk.example.views.ListButton
android:id="@+id/cancel_button"
android:layout_width="125dp"
android:layout_height="80dp"
android:text="Cancel"
android:textSize="20sp" 
android:layout_margin="10dp"
android:padding="2dp"
android:background="#000000"
android:textColor="#ffffff"
android:textStyle="bold"  
/>

Quindi definisco la mia ButtonClickedinterfaccia Listener:

public interface ButtonClickedListener {
    public void ButtonClicked();
}

Quindi uso il mio ascoltatore come se fosse il normale OnClickListener:

final ListButton cancelButton = (ListButton) viewLayout.findViewById(R.id.cancel_button);

    cancelButton.setClickListener(new ButtonClickedListener() {

        @Override
        public void ButtonClicked() {
            //Do your own stuff here...
        }

    });

1

Ho avuto lo stesso problema, stavo usando uno stile per i miei testi nel layout di riga che aveva l'attributo "focalizzabile". Ha funzionato dopo che l'ho rimosso.


1

Nel mio caso, ho dovuto rimuovere la riga successiva da Layout

android:clickable="true"

1

Android: l'attributo di glossario rende anche la messa a fuoco automatica TextView.


0

Se si desidera utilizzare sia il semplice clic che il lungo clic sugli elementi della visualizzazione elenco, il modo migliore per implementare sarebbe utilizzare il menu di scelta rapida per un clic lungo. Evita di usare setItemLongClickListener soprattutto se hai layout di più righe per la visualizzazione elenco.


0

Di fronte allo stesso problema, provato per ore. Se hai provato tutto quanto sopra, prova a cambiare layout_width di Listview ed elabora l'elemento in match_parent da wrap_content.


0

Tutto quanto sopra fallito per me. Tuttavia, sono stato in grado di risolvere il problema (dopo molte ore di sbattere la testa - Google, se stai ascoltando, ti preghiamo di considerare di correggere ciò che ho riscontrato sotto sotto forma di errori del compilatore, se possibile)

Devi davvero stare attento a quali attributi Android aggiungi al tuo layout XML qui (in questa domanda originale, si chiama list_items.xml). Per me, ciò che stava causando il problema era che ero passato da una vista EditText a una TextView e avevo l'attributo residuo che si spostava dalla modifica (nel mio caso, inputType). Il compilatore non l'ha rilevato e la cliccabilità non è riuscita quando sono andato a eseguire l'app. Ricontrolla tutti gli attributi che hai nei nodi xml del layout.


0
private AdapterView.OnItemClickListener onItemClickListener;

@Override
public View getView(final int position, View convertView, final ViewGroup parent) {
 .......

final View view = convertView;
convertView.setOnClickListener(new View.OnClickListener() {
    @Override
     public void onClick(View v) {
         if (onItemClickListener != null) {
             onItemClickListener.onItemClick(null, view, position, -1);
         }
      }
 });

return convertView;
}

public void setOnItemClickListener(AdapterView.OnItemClickListener onItemClickListener) {
    this.onItemClickListener = onItemClickListener;
}

Quindi, nella tua attività, usa adapter.setOnItemClickListener () prima di collegarlo alla visualizzazione elenco.

Copiato da Github ha funzionato per me


0

La cosa che ha funzionato per me è stato aggiungere il codice seguente a ogni sottoview all'interno del layout del mio file row.xml:

android:focusable="false"
android:focusableInTouchMode="false"

Quindi nel mio caso:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">


    <TextView
        android:focusable="false"
        android:focusableInTouchMode="false"
        android:id="@+id/testingId"
        android:text="Name"
       //other stuff 
        />

    <TextView
        android:focusable="false"
        android:focusableInTouchMode="false"
        android:id="@+id/dummyId"
        android:text="icon"
        //other stuff 
        />

    <TextView
        android:focusable="false"
        android:focusableInTouchMode="false"
        android:id="@+id/assignmentColor"
       //other stuff 
       />

    <TextView
        android:focusable="false"
        android:focusableInTouchMode="false"
        android:id="@+id/testID"
        //other stuff 
        />

    <TextView
        android:focusable="false"
        android:focusableInTouchMode="false"
        android:text="TextView"
        //other stuff 
        />

</android.support.constraint.ConstraintLayout>

E questa è la mia chiamata setOnItemClickListener nella mia sottoclasse Fragment:

CustomListView = (PullToRefreshListCustomView) layout.findViewById(getListResourceID());
        CustomListView.setAdapter(customAdapter);
        CustomListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                Log.d("Testing", "onitem click working");
              //  other code
            }

        });

Ho ricevuto la risposta da qui !


-1

Ho risolto il problema rimuovendo le visualizzazioni selezionabili dall'elenco.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.