2012-07-11 20 views
52

Mam problem z widokiem list. jego elementy (wiersze) mają przycisk obrazu. imagebutton ma "android: onClick", więc to zdarzenie onclick działa, ale kliknij wiersz nie działa. jeśli usunę przycisk obrazu z elementu wiersza, kliknij wiersz wierszy (lista list zawiera poprawny lister onclick). Jak mogę to naprawić? Muszę onclick zdarzenie, gdy użytkownik kliknie na ImageButton i standardowe click przypadku, gdy użytkownik wybierz wiersz (nie kliknij ImageButton ale kliknij wiersz)nie można kliknąć wiersza listy z obrazem przycisku

mój ListView:

<ListView xmlns:android="http://schemas.android.com/apk/res/android" 
     android:id="@+id/restaurants_list" 
     android:layout_width="fill_parent" 
     android:layout_height="fill_parent" 
     android:divider="@color/list_devider" 
     android:dividerHeight="1dp" 
     android:cacheColorHint="@color/list_background" /> 

Odpowiedz

170

Niestety

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

nie działa ImageButton.

W końcu znalazłem rozwiązanie here. W swoim szablonie xml dla tych elementów dodaj do widoku głównego widok

Działa doskonale dla urządzenia ListView, które ma ImageButton. Według official reference, blocksDescendants oznacza, że ​​ViewGroup będzie blokował potomkom odbiór ostrości.

+9

Dla 'ToggleButton' wystarczy' android: focusable = "false" 'ale tylko dla ImageButton' android: descendantFocusability = "blocksDescendants" 'zadziała. –

+0

Dodałem ten kod do widoku głównego elementu listy i działa! Mogę bez problemu kliknąć widok listy i ImageButton. Dzięki –

6

Jeśli rząd ListView mieć dowolny klikalny element taki jak Button, Image ..etc..then onItemClick nie będzie działać. Musisz więc zapisać detektor kliknięcia w getView adaptera listy.

Więcej informacji na this.

8

Możesz użyć niestandardowego adaptera do swojego listView (jeśli jeszcze tego nie zrobiłeś). A tam, w metodzie adaptera getView(int position, View inView, ViewGroup parent) zrobić coś takiego:

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

    View v = inView; 
    ViewHolder viewHolder; //Use a viewholder for sufficent use of the listview 

    if (v == null) { 
     LayoutInflater inflater = (LayoutInflater) adaptersContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     v = inflater.inflate(R.layout.list_item, null); 
     viewHolder = new ViewHolder(); 
     viewHolder.image = (ImageView) v.findViewById(R.id.ImageView); 
     v.setTag(viewHolder); 
    } else { 
     viewHolder = (ViewHolder) v.getTag(); 
    } 

     ..... 

    viewHolder.image.setOnClickListener(new OnClickListener() { 

     @Override 
     public void onClick(View v) { 

      //Click on imageView 
     }i 
    }); 

    v.setOnClickListener(new OnClickListener() { 

     @Override 
     public void onClick(View v) { 

      //Click on listView row 
     } 
    }); 

     ..... 

    return (v); 
} 

Zobacz here jeśli potrzebujesz pomocy przy tworzeniu niestandardowego adaptera.

+0

Należy pamiętać, że to rozwiązanie zapobiega wybraniu samego rzędu. W niektórych przypadkach możesz chcieć wyświetlić listę, w której możesz wybrać wiersz I kliknąć przycisk w wierszu. – AndroidDev

+0

Czy jest pożądane utworzenie nowego słuchacza dla każdego żądanego widoku? – Maarten

+0

@Maarten Jeśli pożądane jest, że masz na myśli wydajność, to jest wydajne, ponieważ używając techniki 'ViewHolder',' ListView' będzie przechowywać w pamięci tylko potrzebne wiersze, a nie wszystkie wiersze. – Angelo

2

ustawić te właściwości dla Twojego przycisku:

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

Albo można ustawić go dynamicznie w klasie adaptera:

 yourButton.setFocusable(false); 
    yourButton.setFocusableInTouchMode(false); 

I upewnić się, że ustawienie trybu wyboru jako singiel dla ListView :

 listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE); 
+0

To nie działa. Czy to zweryfikowałeś? – z5h

+0

To zadziałało dla mnie, dlaczego mówisz, że to nie działa? Mam rząd z polem wyboru, innym materiałem i przyciskiem. Wiersz można wybrać, a także przycisk i pole wyboru. – David

+0

Jednak jest naprawdę dziwne, że android: focusable = "false" nie działa dla ImageButton. – Eliko

1

Jeśli wiersz ma wiele klikalnych elementów, funkcja onItemClick() nie będzie działać. Konieczne będzie ustawienie metody OnClickListener w metodzie getView(). Przechowuj detektory znacznika View, aby można je było poddać recyklingowi, dodaj metody do swoich odbiorców, aby mogli specjalizować się w różnych wierszach.

 @Override 
     public View getView(int position, View convertView, ViewGroup parent) { 
     View view = super.getView(position, convertView, parent); 

     RowClickListeners listeners = (RowClickListeners) view.getTag(); 
     if (listeners == null) { 
      listeners = new RowClickListeners(); 
     } 

     // Row click listener: 
     RowClickListener onClickListener = listeners.rowClickListener; 
     if (onClickListener == null) { 
      onClickListener = new RowClickListener(); 
      listeners.rowClickListener = onClickListener; 
     } 
        onClickListener.setToPosition(pos); 
     view.setOnClickListener(onClickListener); 

     // Overflow listener: 
     View btn = view.findViewById(R.id.ic_row_btn); 
     ButtonListener btnListener = listeners.buttonClickListener; 
     if (rowListener == null) { 
      btnListener = new ButtonListener(activity); 
      listeners.rowClickListener = btnListener; 
     } 
        btnListener.setToPosition(pos); 
     btnListener.setCollection(collectionId); 
     btn.setOnClickListener(btnListener); 
    } 


    public static class RowClickListeners { 
     public RowClickListener rowClickListener; 
     public ButtonListener buttonClickListener; 
    } 
1

W moim przypadku android:descendantFocusability="blocksDescendants" dla głównej warstwy nie działa, ani w ListView. Próbowałem też android:focusable="false" android:focusableInTouchMode="false", które słyszałem, że działa dla przycisków, ale miałem ImageButton, więc nie.

Ustawiono właściwości przycisku w pliku CS układu.

var imageButton = view.FindViewById<ImageButton>(Resource.Id.imageButton1); 
imageButton.Focusable = false; 
imageButton.FocusableInTouchMode = false; 
imageButton.Clickable = true; 
+0

Używam własnego ImageButton. inne odpowiedzi nie działały dla mnie, ale to działa. (Użyłem ich w moim adapterze niestandardowym) – Sdghasemi

0

Żadna pojedyncza odpowiedź powyżej nie zadziałała, ale połączenie miało miejsce.

I teraz ustawić android:descendantFocusability="blocksDescendants" na ListView i android:focusable="false" android:focusableInTouchMode="false" na ImageButtons w XML I w Javie również ustawić descendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS) na ListView i focusable(false), focusableInTouchMode(false), clickable(true) na ImageButtons.

Powiązane problemy