ListView setOnItemClickListener nie działa przez dodanie przycisku

92

Mam widok listy z tekstem i przyciskiem w każdym wierszu, widok listy setOnItemClickListener () nie działa. czy można inaczej obsługiwać zdarzenia kliknięcia elementu i kliknięcia przycisku (kliknięcie elementu powinno wywołać ActivityA, a kliknięcie przycisku powinno wywołać ActivityB). Czy ktoś ma rozwiązanie

    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
źródło

Odpowiedzi:

261

Spróbuj ustawić przyciski (lub inne widoki, które chcesz obsługiwać, kliknij wewnątrz elementu listy) w następujący sposób:

android:focusable="false"
android:focusableInTouchMode="false"
Ben Lee
źródło
@Ben Lee: Dodałem je do moich pól wyboru! Wciąż nie działa. Co mogę zrobić źle?
TDaver,
1
android:focusableInTouchMode="false"rozwiązuje moje. Używam dwóch TextView w niestandardowym wierszu LinearLayout. Yuk android ...
Youngjae,
12
ImageButton nie będzie działać. W widoku elementu listy zawiera ImageButton, ustaw android: descendantFocusability = "blocksDescendants".
ChangUZ,
8
dodanie androida: clickable = "false" może być również wymagane (
włączaj
11
Ostrzeżenie: w przypadku, gdy używasz ImageButton, musisz użyć setFocusable (false), ponieważ konstruktor ImageButton włączy ten atrybut po nadmuchaniu z pliku xml. Ale dobra odpowiedź
Mateu
120

Czasami lista nadal nie może zmusić nasłuchiwania kliknięć do przejścia. W tym przypadku może być konieczne dodanie jeszcze jednego atrybutu.

android:descendantFocusability="blocksDescendants" 

I ten atrybut musi zostać dodany do najwyższego układu Twojego XML, gdzie dostarczyłeś elementy ListView.

Andro Selva
źródło
Po prostu nikt inny nie robi tego, co właśnie zrobiłem: będzie to niepożądane, jeśli masz coś wymagającego skupienia się w wierszu, na przykład EditText. Teraz czuję się głupio.
Kitalda
W moim przypadku ta rada pomogła. Mam TextView i RadioButton, pierwszy nie kliknął, drugi nie wybrał TextView. Napisałem "android: clickable =" false "" w RadioButton.
CoolMind
To jest rozwiązanie, gdy przycisk to ImageButton
Mahonster,
Co ciekawe, to rozwiązanie zadziałało na mnie. OnItemClickListener działa bez wpływu na zdarzenia podrzędne. Nie wiem, dlaczego to zadziałało, więc ...
ONE
15

Jeśli masz aktywny widok / widok z możliwością zaznaczenia w widoku listy, to wyłączy się onItemClickListener... możesz spróbować uczynić go nieokreślonym, dodając: android:focusable="false"do dowolnego widoku, który zwykle jest aktywowany.

nilesh
źródło
8

ListenerCałość dodajemy zarówno do całości jak rowViewi do Buttonśrodka Adapter. Coś takiego.

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
źródło
3
Jak to jest nawet odrobinę lepsze? Tworzysz onClickListener dla KAŻDEGO elementu danych w porównaniu z tylko jednym odbiornikiem. Twój przykład nawet nie przetwarza które widoki.
JRomero
@ J.Romero to był tylko przykład, chociaż jest miejsce na optymalizację kodu. Jednak właśnie zaktualizowałem kod.
Adil Soomro,
5

Spróbuj ustawić setClickable(false)dla każdego Button, ImageButtonitp i Viewtak:

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

Musisz też dodać

android:descendantFocusability="blocksDescendants"

do układu głównego (pierwszego poziomu)

Vlad
źródło
2
Znalazłem ustawione blokiDescendants wystarczy, nie ma potrzeby anulowania ustawiania ostrości itp. Android 4.1
djdance
2

Zamiast dodawać przycisk dodaj ImageViewi podaj setOnItemClciklistener, który będzie działał dobrze.

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
źródło
1

Otrzymuję również ten sam błąd. Jeśli na liście układ masz dowolny przycisk, aby zastąpić go z TextViewIE ImageButtonz ImageView. Dla odniesienia ich jest mój kod:

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

Pamiętaj również, aby układ listy był taki sam, jak android:focussable="true"i dla tego przycisku / parametru tekstowego android:focussable="false".

Mukul Aggarwal
źródło
poprawiono , powinien być android: focusable = "false" nie można
focussable
1

Dodaj android:focusable="false"atrybut do przycisku, a do widoku nadrzędnego dodaj android:descendantFocusability="blocksDescendants"atrybut podobny do tego.

<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>
Suhail Kawsara
źródło
0

To niesamowite, że zauważyłem, że zmiana XML powoduje, że setonitemclicked w java działa dla mnie ..

android:descendantFocusability="blocksDescendants"
android:focusable="false"
android:focusableInTouchMode="false"
Waseem Minhas
źródło
0

Zmień wartość atrybutu nadrzędnego, który można kliknąć, na false w ten sposób 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">

Ponownie w obliczu problemu, do wszystkich widoków potomnych dodaj to klikalne fałsz.

REMITH
źródło
0

Nie wiem dokładnie dlaczego, ale czasami kiedy ustawiasz adapter, słuchacze są czyszczeni. Następnie musisz zadzwonić setOnClickListenerpo setAdapterlub setListAdapter.

Tiago Gouvêa
źródło
0

Usuń android:clickable="true"z wewnętrznego widoku klienta z ListView.

Hamid Jolany
źródło