ListView setOnItemClickListener không hoạt động bằng cách thêm nút


89

Tôi có chế độ xem danh sách với văn bản và nút trong mỗi hàng, chế độ xem danh sách setOnItemClickListener () không hoạt động. có thể xử lý các sự kiện nhấp vào mục và nhấp vào nút khác nhau không (nhấp vào mục nên gọi ActivityA và nhấp vào nút nên gọi ActivityB). Có ai có giải pháp không

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

Câu trả lời:


260

Hãy thử đặt các nút của bạn (hoặc bất kỳ chế độ xem nào khác mà bạn muốn xử lý khi nhấp vào bên trong một mục danh sách) như sau:

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

@Ben Lee: Tôi đã thêm những thứ này vào hộp kiểm của mình! Vẫn không làm việc. Tôi có thể làm gì sai?
TDaver

1
android:focusableInTouchMode="false"giải quyết của tôi. Tôi sử dụng hai TextView trong một hàng LinearLayout tùy chỉnh. Yuk android ...
Youngjae

12
ImageButton sẽ không hoạt động. Trong chế độ xem mục danh sách có chứa ImageButton, đặt android :cendantFocusability = "blocksDescendants".
ChangUZ

8
Thêm android: clickable = "false" cũng có thể được yêu cầu (bật và tắt nó trong trình thiết kế bố cục để thêm nó một cách rõ ràng vào XML)
jrg

11
Cảnh báo: Trong trường hợp bạn đang sử dụng ImageButton, bạn cần sử dụng setFocusable (false) vì hàm tạo của ImageButton sẽ kích hoạt thuộc tính này sau khi thổi phồng từ tệp xml. Nhưng câu trả lời tốt mặc dù
Mateu

118

Đôi khi Danh sách vẫn không thể làm cho Trình nghe nhấp chuột vượt qua. Và trong trường hợp này, bạn có thể phải thêm một thuộc tính nữa.

android:descendantFocusability="blocksDescendants" 

Và thuộc tính này phải được thêm vào bố cục trên cùng của XML, nơi bạn đã cung cấp các phần tử ListView.


Chỉ để không ai khác làm những gì tôi vừa làm: Điều này sẽ không mong muốn nếu bạn có thứ gì đó yêu cầu tiêu điểm trong hàng của bạn như EditText. Giờ tôi thấy mình thật ngu ngốc.
Kitalda

Trong trường hợp của tôi, lời khuyên này đã giúp ích. Tôi có TextView và RadioButton, lần đầu tiên không nhấp vào, lần thứ hai đã không chọn TextView. Tôi đã viết "android: clickable =" false "" trong RadioButton.
CoolMind

Đây là giải pháp khi nút là một ImageButton
Mahonster

15

Nếu bạn có chế độ xem đang hoạt động / chế độ xem có thể lấy tiêu điểm trong chế độ xem danh sách của mình thì chế độ này sẽ vô hiệu hóa onItemClickListener... bạn có thể cố gắng làm cho nó không thể tiêu điểm bằng cách thêm: android:focusable="false"vào bất kỳ chế độ xem nào thường có thể lấy tiêu điểm.


8

Batter điều là thêm cả hai Listenervào toàn bộ rowViewButtonbên trong Adapter. Một cái gì đó như thế này.

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
Làm thế nào điều này thậm chí còn tốt hơn từ xa? Bạn đang tạo onClickListener cho MỌI phần tử dữ liệu so với chỉ 1 người nghe. Ví dụ của bạn thậm chí không tái chế các chế độ xem nào.
JRomero

@ J.Romero đây chỉ là một ví dụ, mặc dù có rất nhiều chỗ để tối ưu hóa mã. Tuy nhiên, tôi vừa cập nhật mã.
Adil Soomro

5

Cố gắng thiết lập setClickable(false)cho mỗi Button, ImageButton, vv và Viewnhư thế này:

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

Ngoài ra bạn phải thêm

android:descendantFocusability="blocksDescendants"

đến bố cục chính (cấp độ đầu tiên)


2
Tôi đã tìm thấy bộ blocksDescendants là đủ, không cần phải hủy đặt tiêu điểm, vv Android 4.1
djdance

2

Thay vì thêm nút, hãy thêm ImageViewvà cung cấp trình setOnItemClciknghe sẽ hoạt động tốt.

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

Tôi cũng nhận được lỗi tương tự. Nếu trong bố cục danh sách, bạn có bất kỳ nút nào để thay thế nó bằng TextViewnghĩa là ImageButtonvới ImageView. Để tham khảo, họ là mã của tôi:

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

Cũng cần lưu ý để tạo bố cục danh sách android:focussable="true"và cho việc sử dụng nút / thông số văn bản đó android:focussable="false".


khắc phục nó phải được android: đặt tiêu điểm = "false" không focussable
Kenny Dabiri

1

Thêm android:focusable="false"thuộc tính vào nút và vào chế độ xem phụ huynh, hãy thêm android:descendantFocusability="blocksDescendants"thuộc tính như thế này.

<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

Thật ngạc nhiên khi nhận thấy rằng cách XML thay đổi khiến setonitemclicked trong java Hoạt động đối với tôi ..

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

0

Đặt thuộc tính có thể nhấp chính là false như thế này 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">

Một lần nữa phải đối mặt với vấn đề, sau đó đối với tất cả các chế độ xem con, hãy thêm false có thể nhấp này.


0

Tôi không biết chính xác tại sao, nhưng đôi khi khi bạn đặt bộ điều hợp, người nghe bị xóa. Sau đó, bạn phải gọi setOnClickListenersau setAdapterhoặc setListAdapter.


0

Xóa android:clickable="true"khỏi chế độ xem nội bộ khỏiListView .

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.