百分比布局让其中的控件在指定高度,宽度,margin时使用屏幕宽高的百分比,不使用dp,px。这样一套布局可以适应多个屏幕,方便适配。如:

  app:layout_heightPercent="30%"
  • 它们分别为 图1. 2.7''_ 240*320:ldpi 图2. 4.0''_480*800:hdpi 图3. 5.5''_1440*2560:560dpi 图4. 8.86''_2048*1536:xhdpi
  • 点击可看原图
  • 根百分比布局背景色    :#c2c2c2
  • 其它百分比布局背景色:#8b0a50
  • 2. ConstraintLayout 实现百分比布局

    PercentRelativeLayout等百分比布局与 ConstraintLayout 等不兼容, ConstraintLayout 支持的百分比方法有下面几种:

  • Guideline .
  • bias :              app:layout_constraintHorizontal_bias="0.3" 和 app:layout_constraintVertical_bias="0.3"
  • 百分比值 :       app:layout_constraintWidth_percent="0.4"  和 app:layout_constraintHeight_percent="0.9"
  • 宽高比 :          app:layout_constraintDimensionRatio
  • 2.1 Guideline.

     1     <android.support.constraint.Guideline
     2         android:id="@+id/guideline"
     3         android:layout_width="wrap_content"
     4         android:layout_height="wrap_content"
     5         android:orientation="vertical"
     6         app:layout_constraintGuide_percent="0.3046875" />
     8     <TextView
     9         android:id="@+id/txt_args_minimumLatency"
    10         android:layout_width="0dp"
    11         android:layout_height="wrap_content"
    12         android:layout_marginEnd="8dp"
    13         android:layout_marginLeft="8dp"
    14         android:layout_marginRight="8dp"
    15         android:layout_marginStart="8dp"
    16         android:layout_marginTop="16dp"
    17         android:gravity="end|center_vertical"
    18         android:text="最小反应时间 : "
    19         app:layout_constraintEnd_toStartOf="@+id/guideline"
    20         app:layout_constraintStart_toStartOf="parent"
    21         app:layout_constraintTop_toBottomOf="@+id/txt_arg_connectivity" />

    2.2 bias

    同时指定左右方相对约束后,可以指定在左右之间的百分比。 app:layout_constraintHorizontal_bias="0.9"

    上下同理。 app:layout_constraintVertical_bias="0.8"

     1 <?xml version="1.0" encoding="utf-8"?>
     2 <androidx.constraintlayout.widget.ConstraintLayout
     3         xmlns:android="http://schemas.android.com/apk/res/android"
     4         xmlns:tools="http://schemas.android.com/tools"
     5         xmlns:app="http://schemas.android.com/apk/res-auto"
     6         android:layout_width="match_parent"
     7         android:layout_height="match_parent"
     8         tools:context=".MainActivity">
    10     <TextView
    11             android:layout_width="wrap_content"
    12             android:layout_height="wrap_content"
    13             android:text="Hello World!"
    14             app:layout_constraintVertical_bias="0.8"
    15             app:layout_constraintHorizontal_bias="0.9"
    16             app:layout_constraintBottom_toBottomOf="parent"
    17             app:layout_constraintLeft_toLeftOf="parent"
    18             app:layout_constraintRight_toRightOf="parent"
    19             app:layout_constraintTop_toTopOf="parent"/>
    21 </androidx.constraintlayout.widget.ConstraintLayout> 

    2.3 百分比值

    用app:layout_constraintWidth_percent="0.4"  和 app:layout_constraintHeight_percent="0.9" 设置该控件相对父布局的百分比大小。

    注意:在 android:layout_width="0dp" 时,app:layout_constraintWidth_percent="0.4"才生效,高度百分比同理。

     1  <Button
     2         android:id="@+id/btn_login"
     3         android:layout_width="0dp"
     4         app:layout_constraintWidth_percent="0.4"
     5         android:layout_height="0dp"
     6         app:layout_constraintHeight_percent="0.9"
     7         android:layout_marginStart="8dp"
     8         android:layout_marginTop="8dp"
     9         android:layout_marginEnd="8dp"
    10         android:layout_marginBottom="8dp"
    11         android:background="@drawable/selector_login_button"
    12         android:enabled="false"
    13         android:maxLength="32"
    14         android:maxLines="1"
    15         android:text="登录"
    16         android:textColor="#fff"
    17         android:textSize="15sp"
    18         app:layout_constraintBottom_toBottomOf="parent"
    19         app:layout_constraintEnd_toEndOf="parent"
    20         app:layout_constraintStart_toStartOf="parent"
    21         app:layout_constraintTop_toTopOf="parent"
    22         />

    2.4 宽高比

    宽度/高度的比值:app:layout_constraintDimensionRatio,注意宽、高中必需有一个是0dp,才可以。使用它可以根据宽算高,或者根据高算宽。

     1   <ImageView
     2         android:id="@+id/finish_delete_icon"
     3         android:layout_width="22dp"
     4         android:layout_height="0dp"
     5         app:layout_constraintDimensionRatio="0.5"
     6         android:src="@mipmap/delete"
     7         android:textColor="@color/title_color"
     8         app:layout_constraintEnd_toEndOf="parent"
     9         app:layout_constraintHorizontal_bias="0.33"
    10         app:layout_constraintStart_toStartOf="parent"
    11         app:layout_constraintTop_toTopOf="parent"
    12         />

    2.5 如何用代码修改百分比布局

     1  @Override
     2     public void onKeyboardChange(boolean isShow, int keyboardHeight) {
     3         ConstraintLayout.LayoutParams params = (ConstraintLayout.LayoutParams) mBtnLogin.getLayoutParams();
     4         if (isShow ) {
     5             params.matchConstraintPercentWidth = 0.8f;  //修改百分比宽度
     6             params.verticalBias = 0.93f;                //修改百分比位置,横向同理
     7         } else  {
     8             params.matchConstraintPercentWidth = 0.3f;  //修改百分比宽度
     9             params.verticalBias = 0.65f;                //修改百分比位置,横向同理
    10         }
    12         /*       
    13           //其它同理 ,如:
    14           params.guidePercent = 0.3f;
    15           params.verticalWeight = 2;
    16         */
    18         mBtnLogin.setLayoutParams(params);
    

      上方红底白字是percent支援包版本号,在sdk/extras/android/m2repository/com/android/support/percent/ 目录下有详细的版本。

      可以使用 26.+ 也可以使用具体版本号如:26.0.0-alpha1 .

    4.常用百分比布局

    PercentRelativeLayout 相对百分比布局 PercentFrameLayout 相对层百分比布局 PercentLinearLayout 相对线性百分比布局,这个在com.android.support:percent中没有,本文提供代码。把它加到项目中就可以。

    5.百分比布局属性

    5.1 属性表

    app:layout_widthPercent 控件宽度百分比(相对屏幕宽度) 

    app:layout_widthPercent="100%"

    app:layout_heightPercent 控件高度百分比(相对屏幕高度)

    app:layout_heightPercent="50%"

    5.2 注意事项

  • app:layout_marginStartPercent="10%"与 app:layout_marginEndPercent="10%" 成对出现指定最大宽度
  • app:layout_marginLeftPercent="30%" 与 app:layout_marginRightPercent="30%"成对出现指定最大宽度
  • 只要layout_marginStartPercent 这对中出现一个,则layout_marginLeftPercent 这对无效。
  • app:layout_xxx与android:layout_xxx 在指定相同含义(如都指定左边距)时,取app:layout_xxx的值。
  • 最好只使用百分比系列的属性,也可混合使用。
    1 app:layout_marginRightPercent="30%"
    2 android:layout_marginLeft="5dp"

    6.相对百分比布局

     1 <?xml version="1.0" encoding="utf-8"?>
     2 <android.support.percent.PercentRelativeLayout
     3     xmlns:android="http://schemas.android.com/apk/res/android"
     4     xmlns:app="http://schemas.android.com/apk/res-auto"
     5     android:layout_width="match_parent"
     6     android:layout_height="match_parent">
     9     <ImageButton
    10         android:id="@+id/imageButton"
    12         app:layout_widthPercent="30%"
    13         app:layout_heightPercent="30%"
    15         app:layout_marginLeftPercent="20%"
    16         app:layout_marginRightPercent="20%"
    18         app:layout_marginStartPercent="10%"
    19         app:layout_marginEndPercent="10%"
    21         app:layout_marginTopPercent="10%"
    22         app:layout_marginBottomPercent="10%"
    24         app:srcCompat="@android:drawable/ic_notification_overlay" />
    26     <ImageView
    27         android:id="@+id/imageView"
    29         app:layout_widthPercent="30%"
    30         app:layout_heightPercent="30%"
    33         app:layout_marginLeftPercent="50%"
    34         app:layout_marginRightPercent="10%"
    36         app:layout_marginTopPercent="10%"
    37         app:layout_marginBottomPercent="10%"
    39         app:srcCompat="@drawable/qq" />
    42     <com.google.android.gms.maps.MapView
    43         android:id="@+id/mapView"
    44         android:background="#d3a16c"
    46         app:layout_widthPercent="100%"
    47         app:layout_heightPercent="50%"
    49         app:layout_marginLeftPercent="10%"
    50         app:layout_marginRightPercent="10%"
    52         app:layout_marginStartPercent="3%"
    53         app:layout_marginEndPercent="3%"
    55         app:layout_marginTopPercent="5%"
    56         app:layout_marginBottomPercent="5%"
    58         android:layout_alignParentBottom="true" />
    60 </android.support.percent.PercentRelativeLayout>

    7.层百分比布局

     1 <?xml version="1.0" encoding="utf-8"?>
     2 <android.support.percent.PercentFrameLayout
     3     xmlns:android="http://schemas.android.com/apk/res/android"
     4     xmlns:app="http://schemas.android.com/apk/res-auto"
     5     android:layout_width="match_parent"
     6     android:layout_height="match_parent">
     7     <!-- ... XML CODE -->
     9     <TextView
    10         android:id="@+id/textView"
    12         android:text="hello"
    13         android:textAlignment="center"
    15         app:layout_widthPercent="60%"
    16         app:layout_heightPercent="60%"
    18         app:layout_marginStartPercent="20%"
    19         app:layout_marginEndPercent="20%"
    21         app:layout_marginTopPercent="10%"
    22         app:layout_marginBottomPercent="10%"
    24         android:background="#f5a61e"/>
    26 </android.support.percent.PercentFrameLayout>

    8.线性百分比布局

      把PercentLinearLayout.java加入到源码中:

     1 package com.example.tt.percent;
     3 import android.content.Context;
     4 import android.content.res.TypedArray;
     5 import android.support.percent.PercentLayoutHelper;
     6 import android.util.AttributeSet;
     7 import android.view.ViewGroup;
     8 import android.widget.LinearLayout;
    10 public class PercentLinearLayout extends LinearLayout
    11 {
    13     private PercentLayoutHelper mPercentLayoutHelper;
    15     public PercentLinearLayout(Context context, AttributeSet attrs)
    16     {
    17         super(context, attrs);
    19         mPercentLayoutHelper = new PercentLayoutHelper(this);
    20     }
    23     @Override
    24     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
    25     {
    26         mPercentLayoutHelper.adjustChildren(widthMeasureSpec, heightMeasureSpec);
    27         super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    28         if (mPercentLayoutHelper.handleMeasuredStateTooSmall())
    29         {
    30             super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    31         }
    32     }
    34     @Override
    35     protected void onLayout(boolean changed, int l, int t, int r, int b)
    36     {
    37         super.onLayout(changed, l, t, r, b);
    38         mPercentLayoutHelper.restoreOriginalParams();
    39     }
    41     @Override
    42     public LayoutParams generateLayoutParams(AttributeSet attrs)
    43     {
    44         return new LayoutParams(getContext(), attrs);
    45     }
    48     public static class LayoutParams extends LinearLayout.LayoutParams
    49             implements PercentLayoutHelper.PercentLayoutParams
    50     {
    51         private PercentLayoutHelper.PercentLayoutInfo mPercentLayoutInfo;
    53         public LayoutParams(Context c, AttributeSet attrs)
    54         {
    55             super(c, attrs);
    56             mPercentLayoutInfo = PercentLayoutHelper.getPercentLayoutInfo(c, attrs);
    57         }
    59         @Override
    60         public PercentLayoutHelper.PercentLayoutInfo getPercentLayoutInfo()
    61         {
    62             return mPercentLayoutInfo;
    63         }
    65         @Override
    66         protected void setBaseAttributes(TypedArray a, int widthAttr, int heightAttr)
    67         {
    68             PercentLayoutHelper.fetchWidthAndHeight(this, a, widthAttr, heightAttr);
    69         }
    71         public LayoutParams(int width, int height) {
    72             super(width, height);
    73         }
    76         public LayoutParams(ViewGroup.LayoutParams source) {
    77             super(source);
    78         }
    80         public LayoutParams(MarginLayoutParams source) {
    81             super(source);
    82         }
    84     }
    

      使用相对布局时注意:android:layout_width和height要为0dp。光指定 app:layout_heightPercent 不行。

     1 <?xml version="1.0" encoding="utf-8"?>
     2 <com.example.tt.percent.PercentLinearLayout
     3     xmlns:android="http://schemas.android.com/apk/res/android"
     4     xmlns:app="http://schemas.android.com/apk/res-auto"
     5     android:layout_width="match_parent"
     6     android:layout_height="match_parent"
     7     android:orientation="vertical">
     8     <View
     9         android:layout_width="0dp"
    10         android:layout_height="0dp"
    11         android:background="#ff44aacc"
    12         app:layout_heightPercent="10%"
    13         app:layout_widthPercent="60%"/>
    15     <View
    16         android:layout_width="0dp"
    17         android:layout_height="0dp"
    18         android:background="#ff4400cc"
    19         app:layout_heightPercent="10%"
    20         app:layout_widthPercent="70%"/>
    22 </com.example.tt.percent.PercentLinearLayout>

    9.复合使用百分比布局

      1 <?xml version="1.0" encoding="utf-8"?>
      3 <android.support.percent.PercentRelativeLayout
      4     xmlns:android="http://schemas.android.com/apk/res/android"
      5     xmlns:app="http://schemas.android.com/apk/res-auto"
      6     android:layout_width="match_parent"
      7     android:layout_height="match_parent"
      8     android:background="@color/colorParentLayout">
     11     <com.example.tt.percent.PercentLinearLayout
     12         android:orientation="horizontal"
     13         android:id="@+id/percentLinearLayout"
     14         app:layout_widthPercent="98%"
     15         app:layout_heightPercent="30%"
     16         app:layout_marginStartPercent="1%"
     17         app:layout_marginEndPercent="1%"
     18         app:layout_marginTopPercent="1%"
     19         app:layout_marginBottomPercent="1%"
     20         android:background="@color/colorChildLayout"
     23         <ImageButton
     24             android:id="@+id/imageButton"
     25             android:layout_width="0dp"
     26             android:layout_height="0dp"
     27             android:contentDescription="w=45%,h=94%"
     28             app:layout_widthPercent="45%"
     29             app:layout_heightPercent="94%"
     30             app:layout_marginStartPercent="2%"
     31             app:layout_marginEndPercent="2%"
     32             app:layout_marginTopPercent="3%"
     33             app:layout_marginBottomPercent="3%"
     34             android:background="#efdd82"
     35             app:srcCompat="@android:drawable/ic_notification_overlay" />
     37         <ImageView
     38             android:id="@+id/imageView"
     39             android:layout_width="0dp"
     40             android:layout_height="0dp"
     41             android:background="#7819d2"
     42             app:layout_widthPercent="45%"
     43             app:layout_heightPercent="94%"
     44             app:layout_marginStartPercent="2%"
     45             app:layout_marginEndPercent="2%"
     46             app:layout_marginTopPercent="3%"
     47             app:layout_marginBottomPercent="3%"
     48             android:contentDescription="w=45%,h=94%"
     50             app:srcCompat="@drawable/qq" />
     52     </com.example.tt.percent.PercentLinearLayout>
     54     <android.support.percent.PercentRelativeLayout
     55         android:layout_below="@+id/percentLinearLayout"
     56         app:layout_widthPercent="98%"
     57         app:layout_heightPercent="25%"
     58         android:background="@color/colorChildLayout"
     59         app:layout_marginStartPercent="1%"
     60         app:layout_marginEndPercent="1%"
     61         app:layout_marginTopPercent="1%"
     62         app:layout_marginBottomPercent="1%"
     65         <com.example.tt.percent.PercentLinearLayout
     66             android:id="@+id/lineLayout"
     67             app:layout_widthPercent="46%"
     68             app:layout_heightPercent="100%"
     69             app:layout_marginStartPercent="2%"
     70             app:layout_marginTopPercent="3%"
     71             app:layout_marginBottomPercent="3%"
     72             android:background="#7d6a5e"
     73             android:orientation="vertical">
     75             <TextView
     76                 android:layout_width="0dp"
     77                 android:layout_height="0dp"
     78                 android:background="#ff44aacc"
     79                 android:text="w=78.923%,h=43%"
     80                 app:layout_heightPercent="43%"
     81                 app:layout_widthPercent="78.923%"
     82                 app:layout_marginStartPercent="3%"
     83                 app:layout_marginTopPercent="3%"
     84                 app:layout_marginBottomPercent="3%"/>
     86             <TextView
     87                 android:layout_width="0dp"
     88                 android:layout_height="0dp"
     89                 android:background="#ff4400cc"
     90                 android:text="w=89.99%,h=43%"
     91                 app:layout_heightPercent="43%"
     92                 app:layout_widthPercent="89.99%"
     93                 app:layout_marginStartPercent="3%"
     94                 app:layout_marginTopPercent="3%"
     95                 app:layout_marginBottomPercent="3%"/>
     97         </com.example.tt.percent.PercentLinearLayout>
     99         <android.support.percent.PercentFrameLayout
    100             android:layout_toRightOf="@+id/lineLayout"
    101             app:layout_widthPercent="46%"
    102             app:layout_heightPercent="100%"
    103             android:background="#9f8ea7"
    104             app:layout_marginStartPercent="2%"
    105             app:layout_marginTopPercent="3%"
    106             app:layout_marginBottomPercent="3%"
    108             android:id="@+id/percentFrameLayout">
    110             <TextView
    111                 android:id="@+id/textView"
    112                 android:background="#f5a61e"
    113                 android:text="w=90%,h=60%\nbottom=3%,top=3%\nstart=3%,end=3%"
    114                 app:layout_heightPercent="60%"
    115                 app:layout_widthPercent="90%"
    116                 app:layout_marginStartPercent="3%"
    117                 app:layout_marginEndPercent="3%"
    118                 app:layout_marginTopPercent="3%"
    119                 app:layout_marginBottomPercent="3%"
    120                 />
    122         </android.support.percent.PercentFrameLayout>
    123     </android.support.percent.PercentRelativeLayout>
    125     <android.support.percent.PercentFrameLayout
    126         app:layout_widthPercent="100%"
    127         app:layout_heightPercent="40%"
    128         app:layout_marginStartPercent="1%"
    129         app:layout_marginEndPercent="1%"
    131         app:layout_marginTopPercent="60%"
    132         app:layout_marginBottomPercent="1%"
    133         android:background="@color/colorChildLayout"
    136         <ImageView
    137             android:id="@+id/mapView"
    139             android:contentDescription="w=48%,h=98%"
    140             android:background="#555555"
    141             android:layout_alignParentBottom="true"
    143             app:layout_widthPercent="98%"
    144             app:layout_heightPercent="48%"
    146             app:layout_marginStartPercent="1%"
    147             app:layout_marginEndPercent="1%"
    149             app:layout_marginTopPercent="5%"
    150             app:layout_marginBottomPercent="1%"
    152             app:srcCompat="@drawable/google" />
    154         <Button
    155             android:id="@+id/btn_bottom"
    156             app:layout_widthPercent="98%"
    157             app:layout_heightPercent="40%"
    159             app:layout_marginStartPercent="1%"
    160             app:layout_marginEndPercent="1%"
    162             app:layout_marginTopPercent="55%"
    163             app:layout_marginBottomPercent="1%"
    164             android:textAlignment="center"
    165             android:textAllCaps="false"
    166             android:text="Button:w=98%,h=40%" />
    168     </android.support.percent.PercentFrameLayout>
    171 </android.support.percent.PercentRelativeLayout>

    10.下载示例

      https://git.oschina.net/xi/PercentLayout.git

  •