89 votes

Comment déclencher onListItemClick dans Listactivity avec les boutons dans la liste?

J'ai une simple ListActivity qui utilise un custom ListAdapter pour générer les points de vue dans la liste. Normalement, le ListAdapter serait-il suffit de remplir les vues avec TextViews, mais maintenant, je veux mettre un bouton.

C'est ma compréhension et mon expérience, cependant, que de mettre un focusable vue dans l'élément de la liste empêche le tir de onListItemClick() dans le ListActivity lorsque l'élément de liste est cliqué. Le bouton fonctionne toujours normalement à l'intérieur de l'élément de la liste, mais quand quelque chose en plus le bouton est pressé, je veux onListItemClick d'être déclenchée.

Comment puis-je faire ce travail?

99voto

Ewoks Points 3910

comme je l'ai écrit dans le commentaire précédent, la solution consiste à définirFocusable (false) sur ImageButton.

Il existe une solution encore plus élégante, essayez d'ajouter android:descendantFocusability="blocksDescendants" dans la disposition racine de l'élément de liste. Cela rendra les clics sur ListItem possibles et séparément, vous pourrez gérer les clics de Button ou ImageButton.

J'espère que ça aide ;)

À votre santé

59voto

Ramps Points 2973

J'espère que je peux vous aider ici. Je suppose que vous avez une mise en page personnalisée éléments listView, et cette disposition se compose de bouton et quelques autres points de vue - comme TextView, ImageView ou quoi que ce soit. Maintenant, vous voulez avoir différentes événement lancé sur le bouton et cliquez sur les différents événements tiré sur tout le reste cliqué.

Vous pouvez le faire sans l'aide de onListItemClick() de votre ListActivity.
Voici ce que vous devez faire:

Vous utilisez la mise en page personnalisée, de sorte que probablement vous écrasez getView() la méthode de votre adaptateur personnalisé. L'astuce consiste à définir les différents auditeurs pour votre bouton et différents pour l'ensemble de la vue (votre ligne). Jetez un oeil à l'exemple:

private class MyAdapter extends ArrayAdapter<String> implements OnClickListener {

    public MyAdapter(Context context, int resource, int textViewResourceId,
            List<String> objects) {
        super(context, resource, textViewResourceId, objects);
    }


    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        String text = getItem(position);
        if (null == convertView) {
            convertView = mInflater.inflate(R.layout.custom_row, null);
        }
        //take the Button and set listener. It will be invoked when you click the button.
        Button btn = (Button) convertView.findViewById(R.id.button);
        btn.setOnClickListener(this);
        //set the text... not important     
        TextView tv = (TextView) convertView.findViewById(R.id.text);
        tv.setText(text);
        //!!! and this is the most important part: you are settin listener for the whole row
        convertView.setOnClickListener(new OnItemClickListener(position));
        return convertView;
    }

    @Override
    public void onClick(View v) {
        Log.v(TAG, "Row button clicked");
    }
}

Votre OnItemClickListener la classe peut être déclarée comme ici:

private class OnItemClickListener implements OnClickListener{       
    private int mPosition;
    OnItemClickListener(int position){
        mPosition = position;
    }
    @Override
    public void onClick(View arg0) {
        Log.v(TAG, "onItemClick at position" + mPosition);          
    }       
}

Bien sûr, vous aurez probablement ajouter un peu plus de paramètres à OnItemClickListener constructeur.
Et une chose importante - de la mise en œuvre de getView indiqué ci-dessus est assez laid, normalement, vous devriez utiliser ViewHolder modèle pour éviter findViewById appels.. mais vous savez probablement déjà que.
Mon custom_row.xml fichier est RelativeLayout avec Bouton d'id "bouton", TextView de l'id de "texte" et ImageView de id "image" - juste pour rendre les choses claires.
Ce qui concerne les!

18voto

Rabi Points 1757

Quand un ListView personnalisé contient des éléments activables, onListItemClick ne fonctionnera pas (je pense que c'est le comportement attendu). Supprimez simplement le focus de la vue personnalisée, cela fera l'affaire:

Par exemple:

 public class ExtendedCheckBoxListView extends LinearLayout {

    private TextView mText;
    private CheckBox mCheckBox;

    public ExtendedCheckBoxListView(Context context, ExtendedCheckBox aCheckBoxifiedText) {
         super(context);
         …
         mText.setFocusable(false);
         mText.setFocusableInTouchMode(false);

         mCheckBox.setFocusable(false);
         mCheckBox.setFocusableInTouchMode(false);
        …       
    }
}
 

13voto

fellons Points 201

J'ai le même problème: OnListItemClick pas viré ! [RÉSOLU]
C'est arriver sur la classe qui s'étendent ListActivity,
avec une mise en page pour ListActivity que le contenu de zone de texte et ListView imbriqués dans LinearLayout
et une autre mise en page pour les lignes (une Case à cocher et de la zone de texte imbriqué dans LineraLayout).

C'est le code:

res/layout/configpage.xml (principal pour ListActivity)

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"  
    android:orientation="vertical"  
    android:layout_width="fill_parent"  
    android:layout_height="fill_parent" > 
    <TextView  
        android:id="@+id/selection"  
        android:layout_width="fill_parent"  
        android:layout_height="wrap_content"  
        android:text="pippo" /> 
    <ListView  
        android:id="@android:id/list"  
        android:layout_width="fill_parent"  
        android:layout_height="wrap_content"  
        android:drawSelectorOnTop="false"  
        android:background="#aaFFaa" > 
    </ListView> 
<LinearLayout> 

res/layout/row.xml (layout for single row)  
<LinearLayout  
  xmlns:android="http://schemas.android.com/apk/res/android"  
  android:layout_width="fill_parent"  
  android:layout_height="wrap_content"> 
  <CheckBox  
      android:id="@+id/img"  
      android:layout_width="wrap_content"  
      android:layout_height="wrap_content"  
      **android:focusable="false"**  
      **android:focusableInTouchMode="false"** /> 

  <TextView  
      android:id="@+id/testo"  
      android:layout_width="wrap_content"  
      android:layout_height="wrap_content"  
      **android:focusable="false"**  
      **android:focusableInTouchMode="false"** /> 
</LinearLayout> 

src/.../.../ConfigPage.java

public class ConfigPage extends ListActivity
{
    TextView selection;

    public void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.configpage);  
        // loaded from res/value/strings  
        String[] azioni = getResources().getStringArray(R.array.ACTIONS);  
        setListAdapter(new ArrayAdapter&lt;String&gt;(this, R.layout.row, 
                R.id.testo,   azioni));  
        selection = (TextView) findViewById(R.id.selection);  
    }       

    public void onListItemClick(ListView parent, View view, int position, long id)
    {
        selection.setText(" " + position);
    }
}

C'commencer à travailler quand je l'ai ajouté sur row.xml

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

J'utilise Eclipse 3.5.2
Android SDK 10.0.1
min version du SDK: 3

J'espère que c'est utile
... et désolé pour mon anglais :(

1voto

Ridiculous Points 38

J'ai eu le même problème avec ToggleButton. Après une demi-journée de cogner ma tête contre un mur, j'ai enfin résolu. C'est aussi simple que de prendre la focusable vue de l'onu-peut recevoir le focus, à l'aide de la "android:focusable'. Vous devriez aussi éviter de jouer avec la focalisation et clickability (j'ai juste fait des mots) de la ligne de la liste, juste de les laisser avec la valeur par défaut.

Bien sûr, maintenant que votre focusable vues dans la ligne de la liste de l'onu-peut recevoir le focus, les utilisateurs à l'aide du clavier peut avoir des problèmes, bien, en les concentrant. Il n'est pas susceptible d'être un problème, mais juste au cas où vous souhaitez écrire à 100% impeccable apps, vous pouvez utiliser le onItemSelected de l'événement pour rendre les éléments de la ligne sélectionnée peut recevoir le focus et les éléments de la ligne sélectionnée de l'onu-peut recevoir le focus.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X