开篇
很久没有更新博客了。本篇给同学们分享一个简单的超级好用的均分布局,提升你的开发效率。
场景
在日常开发中会经常用到均分布局,而我们通常的做法是用LinearLayout
和android:layout_weight
配合完成。但是有时候,child
并不需要占用1
个比重,这时候为了满足android:layout_weight
居中,不得不给child
再包一层父类。而此控件就是为了解决这个问题因运而生!当然,通过ConstraintLayout
经过复杂的约束也能达到这个效果,只是AverageLayout
比ConstraintLayout
更简洁方便。
效果截屏
立即体验
扫描以下二维码下载体验App(从0.2.3
版本开始,体验App内嵌版本更新检测功能):
JSCKit库传送门:https://github.com/JustinRoom/JSCKit
简析源码
AverageLayout.java
public class AverageLayout extends ViewGroup implements IViewAttrDelegate{}
- 1、测量
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int childCount = getChildCount();
if (childCount > 0){
measureChildren(widthMeasureSpec, heightMeasureSpec);
LayoutParams params = getLayoutParams();
int width = 0;
int height = 0;
switch (orientation){
case HORIZONTAL:
width = getPaddingLeft() + getPaddingRight();
for (int i = 0; i < childCount; i++) {
View child = getChildAt(i);
width += child.getMeasuredWidth();
height = Math.max(height, child.getMeasuredHeight());
}
height = height + getPaddingTop() + getPaddingBottom();
if (params.width == LayoutParams.WRAP_CONTENT){
widthMeasureSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY);
}
if (params.height == LayoutParams.WRAP_CONTENT){
heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
}
break;
case VERTICAL:
height = getPaddingTop() + getPaddingBottom();
for (int i = 0; i < childCount; i++) {
View child = getChildAt(i);
height += child.getMeasuredHeight();
width = Math.max(width, child.getMeasuredWidth());
}
width = width + getPaddingLeft() + getPaddingRight();
if (params.height == LayoutParams.WRAP_CONTENT){
heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
}
if (params.width == LayoutParams.WRAP_CONTENT){
widthMeasureSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY);
}
break;
}
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
- 2、放置
protected void onLayout(boolean changed, int l, int t, int r, int b)
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
int childCount = getChildCount();
int width = getMeasuredWidth();
int height = getMeasuredHeight();
int left, top, right, bottom;
if (childCount > 0){
switch (orientation){
case HORIZONTAL:
int[] widths = calculateAverageValue(width - getPaddingLeft() - getPaddingRight(), childCount);
int startX = getPaddingLeft();
for (int i = 0; i < childCount; i++) {
View child = getChildAt(i);
LayoutParams childParams = child.getLayoutParams();
if (childParams.width == LayoutParams.MATCH_PARENT) {
left = startX;
right = left + widths[i];
} else {
left = startX + (widths[i] - child.getMeasuredWidth()) / 2;
right = left + child.getMeasuredWidth();
}
if (childParams.height == LayoutParams.MATCH_PARENT) {
top = getPaddingTop();
bottom = height - getPaddingBottom();
} else {
top = (height - child.getMeasuredHeight()) / 2;
bottom = top + child.getMeasuredHeight();
}
child.layout(left, top, right, bottom);
startX += widths[i];
}
break;
case VERTICAL:
int[] heights = calculateAverageValue(height - getPaddingTop() - getPaddingBottom(), childCount);
int startY = getPaddingTop();
for (int i = 0; i < childCount; i++) {
View child = getChildAt(i);
LayoutParams childParams = child.getLayoutParams();
if (childParams.width == LayoutParams.MATCH_PARENT) {
left = getPaddingLeft();
right = width - getPaddingRight();
} else {
left = (width - child.getMeasuredWidth()) / 2;
right = left + child.getMeasuredWidth();
}
if (childParams.height == LayoutParams.MATCH_PARENT) {
top = startY;
bottom = top + heights[i];
} else {
top = startY + (heights[i] - child.getMeasuredHeight()) / 2;
bottom = top + child.getMeasuredHeight();
}
child.layout(left, top, right, bottom);
startY += heights[i];
}
break;
}
}
}
private int[] calculateAverageValue(int value, int childCount) {
int tempAverageValue = value / childCount;
int rest = value - tempAverageValue * childCount;
int[] averageValues = new int[childCount];
for (int i = 0; i < childCount; i++) {
if (rest > 0) {
averageValues[i] = tempAverageValue + 1;
rest --;
} else {
averageValues[i] = tempAverageValue;
}
}
return averageValues;
}
使用示例
其他的不多说了,请自行安装体验app体验,用过才会知道它的好。
童鞋们,如果你们觉得不错的话给我点个吧,谢谢!!!
篇尾
Wechat:eoy9527
。
在人生的道路上,当你的希望一个个落空的时候,你也要坚定,要沉着。 —— 朗费罗