android中ViewStub惰性加載佈局



android中ViewStub惰性加載佈局

我們先來看看看這個控件類吧

一、結構

    public final class ViewStub extends View

    

    java.lang.Object

        android.view.View

              android.view.ViewStub

二、類概述

    ViewStub 是一個隱藏的,不佔用內存空間的視圖對象,它可以在運行時延遲加載佈局資源文件。當ViewStub可見,或者調用 inflate()函數時,纔會加載這個佈局資源文件。 該ViewStub在加載視圖時在父容器中替換它本身。因此,ViewStub會一直存在於視圖中,直到調用setVisibility(int) 或者inflate()爲止。ViewStub的佈局參數會隨着加載的視圖數一同被添加到ViewStub父容器。同樣,你也可以通過使用inflatedId屬性來定義或重命名要加載的視圖對象的Id值。例如:

    

    通過"stud"id可以找到被定義的ViewStub對象。加載佈局資源文件"mySubTree "後, ViewStub對象從其父容器中移除。可以通過id"subTree"找到由佈局資源"mySubTree"創建的View。這個視圖對象最後被指定爲寬120dip,高40dip。執行加載佈局資源文件的推薦方式如下:

    

    當inflate()被調用, 這個ViewStub被加載的視圖替代並且返回這個視圖對象。這使得應用程序不需要額外執行findViewById()來獲取加載視圖的引用。
    (譯者注:這個類大概意思是用ViewStub類和在XML文件裏面指定的佈局資源文件關聯起來,讓佈局資源文件在需要使用的時候再加載上去。主要作用是性能優化,什麼時候用什麼時候加載,不用在開始啓動的時候一次加載,既可以加快程序的啓動速度,又可以節省內存資源。)

 

  三、嵌套類

    接口    ViewStub.OnInflateListener        一個用於接收ViewStub已經成功加載佈局資源文件的通知的監聽器。

 

  四、XML屬性

屬性名稱

相關方法

描述

android:inflatedId

setInflatedId(int)

覆蓋待加載視圖的id值。

android:layout

setLayoutResource(int)

爲待加載的資源視圖提供一個標識,在ViewStub變爲可見或獲取焦點時使用它。(譯者注:要引用的佈局資源文件id

 

  五、構造函數

    ViewStub(Context context, int layoutResource)

    創建一個與指定的佈局資源文件關聯的ViewStub對象。

             參數

                       layoutResource   要加載的佈局資源文件的id值。 


  六、公共方法

         public void draw (Canvas canvas)

         手動在指定的畫布繪製這個視圖(及所有其子視圖)。這個視圖必須在調用這個函數之前做好了整體佈局。當要自己實現一個視圖時,不要重載這個方法;相反,你應該重載onDraw(Canvas)方法。(譯者注:主要用於自定義的視圖組件的方法。

                   參數

                            canvas    這個畫布傳到那個已渲染的視圖對象。

 

         public int getInflatedId ()

         返回加載的佈局資源文件的ID,如果加載的佈局資源文件的idNO_ID,那麼這個加載的View將保留它原來的id值。

                   相關XML 屬性

                            android:inflatedId

                   返回值

                            一個正整數來標識這個要加載的視圖或者NO_ID將保持加載視圖原來的id

                   參見

                            setInflatedId(int)

 

         public int getLayoutResource ()

         返回加載的佈局資源文件的id值。

                   相關XML 屬性

                            android:layout

                   返回值

                            加載到視圖對象的佈局資源文件id值。

                   參見

                            setLayoutResource(int)

                            setVisibility(int)

                            inflate()

 

         public View inflate ()

         加載getLayoutResource()方法標識的佈局資源,並通過加載佈局資源替換父容器中它自己。

                   返回值

                            這個已加載的佈局資源文件.

 

         public void setInflatedId (int inflatedId)

         設置加載視圖的ID。如果這個idNO_ID,這個加載視圖保持它原來的id不變。

                   相關XML 屬性

                            android:inflatedId

                   參數

                            inflatedId         一個正整數來標識這個加載視圖或者NO_ID將保持加載視圖原來的id

                   參見

                            getInflatedId()

 

         public void setLayoutResource (int layoutResource)

         設置待加載的佈局資源文件,當ViewStub被設置爲visibleinvisible或調用inflate()時使用。這個在加載佈局資源文件時創建的視圖用來在父容器中替換它自己。

                   相關XML 屬性

                            android:layout

                   參數

                            layoutResource       一個有效的佈局資源文件id值(不等於0)。

                   參見

                            getLayoutResource()

                            setVisibility(int)

                            inflate()

 

         public void setOnInflateListener (ViewStub.OnInflateListener inflateListener)

      設置成功加載佈局資源文件後事件通知的監聽器。

                 參數

                            inflateListener         OnInflateListener在成功加載後得到事件通知。

                 參見

                            ViewStub.OnInflateListener

 

         public void setVisibility (int visibility)

當可見性設置爲VISIBLEINVISIBLEinflate()將被調用,並且加載視圖資源在父容器中替換ViewStub

                   參數

                            visibility 設置爲VISIBLE(顯示), INVISIBLE(隱藏) GONE(完全隱藏,不暫用佈局位置).

                   參見

                              inflate() 

 

  七、受保護方法

         protected void dispatchDraw (Canvas canvas)

調用這個函數去繪製這個控件的子視圖。可以通過派生類重寫在繪製子類之前獲取控制(但是是在他自己的視圖已經被繪製完之後)

                  參數

                            canvas    這個畫布傳到那個已渲染的視圖對象。

 

         protected void onMeasure (int widthMeasureSpec, int heightMeasureSpec)

測量這個視圖以確定其內容的高度和寬度。通過measure(int, int)來調用這個方法,並且應該由子類重寫以提高內容測量的效率和精確度。

    約定:當該方法被重寫時,你必須調用setMeasuredDimension(int, int)來存儲已測量視圖的高度和寬度。否則將通過measure(int, int)拋出一個IllegalStateException異常。調用父類的onMeasure(int, int)方法是一個有效的辦法。

    父類的實現是以背景大小爲默認大小,除非MeasureSpec(測量細則)允許更大的背景。爲了更好測量內容子類應該重寫onMeasure(int, int)

    如果這個方法被重寫,子類有責任確保測量它的高度和寬度至少是視圖的最小寬度和高度(getSuggestedMinimumHeight()getSuggestedMinimumWidth())。

      參數

  widthMeasureSpec         由於父類有橫向空間要求,參見View.MeasureSpec

                              heightMeasureSpec        由於父類有縱向空間要求,參見View.MeasureSpec 

然後,爲了便於理解,小白特簡單的測試了一下,直接上代碼-------此處順便測試一下include(也可以反覆引用佈局文件)

1、先定義一個佈局文件,作爲引用的佈局文件---文件名爲 next_layout

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >


    <RatingBar
        android:id="@+id/rb"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" />


</LinearLayout>

2、然後繪製主佈局,即activity中聲明加載的,即setcontentView

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >


    <!-- 使用include引用佈局文件 -->


    <include
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        layout="@layout/next_layout" />


    <!-- 使用ViewStub引用佈局文件 -->


    <ViewStub
        android:id="@+id/stub"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout="@layout/next_layout" />


    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical" >


        <Button
            android:id="@+id/button1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="#00ffff"
            android:text="動態加載佈局" />


        <Button
            android:id="@+id/button2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp"
            android:background="#ffff00"
            android:text="動態隱藏佈局" />
    </LinearLayout>


</LinearLayout>

  3、在activity中測試,源碼爲

package com.example.viewstub;


import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewStub;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.RatingBar;


public class MainActivity extends Activity {
private Button button1, button2;
private ViewStub stub;


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 初始化控件
button1 = (Button) findViewById(R.id.button1);
button2 = (Button) findViewById(R.id.button2);
stub = (ViewStub) findViewById(R.id.stub);
// 爲button1設置監聽事件
button1.setOnClickListener(new OnClickListener() {


@Override
public void onClick(View v) {
// TODO Auto-generated method stub


// ViesStub控件只能獲得一次,第二次再使用findViewById獲得該ViewStub對象,則返回null

View v1 = stub.inflate();// 調用此方法,加載佈局。當然也可以通過setVisibility方法
RatingBar rb = (RatingBar) v1.findViewById(R.id.rb);// 從動態加載的佈局中獲得相應控件
rb.setNumStars(3);// 設置已獲得控件的屬性


}
});
// 爲button2設置監聽事件
button2.setOnClickListener(new OnClickListener() {


@Override
public void onClick(View v) {
// TODO Auto-generated method stub
stub.setVisibility(View.GONE);


// 值得注意的是,若使用下面的屬性值,除了佔用佈局空間外,而且,若是你直接點擊此按鈕(沒有加載佈局之前),則他會先自動加載佈局,然後當你再次點擊時,纔會隱藏的。
// 這一點應該引起注意。所以 選用 View.GONE 效果更好,推薦使用。

// stub.setVisibility(View.INVISIBLE);


}
});


}


}


效果圖:
進入應用的效果1


點擊動態加載佈局後的效果




點擊隱藏佈局  後效果


再一次點擊動態加載佈局時效果





最後,歡迎交流,本人小白    QQ 964079433
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章