簡介
組件的布局就是實(shí)現(xiàn)onlayout方法,把子視圖繪制在界面上。比如LinearLayout可以水平的布局,也可以垂直布局,GridView可以實(shí)現(xiàn)宮格方式的布局。下面就通過一個(gè)實(shí)例來說明是如何布局的。
一個(gè)宮格布局實(shí)例
想實(shí)現(xiàn)一個(gè)類似GridView的宮格布局,可以設(shè)置要展示的列數(shù)、橫豎間距。
定義了這些屬性
//列間距
private int columnSpsace = 16;
//行間距private int rowSpace = 16;
//列數(shù)private int column = 3;
也可以通過自定義屬性的方式從布局中獲取。
1、實(shí)現(xiàn)onMeasure方法測量子視圖的寬高、確定自定義組件的寬高
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//定義GridView的寬高為填充父視圖
setMeasuredDimension(getDefaultSize(0, widthMeasureSpec), getDefaultSize(0, heightMeasureSpec));
//計(jì)算子視圖的寬高
int parentWidth = getMeasuredWidth();
int childSize = (parentWidth - (columnSpsace * 2)) / 3;
int count = getChildCount(); int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(childSize, MeasureSpec.EXACTLY);
int childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(childSize, MeasureSpec.EXACTLY);
for (int i = 0; i < count; i++) {
View child = getChildAt(i);
child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
}
}
這里要注意的是測量子視圖的寬高時(shí)要扣除間距,因?yàn)槭怯芯唧w的寬高,子視圖的測量模式定義為MeasureSpec.EXACTLY精確模式。
2、實(shí)現(xiàn)onlayout方法進(jìn)行布局
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
//布局為9宮格
int childCount = getChildCount();
int childL = l;
int childT = t;
for (int i = 0; i < childCount; i++) {
View child = getChildAt(i);
child.layout(childL, childT, childL + child.getMeasuredWidth(), childT + child.getMeasuredHeight());
if (i % 3 == 2) {
childL = l;
childT = childT + rowSpace + child.getMeasuredHeight();
} else {
childL = childL + columnSpsace + child.getMeasuredWidth();
}
}
}
計(jì)算出每個(gè)子視圖的位置,調(diào)用他們的layout方法進(jìn)行布局。
組件的布局并沒有涉及到太多的概念,關(guān)鍵是要結(jié)合測量,根據(jù)定義好的規(guī)則計(jì)算他們的位置。