[Android]關於Android子view超出父view無法響應點選事件
摘要
- 關於Android子view超出父view點選事件失效問題
- 例如button超出父佈局之外的點選事件無效
標題首先看一下結構圖
我根佈局用的LinearLayout;
然後巢狀了一個一定高度的LinearLayout;為上圖頂部寬度撐滿父元素的矩形框;稱之為“線布2”;
線布2 裡又水平佈局了兩個線性佈局;
左邊的線性佈局不管; 右邊的線性佈局裡巢狀了4個button按鈕;
現在的問題是:
- 超出 線布2 的3個button按鈕無法顯示;
- 超出 線布2 的3個button按鈕無法響應點選事件;
對於問題一:
我們想要顯示溢位的3個button按鈕,在 線布2 裡的右佈局中;
所以我們讓這個右佈局能溢位顯示就好了;
相關程式碼
android:clipChildren="false"
android:clipToPadding="false"
官方對於第一行的解釋:
Defines whether a child is limited to draw inside of its bounds or not.
翻譯:定義一個子檢視是否侷限於它的範圍內。
所以我們設定為false,讓子檢視不侷限與自己;官方對於第二行的解釋:
Defines whether the ViewGroup will clip its drawing surface so as to exclude the padding area.
翻譯:定義ViewGroup是否將剪輯其繪圖表面以排除填充區域。
由於筆者是Android新手,對此表示不太理解,也沒有去研究它
(剛入手Android開發一週,只為做一個作品參加學校比賽,不過這作品也是我用心良苦的設計,歡迎大家點選下方連結體驗^ _ ^);
- 對此我們解決了第一個問題,不過筆者實驗了一番,發現把上述兩行程式碼加在 線布2 的xml裡,並沒有顯示 線布2 裡溢位的右佈局,也就是說那幾個button按鈕還是看不見;
- 我搜尋問題時,說是上述兩行程式碼是作用於 孫子檢視 與 兒子檢視;在此不解釋孫子與兒子檢視;
- 而我的 線布2 的父佈局正是根佈局,也就是說我需要在根佈局中使用這兩個引數,才可以使 線布2 裡的右佈局溢位於 線布2 顯示;
實驗成功;
筆者專案中,該問題用了一下午才解決,其實主要是首次開發,佈局檔案過於混亂,所以致使上述引數不生效,(但是我在所有佈局標籤加上也不生效,這點很納悶)無奈之下,我把主要的佈局檔案分離開來,再使用include引入;
模組化確實方便,嘻嘻;
對於問題二:
- 讓溢位的button按鈕可點選
- 這個問題花費了我半天時間,一直搜找解決方案,遺憾的是,相關問題少,解決方案無用;
- 所以我嘗試自己解決此問題,可謂是另闢蹊蹺;
先介紹我搜尋的解決方案,在此歸納成兩條:
1. 使用android:focusable="true"引數
android:focusable="true"
其解釋為:是否可聚焦,也是是否可點選
——
我把此引數在所有控制元件及佈局中放了個遍,也無法觸發溢位的按鈕
——
我也搜找到相關的引數,同樣無法點選。
——
我以為是下邊的佈局覆蓋掉了溢位的按鈕
——
然後我使用相對佈局作為根佈局,讓有button的佈局最後繪製,但結果是lose
——
我摸了摸禿頭,發現事態不對勁,遂重建test佈局,測試了一番;
——
發現沒有其他佈局的時候,也點選不了;
——
事情發展到這一步,我想我已經看破紅塵…哦不是看破Layout了、手動滑稽
——
杰倫–結論:
所有溢位父佈局的控制元件,無法響應事件,但通過引數可以顯示;
其實這個結論是我自己臆想的,但是我實在是找不到方法;
- 這個世界的真理和公理,都是觀物者們眼中的事物;//突然哲學
2. 拒絕使用佈局進行巢狀
- 這個方案就是取消 線布2 佈局,這樣就沒有佈局去限制 線布2 中的button了;
- 但是,熱愛模組化的我怎麼會讓button組脫離組織呢;(其實我差點就屈服於這個方案了)
這種方案就不做詳細解釋;讓我們直接進入下一環:另闢蹊蹺
另闢蹊蹺:
- 我想著如果能在整個Activity視窗捕捉點選事件,就好辦了;
public boolean onTouchEvent(MotionEvent event);
果然,程式設計師的直覺
——
只需要在Activity程式碼區重寫此方法就好了;
不過他只返回布林值,其值含義為是否觸控了螢幕;
聰明的我怎能讓他只幹這件事;
遂:
@Override
public boolean onTouchEvent(MotionEvent event) {
//首先定義一個陣列用來接收按鈕的座標xy值
int[] xy = new int[2];
//獲取按鈕的top/left xy值
//button變數我在onCreat()函式中已經獲取了控制元件,具體按實際情況寫
button.getLocationOnScreen(xy);
//再定義一個陣列用來計算控制元件的bottom/right xy值
int[] xy_end = new int[2];
xy_end[0] = buttom.getWidth() + xy[0];
xy_end[1] = buttom.getHeight() + xy[1];
//現在我們已經得到了按鈕的左上座標和右下座標
//兩個點可以確定一個矩形嘛
//event裡包含了點選的資訊;
//我們判斷點選的座標是否在按鈕座標內,實際就是判斷點選的xy值是否在上述矩形中;
if (event.getX() >= xy[0] && event.getX() <= xy_end[0]
&& event.getY() >= xy[1] && event.getY() <= xy_end[1]) {
//如果是,那麼就執行裡邊的程式碼,在這裡我們可以callOnClick()按鈕
//這裡的程式碼說明
//實際體驗了一番,發現輕點一下和長按均可以啟用按鈕;
//但是,我的按鈕擁有animate()事件,所以連續點選會在動畫未完成時再次點選按鈕,
//所以我做了個判斷,讓動畫未完成時不再執行點選,機制如我
//實際中,讀者完全不用這兩行程式碼
//讓我看看有哪些讀者看都不看直接複製程式碼--手動滑稽
//雖說站在巨人肩膀上,但是也要搞懂其原理才不會摔下來。
if (isMoreShow == false && xy[0] >= button.getHeight())
return false;
//我們callOnClick了按鈕,也就是模擬點選了按鈕;
button.callOnClick();
return false;
}
return super.onTouchEvent(event);
}
- 就這短短几行程式碼,搞了我半天的心態,嚴格說還有一個晚上;
不足:
- 不足之處還是有的
- 如果按鈕過多,就需要寫入更多的判斷,這非常的不優雅;可是總比無法點選要好;
- 如果按鈕有自定義點選背景(按下背景),將不顯示,身為強迫症的我怎麼能忍;
- 依舊沒有女朋友emmm;
展示:
結語
相關文章
- Android View 的事件體系AndroidView事件
- Android自定義View:View(二)AndroidView
- Android XML佈局報錯:android/view/View$OnUnhandledKeyEventListenerAndroidXMLView
- Android View 事件分發原始碼分析AndroidView事件原始碼
- 基於原始碼分析 Android View 事件分發機制原始碼AndroidView事件
- Android View 系統 1 - View樹AndroidView
- Android 自定義View 點贊效果AndroidView
- Android入門教程 | RecyclerView響應子項點選AndroidView
- Android View 的事件體系 -- 事件分發機制AndroidView事件
- Android自定義view-自繪ViewAndroidView
- Android View post 方法AndroidView
- Android 自定義View:處理事件分發(四)AndroidView事件
- Android自定義View之定點寫文字AndroidView
- Android自定義View整合AndroidView
- Android View體系(4)AndroidView
- Android View 的工作原理AndroidView
- Android新手引導ViewAndroidView
- Android 事件分發機制原始碼解析-view層Android事件原始碼View
- Android —— 自定義View中,你應該知道的知識點AndroidView
- Android自定義View之區塊選擇器AndroidView
- Android從原始碼角度剖析View事件分發機制Android原始碼View事件
- Android自定義View之事件分發機制總結AndroidView事件
- Android View系列---RadioGroup與RadioButtonAndroidView
- 重拾Android自定義ViewAndroidView
- Android自定義View:ViewGroup(三)AndroidView
- Android View的工作原理(上)AndroidView
- Android 自定義 View 之 LeavesLoadingAndroidView
- android view 擴充套件方法AndroidView套件
- Android View 原始碼解析(三) – View的繪製過程AndroidView原始碼
- Attempt to invoke virtual method ‘int android.view.View.getImportantForAccessibility()‘ on a null obAndroidViewImportNull
- View繪製01-Android渲染系統中的ViewViewAndroid
- Android事件分發:從原始碼角度分析View事件分發機制Android事件原始碼View
- Android面試複習之View事件體系(原始碼分析)Android面試View事件原始碼
- 基於原始碼分析 Android View 繪製機制原始碼AndroidView
- Android自定義View之分貝儀AndroidView
- Android View的繪製過程AndroidView
- Android自定義View之捲尺AndroidView
- Android自定義View注意事項AndroidView