标签:android ui 布局优化 viewstub 延时加载
New UI-<ViewStub>标签延时加载布局
——转载请注明出处:coder-pig,欢迎转载,请勿用于商业用途!
小猪Android开发交流群已建立,欢迎大家加入,无论是新手,菜鸟,大神都可以,小猪一个人的
力量毕竟是有限的,写出来的东西肯定会有很多纰漏不足,欢迎大家指出,集思广益,让小猪的博文
更加的详尽,帮到更多的人,O(∩_∩)O谢谢!
小猪Android开发交流群:小猪Android开发交流群群号:421858269
新Android UI实例大全目录:http://blog.csdn.net/coder_pig/article/details/42145907
本节引言:
学习完上一节的include布局复用以后,相信大家都体会到了布局优化的好处,
不过当我们include的布局是一些复杂控件的话,而这些控件我们在实际使用
过程中又用得不多的话,往往会降低页面的加载速度;虽然,我们也可以为其设置
visibility = "gone"的属性,但是在inflate布局的时候,这些控件依旧会被inflate,
也就是说依旧会创建对象,会被实例化,设置属性等,依旧会耗费内存资源,
那么在本节中,我们就来介绍一个轻量级的view: ViewStub
让你的布局在你需要的时候再加载(延时加载)
好了,开始本节内容~
本节正文:
ViewStub是一个轻量级的View,在布局中不占用任何控件,也不参加
布局的计算与绘制(又叫渲染),可以理解为控件树上的一个占位符,
仅仅是占着那个位置,没有东西,当我们需要的时候,他才会被渲染(加载)
到主界面上,这种行为也叫做延迟加载,也有人称为"惰性的include"
当我们的app中某个布局,我们并不需要把所有的内容都展示出来,可以隐藏一些View视图,
等需要展示的时候再加载,这个时候就可以用到ViewStub了,有点类似于visibility = "gone",
但是不会随布局进行加载,使用例子如下:(点击listview的item后才加载下方的布局)
<ViewStub
android:id="@+id/stub_add"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:inflatedId="@+id/ly_add"
android:layout="@layout/ly_test" />①id:设置ViewStub的引用id
②inflatedId:设置加载后的布局对应的id
③layout:要加载的那个布局
ps:第二个属性是可选的,当我们的ViewStub加载后,我们就可以直接通过findViewById(R.id.~)
找到加载的那个布局的对应的对象,~是inflatedId的id!因为ViewStub只能用一次!!!!
方法一:通过findViewById找到ViewStub对象后,调用该对象的inflate()方法:
ViewStub stub = (ViewStub) findViewById(R.id.stub_add);
stub.inflate();
方法二:通过改变ViewStub对象的visibility属性
ViewStub stub = (ViewStub) findViewById(R.id.stub_add);
stub.setVisibility(View.VISIBLE);
上面写完后,我们如果获得加载布局的对应对象的话,则要通过findViewById(R.id.inflatedId里的id);
找到对应的布局对象了:
View ly_add = (View)findViewById(R.id.ly_add);
处了上面这种写法还,还有一种写法:
因为ViewStub加载完他引用的布局后,他会从控件树中移除,
所以如果你想对引入后的布局进行相关操作的话,那么还是拿一个View来
放着这个布局吧!所以也可以用下面这种写法:
ViewStub stub = (ViewStub) findViewById(R.id.stub_add);
View view = stub.inflate();
或者:
ViewStub stub = (ViewStub) findViewById(R.id.stub_add);
View view = stub.setVisibility(View.VISIBLE);
好了,至于用哪种,你自己喜欢了!
1)ViewStub只能inflate一次,之后ViewStub对象会被置空所以在编写代码
的时候,就不要使用生命周期很长的变量来引用ViewStub控件了,按照上面的教的写法即可!
2)ViewStub加载的只能是布局文件的id,而非某个View
从"惰性include"这个别名,我们就可以知道ViewStub和include其实是类似的
不过前者并不随着布局的渲染和渲染,而是,在我们Inflate或设置Visibility为VISIBLE时
才渲染,而且只用一次,针对的是一次性的东西,在ListView那里用得较多,
当然见仁见智,这里就演示下简单的用法吧:
效果图:
报错结束了,恩,别着急,先贴下代码:
actvitiy_main.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/LinearLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.jay.example.test.MainActivity" >
<Button
android:id="@+id/btnLoad"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="加载ViewStub" />
<Button
android:id="@+id/btnHide"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="隐藏加载的布局" />
<Button
android:id="@+id/btnShow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="显示加载的布局" />
<ViewStub
android:id="@+id/stub_add"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:inflatedId="@+id/ly_add"
android:layout="@layout/ly_test" />
</LinearLayout><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/LinearLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.jay.example.test.MainActivity"
android:gravity="center">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/back"
android:text="用于测试的ViewStub引入的布局"
android:textColor="#FFFFFF"
android:gravity="center_vertical"
android:textSize="18sp"/>
</LinearLayout>
package com.jay.example.test;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewStub;
import android.widget.Button;
public class MainActivity extends Activity {
private Button btnLoad;
private Button btnHide;
private Button btnShow;
private MyClick myClick;
private ViewStub viewStub;
private View view;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViews();
setUpViews();
}
private void findViews() {
btnLoad = (Button) findViewById(R.id.btnLoad);
btnHide = (Button) findViewById(R.id.btnHide);
btnShow = (Button) findViewById(R.id.btnShow);
}
private void setUpViews() {
myClick = new MyClick();
btnLoad.setOnClickListener(myClick);
btnHide.setOnClickListener(myClick);
btnShow.setOnClickListener(myClick);
}
private class MyClick implements OnClickListener {
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btnLoad:
viewStub = (ViewStub) findViewById(R.id.stub_add);
view = viewStub.inflate();
break;
case R.id.btnHide:
view.setVisibility(View.INVISIBLE);
break;
case R.id.btnShow:
view.setVisibility(View.VISIBLE);
break;
}
}
}
}
代码分析:
代码很简单,要说的问题就是为什么两次加载ViewStub会报错,而且还报了
NullPointerException,这是因为ViewStub只能够inflate一次,用完就没咯
所以后面实现的隐藏和显示的实现就是控制——引入的布局对象!!!
最后说两句:
关于这个ViewStub的使用很简单但也很重要,可能你现在不觉得,但慢慢界面上控件多了,
就知道了,厚积薄发!加油~
本节参考文献:
http://www.cnblogs.com/plokmju/p/android_viewstub.html
http://blog.csdn.net/mayingcai1987/article/details/6238609
http://blog.csdn.net/hitlion2008/article/details/6737537
https://developer.android.com/reference/android/view/ViewStub.html
标签:android ui 布局优化 viewstub 延时加载
原文地址:http://blog.csdn.net/coder_pig/article/details/43234867