inflate()
的时候,布局就会被加载(替换 ViewStub)。因此,ViewStub 一直存在于视图层次结构中直到调用了 setVisibility(int)
或 inflate()
。 final TypedArray a = context.obtainStyledAttributes(attrs,
R.styleable.ViewStub, defStyleAttr, defStyleRes);
// 要被加载的布局 Id
mInflatedId = a.getResourceId(R.styleable.ViewStub_inflatedId, NO_ID);
// 要被加载的布局
mLayoutResource = a.getResourceId(R.styleable.ViewStub_layout, 0);
// ViewStub 的 Id
mID = a.getResourceId(R.styleable.ViewStub_id, NO_ID);
a.recycle();
// 初始状态为 GONE
setVisibility(GONE);
// 设置为不会绘制
setWillNotDraw(true);
}
```
if (viewParent != null && viewParent instanceof ViewGroup) {
// 如果没有指定布局,就会抛出异常
if (mLayoutResource != 0) {
// viewParent 需为 ViewGroup
final ViewGroup parent = (ViewGroup) viewParent;
final LayoutInflater factory;
if (mInflater != null) {
factory = mInflater;
} else {
// 如果没有指定 LayoutInflater
factory = LayoutInflater.from(mContext);
}
// 获取布局
final View view = factory.inflate(mLayoutResource, parent,
false);
// 为 view 设置 Id
if (mInflatedId != NO_ID) {
view.setId(mInflatedId);
}
// 计算出 ViewStub 在 parent 中的位置
final int index = parent.indexOfChild(this);
// 把 ViewStub 从 parent 中移除
parent.removeViewInLayout(this);
// 接下来就是把 view 加到 parent 的 index 位置中
final ViewGroup.LayoutParams layoutParams = getLayoutParams();
if (layoutParams != null) {
// 如果 ViewStub 的 layoutParams 不为空
// 就设置给 view
parent.addView(view, index, layoutParams);
} else {
parent.addView(view, index);
}
// mInflatedViewRef 就是在这里对 view 进行了弱引用
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");
}
}
```
}
}
```
- 在这里创建了弱引用对象
```java
public View inflate() {
final ViewParent viewParent = getParent();
if (viewParent != null && viewParent instanceof ViewGroup) {
if (mLayoutResource != 0) {
mInflatedViewRef = new WeakReference<>(view);
return view;
} else {
throw new IllegalArgumentException("ViewStub must have a valid layoutResource");
}
}
}
```
@Override
public void draw(Canvas canvas) {
}
@Override
protected void dispatchDraw(Canvas canvas) {
}
```
initViewGroup();
initFromAttributes(context, attrs, defStyleAttr, defStyleRes);
}
private void initViewGroup() {
// ViewGroup doesn't draw by default
if (!debugDraw()) {
setFlags(WILL_NOT_DRAW, DRAW_MASK);
}
mGroupFlags |= FLAG_CLIP_CHILDREN;
mGroupFlags |= FLAG_CLIP_TO_PADDING;
mGroupFlags |= FLAG_ANIMATION_DONE;
mGroupFlags |= FLAG_ANIMATION_CACHE;
mGroupFlags |= FLAG_ALWAYS_DRAWN_WITH_CACHE;
if (mContext.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.HONEYCOMB) {
mGroupFlags |= FLAG_SPLIT_MOTION_EVENTS;
}
setDescendantFocusability(FOCUS_BEFORE_DESCENDANTS);
mChildren = new View[ARRAY_INITIAL_CAPACITY];
mChildrenCount = 0;
mPersistentDrawingCache = PERSISTENT_SCROLLING_CACHE;
}
```
if (viewParent != null && viewParent instanceof ViewGroup) {
if (mLayoutResource != 0) {
final ViewGroup parent = (ViewGroup) viewParent;
//这里是加载布局,并且给它设置id
//布局的加载是通过LayoutInflater解析出来的
final View view = inflateViewNoAdd(parent);
//这行代码很重要,下面会将到
replaceSelfWithView(view, parent);
//使用弱引用
mInflatedViewRef = new WeakReference<>(view);
if (mInflateListener != null) {
mInflateListener.onInflate(this, view);
}
return view;
} else {
//如果已经加载出来,再次inflate就会抛出异常呢
throw new IllegalArgumentException("ViewStub must have a valid layoutResource");
}
} else {
throw new IllegalStateException("ViewStub must have a non-null ViewGroup viewParent");
}
}
```
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。