乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      Android 進(jìn)階 - 視圖層級(jí)實(shí)時(shí)分析(含福利)

       codingSmart 2021-10-22

      摘要

      在 App 運(yùn)行過(guò)程中,我們的視圖層級(jí)可能會(huì)由于用戶的操作一直在發(fā)生改變,甚至可能會(huì)有一些出乎預(yù)料的變化,本文將會(huì)介紹如何進(jìn)行Android 視圖實(shí)時(shí)分析,分析 View 的視圖層級(jí)及屬性變化。

      引題

      注:
      1.筆者分析代碼使用的 API 版本為 API 25 (Android 7.1)
      2.筆者使用的模擬器為 Android 7.1

      首先,筆者先來(lái)一個(gè)簡(jiǎn)單的 Demo 實(shí)例。我們使用 Android Studio 新建一個(gè) Empty Android 工程,跑一下程序,界面如下圖所示:

      接下來(lái),我們要對(duì)視圖層級(jí)進(jìn)行分析,但分析之前先給各位介紹兩個(gè)視圖分析工具。

      1.Android SDK 中 tools 包下的 hierarchyviewer,最終展現(xiàn)的視圖效果如下:

      2.Android Studio 也有自帶的視圖分析工具 Layout Inspector(布局檢查器),打開(kāi)方式如下圖所示:

      可以看到 Layout Inspector 最右側(cè)的屬性欄可以查看每一個(gè) View 的所附帶的屬性及屬性值。

      注:筆者推薦 Android Studio 開(kāi)發(fā)者可以使用 Layout Inspector。

      正文

      一.視圖層級(jí)分析

      從根視圖開(kāi)始分析視圖層級(jí),如下圖所示:

      • 我們可以看到視圖的根布局是 DecorView,寬度和高度為模擬器屏幕寬高。

      • DecorView 中包含3個(gè)子View:LinearLayout、View、View


      DecorView 的第一個(gè)子 View(LinearLayout), 如下圖所示:

      • LinearLayout 的高度與屏幕高度相比少了 96像素,從layout_bottomMargin 屬性可以知道這 96像素用來(lái)預(yù)留底部邊界了。


      DecorView 的第二個(gè)子 View(View),如下圖所示:

      • View的ID值表明了這個(gè)視圖的作用:底部導(dǎo)航欄背景

      • 這個(gè)View的高度是96像素(屬性列表間距較大,截圖沒(méi)有截到)


      DecorView 的第三個(gè)子 View(View),如下圖所示:

      • View的ID值表明了這個(gè)視圖的作用:狀態(tài)欄背景

      • 這個(gè)View的高度是48像素(屬性列表間距較大,截圖沒(méi)有截到)

      插入一點(diǎn)劇情:


      有朋友可能會(huì)問(wèn),是不是只要知道這個(gè)ID值(statusBarBackground),我們就可以拿到這個(gè)狀態(tài)欄背景View,之后想怎么操作這個(gè)View都可以?

      答案:可以。但這里有一些注意點(diǎn):

      • 只有在API 21(Android 5.0)以上才能獲取到該"狀態(tài)欄View",如下圖所示:

      • 在onCreate方法里直接獲取該"狀態(tài)欄View"值為null,如下圖所示:

      • 當(dāng)視圖已經(jīng)顯示出來(lái)時(shí),可以拿到這個(gè)"狀態(tài)欄View",如下圖所示:

      • 簡(jiǎn)單說(shuō)明一下在onCreate方法里直接獲取"狀態(tài)欄View"值為null的原因:


        findViewById(int id) 這個(gè)方法最終會(huì)走的DecorView(ViewGroup)的findViewTraversal(int id)方法進(jìn)行View遍歷,根據(jù)id值查找子View。我們Debug走到這個(gè)方法時(shí)發(fā)現(xiàn)DecorView里只有一個(gè)LinearLayout,另外兩個(gè)View還沒(méi)有加載進(jìn)來(lái),如下圖所示:



        結(jié)論:當(dāng)我們?cè)贠nCreate方法里執(zhí)行完setContentView(int id)方法后,"狀態(tài)欄View"和"底部導(dǎo)航欄View"還沒(méi)有添加進(jìn)DecorView,此時(shí)生成的DecorView并不是最終顯示的DecorView。

      至此,DecorView的最外層View全部分析完畢。


      接下來(lái),分析 DecorView 的第一個(gè)子View(LinearLayout),如下圖所示:

      • LinearLayout包含兩個(gè)子View:ViewStub和FrameLayout

      • ViewStub顯示的文字顏色為灰色,說(shuō)明該View沒(méi)有在當(dāng)前視圖上顯示出來(lái)。

      注:ViewStub繼承自View,是一種視圖容器,一般用于對(duì)布局資源的加載流程進(jìn)行優(yōu)化。

      ViewStub的屬性信息,如下圖所示:

      • ViewStub的getVisibility屬性值為 GONE (ViewStub處于隱藏狀態(tài))

      FrameLayout的屬性信息,如下圖所示:

      • FrameLayout的高度值為1136px,相比于父布局LinearLayout又少了48px。

      • 從mTop屬性可以知道,F(xiàn)rameLayout在布局時(shí)頂點(diǎn)坐標(biāo)高度從48px開(kāi)始,空出了狀態(tài)欄的高度。


      接下來(lái),繼續(xù)分析FrameLayout的子View,如下圖所示:

      • FrameLayout只有一個(gè)子View:ActionBarOverlayLayout。

      • ActionBarOverlayLayout的寬度和高度與FrameLayout保持一致。

      • ActionBarOverlayLayout有兩個(gè)子View:ContentFrameLayout和ActionBarContainer

      ContentFrameLayout的視圖屬性,如下圖所示:

      • ContentFrameLayout的高度相比于父布局減少了112px

      • 從layout_topMargin屬性可以看出,這112px用于預(yù)留頂部邊界,空出了標(biāo)題欄的高度。

      • ContentFrameLayout的mID屬性值為content(android.R.id.content)

      • ContentFrameLayout里的子View就是我們activity_main.xml中的視圖了。

      注:這里有個(gè)很有趣的地方,我們activity_main.xml文件里用的是TextView,但是最后卻被轉(zhuǎn)成了AppCompatTextView。限于篇幅,筆者重起了一篇文章Android進(jìn)階 - 源碼中的視圖轉(zhuǎn)換,有興趣的朋友可以看看。

      ActionBarContainer的視圖屬性,如下圖所示:

      • ActionBarContainer從名字也可以看出這是一個(gè)標(biāo)題欄容器。

      • ActionBarContainer的子View中當(dāng)前處于顯示狀態(tài)的只有一個(gè)Toolbar。

      視圖部分分析到這基本上就OK了,筆者就不再向下分析了。只要讀者能學(xué)會(huì)這個(gè)工具的使用方法,基本上就可以自己嘗試分析了。

      不過(guò),還有個(gè)問(wèn)題需要提醒一下,不同機(jī)型,不同系統(tǒng)主題設(shè)置生成的視圖結(jié)構(gòu)可能會(huì)不一樣,舉兩個(gè)例子:

      例一:筆者把使用的模擬器換成自己的手機(jī)(360N5 Android 6.0.1),運(yùn)行后視圖布局如下:

      可以看到筆者的手機(jī)是沒(méi)有NavigationBar(底部導(dǎo)航欄)的。

      例二:筆者把Activity的主題"Theme.AppCompat.Light.DarkActionBar"換成無(wú)標(biāo)題欄主題"Theme.AppCompat.Light.NoActionBar",運(yùn)行后視圖布局如下:

      可以看到視圖結(jié)構(gòu)與我們之前分析的相比,發(fā)生了一些變化。

      最后,還有個(gè)細(xì)節(jié)給各位補(bǔ)充下:Layout Inspector 只能分析出Android Studio當(dāng)前“正在運(yùn)行的APP”的視圖布局結(jié)構(gòu),其他應(yīng)用的視圖布局結(jié)構(gòu)是無(wú)法顯示的。

      如果我們想要分析一個(gè)第三方應(yīng)用(如:微信、QQ)的視圖結(jié)構(gòu)可以使用Android Device Monitor(安卓設(shè)備監(jiān)視器),具體打開(kāi)步驟如下圖所示:

      以QQ為例,我們先打開(kāi)手機(jī)QQ,顯示出QQ主界面,然后按照下圖的"紅色圈選",依次點(diǎn)擊,當(dāng)前的視圖結(jié)構(gòu)就出來(lái)了,但是相比于Layout Inspector工具,視圖屬性信息提供的較少...

      視圖層級(jí)分析到此結(jié)束,有時(shí)間再補(bǔ)篇源碼,分析一下布局加載的流程。

      題外話

      寫這篇文章的時(shí)候被 IOS 同事嘲諷了,它們吐槽 Android 的視圖分析工具太渣,最后對(duì)比看了下,Android 的視圖分析工具確實(shí)沒(méi)有IOS 的高大上......╮(╯▽╰)╭

      最后,秀一下 IOS 的視圖分析工具 Reveal,如下圖所示:

      福利 福利 福利

      留言 + 點(diǎn)廣告,留言點(diǎn)贊前五的本周三中午平分今天的廣告收益哈!

      與之相關(guān)

      6 重福利(贈(zèng)書(shū)),5 個(gè)月精選干貨,感謝你與 code小生共同成長(zhǎng)

      2017 | 我在 5 個(gè)月時(shí)間里分享了 98 篇文章

      微信號(hào):code-xiaosheng

      公眾號(hào)

      「code小生」

        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶 評(píng)論公約

        類似文章 更多