2012-07-11 17 views
52

我有用listview的麻煩。它的項目(行)有圖像按鈕。 imagebutton有「android:onClick」,所以這onclick事件正在工作,但點擊行不起作用。如果我從行項目中刪除imagebutton,點擊行工作(列表視圖有正確的onclick列表)。我該如何解決它?我需要onclick事件當ImageButton的和非標準click事件,當用戶選擇行用戶點擊(不能點擊的ImageButton但單擊行)無法用imagebutton點擊列表視圖行

我的列表視圖:

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

回答

170

不幸的是,

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

不會爲ImageButton工作。

我終於找到了解決方案here。在您的佈局xml中爲這些項目添加

android:descendantFocusability="blocksDescendants" 

到根視圖。

它適用於ListView,它有ImageButton s。根據official referenceblocksDescendants意味着ViewGroup將阻止其後代接受焦點。

+9

對於'ToggleButton','android:focusable =「false」'就足夠了,但對於ImageButton而言,只有'android:descendantFocusability =「blocksDescendants」'可以工作。 – 2013-08-19 08:05:26

+0

我將此代碼添加到我的列表項的根視圖中,並且它工作正常!我可以沒有任何問題點擊列表視圖和ImageButton。謝謝 – 2016-10-11 17:21:28

6

如果ListView控件的一排有任何點擊元素如Button,Image ..等等,那麼onItemClick將不起作用。因此,您需要在列表適配器的getView中編寫點擊監聽器。

更多請閱讀this

8

你可以使用自定義適配器爲你的listView(如果你還沒有)。還有,在適配器的getView(int position, View inView, ViewGroup parent)方法做這樣的事情:

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

here如果你需要幫助創建你的自定義適配器。

+0

請注意,此解決方案可防止選擇行本身。在某些情況下,您可能需要一個列表視圖,您可以在其中選擇一行並單擊一行內的按鈕。 – AndroidDev 2013-01-02 15:45:17

+0

爲每個請求的視圖創建一個新的監聽器是否可取? – Maarten 2013-07-03 14:44:34

+0

@Maarten如果你希望你的意思是有效的,那麼它是有效的,因爲使用'ViewHolder'技術,'ListView'將只存儲在內存中所需的行,而不是所有的行。 – Angelo 2013-07-04 06:19:49

2

設置這些特性爲您的按鈕:

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

或者你可以在你的適配器類動態地設置:

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

,並確保您設置的選擇模式單一的列表視圖:

 listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE); 
+0

這不起作用。你證實了嗎? – z5h 2013-01-18 17:10:39

+0

它爲我工作,你爲什麼說它沒有工作?我有一個複選框,另一個東西和按鈕。該行可以被選中,按鈕和複選框也是如此。 – David 2013-03-01 11:32:23

+0

但是,android:focusable =「false」對ImageButton不起作用確實很奇怪。 – Eliko 2013-07-23 06:53:28

1

如果一行有多個可點擊的元素,onItemClick()將不起作用。您需要在getView()方法中設置OnClickListener。將偵聽器存儲在視圖的標記中,以便它們可以循環使用,向偵聽器中添加方法,以便它們可以專用於不同的行。

 @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

在我的情況下,主層的android:descendantFocusability="blocksDescendants"沒有工作,既不在ListView中。我也嘗試android:focusable="false" android:focusableInTouchMode="false",我聽說它是​​爲按鈕工作,但我有ImageButton,所以它沒有。

但是,在佈局的CS文件中設置了按鈕的屬性。

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

我使用我自己的ImageButton。非其他答案爲我工作,但這是有效的。 (我在我的自定義適配器中使用它們) – Sdghasemi 2015-05-06 14:56:17

0

上面沒有一個單一的答案爲我工作,但一個組合。

我現在在XML 在Java中我也上的ImageButtons的ListView和focusable(false), focusableInTouchMode(false), clickable(true)設置descendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS)設置android:descendantFocusability="blocksDescendants"的ListView和android:focusable="false" android:focusableInTouchMode="false"在ImageButtons。