新技能get:Android應用優化技能之“延遲加載”術


世風日下,人心不古。

如今四海雖看似太平,其實卻暗藏殺機。大到一架飛機一輛公交,小到一個app,都會讓您抓狂。

越來越復雜的界面,越來越多的需求,對app來說本身來說就是一個噩耗,但在人類無窮的想象力,在功能模塊無情的堆積之下,對於應用來說,要么瘦,要么死!

那么如何瘦,怎么瘦?對廣大愛美的程序員和產品和用戶來說,只有簡約,按需才是王道。

旁白:寫文章就寫文章嘛,廢話太多了!

【這是正題】上面一堆廢話其實也是有兩個有用的詞匯的,簡約按需。簡約是設計要想的,那么按需就是我們程序將要做的。

【按需:延遲加載】所謂的延遲加載就是不在初始化界面的時候加載部分view,在需要的時候才加載,在布局多控件的時候能有效的提升界面的加載和響應速度。

【我們普遍在使用的按需加載】稍微有些經驗的android開發程序員都會懂得把一些復雜界面里的一些模塊單獨用一個xml寫的layout獨立寫,然后在需要的時候把它們inflate()到程序中來,這樣達到延遲加載的目的。這樣做在界面不確定,需要多次實例化view或者根據數據遍歷產生view的時候會很方便,完全由java代碼實現。那么如果我們在界面元素確定並且需要延時加載的時候有沒有更直觀的做法呢?當然有:使用viewStub.

【一個輕量級的控件:viewStub】如名字的含義,只是一個view的存根,不占什么內存(區別於<include>),但卻可以占個位置,在程序需要的時候把viewStub指向的view擴展到界面。依照慣例,在我要舉例子的這個時候代碼會悄悄襲來--》

 

 1 <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
 2     xmlns:tools="http://schemas.android.com/tools"
 3     android:layout_width="match_parent"
 4     android:layout_height="match_parent"
 5     tools:context=".MainActivity" >
 6 
 7     <LinearLayout
 8         android:id="@+id/main"
 9         android:layout_width="match_parent"
10         android:layout_height="wrap_content"
11         android:orientation="vertical"
12         android:paddingBottom="@dimen/activity_vertical_margin"
13         android:paddingLeft="@dimen/activity_horizontal_margin"
14         android:paddingRight="@dimen/activity_horizontal_margin"
15         android:paddingTop="@dimen/activity_vertical_margin" >
16 
17         <TextView
18             android:layout_width="wrap_content"
19             android:layout_height="wrap_content"
20             android:text="所謂的延時加載就是不在初始化界面的時候加載部分view,在需要的時候才加載,在布局多控件的時候能有效的提升界面的響應速度。"/>
21 
22         <Button
23             android:id="@+id/btn_by_inflate"
24             android:layout_width="match_parent"
25             android:layout_height="wrap_content"
26             android:text="普通inflate方式" />
27 
28         <Button
29             android:id="@+id/btn_by_viewstub"
30             android:layout_width="match_parent"
31             android:layout_height="wrap_content"
32             android:text="viewStub方式" />
33 
34         <ViewStub
35             android:id="@+id/viewstub"
36             android:layout_width="match_parent"
37             android:layout_height="wrap_content"
38             android:inflatedId="@+id/inflate_view_id"
39             android:layout="@layout/delay_by_viewstub" />
40     </LinearLayout>
41 
42 </ScrollView>

 

 

 

這是我們主界面xml中定義的ViewStub,需要注意的有三點:id->stub的id,根據這個取stub對象;inflatedId->擴展出的視圖id(即指向的視圖的id,可以不定義);layout->將要inflate的layout。好的,太直觀了,不用再解釋什么了。

有了存根,那么我們怎么在程序需要的時候取得?寥寥幾句,view輕松到手。

 1 package com.change.delayloaddemo;
 2 
 3 import android.app.Activity;
 4 import android.graphics.Color;
 5 import android.os.Bundle;
 6 import android.view.Menu;
 7 import android.view.View;
 8 import android.view.View.OnClickListener;
 9 import android.view.ViewStub;
10 import android.widget.Button;
11 import android.widget.LinearLayout;
12 import android.widget.TextView;
13 
14 /**
15  * 兩種延遲加載方式Demo android推薦采用viewStub方式。
16  * 
17  * @author Change
18  * 
19  */
20 public class MainActivity extends Activity implements OnClickListener {
21     private LinearLayout main;
22     private TextView normalInflate, delayByViewStub;
23     private ViewStub mStub;
24     private Button byInflate, byViewStub;
25 
26     @Override
27     protected void onCreate(Bundle savedInstanceState) {
28         super.onCreate(savedInstanceState);
29         setContentView(R.layout.activity_main);
30         initViews();
31     }
32     
33     private void initViews(){
34         main = (LinearLayout) findViewById(R.id.main);
35         byInflate = (Button)findViewById(R.id.btn_by_inflate);
36         byViewStub = (Button)findViewById(R.id.btn_by_viewstub);
37         
38         byInflate.setOnClickListener(this);
39         byViewStub.setOnClickListener(this);
40     }
41 
42     @Override
43     public boolean onCreateOptionsMenu(Menu menu) {
44         // Inflate the menu; this adds items to the action bar if it is present.
45         getMenuInflater().inflate(R.menu.main, menu);
46         return true;
47     }
48 
49     @Override
50     public void onClick(View arg0) {
51         switch (arg0.getId()) {
52         case R.id.btn_by_inflate:
53             normalInflate = (TextView) getLayoutInflater().inflate(
54                     R.layout.delay_by_viewstub, null);
55             main.addView(normalInflate);
56             normalInflate.setText("我是通常的inflate方法加載的view");
57             normalInflate.setBackgroundColor(Color.parseColor("#00ffff"));
58             break;
59         case R.id.btn_by_viewstub:
60             mStub = (ViewStub)findViewById(R.id.viewstub);
61             if(null!=mStub)//mStub執行了一次inflate()方法之后會被置空,所以此處判空
62             delayByViewStub = (TextView)mStub.inflate();
63 //            mStub.setVisibility(View.VISIBLE);//或者這樣可以inflate出view.
64             break;
65 
66         default:
67             break;
68         }
69     }
70 
71 }

以上紅色部分便是使用viewStub延遲加載的幾句代碼。

【需要注意的點】viewStub在執行完inflate()方法或者setVisibility(View.VISIBLE)方法之后會被置空,不能再使用該對象。

【完整代碼】demo的github地址:https://github.com/ChangeWu/SomePoject/tree/master/DelayLoadDemo

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM