Android View类的四个构造函数-面试时总被问到

/**
 * 从代码创建视图时使用的简单构造函数.即在代码中new View(context);
 *
 * @param context 上下文参数
 */
public View(Context context) {
mContext = context;
mResources = context != null ? context.getResources() : null;
...
//获得系统提供的识别用户是否触发了move的最小距离值
mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
setOverScrollMode(OVER_SCROLL_IF_CONTENT_SCROLLS);
...
}


/**
 * 当当前view使用xml方式inflating创建时,调用该构造函数。
 * 并且提供在XML文件中指定的自定义属性。
 * 此构造函数使用默认样式为0,因此创建的view是有自定义属性和系统提供的默认theme属性可用。
 *
 * <p>
 * onFinishInflate()方法将会在所有的children被添加完成时调用,即xml解析完成时调用。
 * @param context 上下文
 * @param attrs 自定义属性.
 * @see 参考三个参数的构造函数#View(Context, AttributeSet, int)
 */
public View(Context context, @Nullable AttributeSet attrs) {
//调用当前类三个参数的构造函数
this(context, attrs, 0);
}


/**
 * 执行xml加载的方式创建view,同时运用android:theme属性给定的主题样式属性值。
 * 这个视图构造函数允许子类在膨胀时使用自己的基本样式。
 * 例如, 一个Button类的构造函数将会执行父类的,
 * 同时申请R.attr.buttonStyle样式通过defStyleAttr参数值
 * 这允许主题的按钮样式修改所有基本视图属性(特别是它的背景)以及按钮类的属性。
 *
 * @param context 上下文.
 * @param attrs 正在加载视图的XML标记的属性.
 * @param defStyleAttr 当前主题中的一个属性,该属性包含对提供视图默认值的样式资源的引用。可以是0不查找默认值。
 * @see #View(Context, AttributeSet)
 */
public View(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
//调用当前类4个参数的构造函数
this(context, attrs, defStyleAttr, 0);
}


/**
 * 从XML执行加载view,并从主题属性或样式资源中应用特定于类的基本样式。
 * 这个视图构造函数允许子类在加载时使用自己的基本样式。
 * <p>
 * 当确定一个特定的属性值时,有些面作用顺序,即作用优先级:
 * <ol>
 * <li>1、控件给定的属性集合AttributeSet.
 * <li>2、在xml中style属性值给定属性集合AttributeSet.
 * <li>3、通过defStyleAttr属性值给定的默认样式值.
 * <li>4、通过defStyleRes属性值给定的默认样式值.
 * <li>5、此主题中的基值.
 * </ol>
 * <p>
 * 上面的12345点,都是经过熟虑且排序的, 即前面的值或覆盖后面的值. 
 * 换句话说,在AttributeSet中定义了一个textColor="#ff000000"值,
 * 那么这个控件的文本永远都是黑色的,不改你再上面的2345等属性中设置什么样的值。
 *
 * @param context 上下文.
 * @param attrs 正在加载视图的XML标记的属性。
 * @param defStyleAttr 当前主题中的一个属性,该属性包含对提供视图默认值的样式资源的引用。可以是0不查找默认值。
 * @param defStyleRes 一个提供视图默认值的样式资源的标识符,仅仅在defStyleAttr为0或者defStyleAttr在theme中找不到时使用。
 *        如果defStyleRes值为0,则不使用该属性值。
 * @see #View(Context, AttributeSet, int)
 */
public View(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
//调用了一个参数的构造函数代码,同时执行后续代码
this(context);


//获取自定义属性
final TypedArray a = context.obtainStyledAttributes(
attrs, com.android.internal.R.styleable.View, defStyleAttr, defStyleRes);


if (mDebugViewAttributes) {
saveAttributeData(attrs, a);
}


Drawable background = null;


//初始化各种变量或对象
int leftPadding = -1;
int topPadding = -1;
int rightPadding = -1;
int bottomPadding = -1;
int startPadding = UNDEFINED_PADDING;
int endPadding = UNDEFINED_PADDING;


...


final int targetSdkVersion = context.getApplicationInfo().targetSdkVersion;


// Set default values.
viewFlagValues |= FOCUSABLE_AUTO;
viewFlagMasks |= FOCUSABLE_AUTO;


//for循环迭代获取到的n个自定义属性值
final int N = a.getIndexCount();
for (int i = 0; i < N; i++) {
int attr = a.getIndex(i);
switch (attr) {
case com.android.internal.R.styleable.View_background:
background = a.getDrawable(attr);
break;
case com.android.internal.R.styleable.View_padding:
padding = a.getDimensionPixelSize(attr, -1);
mUserPaddingLeftInitial = padding;
mUserPaddingRightInitial = padding;
leftPaddingDefined = true;
rightPaddingDefined = true;
break;
case com.android.internal.R.styleable.View_paddingHorizontal:
paddingHorizontal = a.getDimensionPixelSize(attr, -1);
mUserPaddingLeftInitial = paddingHorizontal;
mUserPaddingRightInitial = paddingHorizontal;
leftPaddingDefined = true;
rightPaddingDefined = true;
break;
...
}
}


setOverScrollMode(overScrollMode);


// Cache start/end user padding as we cannot fully resolve padding here (we dont have yet
// the resolved layout direction). Those cached values will be used later during padding
// resolution.
mUserPaddingStart = startPadding;
mUserPaddingEnd = endPadding;


if (background != null) {
setBackground(background);
}


...


//回收自定义属性数组
a.recycle();


// Needs to be called after mViewFlags is set
if (scrollbarStyle != SCROLLBARS_INSIDE_OVERLAY) {
recomputePadding();
}


if (x != 0 || y != 0) {
scrollTo(x, y);
}


if (transformSet) {
setTranslationX(tx);
setTranslationY(ty);
setTranslationZ(tz);
setElevation(elevation);
setRotation(rotation);
setRotationX(rotationX);
setRotationY(rotationY);
setScaleX(sx);
setScaleY(sy);
}


if (!setScrollContainer && (viewFlagValues&SCROLLBARS_VERTICAL) != 0) {
setScrollContainer(true);
}


computeOpaqueFlags();
}

猜你喜欢

转载自blog.csdn.net/fesdgasdgasdg/article/details/78658849