ViewStub使用

介绍

ViewStub是一个轻量级的view。官方解释如下

    A ViewStub is an invisible, zero-sized View that can be used to lazily inflate layout resources at runtime. 
    When a ViewStub is made visible, or when inflate() is invoked, the layout resource is inflated. 
Therefore, the ViewStub exists in the view hierarchy until setVisibility(int) or inflate() is invoked. 
Similarly, you can define/override the inflate View's id by using the ViewStub's inflatedId property. 

本人翻译功底较差,就不误导大家了,相信大家能明白大概意思。

应用场景

在开发应用程序的时候,经常会遇到这样的情况,会在运行时动态根据条件来决定显示哪个View或某个布局。那么最通常的想法就是把可能用到的View都写在上面,先把它们的可见性都设为View.GONE,然后在代码中动态的更改它的可见性。这样的做法的优点是逻辑简单而且控制起来比较灵活。但是它的缺点就是,耗费资源。虽然把View的初始可见View.GONE但是在Inflate布局的时候View仍然会被Inflate,也就是说仍然会创建对象,会被实例化,会被设置属性。也就是说,会耗费内存等资源。
ViewStub是一个轻量级的View,看不见的,不占布局位置,占用资源非常小的控件。可以为ViewStub指定一个布局,在Inflate布局的时候,只有ViewStub会被初始化,然后当ViewStub被设置为可见的时候,或是调用了ViewStub.inflate()的时候,ViewStub所向的布局就会被Inflate和实例化,然后ViewStub的布局属性都会传给它所指向的布局。这样,就可以使用ViewStub来方便的控制某个布局是否显示。

特点

  • 实现View的延迟加载,避免资源的浪费,减少渲染时间,在需要的时候才加载View
  • ViewStub所要替代的layout文件中不能有标签
  • ViewStub只能Inflate一次,之后ViewStub对象会被置为空。按句话说,某个被ViewStub指定的布局被Inflate后,就不会够再通过ViewStub来控制它了。
  • 所以当需要在运行时不止一次的显示和隐藏某个布局,那么ViewStub是做不到的。这时就只能使用View的可见性来控制了。

注意事项

  • 判断是否已经加载过, 如果通过setVisibility来加载,那么通过判断可见性即可;如果通过inflate()来加载是不可以通过判断可见性来处理的,而需要使用方式2来进行判断。
  • findViewById的问题,注意ViewStub中是否设置了inflatedId,如果设置了则需要通过inflatedId来查找目标布局的根元素

使用方法

<ViewStub android:id="@+id/stub"
               android:inflatedId="@+id/subTree"
               android:layout="@layout/mySubTree"
               android:layout_width="120dip"
               android:layout_height="40dip" />
The ViewStub thus defined can be found using the id "stub." After inflation of the layout resource "mySubTree," 
specified by the inflatedId property. The inflated View is finally assigned a width of 120dip and a height of 40dip.
 The preferred way to perform the inflation of the layout resource is the following:
 ViewStub stub = findViewById(R.id.stub);
     View inflated = stub.inflate();
When inflate() is invoked, the ViewStub is replaced by the inflated View and the inflated View is returned. 
This lets applications get a reference to the inflated View without executing an extra findViewById().

例子

public class MainActivity extends Activity {

    View inflated;
    ViewStub stub;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        stub = (ViewStub)findViewById(R.id.stub);

        //stub.setLayoutResource(R.layout.content_main);
        //setLayoutResource方法可以动态更改inflate的layout
        Button button = (Button)findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if(stub!=null && stub.getParent()!=null){
                    inflated = stub.inflate();
                }else{
                    System.out.println(" stub is NULL");
                    inflated.setVisibility(inflated.getVisibility() == View.VISIBLE ? View.GONE :View.VISIBLE);
                }


            }
        });

    }
}

activity_main:

<LinearLayout
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:gravity="center"
      android:orientation="vertical">
      <TextView
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:textSize="20dp"
          android:text="Hello World"/>

      <ViewStub android:id="@+id/stub"
          android:inflatedId="@+id/subTree"
          android:layout="@layout/my_sub_tree"
          android:layout_width="120dip"
          android:layout_height="40dip" />
      <Button
          android:id="@+id/button"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:text="submit"/>
  </LinearLayout>

my_sub_tree:

<?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">
    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="20dp"
        android:textColor="@android:color/holo_red_dark"
        android:text="动态加载的layout"/>
</LinearLayout>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值