OnItemCLickListener ne fonctionne pas dans la vue de liste


243

Activity code de la 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 getViewfonction dans la 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);
    }
}

Y a-t-il un problème avec l'utilisation de deux xml pendant le gonflage?


4
@hiei Mon problème était que j'utilisais des boutons d'image dans mes cellules de disposition. Même après avoir ajouté "android: descendantFocusability", mon écouteur de clics ne répondait pas. Ce que j'ai fait, c'est que j'ai changé tous les ImaegButtons en ImageViews. Cela a résolu mon problème.
Ajith Memana

Réponses:


731

Je viens de trouver une solution d'ici, mais en cliquant profondément.

Si un élément de ligne de la liste contient une vue focalisable ou cliquable, OnItemClickListenercela ne fonctionnera pas.

L'élément de ligne doit avoir un paramètre comme android:descendantFocusability = "blocksDescendants".

Ici, vous pouvez voir un exemple de l'apparence de votre élément de liste. Votre élément de liste xml devrait être ... 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>

ne fonctionne pas pour moi. Quelqu'un peut-il jeter un œil à [ stackoverflow.com/questions/21692209/…
suitianshi

3
Vous pouvez également définir cela par programme avec listView.setDescendantFocusability(int focus);focusest l'un des ViewGroup.FOCUS_BEFORE_DESCENDANTS, ViewGroup.FOCUS_AFTER_DESCENDANTSouViewGroup.FOCUS_BLOCK_DESCENDANTS
Max Worg

Je pense que c'est drôle que comme 20 personnes vous ont remercié dans un commentaire. Je rencontre ce problème depuis 8 heures, merci beaucoup pour cela.
sparticvs

1
Ma question est-ce un bug Android ou est-ce par conception?
fangzhzh

Je suis coincé là-dessus depuis 6 heures maintenant, et j'ai vraiment besoin d'aide. stackoverflow.com/questions/35108940/why-cant-i-remove-an-item/…
Ruchir Baronia

89

Le problème est que vos mises en page contiennent des éléments pouvant être mis au point ou cliquables. Si une vue contient un élément focalisable ou cliquable, OnItemCLickListener ne sera pas appelé.

Cliquez ici pour plus d'informations.

Veuillez publier l'un de vos fichiers XML de mise en page si ce n'est pas le cas.


2
C'était la solution pour moi, je déclarais ma vue cliquable. Merci!
kingraam

1
Merci! J'ai changé mes 2 EditTexts en TextViews, et le a CheckBoxété autorisé à rester (et à basculer) avec l' android:descendantFocusability="blocksDescendants"ajout à mon LinearLayout.
Azurespot

Oui! J'avais android:focusableInTouchMode="true"pour le rang, une fois retiré, il a enfin commencé à fonctionner! :-)
SharpC

58

Pour mes listes, mes lignes ont d'autres choses sur lesquelles on peut cliquer, comme des boutons, donc faire une couverture blocksDescendantsne fonctionne pas. Au lieu de cela, j'ai ajouté une ligne dans le xml du bouton:

android:focusable="false"

Cela empêche les boutons de bloquer les clics sur les lignes, mais permet toujours aux boutons de prendre les clics.


@ user1840899 Ceci est une réponse courante et celle dont j'ai appris, donc je l'ai transmise. Ce sont des informations correctes, pas dignes d'un vote négatif.
Janene Pappas

Cela fonctionne pour moi sur un CheckBox dans les éléments ListView (sans blocsDescendants)
thpitsch

Cela corrige le bug tout en gardant les boutons (ToggleButton pour moi) cliquables
Mohsen Afshin

La seule façon de faire fonctionner une GridView avec RadioButtons était d'appliquer android: descendantFocusability = "blocksDescendants" sur le LinearLayout contenant le RadioButton, et en définissant android: clickable = "false" dans le RadioButton lui-même.
Stephen McCormick

Je suis coincé là-dessus depuis 6 heures maintenant, et j'ai vraiment besoin d'aide. stackoverflow.com/questions/35108940/why-cant-i-remove-an-item/…
Ruchir Baronia

34

vous devez faire 2 étapes dans votre listview_item.xml

  1. définissez la disposition racine avec: android:descendantFocusability="blocksDescendants"
  2. définissez une vue focalisable ou cliquable dans cet élément avec:
    android:clickable="false"
    android:focusable="false"
    android:focusableInTouchMode="false"

Voici un exemple: 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>

Le réglage clickable="truesur la vue de l'élément fera que le onItemClickne sera pas appelé. clickable="false"LinearLayout
Faites

Définir Android: descendantFocusability = "blocksDescendants" m'aide. Merci!
LLIAJLbHOu

21/12/16, et après des heures de recherche, cela a fonctionné, merci mec!
Tanner Summers

Si vous avez la même disposition que paysage, etc. assurez-vous de le faire également.
Immy

19

utilisez le code ci-dessous à l'intérieur de la balise de bouton dans la disposition des lignes personnalisée de listview

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

Great Man its was really helpfull !!
divyansh ingle

cela a fonctionné ici !! J'ai de nombreuses cases à cocher dans cette vue et j'essaie de les android:descendantFocusability="blocksDescendants"bloquer pour les cliquer
Armando Marques Sobrinho

17

J'ai eu le même problème et je viens de voir que j'avais accidentellement réglé:

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

sur ma classe CustomListViewAdapter.

En changeant ceci en:

return true;

J'ai réussi à résoudre le problème. Au cas où quelqu'un aurait fait la même erreur ...


7
Moi aussi, j'ai eu@Override public void onApplicationStart { ExplodeThisDevice(); }
Léon Pelletier

17

Utiliser 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" >

Ajouter ci-dessus dans la disposition racine


2
L'ajout de détails pourrait en faire une meilleure réponse et +1.
Killer

Cela a fonctionné pour moi et mon bouton dans l'élément de liste a toujours fonctionné comme prévu.
Gustav Eriksson


10

si vous avez des vues de texte, des boutons ou stg cliquables ou sélectionnables dans votre affichage de ligne uniquement

android:descendantFocusability="blocksDescendants"

n'est pas assez. Vous devez définir

android:textIsSelectable="false"

à vos vues de texte et

android:focusable="false"

à vos boutons et autres éléments pouvant être mis au point.


Je l'ai appris à la dure. android: textIsSelectable = "false" Surveillez cela :)
diyoda_

10

Même si j'avais le même problème, j'ai une case à cocher, j'ai fait ce qui suit pour masquer le travail itemClickListener,

Ajout des propriétés suivantes à la case à cocher,

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

et ItemClickListner a commencé à fonctionner.

Pour un exemple détaillé, vous pouvez passer par le lien,

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

J'espère que ça aide Cheers !!


5

J'ai eu le même problème et j'ai essayé toutes les solutions mentionnées en vain. grâce à des tests, j'ai trouvé que rendre le texte sélectionnable empêchait l'auditeur d'être appelé. Donc, en le mettant sur false ou en le supprimant, mon auditeur a été rappelé.

android:textIsSelectable="false"

j'espère que cela aide quelqu'un qui était coincé comme moi.


4
  1. Ajoutez ceci dans la disposition principale

    android:descendantFocusability="blocksDescendants"
  2. Écrivez ce code dans chaque bouton, Textview, ImageView etc. qui ont onClick

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

J'espère que cela fonctionnera.


3

Deux solutions impressionnantes étaient les suivantes, si votre extension ListFragment à partir d'un fragment, sait que mListView.setOnItemClickListenerne sera pas appelé avant la création de votre activité, cela garantit qu'il est défini lorsque l'activité a été créée

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

En regardant le code source de ListFragment, je suis tombé sur ce

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 onItemClickListenerobjet est attaché et il appelle en onListItemClick() tant que telle l'autre solution similaire, qui fonctionne exactement de la même manière, c'est de remplaceronListItemClick()

@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

dans mon cas, aucune des propriétés de mise en page xml ne m'a été utile.

J'ajoute juste une seule ligne de code comme ceci: 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;
}

Donc, fondamentalement, cela fait la même chose que la configuration des propriétés dans la mise en page XML, mais c'est la seule chose qui fonctionne dans mon cas.

Ce n'est pas un timing parfait, mais peut-être que cela aidera quelqu'un


1

J'ai essayé tout ce qui précède et RIEN n'a fonctionné.

J'ai résolu le problème comme suit:

Je définis d'abord un bouton personnalisé appelé 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();
    }
}

}

Le XML ressemble à:

<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"  
/>

Ensuite, je définis ma propre ButtonClickedinterface d'écoute:

public interface ButtonClickedListener {
    public void ButtonClicked();
}

Ensuite, j'utilise mon propre écouteur comme si c'était la 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

J'ai eu le même problème, j'utilisais un style pour mes textes dans la disposition des lignes qui avait l'attribut "focusable". Cela a fonctionné après l'avoir retiré.


1

Dans mon cas, j'ai dû supprimer la ligne suivante du Layout

android:clickable="true"


0

Si vous souhaitez utiliser à la fois le simple clic et le long clic sur les éléments de la vue de liste, la meilleure façon de les implémenter serait d'utiliser le menu contextuel pour un long clic. Évitez d'utiliser setItemLongClickListener, surtout si vous disposez de plusieurs dispositions de ligne pour votre affichage de liste.


0

Face au même problème, essayé pendant des heures. Si vous avez essayé toutes les solutions ci-dessus, essayez de modifier layout_width de Listview et list item pour match_parent de wrap_content.


0

Tout ce qui précède a échoué pour moi. Cependant, j'ai pu résoudre le problème (après plusieurs heures à me cogner la tête - Google, si vous écoutez, veuillez envisager de corriger ce que j'ai rencontré ci-dessous sous la forme d'erreurs de compilation, si possible)

Vous devez vraiment faire attention aux attributs Android que vous ajoutez à votre disposition xml ici (dans cette question d'origine, cela s'appelle list_items.xml). Pour moi, ce qui causait le problème, c'est que j'étais passé d'une vue EditText à une TextView et que j'avais laissé les attributs croupir du changement (dans mon cas, inputType). Le compilateur ne l'a pas détecté et la cliquabilité a juste échoué lorsque je suis allé exécuter l'application. Vérifiez tous les attributs que vous avez dans vos nœuds XML de mise en page.


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

Ensuite, dans votre activité, utilisez adapter.setOnItemClickListener () avant de le joindre à la vue de liste.

Copié de github, ça a marché pour moi


0

La chose qui a fonctionné pour moi a été d'ajouter le code ci-dessous à chaque sous-vue à l'intérieur de la disposition de mon fichier row.xml:

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

Donc dans mon cas:

<?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>

Et voici mon appel setOnItemClickListener dans ma sous-classe 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
            }

        });

J'ai obtenu la réponse d' ici !


-1

J'ai résolu le problème en supprimant les vues cliquables de la liste.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.