詳細介紹安卓布局性能優化之(include 、merge、ViewStub)

      網友投稿 833 2022-05-30

      我們在日常開發中,我們可能會遇到有很多相似的布局,如果每一個XML文件都寫一次,不說麻煩,代碼也顯得冗余,而且可讀性也很差.這時候就需要include 了,本編文章將會介紹include、merge和ViewStub標簽的用法供大家學習和參考。

      include標簽

      include標簽常用于將布局中的公共部分提取出來供其他layout共用,以實現布局模塊化,也是平常我們設計布局時用的最多的

      include 官方文檔

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      1.2、Activity的XML布局文件調用include標簽:

      1

      2

      3

      4

      5

      6

      詳細介紹安卓布局性能優化之(include 、merge、ViewStub)

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      19

      20

      21

      22

      23

      1.3、Activity中調用include標簽layout中的子View:

      private void initView() { //如果include布局根容器和include標簽中的id設置的是不同的值,這里獲取的mToolbar值將為null Toolbar mToolbar = (Toolbar) findViewById(R.id.tb_toolbar); setSupportActionBar(mToolbar); //普通include標簽用法,直接拿子View屬性實現 TextView textView = (TextView) findViewById(R.id.textView); textView.setText("不加ID實現的include標簽"); //多個include標簽用法,添加ID,findViewByID找到layout,再找子控件 View view_include = findViewById(R.id.include_text1); TextView view_include_textView = (TextView) view_include.findViewById(R.id.textView); view_include_textView.setText("加了ID實現的include標簽"); //多個include標簽用法,添加ID,findViewByID找到layout,再找子控件 View view_include_Relative = findViewById(R.id.include_text2); TextView view_textView_relative = (TextView) view_include_Relative.findViewById(R.id.textView); view_textView_relative.setText("加了ID實現的include標簽(RelaviteLayout)"); }

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      include使用注意

      一個xml布局文件有多個include標簽需要設置ID,才能找到相應子View的控件,否則只能找到第一個include的layout布局,以及該布局的控件

      include標簽如果使用layout_xx屬性,會覆蓋被include的xml文件根節點對應的layout_xx屬性,建議在include標簽調用的布局設置好寬高位置,防止不必要的bug

      include 添加id,會覆蓋被include的xml文件根節點ID,這里建議include和被include覆蓋的xml文件根節點設置同名的ID,不然有可能會報空指針異常

      如果要在include標簽下使用RelativeLayout,如layout_margin等其他屬性,記得要同時設置layout_width和layout_height,不然其它屬性會沒反應

      merge 標簽

      merge標簽主要用于輔助include標簽,在使用include后可能導致布局嵌套過多,多余的layout節點或導致解析變慢(可通過hierarchy viewer工具查看布局的嵌套情況)

      官方文檔說明:merge用于消除視圖層次結構中的冗余視圖,例如根布局是Linearlayout,那么我們又include一個LinerLayout布局就沒意義了,反而會減慢UI加載速度

      merge 官方文檔

      merge標簽常用場景:

      1.根布局是FrameLayout且不需要設置background或padding等屬性,可以用merge代替,因為Activity的ContentView父元素就是FrameLayout,所以可以用merge消除只剩一個。

      2.某布局作為子布局被其他布局include時,使用merge當作該布局的頂節點,這樣在被引入時頂結點會自動被忽略,而將其子節點全部合并到主布局中。

      3.自定義View如果繼承LinearLayout(ViewGroup),建議讓自定義View的布局文件根布局設置成merge,這樣能少一層結點。

      merge標簽使用:

      在XML布局文件的根布局如RelativeLayout直接改成merge即可

      merge使用注意

      1.因為merge標簽并不是View,所以在通過LayoutInflate.inflate()方法渲染的時候,第二個參數必須指定一個父容器,且第三個參數必須為true,也就是必須為merge下的視圖指定一個父親節點.

      2.因為merge不是View,所以對merge標簽設置的所有屬性都是無效的.

      3.注意如果include的layout用了merge,調用include的根布局也使用了merge標簽,那么就失去布局的屬性了

      4.merge標簽必須使用在根布局

      5.ViewStub標簽中的layout布局不能使用merge標簽

      ViewStub 標簽

      我們在做安卓項目的時候,經常會有一個使用場景:需要在運行時根據數據動態決定顯示或隱藏某個View和布局。

      上述場景,我們通常的解決方案就是:就是把可能用到的View先寫在布局里,再初始化其可見性都設為View.GONE,然后在代碼中根據數據動態的更改它的可見性。

      雖然這樣的實現,邏輯簡單而且控制起來比較靈活;但是也存在一定的缺點耗費資源。

      ViewStub 標簽最大的優點是當你需要時才會加載,使用它并不會影響UI初始化時的性能.各種不常用的布局像進度條、顯示錯誤消息等可以使用ViewStub標簽,以減少內存使用量,加快渲染速度.ViewStub是一個不可見的,實際上是把寬高設置為0的View.效果有點類似普通的view.setVisible(),但性能體驗提高不少

      第一次初始化時,初始化的是ViewStub View,當我們調用inflate()或setVisibility()后會被remove掉,然后在將其中的layout加到當前view hierarchy中。

      先來看看布局,一個是主布局,里面只定義二個ViewStub,一個用來控制TextView一個用來控制ImageView,另外就是一個是為顯示文字的做的TextView布局,一個是為ImageView而做的布局:

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      19

      20

      21

      22

      23

      為TextView的布局:

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      為ImageView的布局:

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      下面來看代碼,決定來顯示哪一個,只需要找到相應的ViewStub然后調用其infalte()就可以獲得相應想要的布局:

      public class ViewStubDemoActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.viewstub_demo_activity); if ((((int) (Math.random() * 100)) & 0x01) == 0) { // to show text // all you have to do is inflate the ViewStub for textview ViewStub stub = (ViewStub) findViewById(R.id.viewstub_demo_text); stub.inflate(); TextView text = (TextView) findViewById(R.id.viewstub_demo_textview); text.setText("The tree of liberty must be refreshed from time to time" + " with the blood of patroits and tyrants! Freedom is nothing but " + "a chance to be better!"); } else { // to show image // all you have to do is inflate the ViewStub for imageview ViewStub stub = (ViewStub) findViewById(R.id.viewstub_demo_image); stub.inflate(); ImageView image = (ImageView) findViewById(R.id.viewstub_demo_imageview); image.setImageResource(R.drawable.happy_running_dog); } } }

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      19

      20

      21

      22

      23

      24

      ViewStub標簽使用注意

      ViewStub標簽不支持merge標簽

      ViewStub的inflate只能被調用一次,第二次調用會拋出異常,setVisibility可以被調用多次,但不建議這么做(ViewStub 調用過后,可能被GC掉,再調用setVisibility()會報異常)

      為ViewStub賦值的android:layout_XX屬性會替換待加載布局文件的根節點對應的屬性

      擴展:

      Space組件

      在ConstraintLayout出來前,我們寫布局都會使用到大量的margin或padding,但是這種方式可讀性會很差,加一個布局嵌套又會損耗性能

      鑒于這種情況,我們可以使用space,使用方式和View一樣,不過主要用來占位置,不會有任何顯示效果

      XML 容器

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:Pathlib庫:Python面向對象的文件路徑處理
      下一篇:基于FusionInsight的離線數倉場景案例
      相關文章
      亚洲人成人77777网站| 亚洲欧美日韩中文无线码| 亚洲av成人片在线观看| 亚洲伦理一二三四| 久热综合在线亚洲精品| 亚洲中久无码永久在线观看同 | 亚洲综合久久夜AV | 国产在亚洲线视频观看| 狠狠入ady亚洲精品| 蜜臀亚洲AV无码精品国产午夜.| 亚洲精品天堂无码中文字幕| 亚洲国产精品免费观看| 亚洲成_人网站图片| 亚洲中文无码mv| 亚洲精品无码久久久久秋霞| 国产精品亚洲精品观看不卡| 色在线亚洲视频www| 亚洲一区欧洲一区| 亚洲人成网站999久久久综合| 亚洲色精品VR一区区三区| 亚洲欧美成人一区二区三区| 亚洲精品蜜夜内射| 亚洲av无码日韩av无码网站冲| 美国毛片亚洲社区在线观看 | 亚洲精品成a人在线观看☆| 亚洲乱码无人区卡1卡2卡3| 亚洲人成色99999在线观看| 亚洲成a人无码亚洲成av无码| 麻豆亚洲AV成人无码久久精品 | 亚洲黄色免费在线观看| 亚洲图片中文字幕| 亚洲永久在线观看| 激情无码亚洲一区二区三区| 亚洲成a人片在线观看国产| 亚洲人成人无码网www国产| 亚洲综合无码AV一区二区 | 久久夜色精品国产亚洲| 91嫩草私人成人亚洲影院| 亚洲国产美女视频| 亚洲依依成人亚洲社区| 噜噜噜亚洲色成人网站|