[ACCEPTED]-How to check if a viewStub is already inflated?-viewstub
We can view the ViewStub
source code, the most important 4 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 3 in layout after inflate.so we can check 2 if a viewStub is already inflated by this 1 way.
if (mViewStub.getParent() != null) {
mViewStub.inflate();
} else {
mViewStub.setVisibility(View.VISIBLE);
}
if (mViewStub.getParent() != null) {
//have not been inflated
mViewStub.inflate();
} else {
//already inflated
}
0
note from google:
When a ViewStub is made 3 visible, or when inflate() is invoked, the layout 2 resource is inflated.
so you can check the 1 visibility (or even checking if it's "null").
A more simple approach, in Kotlin:
if (viewStub != null) {
viewStub.isVisible = true
} else {
// The view has been inflated already.
}
0
You can use this extension:
/**
* 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()
}
0
you can use this in Kotlin.. i know that 3 it uses tag (its not cool) but its easy 2 to use. this is kotlin extension function:
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)
}
}
and 1 you can use it like this :
myViewStub.doInflate({
//code that run with initialisation
}, {
//code that run if stub already inflated
})
As the documentation suggests, we should 4 not keep a long lived reference to the ViewStub, and 3 android also allows assigning an inflatedId
to ViewStub, which 2 comes into existence once its inflated
so 1 we can have a function signature like 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)
}
More Related questions
We use cookies to improve the performance of the site. By staying on our site, you agree to the terms of use of cookies.