/**
* 從代碼創建視圖時使用的簡單構造函數.即在代碼中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();
}
本站文章版權歸原作者及原出處所有 。內容為作者個人觀點, 并不代表本站贊同其觀點和對其真實性負責,本站只提供參考并不構成任何投資及應用建議。本站是一個個人學習交流的平臺,網站上部分文章為轉載,并不用于任何商業目的,我們已經盡可能的對作者和來源進行了通告,但是能力有限或疏忽,造成漏登,請及時聯系我們,我們將根據著作權人的要求,立即更正或者刪除有關內容。本站擁有對此聲明的最終解釋權。