ListView setOnItemClickListener düğme ekleyerek çalışmıyor


92

Her satırda metin ve düğme bulunan bir liste görünümüm var, liste görünümü setOnItemClickListener () çalışmıyor. öğe tıklama ve düğme tıklama olaylarını farklı şekilde işlemek mümkün mü (öğe tıklaması ActivityA'yı çağırmalı ve düğme tıklaması ActivityB'yi çağırmalıdır). Çözümü olan var mı

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

Yanıtlar:


261

Düğmelerinizi (veya bir liste öğesinin içindeki tıklamayı işlemek istediğiniz diğer görünümleri) aşağıdaki gibi ayarlamayı deneyin:

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

@Ben Lee: Bunları onay kutularıma ekledim! Hala çalışmıyor. Neyi yanlış yapıyor olabilirim?
TDaver

1
android:focusableInTouchMode="false"benimkini çözer. Özel bir LinearLayout satırında iki TextView kullanıyorum. Yuk android ...
Youngjae

12
ImageButton çalışmayacak. Liste öğesi görünümünde ImageButton bulunur, android: descendantFocusability = "BlocksDescendants" olarak ayarlayın.
ChangUZ

8
android: clickable = "false" eklenmesi de gerekli olabilir (XML'e açıkça eklenmesini sağlamak için düzen tasarımcısında açıp kapatın)
jrg

11
Uyarı: Bir ImageButton kullanıyorsanız setFocusable (false) kullanmanız gerekir, çünkü ImageButton yapıcısı xml dosyasından şişirildikten sonra bu niteliği etkinleştirecektir. Ama yine de güzel cevap
Mateu

120

Bazen Liste, Tıklama İşleyicinin geçmesini sağlayamayabilir. Ve bu durumda, bir özellik daha eklemeniz gerekebilir.

android:descendantFocusability="blocksDescendants" 

Ve bu özniteliğin, ListView öğelerini sağladığınız XML'inizin en üst düzenine eklenmesi gerekir.


Öyleyse hiç kimse benim yaptığımı yapmıyor: Satırınızda EditText gibi odaklanma gerektiren bir şey varsa bu istenmeyen bir durum olacaktır. Şimdi kendimi aptal hissediyorum.
Kitalda

Benim durumumda bu tavsiye yardımcı oldu. Bir TextView ve RadioButton'ım var, 1'inci tıklamamış, 2'nci TextView'ı seçmemiş. RadioButton'a "android: clickable =" false "" yazdım.
CoolMind

Düğme bir ImageButton olduğunda çözüm budur
Mahonster

Merakla, bu çözüm benim için çalıştı. OnItemClickListener, soyundan gelen olayları etkilemeden çalışır. Neden işe yaradığından emin değilim, bu yüzden ...
BİR

15

Liste görünümünüzde aktif bir görünüm / odaklanabilir bir görünüm varsa, devre dışı onItemClickListenerbırakılır ... android:focusable="false"genellikle odaklanabilir olan herhangi bir görünüme : ekleyerek odaklanamaz hale getirmeyi deneyebilirsiniz .


8

Meyilli şey, hem Listenerbütününe hem rowViewdeButton içten Adapter. Bunun gibi bir şey.

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

3
Bu nasıl uzaktan daha iyi? Yalnızca 1 dinleyiciye karşılık HER veri öğesi için bir onClickListener oluşturuyorsunuz. Örneğiniz, hangi görünümleri geri dönüştürmüyor bile.
JRomero

@ J.Romero bu sadece bir örnekti, ancak kod optimizasyonu için çok fazla yer var. Ancak kodu yeni güncelledim.
Adil Soomro

5

Set deneyin setClickable(false)her biri için Button, ImageButtonvb ve Viewbunun gibi:

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

Ayrıca eklemelisin

android:descendantFocusability="blocksDescendants"

ana (birinci seviye) yerleşim düzenine


2
Set blokları buldumDescendants yeterli, odaklanabilir vb. İptal etmeye gerek yok. Android 4.1
djdance

2

Düğme eklemek yerine, iyi çalışacak bir dinleyici ekleyin ImageViewve sağlayın setOnItemClcik.

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

1

Ben de aynı hatayı alıyorum. Liste düzeninde TextViewie ImageButtonile değiştirmek için herhangi bir butonunuz varsa ImageView. Referans için benim kodum:

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

Ayrıca android:focussable="true", bu düğme / metin parametresi kullanımıyla birlikte liste düzeni yapmayı da unutmayın android:focussable="false".


düzeltilmiş olması gerektiği android: odaklanabilir = "false" focussable değil
Kenny Dabiri

1

Ekle android:focusable="false"düğmesine ve ana görünümü eklenti için niteliğini android:descendantFocusability="blocksDescendants"böyle özniteliği.

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

0

XML'in nasıl değiştiğinin, java'da setonitemclicked bende çalışmasına neden olduğunu fark etmek şaşırtıcı ..

android:descendantFocusability="blocksDescendants"
android:focusable="false"
android:focusableInTouchMode="false"

0

Üst tıklanabilir özelliği bu şekilde yanlış yapın 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">

Yine karşılaşılan sorun, daha sonra tüm alt görünümler için bu tıklanabilir yanlışı ekleyin.


0

Tam olarak nedenini bilmiyorum ama bazen adaptörü ayarladığınızda dinleyiciler temizleniyor. Daha setOnClickListenersonra setAdapterveya sonrasında aramanız gerekir setListAdapter.


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.