思路:通过自定义ViewGroup,在onMeasure中,根据xml中设置的百分比重新设置子View的宽高
撸码
代码逻辑相对简单,记录一下一种适配思想
1.定义相关属性
<resources>
<declare-styleable name="LinearLayout">
<attr name="percent_width" format="float" />
<attr name="percent_height" format="float" />
<attr name="percent_left_margin" format="float" />
<attr name="percent_right_margin" format="float" />
<attr name="percent_top_margin" format="float" />
<attr name="percent_bottom_margin" format="float" />
</declare-styleable>
2.重写LinearLayout
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.Nullable;
public class LinearLayout extends android.widget.LinearLayout {
public LinearLayout(Context context) {
super(context);
}
public LinearLayout(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public LinearLayout(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
/**
* 将AttributeSet封装成LayoutParams
*/
static class LayoutParams extends android.widget.LinearLayout.LayoutParams {
//宽高百分比
private float percentWidth;
private float percentHeight;
//水平方向margin百分比
private float percentLeftMargin;
private float percentRightMargin;
//垂直方向margin百分比
private float percentTopMargin;
private float percentBottomMargin;
LayoutParams(Context c, AttributeSet attrs) {
super(c, attrs);
TypedArray array = c.obtainStyledAttributes(attrs, R.styleable.LinearLayout);
//获取相关属性
percentWidth = array.getFloat(R.styleable.LinearLayout_percent_width, 0);
percentHeight = array.getFloat(R.styleable.LinearLayout_percent_height, 0);
percentLeftMargin = array.getFloat(R.styleable.LinearLayout_percent_left_margin, 0);
percentRightMargin = array.getFloat(R.styleable.LinearLayout_percent_right_margin, 0);
percentTopMargin = array.getFloat(R.styleable.LinearLayout_percent_top_margin, 0);
percentBottomMargin = array.getFloat(R.styleable.LinearLayout_percent_bottom_margin, 0);
array.recycle();
}
}
@Override
public LayoutParams generateLayoutParams(AttributeSet attrs) {
return new LayoutParams(getContext(), attrs);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//得到当前父控件的宽高
float width = MeasureSpec.getSize(widthMeasureSpec);
float height = MeasureSpec.getSize(heightMeasureSpec);
//循环遍历所有子控件
int count = getChildCount();
for (int i = 0; i < count; i++) {
View child = getChildAt(i);
ViewGroup.LayoutParams layoutParams = child.getLayoutParams();
//如果子控件的LayoutParams是属于该ViewGroup的LayoutParams
if (layoutParams instanceof LayoutParams) {
float percentWidth = ((LayoutParams) layoutParams).percentWidth;
float percentHeight = ((LayoutParams) layoutParams).percentHeight;
float percentLeftMargin = ((LayoutParams) layoutParams).percentLeftMargin;
float percentRightMargin = ((LayoutParams) layoutParams).percentRightMargin;
float percentTopMargin = ((LayoutParams) layoutParams).percentTopMargin;
float percentBottomMargin = ((LayoutParams) layoutParams).percentBottomMargin;
// 如果百分比为0则不处理相关的计算
if (percentWidth > 0) {
layoutParams.width = (int) (width * percentWidth);
}
if (percentHeight > 0) {
layoutParams.height = (int) (height * percentHeight);
}
if (percentLeftMargin > 0) {
((LayoutParams) layoutParams).leftMargin = (int) (width * percentLeftMargin);
}
if (percentRightMargin > 0) {
((LayoutParams) layoutParams).rightMargin = (int) (width * percentRightMargin);
}
if (percentTopMargin > 0) {
((LayoutParams) layoutParams).topMargin = (int) (height * percentTopMargin);
}
if (percentBottomMargin > 0) {
((LayoutParams) layoutParams).bottomMargin = (int) (width * percentBottomMargin);
}
}
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}