ListView setOnItemClickListener tidak berfungsi dengan menambahkan tombol


92

Saya memiliki tampilan daftar dengan teks dan tombol di setiap baris, tampilan daftar setOnItemClickListener () tidak berfungsi. apakah mungkin menangani peristiwa klik item dan klik tombol secara berbeda (klik item harus memanggil ActivityA dan klik tombol harus memanggil ActivityB). Apakah ada yang punya solusi

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

Jawaban:


261

Coba atur tombol Anda (atau tampilan lain yang ingin Anda tangani klik di dalam item daftar) seperti ini:

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

@ Ben Lee: Saya menambahkan ini ke kotak centang saya! Masih tidak bekerja. Apa yang bisa saya lakukan salah?
TDaver

1
android:focusableInTouchMode="false"memecahkan milikku. Saya menggunakan dua TextView di baris LinearLayout kustom. Yuk android ...
Youngjae

12
ImageButton tidak akan berfungsi. Dalam tampilan item daftar berisi ImageButton, setel android: descendantFocusability = "blocksDescendants".
ChangUZ

8
menambahkan android: clickable = "false" juga bisa diperlukan (aktifkan dan nonaktifkan, di desainer tata letak untuk menambahkannya secara eksplisit ke XML)
jrg

11
Peringatan: Jika Anda menggunakan ImageButton, Anda perlu menggunakan setFocusable (false) karena konstruktor ImageButton akan mengaktifkan atribut ini setelah memekarkan dari file xml. Tapi jawaban yang bagus
Mateu

120

Terkadang List tersebut masih belum bisa membuat Click Listener lewat. Dan pada kasus ini Anda mungkin harus menambahkan satu atribut lagi.

android:descendantFocusability="blocksDescendants" 

Dan atribut ini harus ditambahkan ke tata letak paling atas dari XML Anda di mana Anda telah menyediakan elemen ListView.


Agar tidak ada orang lain yang melakukan apa yang baru saja saya lakukan: Ini tidak akan diinginkan jika Anda memiliki sesuatu yang memerlukan fokus di baris Anda seperti EditText. Saya merasa bodoh sekarang.
Kitalda

Dalam kasus saya, nasihat ini telah membantu. Saya memiliki TextView dan RadioButton, yang pertama tidak mengklik, yang kedua tidak memilih TextView. Saya menulis "android: clickable =" false "" di RadioButton.
CoolMind

Ini adalah solusi jika tombolnya adalah ImageButton
Mahonster

Anehnya, solusi ini berhasil untuk saya. OnItemClickListener bekerja tanpa memengaruhi peristiwa turunan. Tidak yakin mengapa itu berhasil, jadi ... pergilah.
SATU

15

Jika Anda memiliki tampilan aktif / tampilan yang dapat difokuskan dalam tampilan daftar, maka tampilan tersebut akan dinonaktifkan onItemClickListener... Anda dapat mencoba membuatnya tidak dapat difokuskan dengan menambahkan: android:focusable="false"ke tampilan apa pun yang biasanya dapat difokuskan.


8

Hal adonan adalah menambahkan baik Listenerke seluruh rowViewdan ke Buttondalam Adapter. Sesuatu seperti ini.

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
Bagaimana ini bisa jauh lebih baik? Anda membuat onClickListener untuk SETIAP elemen data vs hanya 1 pemroses. Anda contoh bahkan tidak mendaur ulang tampilan mana.
JRomero

@ J.Romero ini hanya sebuah contoh, meskipun ada banyak ruang untuk pengoptimalan kode. Namun saya baru saja memperbarui kodenya.
Adil Soomro

5

Coba ditetapkan setClickable(false)untuk masing-masing Button, ImageButton, dll dan Viewseperti ini:

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

Anda juga harus menambahkan

android:descendantFocusability="blocksDescendants"

ke tata letak utama (tingkat pertama)


2
Saya telah menemukan set blockDescendants sudah cukup, tidak perlu membatalkan fokus, dll. Android 4.1
djdance

2

Alih-alih menambahkan tombol tambahkan ImageViewdan sediakan setOnItemClcikpendengar yang akan berfungsi dengan baik.

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

Saya juga mendapatkan kesalahan yang sama. Jika dalam tata letak daftar Anda memiliki tombol untuk menggantinya dengan TextViewie ImageButtondengan ImageView. Untuk Referensi, mereka adalah kode saya:

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

Juga perlu diingat untuk membuat tata letak daftar sebagai android:focussable="true"dan untuk tombol / parameter teks itu digunakan android:focussable="false".


dikoreksi seharusnya android: focusable = "false" not focussable
Kenny Dabiri

1

Tambahkan android:focusable="false"atribut ke tombol dan ke tampilan induk tambahkan android:descendantFocusability="blocksDescendants"atribut seperti ini.

<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

Sungguh menakjubkan mengetahui bahwa bagaimana XML berubah menyebabkan setonitemklik di java Berfungsi untuk saya ..

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

0

Buat atribut induk yang dapat diklik menjadi false seperti ini 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">

Sekali lagi menghadapi masalah, maka untuk semua tampilan anak tambahkan false yang dapat diklik ini.


0

Saya tidak tahu persis mengapa, tetapi terkadang saat Anda menyetel adaptor, pendengar dihapus. Kemudian, Anda harus menelepon setOnClickListenersetelah setAdapteratau setListAdapter.


0

Hapus android:clickable="true"dari tampilan custome internal dari ListView.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.