关闭

用ViewStub优化布局

标签: Android布局优化
359人阅读 评论(0) 收藏 举报
分类:

Google有关ViewStub 的介绍:

“ViewStub 是一种不可视并且大小为 0 的视图,可以延迟到 运行时填充(inflate)布局资源。当 ViewStub
设置为可视或者 inflate() 方法被调用后,就会填充布局资源,然后 ViewStub 便会 被填充的视图替代。”
使用特点:

  • 最佳用途就是实现View的延迟加载,避免资源浪费,在需要的时候才加载View
  • 如果是经常要来回切换ViewStub的显示和隐藏,ViewStub就不适用

先看一个简单的代码:

MainActivity

public class MainActivity extends AppCompatActivity {
    private Button mBtnShow;
    private ViewStub mViewStub;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mBtnShow = (Button) findViewById(R.id.btn_show);
        mViewStub = (ViewStub) findViewById(R.id.viewStub);
        mBtnShow.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //两种方法都可以显示ViewStub中的内容
//                mViewStub.inflate();
                mViewStub.setVisibility(View.VISIBLE);
            }
        });
    }
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <Button
        android:id="@+id/btn_show"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Show ViewStub"
        android:textAllCaps="false" />

    <ViewStub
        android:id="@+id/viewStub"
        android:layout="@layout/content"
        android:layout_width="match_parent"
        android:layout_height="300dp"
        android:inflatedId="@+id/content_stub" />

</LinearLayout>

content.xml

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/tv_content"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/colorAccent"
    android:text="ViewStub 是一种不可视并且大小为 0 的视图,可以延迟到 运行时填充(inflate)布局资源。当 ViewStub
设置为可视或者 inflate() 方法被调用后,就会填充布局资源,然后 ViewStub 便会 被填充的视图替代。"
    tools:showIn="@layout/activity_main" />

这就是ViewStub的简单使用

需要注意两个异常:

java.lang.IllegalArgumentException: ViewStub must have a valid layoutResource

android:layout=”@layout/content”
ViewStub标签里面用的@layout 前面是android:layout include里面是layout
写错了会抛出上面的异常

java.lang.IllegalStateException: ViewStub must have a non-null ViewGroup viewParent

当ViewStub inflate后,这个ViewStub就从View层次中移除了。(findViewById(R.id.viewStub)也会返回null)
所以MainActivity中mViewStub.inflate(); 应该这样写:

public class MainActivity extends AppCompatActivity {
    private Button mBtnShow;
    private ViewStub mViewStub;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mBtnShow = (Button) findViewById(R.id.btn_show);
        mBtnShow.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mViewStub = (ViewStub) findViewById(R.id.viewStub);
                if (mViewStub != null) {
                    mViewStub.inflate();
                }
            }
        });
    }
}

inflate()和setVisibility(View.VISIBLE);

这两个放到都可以显示ViewStub的视图
setVisibility(View.VISIBLE)会调用inflate()方法
inflate()方法可以返回当前的View

 View stubView = mViewStub.inflate();

ViewStub中的layout_width 和 layout_height

来上一张图:
这里写图片描述
我在ViewStub标签里面的width和height如下:

android:layout_width="match_parent"
android:layout_height="300dp"

在@layout/content中如下

android:layout_width="match_parent"
android:layout_height="match_parent"

可以看到, ViewStub标签里面的width和height属性会覆盖掉填充的布局的属性.

android:inflatedId=”@+id/content_stub”

mBtnShow.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mViewStub = (ViewStub) findViewById(R.id.viewStub);
                if (mViewStub != null) {
                    mViewStub.inflate();
                    ((TextView) findViewById(R.id.content_stub)).setText("我只是一个不明真相的吃瓜群众");
                }
            }
        });

现在把 android:inflatedId=”@+id/content_stub” 去掉

mBtnShow.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mViewStub = (ViewStub) findViewById(R.id.viewStub);
                if (mViewStub != null) {
                    mViewStub.inflate();
                    ((TextView) findViewById(R.id.tv_content)).setText("我只是一个不明真相的吃瓜群众");
                }
            }
        });

这里写图片描述

可以看到, android:inflatedId=”@+id/content_stub”会覆盖content.xml中根元素的id属性, 这个属性可以不添加.

再看这里

 mBtnShow.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mViewStub = (ViewStub) findViewById(R.id.viewStub);
                if (mViewStub != null) {
                    ((TextView) mViewStub.inflate()).setText("我只是一个不明真相的吃瓜群众");
                }
            }
        });

可以看到, mViewStub.inflate()返回的也是content.xml中的TextView.(content.xml的根元素)

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:148926次
    • 积分:2513
    • 等级:
    • 排名:第16413名
    • 原创:104篇
    • 转载:6篇
    • 译文:0篇
    • 评论:25条
    文章分类
    最新评论