原則:先獲取焦點,再執行觸摸onTouch事件,再執行單擊事件. 當你按下按鈕不放,移動到按鈕外再松手,這樣是不會執行按鈕的單擊事件的,因為按下和松開的坐標不同
當點擊ListView的時候,如果此時的item中有能自動獲取焦點的控件(比如按鈕,單選框...等等),那么這些控件就會把點擊item的焦點搶到,也就無法實現item的單擊事件了.但是搶到焦點你又沒點擊到按鈕上,那按鈕的單擊事件也不會響應,這也就有點占着茅坑不拉屎的感覺了
比如在listView上放一個Button:
我們可以觸發Button的點擊事件,但是item的點擊事件並不會被觸發,也就是說,Button控件搶奪了item的焦點事件,
使得item不能觸發相應的點擊事件,那么,如果我們既想觸發Button的點擊事件,又想觸發item的點擊事件,我們應該怎么做呢?
這里有二種解決方案
* 方法1:將button的屬性設為: android:focusable="false" 當然你也可以在代碼中設置
* 方法2:設置item的布局的根屬性:android:descendantFocusability="blocksDescendant"
我們可以發現,其實這兩種方法都是為了讓Button等控件不能獲取焦點,從而使得item可以響應點擊事件。
第二種方法使用起來相對方便,因為它是將item布局中的其他所有控件都設置為不能自動獲取焦點。
* 由於button是可以自動獲取焦點的,所以在點擊item的時候,button會把item的單擊事件給搶走,
* 但是如果是在item上加一個textView的單擊事件,就不會跟item的單擊事件有沖突,因為textView不能自動獲取焦點
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:descendantFocusability="blocksDescendants" //方法二的使用,在item布局中加上這個屬性 android:layout_height="match_parent"> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/btItem" android:text="點我"/> </LinearLayout>
android:descendantFocusability屬性共有三個取值,分別為
beforeDescendants:viewgroup會優先其子類控件而獲取到焦點
afterDescendants:viewgroup 只有當其子類控件不需要獲取焦點時才獲取焦點
blocksDescendants:viewgroup 會覆蓋子類控件而直接獲得焦點(也就是當點擊item的時候,不讓子控件搶到焦點,除非是點到了子控件上才讓子控件獲取)
2.當RecyclerView的item中有edittext時,RecyclerView會自動滾,被編輯框獲取了焦點,解決辦法:在RecyclerView布局中加上:
android:descendantFocusability="beforeDescendants"