世風日下,人心不古。
如今四海雖看似太平,其實卻暗藏殺機。大到一架飛機一輛公交,小到一個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