原理:以父容器尺寸爲參考,在View的加載過程,根據當前父容器的實際尺寸計算出目標尺寸,再做用在view上。java
例如:設計師給的佈局像素是720 * 1080,佈局中有一個view的寬度是360px,爲屏幕寬度的一半,若是咱們再手機像素爲1080 * 1920的手機上設置寬度爲360px時,顯然不合適,正常的寬度應該是540px,這裏咱們能夠經過設置比例的方式來實現,好比設置爲屏幕寬度的0.5。android
下面以RelativeLayout爲例自定義佈局。建立PercentLayout繼承RelativeLayout。在attr.xml文件中設置自定義屬性。bash
1.代碼實現:app
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="PercentLayout">
<attr name="widthPercent" format="float" />
<attr name="heightPercent" format="float" />
<attr name="marginLeftPercent" format="float" />
<attr name="marginRightPercent" format="float" />
<attr name="marginTopPercent" format="float" />
<attr name="marginBottomPercent" format="float" />
</declare-styleable>
</resources>複製代碼
java代碼實現:ide
public class PercentLayout extends RelativeLayout {
public PercentLayout(Context context) {
super(context);
}
public PercentLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public PercentLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//測量以前先對view百分比設置
//獲取父容器的寬高
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int count = getChildCount();
for (int i = 0; i < count; i++) {
//從新設置子view的佈局屬性,再進行View的測量
View child = getChildAt(i);
ViewGroup.LayoutParams params = child.getLayoutParams();
if (checkLayoutParams(params)) {
LayoutParams layoutParams = (LayoutParams) params; //強轉成layoutParams
//獲取百分比屬性
float widthPercent = layoutParams.widthPercent;
float heightPercent = layoutParams.heightPercent;
float marginLeftPercent = layoutParams.marginLeftPercent;
float marginRightPercent = layoutParams.marginRightPercent;
float marginTopPercent = layoutParams.marginTopPercent;
float marginBottomPercent = layoutParams.marginBottomPercent;
if (widthPercent > 0) { //賦值成功
layoutParams.width = (int) (widthSize * widthPercent); //尺寸大小爲:父容器寬*百分比
}
if (heightPercent > 0) {
layoutParams.height = (int) (heightSize * heightPercent);
}
if (marginLeftPercent > 0) {
layoutParams.leftMargin = (int) (widthSize * marginLeftPercent);
}
if (marginRightPercent > 0) {
layoutParams.rightMargin = (int) (widthSize * marginRightPercent);
}
if (marginTopPercent > 0) {
layoutParams.topMargin = (int) (heightSize * marginTopPercent);
}
if (heightPercent > 0) {
layoutParams.bottomMargin = (int) (heightSize * marginBottomPercent);
}
}
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
//用於LayoutParams的判斷,判斷是否爲當前類的子類(參考RelativeLayout中的此方法)
@Override
protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
return p instanceof LayoutParams; //判斷是不是PercentLayout.LayoutParams
}
//重寫此方法,用於返回咱們內部建立的LayoutParams(參考RelativeLayout中的此方法)
@Override
public LayoutParams generateLayoutParams(AttributeSet attrs) {
return new LayoutParams(getContext(), attrs);
}
//這裏參考RelativeLayout中將自定屬性封裝在LayoutParams中
public static class LayoutParams extends RelativeLayout.LayoutParams {
private float heightPercent;
private float widthPercent;
private float marginLeftPercent;
private float marginRightPercent;
private float marginTopPercent;
private float marginBottomPercent;
public LayoutParams(Context c, AttributeSet attrs) {
super(c, attrs);
//添加自定義屬性
TypedArray typedArray = c.obtainStyledAttributes(attrs, R.styleable.PercentLayout);
heightPercent = typedArray.getFloat(R.styleable.PercentLayout_heightPercent, 0);
widthPercent = typedArray.getFloat(R.styleable.PercentLayout_widthPercent, 0);
marginLeftPercent = typedArray.getFloat(R.styleable.PercentLayout_marginLeftPercent, 0);
marginRightPercent = typedArray.getFloat(R.styleable.PercentLayout_marginRightPercent, 0);
marginTopPercent = typedArray.getFloat(R.styleable.PercentLayout_marginTopPercent, 0);
marginBottomPercent = typedArray.getFloat(R.styleable.PercentLayout_marginBottomPercent, 0);
typedArray.recycle();
}
}
}
複製代碼
2.xml佈局文件中設置子view的百分比:佈局
這裏咱們設置了寬高都是爲屏幕的0.5。ui
<?xml version="1.0" encoding="utf-8"?>
<com.xuwei.screenpercentlayout.PercentLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:background="@color/colorPrimary"
android:text="寬50%,高75%"
app:heightPercent="0.5"
app:widthPercent="0.5" />
</com.xuwei.screenpercentlayout.PercentLayout>複製代碼
3.運行效果:spa