OnItemCLickListener funktioniert nicht in der Listenansicht


242

Activity Klassencode:

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

Die getViewFunktion in der AdapterKlasse:

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

Gibt es ein Problem mit der Verwendung von zwei xml beim Aufblasen?


4
@hiei Mein Problem war, dass ich Bildschaltflächen in meinen Layoutzellen verwendete. Selbst nach dem Hinzufügen von "android: descantFocusability" reagierte mein Klick-Listener nicht. Ich habe alle ImaegButtons in ImageViews geändert. Das hat mein Problem gelöst.
Ajith Memana

Antworten:


730

Ich habe gerade eine Lösung von hier gefunden, aber durch tiefes Klicken.

Wenn ein Zeilenelement der Liste eine fokussierbare oder anklickbare Ansicht enthält, funktioniert dies OnItemClickListenernicht.

Das Zeilenelement muss einen Parameter wie haben android:descendantFocusability = "blocksDescendants".

Hier sehen Sie ein Beispiel, wie Ihr Listenelement aussehen sollte. Ihr Listenelement xml sollte ... 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>

nicht für mich arbeiten. Kann jemand einen Blick auf [ stackoverflow.com/questions/21692209/…
Suitianshi

3
Sie können dies auch einstellen programmatisch mit listView.setDescendantFocusability(int focus);denen focuseines von ViewGroup.FOCUS_BEFORE_DESCENDANTS, ViewGroup.FOCUS_AFTER_DESCENDANTSoderViewGroup.FOCUS_BLOCK_DESCENDANTS
Max Worg

Ich finde das lustig, dass sich wie 20 Leute in einem Kommentar bei dir bedankt haben. Ich bin in den letzten 8 Stunden auf dieses Problem gestoßen, vielen Dank dafür.
Sparticvs

1
Meine Frage ist, dass dies ein Android-Fehler ist oder beabsichtigt ist?
Fangzhzh

Ich bin jetzt seit 6 Stunden dabei und brauche wirklich Hilfe. stackoverflow.com/questions/35108940/why-cant-i-remove-an-item/…
Ruchir Baronia

89

Das Problem ist, dass Ihre Layouts entweder fokussierbare oder anklickbare Elemente enthalten. Wenn eine Ansicht entweder ein fokussierbares oder ein anklickbares Element enthält, wird der OnItemCLickListener nicht aufgerufen.

Klicken Sie hier für weitere Informationen.

Bitte poste eine deiner Layout-XMLs, wenn dies nicht der Fall ist.


2
Dies war die Lösung für mich, ich erklärte meine Ansicht als anklickbar. Vielen Dank!
Kingraam

1
Vielen Dank! Ich habe meine 2 EditTexts in TextViews geändert und das CheckBoxdurfte bleiben (und umschaltbar bleiben) mit android:descendantFocusability="blocksDescendants"zu meinem hinzugefügt LinearLayout.
Azurespot

Ja! Ich hatte android:focusableInTouchMode="true"für die Reihe, sobald es entfernt wurde, fing es endlich an zu funktionieren! :-)
SharpC

58

Für meine Listen haben meine Zeilen andere Dinge, auf die geklickt werden kann, wie z. B. Schaltflächen, sodass das Ausführen einer Decke blocksDescendantsnicht funktioniert. Stattdessen habe ich eine Zeile in die XML-Datei der Schaltfläche eingefügt:

android:focusable="false"

Dadurch wird verhindert, dass die Schaltflächen die Klicks auf die Zeilen blockieren, die Schaltflächen können jedoch weiterhin die Klicks ausführen.


@ user1840899 Dies ist eine häufige Antwort, von der ich gelernt habe, also habe ich sie weitergegeben. Es handelt sich um korrekte Informationen, die es nicht wert sind, herabgestimmt zu werden.
Janene Pappas

Dies funktioniert für mich auf einer CheckBox in ListView-Elementen (ohne BlocksDescendants)
Thpitsch

Dies behebt den Fehler, während die Schaltflächen (ToggleButton für mich) anklickbar bleiben
Mohsen Afshin

Die einzige Möglichkeit, eine GridView mit RadioButtons zum Laufen zu bringen, bestand darin, android: descantFocusability = "blocksDescendants" auf das LinearLayout anzuwenden, das den RadioButton enthält, und android: clickable = "false" im RadioButton selbst festzulegen.
Stephen McCormick

Ich bin jetzt seit 6 Stunden dabei und brauche wirklich Hilfe. stackoverflow.com/questions/35108940/why-cant-i-remove-an-item/…
Ruchir Baronia

34

Sie müssen 2 Schritte in Ihrer listview_item.xml ausführen

  1. Legen Sie das Root-Layout fest mit: android:descendantFocusability="blocksDescendants"
  2. Stellen Sie eine fokussierbare oder anklickbare Ansicht in diesem Element ein mit:
    android:clickable="false"
    android:focusable="false"
    android:focusableInTouchMode="false"

Hier ist ein Beispiel: 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>

Durch die Einstellung clickable="truein der Elementansicht wird das onItemClicknicht aufgerufen. clickable="false"LinearLayout
Achten Sie

Das Einstellen von android: descantFocusability = "blocksDescendants" hilft mir. Vielen Dank!
LLIAJLbHOu

21.12.16, und nach stundenlangem Suchen hat DAS funktioniert, danke Mann!
Tanner Summers

Wenn Sie das gleiche Layout wie Querformat usw. haben, stellen Sie sicher, dass Sie es auch dort tun.
Immy

19

Verwenden Sie den folgenden Code im Schaltflächen-Tag im benutzerdefinierten Zeilenlayout der Listenansicht

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

Toller Mann, es war wirklich hilfreich !!
Divyansh Ingle

das hat hier geklappt !! Ich habe viele Kontrollkästchen in dieser Ansicht und ich versuche android:descendantFocusability="blocksDescendants", diese Kontrollkästchen für Klick zu blockieren
Armando Marques Sobrinho

17

Ich hatte das gleiche Problem und sah nur, dass ich versehentlich eingestellt hatte:

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

in meiner CustomListViewAdapter-Klasse.

Indem Sie dies ändern in:

return true;

Ich habe es geschafft, das Problem zu beheben. Nur für den Fall, dass jemand den gleichen Fehler gemacht hat ...


7
Ich hatte auch eine@Override public void onApplicationStart { ExplodeThisDevice(); }
Léon Pelletier

17

Verwenden Sie android: descantFocusability

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

Fügen Sie oben im Root-Layout hinzu


2
Durch Hinzufügen von Details ist dies möglicherweise eine bessere Antwort und +1.
Killer

Dies funktionierte für mich und meine Schaltfläche im Listenelement funktionierte immer noch wie beabsichtigt.
Gustav Eriksson


10

Wenn Sie Textansichten, Schaltflächen oder stg nur in Ihrer Zeilenansicht anklickbar oder auswählbar haben

android:descendantFocusability="blocksDescendants"

ist nicht genug. Du musst einstellen

android:textIsSelectable="false"

zu Ihren Textansichten und

android:focusable="false"

zu Ihren Schaltflächen und anderen fokussierbaren Elementen.


Ich habe das auf die harte Tour gelernt. android: textIsSelectable = "false" Achten Sie darauf :)
diyoda_

10

Sogar ich hatte das gleiche Problem, ich habe ein Kontrollkästchen, habe die folgenden Schritte ausgeführt, um itemClickListener zu maskieren:

Dem Kontrollkästchen wurden die folgenden Eigenschaften hinzugefügt:

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

und ItemClickListner begannen zu arbeiten.

Für ein detailliertes Beispiel können Sie über den Link gehen,

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

Hoffe es hilft Prost !!


5

Ich hatte das gleiche Problem und versuchte alle genannten Lösungen ohne Erfolg. Durch Tests stellte ich fest, dass das Auswählen des Textes das Aufrufen des Listeners verhinderte. Durch Umschalten auf false oder Entfernen wurde mein Listener erneut aufgerufen.

android:textIsSelectable="false"

hoffe, das hilft jemandem, der wie ich feststeckte.


4
  1. Fügen Sie dies im Hauptlayout hinzu

    android:descendantFocusability="blocksDescendants"
  2. Schreiben Sie diesen Code in jede Schaltfläche, Textansicht, Bildansicht usw., die onClick haben

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

Hoffe es wird funktionieren.


3

Zwei großartige Lösungen waren: Wenn Sie ListFragment aus einem Fragment erweitern und wissen, dass mListView.setOnItemClickListeneres nicht aufgerufen wird, bevor Ihre Aktivität erstellt wird, wird sichergestellt, dass es festgelegt wird, wenn die Aktivität erstellt wurde

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

Beim Betrachten des Quellcodes für ListFragment bin ich darauf gestoßen

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

Ein onItemClickListenerObjekt wird angehängt und onListItemClick() als solches aufgerufen. Die andere ähnliche Lösung, die genauso funktioniert, besteht darin, sie zu überschreibenonListItemClick()

@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

In meinem Fall war keine der XML-Layout-Eigenschaften nicht hilfreich.

Ich füge nur eine einzelne Codezeile wie folgt hinzu : 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;
}

Im Grunde macht es dasselbe wie das Einrichten von Eigenschaften im XML-Layout, aber es war nur das, was in meinem Fall funktioniert.

Es ist kein perfektes Timing, aber vielleicht hilft es jemandem. Happy Coding


1

Ich habe alles oben versucht und NICHTS hat funktioniert.

Ich habe das Problem wie folgt gelöst:

Zuerst definiere ich einen benutzerdefinierten Button namens 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();
    }
}

}

Das XML sieht aus wie:

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

Dann definiere ich meine eigene ButtonClickedListener-Oberfläche:

public interface ButtonClickedListener {
    public void ButtonClicked();
}

Dann benutze ich meinen eigenen Hörer, als wäre es normal 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

Ich hatte das gleiche Problem, ich verwendete einen Stil für meine Texte im Zeilenlayout, der das Attribut "fokussierbar" hatte. Es hat funktioniert, nachdem ich es entfernt habe.


1

In meinem Fall musste ich die nächste Zeile aus dem entfernen Layout

android:clickable="true"


0

Wenn Sie sowohl den einfachen Klick als auch den langen Klick auf Listenansichtselemente verwenden möchten, können Sie dies besser implementieren, indem Sie das Kontextmenü für den langen Klick verwenden. Vermeiden Sie die Verwendung von setItemLongClickListener, insbesondere wenn Sie mehrere Zeilenlayouts für Ihre Listenansicht haben.


0

Konfrontiert das gleiche Problem, stundenlang versucht. Wenn Sie alle oben genannten Schritte ausgeführt haben, ändern Sie die layout_width von Listview und das Listenelement von wrap_content in match_parent.


0

All das ist für mich gescheitert. Ich konnte das Problem jedoch beheben (nach vielen Stunden Kopfschlag - Google, wenn Sie zuhören, sollten Sie in Betracht ziehen, das, was ich unten festgestellt habe, wenn möglich in Form von Compilerfehlern zu beheben).

Sie müssen wirklich vorsichtig sein, welche Android-Attribute Sie Ihrem XML-Layout hier hinzufügen (in dieser ursprünglichen Frage heißt es list_items.xml). Für mich war das Problem, dass ich von einer EditText-Ansicht zu einer TextView gewechselt war und das Attribut cruft aus der Änderung übrig hatte (in meinem Fall inputType). Der Compiler hat es nicht abgefangen und die Klickbarkeit ist einfach fehlgeschlagen, als ich die App ausgeführt habe. Überprüfen Sie alle Attribute, die Sie in Ihren Layout-XML-Knoten haben.


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

Verwenden Sie dann in Ihrer Aktivität adapter.setOnItemClickListener (), bevor Sie es an die Listenansicht anhängen.

Von Github kopiert, hat es für mich funktioniert


0

Für mich hat es funktioniert, jeder Unteransicht im Layout meiner Datei row.xml den folgenden Code hinzuzufügen:

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

Also in meinem Fall:

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

Und dies ist mein setOnItemClickListener-Aufruf in meiner Fragment-Unterklasse:

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
            }

        });

Ich habe die Antwort von hier !


-1

Ich habe das Problem gelöst, indem ich die anklickbaren Ansichten aus der Liste entfernt habe.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.