Android鬼点子-使用ViewStub进行延迟加载


       Android鬼点子系列隆重登场,这个系列主要讲述的一些在开发中可能会提高程序质量,或者提高开发效率的鬼点子!第一篇就来说说ViewStub。

       让View进行延迟加载这件事,在实际开发的尝尽中是很常见的。比如,在一个ListView中,使用了2级菜单。点击了一个Item中的按钮,以个Item就会展开,这里展开的内容就是咱们说到的延迟加载的内容。这样做的好处就是提高渲染效率,减少内存消耗。

       ViewStub是一个不可视并且大小为0的视图,可以延迟到运行时填充布局资源。当ViewStub设置为Visible或调用inflate()之后,就会填充布局资源,ViewStub便会被填充的视图替代。以上是官方介绍。

       下面写一个简单的例子。界面上放一个Button,点击Button,打开隐藏的部分。

       布局文件文件中使用了include标签,使用include标签是为了避免代码的重复。后面会介绍include标签与marge标签的区别。


mainactivity.xml

1
2
3
4
5
6
7
<?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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?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。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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怎么办?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?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

1
2
3
4
5
6
7
8
9
10
<?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标签的使用减少了一个绘制层级。

文章目录
|