ListView setOnItemClickListener funktioniert nicht durch Hinzufügen einer Schaltfläche

88

Ich habe eine Listenansicht mit Text und Schaltfläche in jeder Zeile, Listenansicht setOnItemClickListener () funktioniert nicht. Ist es möglich, Elementklick- und Schaltflächenklickereignisse unterschiedlich zu behandeln (Elementklick sollte ActivityA aufrufen und Schaltflächenklick sollte ActivityB aufrufen). Hat jemand eine Lösung

    private ArrayList<String> userIDArr = null;
    private ArrayList<String> userNameArr = null;
    private DatabaseHelper dbHelper = null;
    private ListView userListView=null; 


    public void onCreate(Bundle savedInstanceState) 
        {
          super.onCreate(savedInstanceState);         
          setContentView(R.layout.list_view);         
          dbHelper = new DatabaseHelper(this.getApplicationContext());        
          Map<String,ArrayList<String>> displayMap = dbHelper.getUserListToDisplay();
          userIDArr = displayMap.get("UserID");
          userNameArr = displayMap.get("FirstName1");           


          userListView = (ListView) findViewById(R.id.listView2);
          userListView.setAdapter(new UserListAdapter(this,userIDArr));


          userListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
              @Override
              public void onItemClick(AdapterView<?> arg0, View arg1, int position, long arg3) {

                  Toast.makeText(usersListActivity.this,
                            "Item in position " + position + " clicked", Toast.LENGTH_LONG).show();
              }
            });
     }


    public class UserListAdapter extends ArrayAdapter<String>
    {
        Activity context;
        public UserListAdapter(Activity context, ArrayList<String> names) {
            super(context, R.layout.list_item, names);
            this.context = context;
        }
        private class ViewHolder {
            public TextView UserNameAndID;
            public TextView Description;
            public Button  UploadBtn;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            ViewHolder holder;
            View rowView = convertView;
            if (rowView == null) {
                LayoutInflater inflater = context.getLayoutInflater();
                rowView = inflater.inflate(R.layout.list_item, null, true);
                holder = new ViewHolder();
                holder.UserNameAndID = (TextView) rowView.findViewById(R.id.User_detailsTxt);
                holder.Description = (TextView) rowView.findViewById(R.id.User_status);
                holder.UploadBtn = (Button) rowView.findViewById(R.id.uploadbutton);
                holder.UploadBtn.setOnClickListener(new View.OnClickListener() {  

                        public void onClick(View v) {  
                        Toast.makeText(usersListActivity.this," Button clicked",Toast.LENGTH_SHORT).show();
                        }   
                    }); 
                    rowView.setTag(holder);
            } else {
                holder = (ViewHolder) rowView.getTag();
            }
            String s = userNameArr.get(position)+","+userIDArr.get(position);
            holder.UserNameAndID.setText(s);
            holder.Description.setText("U r in middle");
            return rowView;
        }
    }
}`
Kishore
quelle

Antworten:

260

Versuchen Sie, Ihre Schaltflächen (oder andere Ansichten, die Sie bearbeiten möchten, klicken Sie in ein Listenelement) wie folgt einzustellen:

android:focusable="false"
android:focusableInTouchMode="false"
Ben Lee
quelle
@ Ben Lee: Ich habe diese zu meinen Kontrollkästchen hinzugefügt! Funktioniert immer noch nicht. Was kann ich falsch machen?
TDaver
1
android:focusableInTouchMode="false"löst meine. Ich verwende zwei TextView in einer benutzerdefinierten LinearLayout-Zeile. Yuk Android ...
Youngjae
12
ImageButton funktioniert nicht. In der Listenelementansicht, die ImageButton enthält, setzen Sie android: descantFocusability = "blocksDescendants".
ChangUZ
8
Hinzufügen von Android: clickable = "false" kann ebenfalls erforderlich sein (Ein- und Ausschalten im Layout-Designer, um es explizit zum XML
hinzuzufügen
11
Warnung: Wenn Sie einen ImageButton verwenden, müssen Sie setFocusable (false) verwenden, da der Konstruktor von ImageButton dieses Attribut nach dem Aufblasen aus der XML-Datei aktivieren würde. Aber gute Antwort
Mateu
118

Manchmal kann die Liste den Click Listener immer noch nicht zum Bestehen bringen. In diesem Fall müssen Sie möglicherweise ein weiteres Attribut hinzufügen.

android:descendantFocusability="blocksDescendants" 

Dieses Attribut muss dem obersten Layout Ihres XML hinzugefügt werden, in dem Sie die ListView-Elemente bereitgestellt haben.

Andro Selva
quelle
Nur damit niemand anderes das tut, was ich gerade getan habe: Dies ist unerwünscht, wenn Sie etwas in Ihrer Zeile haben, das den Fokus erfordert, wie einen EditText. Ich fühle mich jetzt dumm.
Kitalda
In meinem Fall hat dieser Rat geholfen. Ich habe eine TextView und einen RadioButton, die 1. hatte nicht geklickt, die 2. hatte die TextView nicht ausgewählt. Ich habe "android: clickable =" false "" in RadioButton geschrieben.
CoolMind
Dies ist die Lösung, wenn die Schaltfläche ein ImageButton
Mahonster
15

Wenn Ihre Listenansicht eine aktive Ansicht / fokussierbare Ansicht enthält, wird diese deaktiviert onItemClickListener. Sie können versuchen, sie nicht fokussierbar zu machen, indem Sie Folgendes hinzufügen: android:focusable="false"zu jeder Ansicht, die normalerweise fokussierbar ist.

Nilesh
quelle
8

Die Sache mit dem Teig ist, sowohl Listenerdas Ganze rowViewals auch das ButtonInnere zu ergänzen Adapter. Etwas wie das.

public class MyAdapter extends BaseAdapter implements View.OnClickListener{

    @Override
    public View getView(int position, View convertView, ViewGroup parent)
    {
            View rowView = convertView;
            if(rowView == null)
            {
                    //intialize rowView, and set onclick listener only once.
                    rowView = someIntilizationMehhodOrInflatorMethod();
                    //add listener to the button also and also to the row view
                    rowView.setOnClickListener(this);
            }
            //all your inflation and setting values goes here and at the end,
            //set position as tag to get the correct position, rather buggy one.
            rowView.setTag(String.valueOf(position));


            return rowView;
    }
    public void onClick(View v)
    {
            //now get the tag of View v and convert it to integer.
            int pos = Integer.parseInt(v.getTag().toString());
            Toast.makeText(context,"Item in position " + pos + " clicked",Toast.LENGTH_LONG).show();
    }
}
Adil Soomro
quelle
3
Wie ist das noch besser? Sie erstellen einen onClickListener für JEDES Datenelement gegenüber nur einem Listener. Ihr Beispiel recycelt nicht einmal welche Ansichten.
JRomero
@ J.Romero Dies war nur ein Beispiel, obwohl es viel Raum für Codeoptimierung gibt. Allerdings habe ich gerade den Code aktualisiert.
Adil Soomro
5

Versuchen Sie setzen setClickable(false)für jeden Button, ImageButtonusw. und Viewwie folgt aus :

view.setClickable(false);
button.setClickable(false);
imagebutton.setClickable(false);

Auch muss man hinzufügen

android:descendantFocusability="blocksDescendants"

zum Hauptlayout (erste Ebene)

Vlad
quelle
2
Ich habe Set-Blöcke gefunden. Nachkommen sind genug, keine Notwendigkeit, fokussierbar abzubrechen usw. Android 4.1
DJDance
2

Anstatt eine Schaltfläche hinzuzufügen ImageView, fügen Sie einen setOnItemClcikListener hinzu, der gut funktionieren würde.

public View getView(final int position, View convertView, ViewGroup parent) {
     MyViewHolder mViewHolder;
     if(convertView == null) {
         convertView = inflater.inflate(R.layout.youtubesearchrow, null);
         mViewHolder = new MyViewHolder();
         mViewHolder.alarm = (ImageView)convertView.findViewById(R.id.alarm);
         convertView.setTag(mViewHolder);
     } else {
         mViewHolder = (MyViewHolder) convertView.getTag();
     }

     mViewHolder.tvTitle = detail(convertView, R.id.tvTitle,    
     // mViewHolder.tvDesc  = detail(convertView, R.id.tvDesc,  
     mViewHolder.ivIcon  = detail_image(convertView, R.id.ivIcon,  

     mViewHolder.alarm.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
        // TODO Auto-generated method stub
        }
    });

        return convertView;
}
Sharath Yadhav
quelle
1

Ich bekomme auch den gleichen Fehler. Wenn Sie im Listenlayout eine Schaltfläche haben, durch die Sie diese ersetzen können, z. TextViewB. ImageButtondurch ImageView. Als Referenz ist mein Code:

private Activity activity;
private LayoutInflater inflater;

private List<ItemList> itemListsItems;

private Bookmark_SharedPref pref;

ImageLoader imageLoader = AppController.getInstance().getImageLoader();

public CustomListAdapter_Item(Activity activity,List<ItemList> itemListsItems){
    this.activity=activity;
    this.itemListsItems=itemListsItems;
    pref = new Bookmark_SharedPref(activity);
}


@Override
public int getCount() {
    return itemListsItems.size();
}

@Override
public Object getItem(int position) {
    return itemListsItems.get(position);
}

@Override
public long getItemId(int position) {
    return position;
}

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

    View v = convertView;
    ViewHolder holder;

    if(inflater == null){
        inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }
    if(convertView == null){
        convertView = inflater.inflate(R.layout.item_layout,null);

        holder = new ViewHolder();
        convertView.setTag(holder);
    }
    else{
        holder = (ViewHolder)convertView.getTag();
    }


    if(imageLoader == null){
        imageLoader = AppController.getInstance().getImageLoader();
    }




     holder.img = (NetworkImageView)convertView.findViewById(R.id.item_image);
    holder.Title = (TextView)convertView.findViewById(R.id.item_title);
    holder.Cat = (TextView)convertView.findViewById(R.id.item_category);

    holder.id = (TextView)convertView.findViewById(R.id.itemid);

    holder.Desc = (TextView)convertView.findViewById(R.id.item_description);

    holder.book = (ImageView)convertView.findViewById(R.id.bookmark_star);



    // getting blog data or the row
    ItemList il = itemListsItems.get(position);

    //setting image
    holder.img.setImageUrl(il.getImageUrl(), imageLoader);

    // setting title
    holder.Title.setText(il.getTitle());

    //setting category
    holder.Cat.setText(il.getCategory());


    //setting blog id
    holder.id.setText(il.getId());

    //setting description
    holder.Desc.setText(il.getDescription());

    //bookmarking the post
    holder.book.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            itemListsItems.get(position).isFav = !itemListsItems.get(position).isFav;
            ((ImageView)v.findViewById(R.id.bookmark_star)).setImageResource(itemListsItems.get(position).isFav ? R.mipmap.active_star : R.mipmap.inactive_star);

            if(itemListsItems.get(position).isFav){
                String data = Integer.toString(itemListsItems.get(position).id);
                Toast.makeText(v.getContext(),"fav hai "+data,Toast.LENGTH_SHORT).show();
                pref.addPref(data);
            } else {
                String data = Integer.toString(itemListsItems.get(position).id);
                Toast.makeText(v.getContext(),"not fav"+ data,Toast.LENGTH_SHORT).show();
                pref.removePref(data);
            }
            //notifyDataSetChanged();
        }
    });

    ((ImageView)convertView.findViewById(R.id.bookmark_star)).setImageResource(itemListsItems.get(position).isFav ? R.mipmap.active_star : R.mipmap.inactive_star);

    /*
    if(itemListsItems.get(position).isFav){
        String data = Integer.toString(itemListsItems.get(position).id);
        Toast.makeText(convertView.getContext(),"fav hai "+data,Toast.LENGTH_SHORT).show();
        pref.addPref(data);
    } else {
        String data = Integer.toString(itemListsItems.get(position).id);
        //Toast.makeText(convertView.getContext(),"not fav"+ data,Toast.LENGTH_SHORT).show();
        pref.removePref(data);
    }
    */
    return convertView;
}

private static class ViewHolder {
   public TextView Title, Desc,Cat,id;
    ImageView book;
    NetworkImageView img;
}

Denken Sie auch daran, das Listenlayout so zu gestalten, android:focussable="true"wie es für diese Schaltfläche / Textparameter verwendet wird android:focussable="false".

Mukul Aggarwal
quelle
korrigiert sollte es android sein: focusable = "false" nicht fokussierbar
Kenny Dabiri
1

In android:focusable="false"Attribut - Taste und zu übergeordnetem Ansicht Add - android:descendantFocusability="blocksDescendants"Attribute wie diese.

<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:descendantFocusability="blocksDescendants">

    <ImageButton
        android:id="@+id/sell_button"
        android:layout_width="wrap_content"
        android:focusable="false"
        android:layout_height="wrap_content"
        android:src="@drawable/ic_sell" />
</RelativeLayout>
Süheyl Kawsara
quelle
0

Es ist erstaunlich zu bemerken, dass die Änderung von XML dazu führt, dass der in Java angeklickte Satz für mich funktioniert.

android:descendantFocusability="blocksDescendants"
android:focusable="false"
android:focusableInTouchMode="false"
Waseem Minhas
quelle
0

Machen Sie das übergeordnete anklickbare Attribut wie folgt auf false android:clickable="false".

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:clickable="false"
    android:orientation="vertical">

Wieder vor dem Problem, dann fügen Sie für alle untergeordneten Ansichten dieses anklickbare Falsch hinzu.

REMITH
quelle
0

Ich weiß nicht genau warum, aber manchmal, wenn Sie den Adapter einstellen, werden die Listener gelöscht. Dann müssen Sie setOnClickListenernach setAdapteroder anrufen setListAdapter.

Tiago Gouvêa
quelle
0

android:clickable="true"Aus der internen Kundenansicht aus dem entfernen ListView.

Hamid Jolany
quelle