一、引言
因为Android的开源,所以厂商无需自行研发OS操作系统,由于各自厂商存在竞争,导致手机的生产存在差异,与此同时的是相继出现不同分辨率的版本手机,给广大开发者的苦不堪言痛苦,各种神奇的小板儿考验着app的兼容性,各种定制的rom不经意间就让app崩溃,光是界面上的调整就已经够你喝一壶了,为了解决这一问题,这段时间,无意间,在github上找到了一个开源框架,我在这里做了一些整理,经过测试,目前这个框架,兼容sdk最低到11,最高到23,其他的范围还没有测试,还有待测试。
二、说明
由于Google开始支持百分比的方式布局了,所以今后可能越来越流行这种布局适配,我把核心的东西抽出,做了一个整理。
三、集成步骤:
1.res/value/values.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="PercentLayout_Layout">
<attr name="layout_widthPercent" format="fraction" />
<attr name="layout_heightPercent" format="fraction" />
<attr name="layout_marginPercent" format="fraction" />
<attr name="layout_marginLeftPercent" format="fraction" />
<attr name="layout_marginTopPercent" format="fraction" />
<attr name="layout_marginRightPercent" format="fraction" />
<attr name="layout_marginBottomPercent" format="fraction" />
<attr name="layout_marginStartPercent" format="fraction" />
<attr name="layout_marginEndPercent" format="fraction" />
</declare-styleable>
</resources>
2.src/android.support.percent包里加入:
PercentFrameLayout.java;
PercentLayoutHelper.java;
PercentLinearLayout.java;
PercentRelativeLayout.java;
代码如下:
(1) PercentFrameLayout.java;
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
package android.support.percent;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
import android.support.percent.PercentLayoutHelper;
import android.support.percent.PercentLayoutHelper.PercentLayoutInfo;
import android.support.percent.PercentLayoutHelper.PercentLayoutParams;
import android.util.AttributeSet;
import android.view.ViewGroup.MarginLayoutParams;
import android.widget.FrameLayout;
public class PercentFrameLayout extends FrameLayout {
private final PercentLayoutHelper mHelper = new PercentLayoutHelper(this);
public PercentFrameLayout(Context context) {
super(context);
}
public PercentFrameLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public PercentFrameLayout(Context context, AttributeSet attrs,
int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public PercentFrameLayout.LayoutParams generateLayoutParams(
AttributeSet attrs) {
return new PercentFrameLayout.LayoutParams(this.getContext(), attrs);
}
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
this.mHelper.adjustChildren(widthMeasureSpec, heightMeasureSpec);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if (this.mHelper.handleMeasuredStateTooSmall()) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
protected void onLayout(boolean changed, int left, int top, int right,
int bottom) {
super.onLayout(changed, left, top, right, bottom);
this.mHelper.restoreOriginalParams();
}
public static class LayoutParams extends
android.widget.FrameLayout.LayoutParams implements
PercentLayoutParams {
private PercentLayoutInfo mPercentLayoutInfo;
public LayoutParams(Context c, AttributeSet attrs) {
super(c, attrs);
this.mPercentLayoutInfo = PercentLayoutHelper.getPercentLayoutInfo(
c, attrs);
}
public LayoutParams(int width, int height) {
super(width, height);
}
public LayoutParams(int width, int height, int gravity) {
super(width, height, gravity);
}
public LayoutParams(android.view.ViewGroup.LayoutParams source) {
super(source);
}
public LayoutParams(MarginLayoutParams source) {
super(source);
}
@SuppressLint("NewApi")
public LayoutParams(android.widget.FrameLayout.LayoutParams source) {
super(source);
this.gravity = source.gravity;
}
@SuppressLint("NewApi")
public LayoutParams(PercentFrameLayout.LayoutParams source) {
this((android.widget.FrameLayout.LayoutParams) source);
this.mPercentLayoutInfo = source.mPercentLayoutInfo;
}
public PercentLayoutInfo getPercentLayoutInfo() {
return this.mPercentLayoutInfo;
}
protected void setBaseAttributes(TypedArray a, int widthAttr,
int heightAttr) {
PercentLayoutHelper.fetchWidthAndHeight(this, a, widthAttr,
heightAttr);
}
}
}
(2) PercentLayoutHelper.java; 核心类的帮助类;
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
package android.support.percent;
import com.example.testpercent.R.styleable;
import android.content.Context;
import android.content.res.TypedArray;
//import android.support.percent.R.styleable;
import android.support.v4.view.MarginLayoutParamsCompat;
import android.support.v4.view.ViewCompat;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.MeasureSpec;
import android.view.ViewGroup.LayoutParams;
import android.view.ViewGroup.MarginLayoutParams;
public class PercentLayoutHelper {
private static final String TAG = "PercentLayout";
private final ViewGroup mHost;
public PercentLayoutHelper(ViewGroup host) {
this.mHost = host;
}
public static void fetchWidthAndHeight(LayoutParams params, TypedArray array, int widthAttr, int heightAttr) {
params.width = array.getLayoutDimension(widthAttr, 0);
params.height = array.getLayoutDimension(heightAttr, 0);
}
public void adjustChildren(int widthMeasureSpec, int heightMeasureSpec) {
if(Log.isLoggable("PercentLayout", 3)) {
Log.d("PercentLayout", "adjustChildren: " + this.mHost + " widthMeasureSpec: " + MeasureSpec.toString(widthMeasureSpec) + " heightMeasureSpec: " + MeasureSpec.toString(heightMeasureSpec));
}
int widthHint = MeasureSpec.getSize(widthMeasureSpec);
int heightHint = MeasureSpec.getSize(heightMeasureSpec);
int i = 0;
for(int N = this.mHost.getChildCount(); i < N; ++i) {
View view = this.mHost.getChildAt(i);
LayoutParams params = view.getLayoutParams();
if(Log.isLoggable("PercentLayout", 3)) {
Log.d("PercentLayout", "should adjust " + view + " " + params);
}
if(params instanceof PercentLayoutHelper.PercentLayoutParams) {
PercentLayoutHelper.PercentLayoutInfo info = ((PercentLayoutHelper.PercentLayoutParams)params).getPercentLayoutInfo();
if(Log.isLoggable("PercentLayout", 3)) {
Log.d("PercentLayout", "using " + info);
}
if(info != null) {
if(params instanceof MarginLayoutParams) {
info.fillMarginLayoutParams((MarginLayoutParams)params, widthHint, heightHint);
} else {
info.fillLayoutParams(params, widthHint, heightHint);
}
}
}
}
}
public static PercentLayoutHelper.PercentLayoutInfo getPercentLayoutInfo(Context context, AttributeSet attrs) {
PercentLayoutHelper.PercentLayoutInfo info = null;
TypedArray array = context.obtainStyledAttributes(attrs, styleable.PercentLayout_Layout);
float value = array.getFraction(styleable.PercentLayout_Layout_layout_widthPercent, 1, 1, -1.0F);
if(value != -1.0F) {
if(Log.isLoggable("PercentLayout", 2)) {
Log.v("PercentLayout", "percent width: " + value);
}
info = info != null?info:new PercentLayoutHelper.PercentLayoutInfo();
info.widthPercent = value;
}
value = array.getFraction(styleable.PercentLayout_Layout_layout_heightPercent, 1, 1, -1.0F);
if(value != -1.0F) {
if(Log.isLoggable("PercentLayout", 2)) {
Log.v("PercentLayout", "percent height: " + value);
}
info = info != null?info:new PercentLayoutHelper.PercentLayoutInfo();
info.heightPercent = value;
}
value = array.getFraction(styleable.PercentLayout_Layout_layout_marginPercent, 1, 1, -1.0F);
if(value != -1.0F) {
if(Log.isLoggable("PercentLayout", 2)) {
Log.v("PercentLayout", "percent margin: " + value);
}
info = info != null?info:new PercentLayoutHelper.PercentLayoutInfo();
info.leftMarginPercent = value;
info.topMarginPercent = value;
info.rightMarginPercent = value;
info.bottomMarginPercent = value;
}
value = array.getFraction(styleable.PercentLayout_Layout_layout_marginLeftPercent, 1, 1, -1.0F);
if(value != -1.0F) {
if(Log.isLoggable("PercentLayout", 2)) {
Log.v("PercentLayout", "percent left margin: " + value);
}
info = info != null?info:new PercentLayoutHelper.PercentLayoutInfo();
info.leftMarginPercent = value;
}
value = array.getFraction(styleable.PercentLayout_Layout_layout_marginTopPercent, 1, 1, -1.0F);
if(value != -1.0F) {
if(Log.isLoggable("PercentLayout", 2)) {
Log.v("PercentLayout", "percent top margin: " + value);
}
info = info != null?info:new PercentLayoutHelper.PercentLayoutInfo();
info.topMarginPercent = value;
}
value = array.getFraction(styleable.PercentLayout_Layout_layout_marginRightPercent, 1, 1, -1.0F);
if(value != -1.0F) {
if(Log.isLoggable("PercentLayout", 2)) {
Log.v("PercentLayout", "percent right margin: " + value);
}
info = info != null?info:new PercentLayoutHelper.PercentLayoutInfo();
info.rightMarginPercent = value;
}
value = array.getFraction(styleable.PercentLayout_Layout_layout_marginBottomPercent, 1, 1, -1.0F);
if(value != -1.0F) {
if(Log.isLoggable("PercentLayout", 2)) {
Log.v("PercentLayout", "percent bottom margin: " + value);
}
info = info != null?info:new PercentLayoutHelper.PercentLayoutInfo();
info.bottomMarginPercent = value;
}
value = array.getFraction(styleable.PercentLayout_Layout_layout_marginStartPercent, 1, 1, -1.0F);
if(value != -1.0F) {
if(Log.isLoggable("PercentLayout", 2)) {
Log.v("PercentLayout", "percent start margin: " + value);
}
info = info != null?info:new PercentLayoutHelper.PercentLayoutInfo();
info.startMarginPercent = value;
}
value = array.getFraction(styleable.PercentLayout_Layout_layout_marginEndPercent, 1, 1, -1.0F);
if(value != -1.0F) {
if(Log.isLoggable("PercentLayout", 2)) {
Log.v("PercentLayout", "percent end margin: " + value);
}
info = info != null?info:new PercentLayoutHelper.PercentLayoutInfo();
info.endMarginPercent = value;
}
array.recycle();
if(Log.isLoggable("PercentLayout", 3)) {
Log.d("PercentLayout", "constructed: " + info);
}
return info;
}
public void restoreOriginalParams() {
int i = 0;
for(int N = this.mHost.getChildCount(); i < N; ++i) {
View view = this.mHost.getChildAt(i);
LayoutParams params = view.getLayoutParams();
if(Log.isLoggable("PercentLayout", 3)) {
Log.d("PercentLayout", "should restore " + view + " " + params);
}
if(params instanceof PercentLayoutHelper.PercentLayoutParams) {
PercentLayoutHelper.PercentLayoutInfo info = ((PercentLayoutHelper.PercentLayoutParams)params).getPercentLayoutInfo();
if(Log.isLoggable("PercentLayout", 3)) {
Log.d("PercentLayout", "using " + info);
}
if(info != null) {
if(params instanceof MarginLayoutParams) {
info.restoreMarginLayoutParams((MarginLayoutParams)params);
} else {
info.restoreLayoutParams(params);
}
}
}
}
}
public boolean handleMeasuredStateTooSmall() {
boolean needsSecondMeasure = false;
int i = 0;
for(int N = this.mHost.getChildCount(); i < N; ++i) {
View view = this.mHost.getChildAt(i);
LayoutParams params = view.getLayoutParams();
if(Log.isLoggable("PercentLayout", 3)) {
Log.d("PercentLayout", "should handle measured state too small " + view + " " + params);
}
if(params instanceof PercentLayoutHelper.PercentLayoutParams) {
PercentLayoutHelper.PercentLayoutInfo info = ((PercentLayoutHelper.PercentLayoutParams)params).getPercentLayoutInfo();
if(info != null) {
if(shouldHandleMeasuredWidthTooSmall(view, info)) {
needsSecondMeasure = true;
params.width = -2;
}
if(shouldHandleMeasuredHeightTooSmall(view, info)) {
needsSecondMeasure = true;
params.height = -2;
}
}
}
}
if(Log.isLoggable("PercentLayout", 3)) {
Log.d("PercentLayout", "should trigger second measure pass: " + needsSecondMeasure);
}
return needsSecondMeasure;
}
private static boolean shouldHandleMeasuredWidthTooSmall(View view, PercentLayoutHelper.PercentLayoutInfo info) {
int state = ViewCompat.getMeasuredWidthAndState(view) & -16777216;
return state == 16777216 && info.widthPercent >= 0.0F && info.mPreservedParams.width == -2;
}
private static boolean shouldHandleMeasuredHeightTooSmall(View view, PercentLayoutHelper.PercentLayoutInfo info) {
int state = ViewCompat.getMeasuredHeightAndState(view) & -16777216;
return state == 16777216 && info.heightPercent >= 0.0F && info.mPreservedParams.height == -2;
}
public interface PercentLayoutParams {
PercentLayoutHelper.PercentLayoutInfo getPercentLayoutInfo();
}
public static class PercentLayoutInfo {
public float widthPercent = -1.0F;
public float heightPercent = -1.0F;
public float leftMarginPercent = -1.0F;
public float topMarginPercent = -1.0F;
public float rightMarginPercent = -1.0F;
public float bottomMarginPercent = -1.0F;
public float startMarginPercent = -1.0F;
public float endMarginPercent = -1.0F;
final MarginLayoutParams mPreservedParams = new MarginLayoutParams(0, 0);
public PercentLayoutInfo() {
}
public void fillLayoutParams(LayoutParams params, int widthHint, int heightHint) {
this.mPreservedParams.width = params.width;
this.mPreservedParams.height = params.height;
if(this.widthPercent >= 0.0F) {
params.width = (int)((float)widthHint * this.widthPercent);
}
if(this.heightPercent >= 0.0F) {
params.height = (int)((float)heightHint * this.heightPercent);
}
if(Log.isLoggable("PercentLayout", 3)) {
Log.d("PercentLayout", "after fillLayoutParams: (" + params.width + ", " + params.height + ")");
}
}
public void fillMarginLayoutParams(MarginLayoutParams params, int widthHint, int heightHint) {
this.fillLayoutParams(params, widthHint, heightHint);
this.mPreservedParams.leftMargin = params.leftMargin;
this.mPreservedParams.topMargin = params.topMargin;
this.mPreservedParams.rightMargin = params.rightMargin;
this.mPreservedParams.bottomMargin = params.bottomMargin;
MarginLayoutParamsCompat.setMarginStart(this.mPreservedParams, MarginLayoutParamsCompat.getMarginStart(params));
MarginLayoutParamsCompat.setMarginEnd(this.mPreservedParams, MarginLayoutParamsCompat.getMarginEnd(params));
if(this.leftMarginPercent >= 0.0F) {
params.leftMargin = (int)((float)widthHint * this.leftMarginPercent);
}
if(this.topMarginPercent >= 0.0F) {
params.topMargin = (int)((float)heightHint * this.topMarginPercent);
}
if(this.rightMarginPercent >= 0.0F) {
params.rightMargin = (int)((float)widthHint * this.rightMarginPercent);
}
if(this.bottomMarginPercent >= 0.0F) {
params.bottomMargin = (int)((float)heightHint * this.bottomMarginPercent);
}
if(this.startMarginPercent >= 0.0F) {
MarginLayoutParamsCompat.setMarginStart(params, (int)((float)widthHint * this.startMarginPercent));
}
if(this.endMarginPercent >= 0.0F) {
MarginLayoutParamsCompat.setMarginEnd(params, (int)((float)widthHint * this.endMarginPercent));
}
if(Log.isLoggable("PercentLayout", 3)) {
Log.d("PercentLayout", "after fillMarginLayoutParams: (" + params.width + ", " + params.height + ")");
}
}
public String toString() {
return String.format("PercentLayoutInformation width: %f height %f, margins (%f, %f, %f, %f, %f, %f)", new Object[]{Float.valueOf(this.widthPercent), Float.valueOf(this.heightPercent), Float.valueOf(this.leftMarginPercent), Float.valueOf(this.topMarginPercent), Float.valueOf(this.rightMarginPercent), Float.valueOf(this.bottomMarginPercent), Float.valueOf(this.startMarginPercent), Float.valueOf(this.endMarginPercent)});
}
public void restoreMarginLayoutParams(MarginLayoutParams params) {
this.restoreLayoutParams(params);
params.leftMargin = this.mPreservedParams.leftMargin;
params.topMargin = this.mPreservedParams.topMargin;
params.rightMargin = this.mPreservedParams.rightMargin;
params.bottomMargin = this.mPreservedParams.bottomMargin;
MarginLayoutParamsCompat.setMarginStart(params, MarginLayoutParamsCompat.getMarginStart(this.mPreservedParams));
MarginLayoutParamsCompat.setMarginEnd(params, MarginLayoutParamsCompat.getMarginEnd(this.mPreservedParams));
}
public void restoreLayoutParams(LayoutParams params) {
params.width = this.mPreservedParams.width;
params.height = this.mPreservedParams.height;
}
}
}
(3)PercentLinearLayout.java;
package android.support.percent;
import android.content.Context;
import android.content.res.TypedArray;
import android.support.percent.PercentLayoutHelper;
import android.util.AttributeSet;
import android.view.ViewGroup;
import android.widget.LinearLayout;
public class PercentLinearLayout extends LinearLayout
{
private PercentLayoutHelper mPercentLayoutHelper;
public PercentLinearLayout(Context context, AttributeSet attrs)
{
super(context, attrs);
mPercentLayoutHelper = new PercentLayoutHelper(this);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
mPercentLayoutHelper.adjustChildren(widthMeasureSpec, heightMeasureSpec);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if (mPercentLayoutHelper.handleMeasuredStateTooSmall())
{
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b)
{
super.onLayout(changed, l, t, r, b);
mPercentLayoutHelper.restoreOriginalParams();
}
@Override
public LayoutParams generateLayoutParams(AttributeSet attrs)
{
return new LayoutParams(getContext(), attrs);
}
public static class LayoutParams extends LinearLayout.LayoutParams
implements PercentLayoutHelper.PercentLayoutParams
{
private PercentLayoutHelper.PercentLayoutInfo mPercentLayoutInfo;
public LayoutParams(Context c, AttributeSet attrs)
{
super(c, attrs);
mPercentLayoutInfo = PercentLayoutHelper.getPercentLayoutInfo(c, attrs);
}
@Override
public PercentLayoutHelper.PercentLayoutInfo getPercentLayoutInfo()
{
return mPercentLayoutInfo;
}
@Override
protected void setBaseAttributes(TypedArray a, int widthAttr, int heightAttr)
{
PercentLayoutHelper.fetchWidthAndHeight(this, a, widthAttr, heightAttr);
}
public LayoutParams(int width, int height) {
super(width, height);
}
public LayoutParams(ViewGroup.LayoutParams source) {
super(source);
}
public LayoutParams(MarginLayoutParams source) {
super(source);
}
}
}
(4)PercentRelativeLayout.java;
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
package android.support.percent;
import android.content.Context;
import android.content.res.TypedArray;
import android.support.percent.PercentLayoutHelper;
import android.support.percent.PercentLayoutHelper.PercentLayoutInfo;
import android.support.percent.PercentLayoutHelper.PercentLayoutParams;
import android.util.AttributeSet;
import android.widget.RelativeLayout;
public class PercentRelativeLayout extends RelativeLayout {
private final PercentLayoutHelper mHelper = new PercentLayoutHelper(this);
public PercentRelativeLayout(Context context) {
super(context);
}
public PercentRelativeLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public PercentRelativeLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public PercentRelativeLayout.LayoutParams generateLayoutParams(AttributeSet attrs) {
return new PercentRelativeLayout.LayoutParams(this.getContext(), attrs);
}
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
this.mHelper.adjustChildren(widthMeasureSpec, heightMeasureSpec);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if(this.mHelper.handleMeasuredStateTooSmall()) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
this.mHelper.restoreOriginalParams();
}
public static class LayoutParams extends android.widget.RelativeLayout.LayoutParams implements PercentLayoutParams {
private PercentLayoutInfo mPercentLayoutInfo;
public LayoutParams(Context c, AttributeSet attrs) {
super(c, attrs);
this.mPercentLayoutInfo = PercentLayoutHelper.getPercentLayoutInfo(c, attrs);
}
public LayoutParams(int width, int height) {
super(width, height);
}
public LayoutParams(android.view.ViewGroup.LayoutParams source) {
super(source);
}
public LayoutParams(MarginLayoutParams source) {
super(source);
}
public PercentLayoutInfo getPercentLayoutInfo() {
return this.mPercentLayoutInfo;
}
protected void setBaseAttributes(TypedArray a, int widthAttr, int heightAttr) {
PercentLayoutHelper.fetchWidthAndHeight(this, a, widthAttr, heightAttr);
}
}
}
接下来是一些布局的使用案列:
percent_framelayout.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.percent.PercentFrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#ff44aacc"
app:layout_heightPercent="100%"
app:layout_widthPercent="100%" />
<View
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_below="@+id/top_left"
android:background="#ff00ff22"
app:layout_heightPercent="20%"
app:layout_widthPercent="20%"
android:layout_gravity="bottom|end" />
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#ffe40000"
app:layout_heightPercent="50%"
app:layout_widthPercent="50%" />
</android.support.percent.PercentFrameLayout>
效果图如下:
percent_linearlayout.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.percent.PercentLinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#ff44aacc"
android:text="width:60%,height:5%"
android:textColor="#ffffff"
app:layout_heightPercent="5%"
app:layout_marginBottomPercent="5%"
app:layout_widthPercent="60%"/>
<TextView
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#ff4400cc"
android:gravity="center"
android:textColor="#ffffff"
android:text="width:70%,height:10%"
app:layout_heightPercent="10%"
app:layout_marginBottomPercent="5%"
app:layout_widthPercent="70%"/>
<TextView
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#ff44aacc"
android:gravity="center"
android:text="width:80%,height:15%"
android:textColor="#ffffff"
app:layout_heightPercent="15%"
app:layout_marginBottomPercent="5%"
app:layout_widthPercent="80%"/>
<TextView
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#ff4400cc"
android:gravity="center"
android:text="width:90%,height:5%"
android:textColor="#ffffff"
app:layout_heightPercent="20%"
app:layout_marginBottomPercent="5%"
app:layout_widthPercent="90%"/>
<TextView
android:layout_width="match_parent"
android:layout_height="0dp"
android:background="#ff44aacc"
android:gravity="center"
android:text="width:100%,height:25%"
android:textColor="#ffffff"
app:layout_heightPercent="25%"
app:layout_marginBottomPercent="5%"
/>
</android.support.percent.PercentLinearLayout>
效果图如下:
percent_relativelayout.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.percent.PercentRelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="true">
<View
android:id="@+id/row_one_item_one"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_alignParentTop="true"
android:background="#5182bb"
app:layout_heightPercent="15%"
app:layout_widthPercent="30%" />
<View
android:id="@+id/row_one_item_two"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_toRightOf="@+id/row_one_item_one"
android:background="#396190"
app:layout_heightPercent="15%"
app:layout_widthPercent="30%" />
<View
android:id="@+id/row_one_item_three"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_toRightOf="@+id/row_one_item_two"
android:background="#8fb5e1"
app:layout_heightPercent="15%"
app:layout_widthPercent="40%" />
<View
android:id="@+id/row_two_item_one"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_below="@+id/row_one_item_one"
android:background="#d89695"
app:layout_heightPercent="15%" />
<View
android:id="@+id/row_three_item_one"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_below="@+id/row_two_item_one"
android:background="#f9c093"
app:layout_heightPercent="20%"
app:layout_widthPercent="40%" />
<View
android:id="@+id/row_three_item_two"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_below="@+id/row_two_item_one"
android:layout_toRightOf="@+id/row_three_item_one"
android:background="#948957"
app:layout_heightPercent="10%"
app:layout_widthPercent="60%" />
<View
android:id="@+id/row_four_item_one"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_below="@+id/row_three_item_one"
android:background="#ccc2d9"
app:layout_heightPercent="20%"
app:layout_widthPercent="40%" />
<View
android:id="@+id/row_four_item_two"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_below="@+id/row_three_item_two"
android:layout_toRightOf="@+id/row_four_item_one"
android:background="#c3d59e"
app:layout_heightPercent="25%"
app:layout_widthPercent="60%" />
<View
android:id="@+id/row_five_item_one"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_below="@+id/row_four_item_one"
android:background="#948957"
app:layout_heightPercent="10%"
app:layout_widthPercent="40%" />
<View
android:id="@+id/row_five_item_two"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_below="@+id/row_four_item_two"
android:layout_toRightOf="@+id/row_five_item_one"
android:background="#e6e0ec"
app:layout_heightPercent="10%"
app:layout_widthPercent="60%" />
<View
android:id="@+id/row_six_item_one"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_below="@+id/row_five_item_one"
android:background="#f9c093"
app:layout_heightPercent="20%"
app:layout_widthPercent="20%" />
<View
android:id="@+id/row_six_item_two"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_below="@+id/row_five_item_one"
android:layout_toRightOf="@+id/row_six_item_one"
android:background="#588fd3"
app:layout_heightPercent="20%"
app:layout_widthPercent="20%" />
<View
android:id="@+id/row_six_item_three"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_below="@+id/row_five_item_two"
android:layout_toRightOf="@+id/row_six_item_two"
android:background="#a6a6a6"
app:layout_heightPercent="25%"
app:layout_widthPercent="60%" />
</android.support.percent.PercentRelativeLayout>
效果图如下:
来自 gitbub:https://github.com/JulienGenoud/android-percent-support-lib-sample
来源:CSDN
作者:qq_26337701
链接:https://blog.csdn.net/qq_26337701/article/details/52210723