日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

android 自定义控件的宽高_巧用Handler获取View控件信息

發布時間:2024/7/23 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 android 自定义控件的宽高_巧用Handler获取View控件信息 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

眾所周知,在Android實際開發中,對于某些復雜多變的情況,控件的位置擺放、大小控制并非是xml類型的layout文件完全可以搞定的。此時,我們通常會使用Java代碼來通過動態計算,將指定的控件擺放在相應的位置,并限定其大小。同樣地,也需要獲取某個控件的大小。 對于獲取控件寬、高的方法,大家可以自行谷歌或者百度,大抵無非一下三種方法:

  • 給相應的View控件添加ViewTreeObserver回調;
  • Override onWindowFocusChange方法;
  • 在需要測量時(而不是onCreate或onResume中),使用MeasureSpec內部類獲取寬高。
  • 對于上述第三種情況,我們暫且不論。對于前二者而言,有沒有更簡單的實現呢?

    為何獲取寬高要如此?

    對于初學者,可能會有這樣的疑問:為什么我們不能在onCreate()或者onResume()中直接使用上述第三種方案獲取寬高呢? 結論是:那樣的話,獲取來的值很可能皆為0,即使實際的寬高不是0。那么這是為何呢? 這其實是由Android的UI繪制流程決定的。大家不妨試著做一下實驗,即使是在onResume()方法后,它的意義也僅僅是指Activity進入了可見的狀態,這并不意味著界面繪制的結束。我們可以用一個簡單的帶有寬高值得View來做實驗,觀察Activity中各回調方法的調用順序,得到的結果將是這樣的:

    Activity.oncreate() → Activity.onResume() → View.onMeasure() → View.onLayout() → onGlobalLayoutListener() → Activity.onWidnowFocusChanged() → ... → View.onDraw() -> ...

    因此,如果我們在onResume()中嘗試獲取View寬高的話,很大概率是會失敗的。

    巧用Handler獲取View控件信息

    這里我們開門見山地先放上代碼片:

    private

    上述代碼作為通用的方法將獲取任意View的寬高做了封裝,其妙處就在‘view.post’處。 將其置于onCreate()、onResume()方法中調用,均可獲取到正確的寬高。

    @Override

    Logcat中的運行結果:

    2019-01-14 22:33:13.874 18355-18355/com.example.wenhan.helloandroid I/MainActivity: Width: 225, height: 57 2019-01-14 22:33:13.874 18355-18355/com.example.wenhan.helloandroid I/MainActivity: Width: 225, height: 57

    為何如此就可獲取到正確的值了呢?

    其中的玄機在于,我們在View.post()中所寫的語句并沒有立即執行,而在其真正執行的時候,View的寬高已經被測量完成了,那時我們再去獲取寬高時,就會很容易地獲取到正確的值了。 通過斷點Debug,可以輕松地發現,在Activity啟動過程的調用棧中,存在ActivityThread類被執行了,具體按照:

    main() -> handleResumeActivity() -> addView() -> setView() -> requestLayout() -> scheduleTraversals() -> 執行mTraversalRunnable異步線程 -> doTraversal() -> performTraversals() -> ... -> performMeasure() -> ...

    的執行順序。 在我們獲取寬高的語句執行前,主線程的Handler正在執行TraversalRunnable(見上述方法具體實現),而performMeasure也被包含其中。又因為我們獲取寬高的語句要排隊,處于等待狀態,直到主線程Handler輪到執行我們的語句,而此時View的寬高的測量已經結束。

    完整示例代碼:

    wh1990xiao2005/FetchViewSizeDemo?github.com

    總結

    以上是生活随笔為你收集整理的android 自定义控件的宽高_巧用Handler获取View控件信息的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。