19

我没有发现任何布尔方法可以完成此任务。我可以通过检查 的 是否更改为指定为 来做到这id一点viewStubinflatedid

Java代码:

    protected void plantViewTree() {
    // TODO Auto-generated method stub

        ViewStub mViewstub = (ViewStub) findViewById(R.id.viewStub00);

            if (mViewStub is inflated) {
              //do somthing
              }else
               mViewstub.inflate();

}

更新 关于 eOutput 的评论

根据此代码,toast始终显示其消息,这意味着由于mViewStub分配给findViewById它永远不会为空,除非viewstub底层 alyout 中的视图不可用。有什么建议么。?

protected void plantViewTree() {
    // TODO Auto-generated method stub
    ViewStub mViewstub = (ViewStub) findViewById(R.id.viewStub00);
    if (mViewstub != null)
        Toast.makeText(getApplicationContext(), "view is inflated", 
Toast.LENGTH_LONG).show();
    else
        mViewstub.inflate();
}
4

9 回答 9

30

We can view the ViewStub source code, the most important method is inflate(),

 public View inflate() {
    final ViewParent viewParent = getParent();

    if (viewParent != null && viewParent instanceof ViewGroup) {
        if (mLayoutResource != 0) {
            final ViewGroup parent = (ViewGroup) viewParent;
            final LayoutInflater factory;
            if (mInflater != null) {
                factory = mInflater;
            } else {
                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>(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");
    }
}

Notice this line parent.removeViewInLayout(this) ,it had removed in layout after inflate.so we can check if a viewStub is already inflated by this way.

if (mViewStub.getParent() != null) {
    mViewStub.inflate();
} else {
    mViewStub.setVisibility(View.VISIBLE);
}
于 2015-02-06T10:27:56.607 回答
6
if (mViewStub.getParent() != null) { 
    //have not been inflated
    mViewStub.inflate();
} else { 
    //already inflated
}
于 2017-09-07T08:07:34.220 回答
3

来自谷歌的注释:

当 ViewStub 可见,或者调用 inflate() 时,布局资源会膨胀。

因此您可以检查可见性(甚至检查它是否为“null”)。

于 2014-05-21T12:44:02.567 回答
1

更简单的方法,在 Kotlin 中:

if (viewStub != null) {
   viewStub.isVisible = true
} else {
   // The view has been inflated already.
}
于 2018-07-09T02:25:32.530 回答
0

正如文档所暗示的那样,我们不应该对 ViewStub 进行长期引用,并且 android 还允许将一个分配inflatedId给 ViewStub,一旦它膨胀,它就会存在

所以我们可以有一个函数签名,比如getInflatedView(): View

fun getInflatedView(@LayoutRes layoutId: Int): View {
    val stub: ViewStub? = findViewById(R.id.stubId)
    stub?.layoutResource = layoutId
    return stub?.inflate() ?: findViewById(R.id.inflatedId)
}
于 2019-06-04T19:38:07.247 回答
0

你可以使用这个扩展:

/**
 * To prevent crash when we try inflate view that was already inflated. Because OS delete ViewStub by inflating.
 */
fun ViewStub?.safeInflate() {
    if (this?.parent != null) inflate()
}
于 2021-02-01T14:57:42.113 回答
0

你可以在 Kotlin 中使用它。我知道它使用标签(它不酷)但它易于使用。这是 kotlin 扩展功能:

fun ViewStub.doInflate(init: View.() -> Unit = {}, action: (View) -> Unit = {}) {
val isInflated = (tag as? Boolean) ?: false
if (!isInflated) {
    setOnInflateListener { _, view ->
        this.tag = true
        init.invoke(view)
        action.invoke(view)
    }
    this.inflate()
} else {
    action.invoke(this.rootView)
}

}

你可以像这样使用它:

 myViewStub.doInflate({
            //code that run with initialisation
        }, {
           //code that run if stub already inflated
        })
于 2018-12-23T06:12:28.397 回答
-1

打电话给yourViewStub.visibility(View.VISIBLE)你不需要检查它是否膨胀。

于 2016-08-05T02:30:34.197 回答
-5

我使用flags. 我声明了一个全局布尔变量isInflatedBefore,最初设置为false

代码:

//declaration of the variable
private boolean isInflatedBefore = false

...
... 
...

protected void plantViewTree() {
    // TODO Auto-generated method stub

    ViewStub mViewstub = (ViewStub) findViewById(R.id.viewStub00);

    if (! isInflatedBefore) {
        isInflatedBefore = true;
        mViewstub.inflate();
              }else {
                //some code
               }
于 2014-05-21T15:39:54.353 回答