引言
一些需求中需要一些好看的View或者ViewGroup,沒有現(xiàn)成的,就可以自定義.
View is the base class for widgets, which are used to create interactive UI components (buttons, text fields, etc.).
View是控件的基礎(chǔ)類,常用于UI交互組件中(按鈕,文本,字段等)。
A ViewGroup is a special view that can contain other views (called children.) The view group is the base class for layouts and views containers.
ViewGroup是用來包含其他view(稱之為兒子節(jié)點)的特殊View,ViewGroup是布局和視圖容器的基礎(chǔ)類。
看下源碼就一目了然:
自定義View
1.View如何使用
1.Constructors (構(gòu)造器)
- public void View(Context context) {}
//new即實例化的時候調(diào)用 - public void View(Context context, AttributeSet attrs) {}
//寫在layout文件中會被調(diào)用 - public void View(Context context, AttributeSet attrs, int defStyleAttr) {}
//多出的defStyleAttr是當前主題中的樣式屬性 - public void View(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {}
//只有API21以上才會使用.多出來的defStyleRes是和資源有關(guān)的樣式
2.onMeasure method(限定View屏幕中的尺寸)
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
widthMeasureSpec和heightMeasureSpec是和寬和高有關(guān)的兩個參數(shù),但是他們不是實際的寬和高,而是由寬沃呢、高和各自方向上對應(yīng)的測量模式來合成的一個值.
測量模式有三種:
pattern | description |
---|---|
UNSPECIFIED | 對應(yīng)layout_width 或者layout_height =match_parent |
AT_MOST | 對應(yīng)wrap_content |
EXACTLY | 對應(yīng)固定大小 例如20dp |
通過widthMeasureSpec和heightMeasureSpec獲取寬高和模式
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
所以實際代碼中你可以這么定義onMearsue method:
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec),
getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec));
}
public static int getDefaultSize(int size, int measureSpec) {
int result = size;
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
switch (specMode) {
case MeasureSpec.UNSPECIFIED:
result = size;
break;
case MeasureSpec.AT_MOST:
case MeasureSpec.EXACTLY:
result = specSize;
break;
}
return result;
}
3.onLayout method
- protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
}
//Called from layout when this view should
assign a size and position to each of its children.
在布局對子view分配大小和位置的時候調(diào)用。
參數(shù)明確:這四個參數(shù)在View中都有訪問器纺腊。
名稱 | 說明 |
---|---|
l | View左側(cè)距父View左側(cè)的距離 |
t | View頂部距父View頂部的距離 |
r | View右側(cè)距父View左側(cè)的距離 |
b | View底部距父View頂部的距離 |
這里涉及到坐標系,簡單說一下屏幕以左上角為原點,向下是y軸正方向,向右是x軸正方向畔咧。
4.onDraw method
-
protected void onDraw(Canvas canvas) {
}
//Implement this to do your drawing.
重寫此方法進行繪畫。提醒:canvs下的draw方法(比如畫點,畫線)在AndroidStudio layout可視化是(is not supported)不支持的,需要啟動虛擬機運行查看才行摹菠。
5.自定義 method
以上就是繪制View的基本流程,然后你可以根據(jù)你的需求做一些對外接口 etc.
自定義ViewGroup
1.Constructors :
public ViewGroup(Context context) {
this(context, null);
}public ViewGroup(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}public ViewGroup(Context context, AttributeSet attrs, int defStyleAttr) {
this(context, attrs, defStyleAttr, 0);
}public ViewGroup(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
initViewGroup();
initFromAttributes(context, attrs, defStyleAttr, defStyleRes);
}
你會發(fā)現(xiàn)ViewGroup和View的構(gòu)造器基本一樣盒卸。因為ViewGroup是一個特殊View。具體參考View即可
2.onMeasure method :
ViewGroup中onMeasure進行設(shè)置子View的大小,上層調(diào)用下層,簡單看下ListView中的onMeasure的調(diào)用就一目了然次氨。
3.onLayout method :
同理onLayout也是設(shè)置子View的位置蔽介。因為ListView是繼承AbsListView,所以看下AbsListView下的onLayout也一目了然:
4.和布局參數(shù)有關(guān)的函數(shù):
@Override
public LayoutParams generateLayoutParams(AttributeSet attrs) {
return new CustomLayout.LayoutParams(getContext(), attrs);
}
@Override
protected LayoutParams generateDefaultLayoutParams() {
return new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
}
@Override
protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
return new LayoutParams(p);
}
@Override
protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
return p instanceof LayoutParams;
}
- generateLayoutParams method :在layout set的屬性基礎(chǔ)上可以進行擴增。
- generateDefaultLayoutParams method :返回一個默認的布局參數(shù)
- generateLayoutParams(ViewGroup.LayoutParams p)返回一個在原有布局參數(shù)上的安全的布局參數(shù)
- checkLayoutParams 檢查布局參數(shù)類型
總結(jié):
對比View和ViewGroup功能上和用法上很相似,不過因為一個是父,一個是子,上下調(diào)用的關(guān)系煮寡。
如果你看了覺得寫的不好 請您告訴我囊扳。