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?

hiei
la source
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>
Bhavesh Hirpara
la source
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.

balazsbalazs
la source
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.

Janene Pappas
la source
@ 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>
Tourbillon
la source
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"
Milan Shukla
la source
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 ...

Boisé
la source
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

Amar Gore
la source
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
11

Je l'ai résolu avec l'aide de cette réponse

1.Ajoutez les éléments suivants dans Disposition linéaire de list_items.xml android:descendantFocusability="blocksDescendants"

2. Vues d'enfant de LinearLayout dans list_items.xml

 android:focusable="false" 
RAJESH KUMAR ARUMUGAM
la source
Votre lien est rompu.
Jason C
1
@JasonC Merci pour vos informations. Voici le lien stackoverflow.com/a/14915758/5740760
RAJESH KUMAR ARUMUGAM
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.

population
la source
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 !!

Gokul Kulkarni
la source
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.

u2tall
la source
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.

Wajid khan
la source
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);
} 
Rowland Mtetezi
la source
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

Marek Skóra
la source
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...
        }

    });
AndreasReiff
la source
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é.

Miguel Rdz
la source
1

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

android:clickable="true"
IgniteCoders
la source
1

Android: l'attribut autoText rend également TextView auto focusable.

Yury Finchenko
la source
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.

Samuel Robert
la source
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.

prashant
la source
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.

Ted_Zactly
la source
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

Muhammad Waleed
la source
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 !

spcarlin
la source
-1

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

sidKhalid
la source