标签:
res/layout/main.xml <LinearLayout > <ViewStub android:id="@+id/viewstub" android:layout_width="100dip" android:layout_marginTop="100dip" android:layout_height="wrap_content" android:layout="@layout/sub_layout" /> </LinearLayout> res/layout/sub_layout.xml <TextView android:layout_width="50dip" android:layout_marginTop="50dip" android:layout_height="wrap_content" android:text="ViewStub中包含的TextVeiw"/>
@Override @android.view.RemotableViewMethod 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(); } } }
public final class ViewStub extends View { ...... public View inflate() { final ViewParent viewParent = getParent(); // 1 为什么可以直接获取父视图? // ViewStub的父视图必须是ViewGroup的子类 if (viewParent != null && viewParent instanceof ViewGroup) { if (mLayoutResource != 0) { // ViewStub必须设置android:layout属性 final ViewGroup parent = (ViewGroup) viewParent; final LayoutInflater factory; if (mInflater != null) { factory = mInflater; } else { factory = LayoutInflater.from(mContext); } // 2 inflate被加载视图 final View view = factory.inflate(mLayoutResource, parent, false); if (mInflatedId != NO_ID) { view.setId(mInflatedId); } // 从父视图中获取当前ViewStub在父视图中的位置 final int index = parent.indexOfChild(this); // 当前ViewStub也是个View仅仅只是用来占位,所以先把占位的ViewStub视图删除 parent.removeViewInLayout(this); // 3 此处获取的是ViewStub上面设置的参数 final ViewGroup.LayoutParams layoutParams = getLayoutParams(); if (layoutParams != null) { parent.addView(view, index, layoutParams); } else { parent.addView(view, index); } // 目的是在复写的setVisibility方法中使用 // 因为ViewStub.setVisibility操作的是被加载视图并非当前ViewStub视图 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"); } } ...... }
public class View { public final ViewParent getParent() { return mParent; } void assignParent(ViewParent parent) { if (mParent == null) { mParent = parent; } else if (parent == null) { mParent = null; } else { throw new RuntimeException("view " + this + " being added, but" + " it already has a parent"); } } }
public class ViewGroup { public void addView(View child, int index, LayoutParams params) { ...... addViewInner(child, index, params, false); } private void addViewInner(View child, int index, LayoutParams params, boolean preventRequestLayout) { ...... // tell our children if (preventRequestLayout) { child.assignParent(this); } else { child.mParent = this; } ...... } }
public final class ViewStub extends View { public ViewStub(Context context) { initialize(context); } private void initialize(Context context) { mContext = context; setVisibility(GONE); // 初始化时把自己设置为隐藏 setWillNotDraw(true); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { setMeasuredDimension(0, 0); // 所有子视图都设置为宽高为0 } @Override public void draw(Canvas canvas) { // 不对自身与子视图进行绘制 } @Override protected void dispatchDraw(Canvas canvas) { } }
标签:
原文地址:http://blog.csdn.net/androiddevelop/article/details/46632323