在Android开发中,View是我们必须要接触的用来展示的技术.通常情况下随着View视图的越来越复杂,整体布局的性能也会随之下降.这里介绍一个在某些场景下提升布局性能的View,它就是ViewStub.

让客户满意是我们工作的目标,不断超越客户的期望值来自于我们对这个行业的热爱。我们立志把好的技术通过有效、简单的方式提供给客户,将通过不懈努力成为客户在信息化领域值得信任、有价值的长期合作伙伴,公司提供的服务项目有:域名注册、网站空间、营销软件、网站建设、银川网站维护、网站推广。
ViewStub是什么
注,关于Stub的解释
A stub is a small program routine that substitutes for a longer program, possibly to be loaded later or that is located remotely
在Java中,桩是指用来代替关联代码或者未实现代码的代码.
ViewStub使用场景
如上图所示,
所以,这时候就ViewStub就派上用处了.使用ViewStub可以延迟加载布局资源.
ViewStub 怎么用
1.在布局文件中使用ViewStub标签
- 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"
 - android:paddingLeft="@dimen/activity_horizontal_margin"
 - android:paddingRight="@dimen/activity_horizontal_margin"
 - android:paddingTop="@dimen/activity_vertical_margin"
 - android:paddingBottom="@dimen/activity_vertical_margin"
 - tools:context="com.droidyue.viewstubsample.MainActivity">
 
2.在代码中inflate布局
- ViewStub myViewStub = (ViewStub)findViewById(R.id.myViewStub);
 - if (myViewStub != null) {
 - myViewStub.inflate();
 - //或者是下面的形式加载
 - //myViewStub.setVisibility(View.VISIBLE);
 - }
 
关于ViewStub的事
ViewStub的不足
官方的文档中有这样一段描述
Note: One drawback of ViewStub is that it doesn’t currently support the tag in the layouts to be inflated.
意思是ViewStub不支持 标签.
关于不支持 标签的程度,我们进行一个简单的验证
验证一:直接 标签
如下,我们有布局文件名为merge_layout.xml
替换对应的ViewStub的android:layout属性值之后,运行后(点击Button按钮)得到产生了如下的崩溃
- E AndroidRuntime: android.view.InflateException: Binary XML file line #1:
 can be used only with a valid ViewGroup root and attachToRoot=true - E AndroidRuntime: at android.view.LayoutInflater.inflate(LayoutInflater.java:551)
 - E AndroidRuntime: at android.view.LayoutInflater.inflate(LayoutInflater.java:429)
 - E AndroidRuntime: at android.view.ViewStub.inflate(ViewStub.java:259)
 - E AndroidRuntime: at com.droidyue.viewstubsample.MainActivity$1.onClick(MainActivity.java:20)
 - E AndroidRuntime: at android.view.View.performClick(View.java:5697)
 - E AndroidRuntime: at android.widget.TextView.performClick(TextView.java:10815)
 - E AndroidRuntime: at android.view.View$PerformClick.run(View.java:22526)
 - E AndroidRuntime: at android.os.Handler.handleCallback(Handler.java:739)
 - E AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:95)
 - E AndroidRuntime: at android.os.Looper.loop(Looper.java:158)
 - E AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:7237)
 - E AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method)
 - E AndroidRuntime: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
 - E AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
 - E AndroidRuntime: Caused by: android.view.InflateException:
 can be used only with a valid ViewGroup root and attachToRoot=true - E AndroidRuntime: at android.view.LayoutInflater.inflate(LayoutInflater.java:491)
 - E AndroidRuntime: ... 13 more
 
可见,直接的 标签,ViewStub是不支持的.
验证二 间接的ViewStub
下面布局间接使用了merge标签.文件名为 include_merge.xml
- android:orientation="vertical"
 - android:layout_width="match_parent"
 - android:layout_height="match_parent">
 
然后修改ViewStub的 android:layout 值,运行,一切正常.
除此之外,本例也验证了ViewStub也是对 标签支持良好的.
关于ViewStub的一点代码剖析
inflate vs setVisibility
inflate和setVisibility的共同点是都可以实现加载布局
- /** * When visibility is set to {@link #VISIBLE} or {@link #INVISIBLE},
 - * {@link #inflate()} is invoked and this StubbedView is replaced in its parent
 - * by the inflated layout resource.
 - *
 - * @param visibility One of {@link #VISIBLE}, {@link #INVISIBLE}, or {@link #GONE}.
 - *
 - * @see #inflate()
 - */
 - @Override
 - public void setVisibility(int visibility) {
 - if (mInflatedViewRef != null) {
 - View view = mInflatedViewRef.get();
 - if (view != null) {
 - view.setVisibility(visibility);
 - } else {
 - throw new IllegalStateException("setVisibility called on un-referenced view");
 - }
 - } else {
 - super.setVisibility(visibility);
 - if (visibility == VISIBLE || visibility == INVISIBLE) {
 - inflate();
 - }
 - }
 - }
 
setVisibility只是在ViewStub***次延迟初始化时,并且visibility是非 GONE 时,调用了 inflate 方法.
inflate源码
通过阅读下面的inflate方法实现,我们将更加理解
- /** * Inflates the layout resource identified by {@link #getLayoutResource()}
 - * and replaces this StubbedView in its parent by the inflated layout resource.
 - *
 - * @return The inflated layout resource.
 - *
 - */
 - public View inflate() {
 - final ViewParent viewParent = getParent();
 - if (viewParent != null && viewParent instanceof ViewGroup) {
 - if (mLayoutResource != 0) {
 - final ViewGroup parent = (ViewGroup) viewParent;
 - final LayoutInflater factory = LayoutInflater.from(mContext);
 - final View view = factory.inflate(mLayoutResource, parent,
 - false);
 - if (mInflatedId != NO_ID) {
 - view.setId(mInflatedId);
 - }
 - final int index = parent.indexOfChild(this);
 - parent.removeViewInLayout(this);
 - final ViewGroup.LayoutParams layoutParams = getLayoutParams();
 - if (layoutParams != null) {
 - parent.addView(view, index, layoutParams);
 - } else {
 - parent.addView(view, index);
 - }
 - mInflatedViewRef = new WeakReference
 (view); - if (mInflateListener != null) {
 - mInflateListener.onInflate(this, view);
 - }
 - return view;
 - } else {
 - throw new IllegalArgumentException("ViewStub must have a valid layoutResource");
 - }
 - } else {
 - throw new IllegalStateException("ViewStub must have a non-null ViewGroup viewParent");
 - }
 - }
 
                本文题目:Android使用ViewStub提高布局性能
                
                URL分享:http://www.csdahua.cn/qtweb/news8/545758.html
            
网站建设、网络推广公司-快上网,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 快上网