編輯:關於android開發
春節後,又重新“開張”。各位高手請繼續支持。謝謝!
原文標題:Kotlin recipes for Android (I): OnGlobalLayoutListener
原文鏈接:http://antonioleiva.com/kotlin-ongloballayoutlistener/
原文作者:Antonio Leiva(http://antonioleiva.com/about/)
原文發布:2016-03-16
Android的Kotlin秘方(I):OnGlobalLayoutListener
今天一位同伴問我怎樣恰當使用OnGlobalLayoutListener,而不需要太多的模板。這是一個棘手的問題,我們需要進一步深入研究。
這個偵聽器對於任何試圖的ViewTreeObserver都適用,並且在已知視圖寬度和高度進行各種計算、動畫等等時,為擴展和測量視圖常常回調它。
幸虧Kotlin提供很好的與Java互操作性,我們能夠以一種非常清晰的方法 —— 使用它的模擬屬性和Lambda表達式 —— 實現單一方法接口:
1 recycler.viewTreeObserver.addOnGlobalLayoutListener { 2 // do whatever 3 }
這裡有什麼問題嗎?為了預防洩漏,推薦的實踐是在完成使用它後,立即刪除這個偵聽器。但是由於使用了Lambda表達式,Lambda沒有對象那麼精確,我們沒有對象的引用。
原方式還是可以用,但是在Kotlin中直接用匿名對象,每次都會有一只小貓死去。如果仍然需要做下面這樣的事,沒法改用更好開發語言:
1 recycler.viewTreeObserver.addOnGlobalLayoutListener( 2 object : ViewTreeObserver.OnGlobalLayoutListener { 3 override fun onGlobalLayout() { 4 recycler.viewTreeObserver.removeOnGlobalLayoutListener(this); 5 // do whatever 6 } 7 });
好了,既已知不要那樣做。那麼有什麼更好的方法嗎?我們被迫使用一種看上去沒有那麼好看的方法,但是可能是一種好的選擇,將擴展函數隱藏起來。
為視圖接收另一個函數創建一個新函數,由它自己創建和刪除偵聽器。就像這樣:
1 inline fun View.waitForLayout(crossinline f: () -> Unit) = with(viewTreeObserver) { 2 addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener { 3 override fun onGlobalLayout() { 4 removeOnGlobalLayoutListener(this) 5 f() 6 } 7 }) 8 }
現在你就可以調用這個函數,確保其自己添加和刪除偵聽器。除非,你永遠不會忘記刪除:
1 recycler.waitForLayout { 2 // do whatever 3 }
如果喜歡,可以用擴展ViewTreeObserver的函數,而不是直接用View。這取決你。
這是在測試視圖後布局偵聽器通常要做的一些事,所以需要等待寬度和高度大於0。而且可能要在視圖中調用它時做一些事,這為什麼不能轉換參數函數到擴展函數?
我還泛型該函數使它能夠在任何繼承View的對象中使用,也能夠從編寫的函數中訪問所有它的指定函數和屬性。
1 inline fun <T: View> T.afterMeasured(crossinline f: T.() -> Unit) { 2 viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener { 3 override fun onGlobalLayout() { 4 if (measuredWidth > 0 && measuredHeight > 0) { 5 viewTreeObserver.removeOnGlobalLayoutListener(this) 6 f() 7 } 8 } 9 }) 10 }
這個afterMeasured函數非常類似前者,但是在Lambda表達式內直接用視圖的屬性和public方法。例如,我們能夠得到recycler的寬度和基於它用列的動態數組設置布局。
1 recycler.afterMeasured { 2 val columnCount = width / columnWidth 3 layoutManager = GridLayoutManager(context, columnCount) 4 }
在Android中運行時,這確實仍有些事情做的不是很好,即使是移植Kotlin,但是總是可以通過隱藏在其他結構背後的不確定因素,找到提升可讀性和避免不確定因素的選擇。至少,僅需要編寫一次,而其它代碼則非常漂亮!
Android文件下載之進度檢測,android文件下載 近期因為項目的需要,研究了一下Android文件下載進度顯示的功能實現,接下來就和大家一起分享學習一下,希望對
Android基礎入門教程——10.7 WindowManager(窗口管理服務) Android基礎入門教程——10.7 WindowManag
win通過dos配置注冊列表由於服務器數量眾多,需求是配置環境變量,為了不被累屎,為了減輕壓力所以有了這篇文章!嘿嘿……需求如圖: _<)~~~~ )1、注冊表設置win
Activity啟動模式之SingleInstance,singleinstance模式 終於到了最後一種啟動模式了,指定為singleInstance模式的活動會啟用