0
点赞
收藏
分享

微信扫一扫

ViewStub用法

介绍

ViewStub 是一个轻量级的View,没有尺寸,不绘制任何东西,因此绘制或者移除时更省时(ViewStub不可见,大小为0)

优点

实现View的延迟加载,避免资源的浪费,减少渲染时间,在需要的时候才加载View

缺点

  • ViewStub所要替代的layout文件中不能有​​<merge>​​标签
  • ViewStub在加载完后会被移除,或者说是被加载进来的layout替换掉了

用法

<ViewStub
android:id="@+id/stub_import"
android:inflatedId="@+id/panel_import"
android:layout="@layout/progress_overlay"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom" />

用ViewStub加载layout文件时,可以调用setVisibility(View.VISIBLE) 或者 inflate()

((ViewStub) findViewById(R.id.stub_import)).setVisibility(View.VISIBLE);
// or
View importPanel = ((ViewStub) findViewById(R.id.stub_import)).inflate();

注意

  • 一旦ViewStub visible/inflated,则ViewStub将从视图框架中移除,其id stub_import 也会失效
  • ViewStub被绘制完成的layout文件取代,并且该layout文件的root view的id是android:inflatedId指定的id panel_import,root view的布局和ViewStub视图的布局保持一致

实例

layout_viewstub.xml

<!-- layout_viewstub.xml 要延迟加载的view -->
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout android:id="@+id/layout_viewstub_old"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:background="@android:color/darker_gray"
android:padding="5dp"
android:text="This is the layout instead of ViewStub view."/>

</LinearLayout>

act_test_viewstub.xml

<!-- act_test_viewstub.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:gravity="center_horizontal"
android:orientation="vertical">

<TextView
android:id="@+id/act_test_viewstub_tv_show"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:background="@android:color/darker_gray"
android:padding="5dp"
android:text="Show ViewStub"/>

<ViewStub
android:id="@+id/act_test_viewstub_viewstub"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inflatedId="@+id/act_layout_viewstub_new"
android:layout="@layout/layout_viewstub"/>

<!--<include-->
<!--android:layout_width="wrap_content"-->
<!--android:layout_height="wrap_content"-->
<!--layout="@layout/layout_viewstub"/>-->

</LinearLayout>

MainActivity

public class MainActivity extends AppCompatActivity {
private static final String TAG = "test_viewstub";
protected ViewStub mViewStub;

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

mViewStub = (ViewStub) findViewById(R.id.act_test_viewstub_viewstub);

findViewById(R.id.act_test_viewstub_tv_show).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
View layoutView;
layoutView = mViewStub.inflate();

Log.e(TAG, "mViewStub: " + mViewStub);
// ViewStub在visible/inflated后会被移除,所以此处为null
Log.e(TAG, "viewstub: " + findViewById(R.id.act_test_viewstub_viewstub));
//layoutView = findViewById(R.id.act_layout_viewstub_new);
Log.e(TAG, "layoutView equals finviewbyid(layout): " +
layoutView.equals(findViewById(R.id.act_layout_viewstub_new)));
Log.e(TAG, "layout: " + layoutView);

if (layoutView != null) {
// layoutView的root view id 是mViewStub inflatedId指定的ID
if (layoutView.getId() == R.id.act_layout_viewstub_new) {
Log.e(TAG, "layout root id is act_layout_viewstub_new");
} else if (layoutView.getId() == R.id.layout_viewstub_old) {
Log.e(TAG, "layout root id is layout_viewstub_old");
} else {
Log.e(TAG, "layout root id is anyone : " + layoutView.getId());
}

// layoutView的root view布局 和mViewStub的布局保持一致
int width = layoutView.getLayoutParams().width;
if (width == ViewGroup.LayoutParams.MATCH_PARENT) {
Log.e(TAG, "layout width is MATCH_PARENT");
} else if (width == ViewGroup.LayoutParams.WRAP_CONTENT) {
Log.e(TAG, "layout width is WRAP_CONTENT");
} else {
Log.e(TAG, "layout width is anyone : " + width);
}
}
}
});
}

}

ViewStub用法_android


在窗口中存在一个默认的帧布局, 界面中的帧布局,放入窗口默认帧布局显示, 会嵌套两层帧布局

这样是没有必要的,正确做法是,把帧布局中的控件直接添加到默认帧布局中

merge主要是进行UI布局的优化的,删除多余的层级,优化UI。多用于替换frameLayout或者当一个布局包含另一个布局的时候,标签用于消除师徒层次结构中多余的视图组

标签也就是排除一个布局插入另一个布局产生的多余的viewgroup

用法1

<merge
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.xy.csdnproject.FrameLayoutActivity">

<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="button1"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="button2"
/>

</merge>

布局的效果<这里注意是frameLayout的效果>,android有一个默认的FrameLayout的布局

ViewStub用法_xml_02

用法2

当把有标签的布局放在中的时候,就会忽视

<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.xy.csdnproject.FrameLayoutActivity">

<include layout="@layout/activity_merge_layout"/>

</LinearLayout>

效果

ViewStub用法_viewstub_03

限时
只能作为XML布局的根标签使用。

当Inflate以开头的布局文件时,必须指定一个父ViewGroup,并且必须设定attachToRoot为true。

作者:蚊子Skeeter

举报

相关推荐

0 条评论