如何检查 viewStub 是不是已经膨胀?
Posted
技术标签:
【中文标题】如何检查 viewStub 是不是已经膨胀?【英文标题】:How to check if a viewStub is already inflated?如何检查 viewStub 是否已经膨胀? 【发布时间】:2014-05-21 12:25:29 【问题描述】:我没有找到任何布尔方法来完成这项任务。我可以通过检查 viewStub
的 id
是否更改为指定为 inflatedid
的那个来做到这一点吗?
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
,它永远不会为空,除非底层 alyout 中的 viewstub
视图不可用。有什么建议吗?
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();
【问题讨论】:
如果不充气,则为空。你可以检查它是否为空。 @Eu.Dr.请看更新 【参考方案1】:我们可以查看ViewStub
源码,最重要的方法是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");
注意这一行parent.removeViewInLayout(this)
,它在inflate之后在布局中被删除了。所以我们可以通过这种方式检查viewStub是否已经被inflate。
if (mViewStub.getParent() != null)
mViewStub.inflate();
else
mViewStub.setVisibility(View.VISIBLE);
【讨论】:
查看viewstub是否完成了它的工作只是检查,mViewStub.getParent() != null,如果它没有完成它的工作父将是!= null否则父将是null【参考方案2】:if (mViewStub.getParent() != null)
//have not been inflated
mViewStub.inflate();
else
//already inflated
【讨论】:
【参考方案3】:来自谷歌的注释:
当 ViewStub 可见,或调用 inflate() 时, 布局资源被夸大了。
这样您就可以检查可见性(甚至检查它是否为“null”)。
【讨论】:
这不是真的,viewstub 在膨胀时不为空【参考方案4】:一种更简单的方法,在 Kotlin 中:
if (viewStub != null)
viewStub.isVisible = true
else
// The view has been inflated already.
【讨论】:
【参考方案5】:你可以在 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
)
【讨论】:
【参考方案6】:正如文档所暗示的,我们不应该对 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)
【讨论】:
【参考方案7】:你可以使用这个扩展:
/**
* 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()
【讨论】:
【参考方案8】:致电yourViewStub.visibility(View.VISIBLE)
,您无需检查它是否充气。
【讨论】:
得到了同样的迷恋。【参考方案9】:我使用flags
解决了这个问题。我声明了一个全局布尔变量isInflatedBefore
set
最初是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
【讨论】:
以上是关于如何检查 viewStub 是不是已经膨胀?的主要内容,如果未能解决你的问题,请参考以下文章
我们可以通过检查 isRegisteredForLocalNotifications 从 didRegisterForRemoteNotificationsWithDeviceToken 更新 Vie