MongoDB指南/引言
Android鬼點子系列隆重登場,這個系列主要講述的一些在開發中可能會提高程序質量,或者提高開發效率的鬼點子!第一篇就來說說ViewStub。
讓View進行延遲加載這件事,在實際開發的嘗盡中是很常見的。比如,在一個ListView中,使用了2級菜單。點擊了一個Item中的按鈕,以個Item就會展開,這里展開的內容就是咱們說到的延遲加載的內容。這樣做的好處就是提高渲染效率,減少內存消耗。
ViewStub是一個不可視并且大小為0的視圖,可以延遲到運行時填充布局資源。當ViewStub設置為Visible或調用inflate()之后,就會填充布局資源,ViewStub便會被填充的視圖替代。以上是官方介紹。
下面寫一個簡單的例子。界面上放一個Button,點擊Button,打開隱藏的部分。
布局文件文件中使用了include標簽,使用include標簽是為了避免代碼的重復。后面會介紹include標簽與marge標簽的區別。
mainactivity.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<include layout="@layout/item"></include>
</LinearLayout>
item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/bt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="點擊打開"/>
<ViewStub
android:id="@+id/vs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout="@layout/item2"
android:inflatedId="@+id/item2"/>
</LinearLayout>
item2.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="延遲加載的內容"
android:layout_alignParentTop="true"
android:layout_alignParentStart="true"
android:layout_marginStart="129dp"
android:id="@+id/textView" />
</RelativeLayout>
在mainactivity.xml中使用了include標簽引入了item.xml,在item.xml中有一個ViewStub,注意android:layout=”@layout/item2” 這里就是指明需要延遲加載的layout,android:inflatedId=”@+id/item2”是延遲加載后得到的Layout的Id。
public class MainActivity extends Activity {
ViewStub mViewStub;
Button mButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.mainactivity);
initView();
}
private void initView() {
mViewStub = (ViewStub)findViewById(R.id.vs);
mButton = (Button) findViewById(R.id.bt);
mButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mViewStub.inflate();
}
});
}
}
mViewStub.inflate();就是執行加載操作。這里使用mViewStub.setVisibility(View.VISIBLE);替代,也會達到相同想效果。如果想繼續操作延遲加載后得到的Layout怎么辦?
public class MainActivity extends Activity {
ViewStub mViewStub;
Button mButton;
TextView tv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.mainactivity);
initView();
}
private void initView() {
mViewStub = (ViewStub)findViewById(R.id.vs);
mButton = (Button) findViewById(R.id.bt);
mButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v)
mViewStub.inflate();
//mViewStub.setVisibility(View.VISIBLE);
tv = (TextView) (findViewById(R.id.item2).findViewById(R.id.textView));
tv.setText("……");
}
});
}
}
marege標簽與include標簽,個人理解,include的進來的布局是要有一個根布局的,比如item.xml中最外層的LinearLayout,但是mainactivity.xml的最外層已經是LinearLayout了,include進來的布局不需要再額外增加一層了,這樣會影響渲染效率。這里就可以用到merge標簽了。
使用了merge標簽的item.xml
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<Button
android:id="@+id/bt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="點擊打開"/>
<ViewStub
android:id="@+id/vs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout="@layout/item2"
android:inflatedId="@+id/item2"/>
</merge>
注意這里沒有給出layout_width和layout_height信息,所以這兩個信息需要在include標簽中給出。
mainactivity.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<include layout="@layout/item"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
</include>
</LinearLayout>
以上就通過merge標簽的使用減少了一個繪制層級。