android UI進階之布局的最佳化(二)

來源:互聯網
上載者:User

上一篇部落格中介紹了布局最佳化的工具,層級觀察器Hierarchy Viewer和布局最佳化分析工具layoutopt。如果看過上篇部落格的會注意到,layoutopt工具提示可以將<FrameLayout/>換成<merge/>。其實<merge/>標籤在UI的結構最佳化中起著非常重要的作用,通過它可以刪減多餘的層級,達到最佳化UI的目的。

  再來看一下上篇部落格中使用的架構布局的樹形結構圖:

     根節點和LinearLayout上面那個子樹為android的視窗布局,後面的TextView即為標籤。黃色框內的這部分樹形圖即為我們的布局。可以發現紅色框出的FrameLayout是另一個FrameLayout的唯一子項目,並且該父節點並沒有額外的屬性,也就是說,它是完全冗餘的,這時候就要用<merge/>標籤來解決這個問題。用<merge/>替換原來的<FrameLayout/>標籤,修改後的布局代碼如下:

<?xml version="1.0" encoding="utf-8"?><br /><merge xmlns:android="http://schemas.android.com/apk/res/android"<br /> android:orientation="vertical"<br /> android:layout_width="fill_parent"<br /> android:layout_height="fill_parent"<br /> ><br /><TextView<br /> android:layout_width="300dip"<br /> android:layout_height="300dip"<br /> android:background="#00008B"<br /> android:layout_gravity="center"<br /> /><br /><TextView<br /> android:layout_width="250dip"<br /> android:layout_height="250dip"<br /> android:background="#0000CD"<br /> android:layout_gravity="center"<br /> /><br /><TextView<br /> android:layout_width="200dip"<br /> android:layout_height="200dip"<br /> android:background="#0000FF"<br /> android:layout_gravity="center"<br /> /><br /><TextView<br /> android:layout_width="150dip"<br /> android:layout_height="150dip"<br /> android:background="#00BFFF"<br /> android:layout_gravity="center"<br /> /><br /><TextView<br /> android:layout_width="100dip"<br /> android:layout_height="100dip"<br /> android:background="#00CED1"<br /> android:layout_gravity="center"<br /> /><br /></merge>

     
再觀察下它的樹形圖,,顯然層次更簡單了。

為什麼會這樣呢,因為Activity的根節點都是FrameLayout,所以用merge標籤可以直接添加到這個FrameLayout而不要再增加一個FrameLayout節點。但是如果你的布局是以LinearLayout等為根節點,就不能這麼做了。

        
<merge/>其實還有很多作用,它和<include/>標籤就能完美的結合。<include/>標籤用來實現代碼的重用以及布局的模組化。如果UI中需要多次用到同一個布局,
<include/>標籤會大大提高我們的開發效率。看個例子:

建立一個共用布局:share.xml

<?xml version="1.0" encoding="utf-8"?><br /><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"<br /> android:orientation="vertical"<br /> android:layout_width="fill_parent"<br /> android:layout_height="fill_parent"<br /> ><br /><TextView<br /> android:layout_width="fill_parent"<br /> android:layout_height="wrap_content"<br /> android:text="這是一個共用布局"<br /> /><br /></LinearLayout>

 

然後在需要使用這個布局的布局中使用<include/>標籤,並且我們可以重寫它的一些屬性(下面的代碼就重寫了它的id):

<?xml version="1.0" encoding="utf-8"?><br /><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"<br /> android:orientation="vertical"<br /> android:layout_width="fill_parent"<br /> android:layout_height="fill_parent"><br /> <include android:id="@+id/new" layout="@layout/share"></include><br /></LinearLayout>

如果在我們的布局中只需要使用共用布局的內容,這時候就可以用merge標籤,這樣使得布局更加高效靈活。

<?xml version="1.0" encoding="utf-8"?><br /><merge xmlns:android="http://schemas.android.com/apk/res/android"<br /> <include android:id="@+id/newone" layout="@layout/share"></include><br /><include android:id="@+id/newtwo" layout="@layout/share"></include><br /></merge>

有了<include/>標籤,很容易就能做到共用和重用布局,可是很多情況下,一個布局中有很多View並不常用,這就造成了資源的浪費,android為此提供了ViewStub標籤來解決這個問題。在預設情況下ViewStub下的標籤都有visibility=GONE屬性(不可見),更重要的是在這個標籤下的內容不會佔用任何的空間。其實ViewStub和include類似,不過區別就在於ViewStub只會在你需要的時候進入你的介面,viewStub通過inflate()方法來通知系統載入其內部的View。這樣就可以讓我們既享受到<include/>的便利,又不會產生過多沒用的View。 還是看個例子:

其中share.xml前面已經介紹過了,main.xml的布局檔案:

<?xml version="1.0" encoding="utf-8"?><br /><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"<br /> android:orientation="vertical"<br /> android:layout_width="fill_parent"<br /> android:layout_height="fill_parent"<br /> ><br /><Button<br />android:id="@+id/show"<br />android:layout_width="wrap_content"<br />android:layout_height="wrap_content"<br />android:text="點擊匯入"<br />/><br /><ViewStub<br /> android:id="@+id/viewStub"<br /> android:layout="@layout/share"<br /> android:layout_width="wrap_content"<br /> android:layout_height="wrap_content"<br /> /><br /></LinearLayout><br />

MyViewStub.java代碼:

 

package com.notice520.viewstub;</p><p>import android.app.Activity;<br />import android.os.Bundle;<br />import android.view.View;<br />import android.view.ViewStub;<br />import android.view.View.OnClickListener;<br />import android.widget.Button;</p><p>public class MyViewStub extends Activity {</p><p>private ViewStub mViewStub;<br />private Button showButton;</p><p> /** Called when the activity is first created. */<br /> @Override<br /> public void onCreate(Bundle savedInstanceState) {<br /> super.onCreate(savedInstanceState);<br /> setContentView(R.layout.main);</p><p> mViewStub = (ViewStub)findViewById(R.id.viewStub);//執行個體化ViewStub控制項,這裡可以看出我們必//須為ViewStub設定id<br /> showButton = (Button)findViewById(R.id.show);</p><p> /*為按鈕添加點擊監聽事件,後面的章節會介紹*/<br /> showButton.setOnClickListener(new OnClickListener(){</p><p> @Override<br /> public void onClick(View v) {<br /> if (mViewStub != null) {<br /> mViewStub.inflate(); //點擊即匯入ViewStub標籤的內容<br /> }<br /> }<br /> });<br /> }<br />}<br />

    
運行效果,當點擊按鈕後,匯入的布局就會顯示,。這裡要注意的是,其實很多時候我們不需要保留ViewStub的引用(這個例子中我們在欄位裡保留了ViewStub的引用),因為當ViewStub inflate後,這個ViewStub就從View層次中移除了。在讀者深入學習後,會經常用到infate()方法來匯入布局載入到原來的view上,那時候你會發現用ViewStub是個比那更好的辦法。但是要注意的是,ViewStub還不支援<merge/>標籤。

   

 好了,今天就寫到這了。希望對大家有協助,有問題可以留言交流。歡迎轉載,但是請註明出處http://blog.csdn.net/notice520/article/details/6317992。這裡分享幾個android學習的qq群。

106894847   500人群   需要的可以加下,一起討論android技術~

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.