Android百分比布局方案
百分比布局让其中的控件在指定高度,宽度,margin时使用屏幕宽高的百分比,不使用dp,px。这样一套布局可以适应多个屏幕,方便适配。如:
app:layout_heightPercent="30%"
1.效果
- 它们分别为 图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" /> 7 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"> 9 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"/> 20 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 } 11 12 /* 13 //其它同理 ,如: 14 params.guidePercent = 0.3f; 15 params.verticalWeight = 2; 16 */ 17 18 mBtnLogin.setLayoutParams(params); 19 }
下面是原百分比布局示例,可以不用往下看了
3.引入库
在module的build.gradle的加入 compile 'com.android.support:percent:26.+'
1 dependencies { 2 //... 3 compile 'com.android.support:percent:26.+' 4 }
上方红底白字是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%" |
app:layout_marginLeftPercent |
控件的左边距百分比(相对于屏幕宽度) |
app:layout_marginLeftPercent="1%" |
app:layout_marginRightPercent |
控件的右边距百分比(相对于屏幕宽度) |
app:layout_marginRightPercent="1%" |
app:layout_marginStartPercent |
控件开始距离百分比(相对于屏幕宽度或高度) |
app:layout_marginStartPercent="1%" |
app:layout_marginEndPercent |
控件结尾距离百分比(相对于屏幕宽度或高度) |
app:layout_marginEndPercent="1%" |
app:layout_marginTopPercent |
上边距百分比(相对于屏幕高度) |
app:layout_marginTopPercent="1%" |
app:layout_marginBottomPercent |
下边距百分比(相对于屏幕高度) |
app:layout_marginBottomPercent="1%" |
app:marginPercent |
所有边距百分比(相对于屏幕高度和高度) |
app:marginPercent="1%" |
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"> 7 8 9 <ImageButton 10 android:id="@+id/imageButton" 11 12 app:layout_widthPercent="30%" 13 app:layout_heightPercent="30%" 14 15 app:layout_marginLeftPercent="20%" 16 app:layout_marginRightPercent="20%" 17 18 app:layout_marginStartPercent="10%" 19 app:layout_marginEndPercent="10%" 20 21 app:layout_marginTopPercent="10%" 22 app:layout_marginBottomPercent="10%" 23 24 app:srcCompat="@android:drawable/ic_notification_overlay" /> 25 26 <ImageView 27 android:id="@+id/imageView" 28 29 app:layout_widthPercent="30%" 30 app:layout_heightPercent="30%" 31 32 33 app:layout_marginLeftPercent="50%" 34 app:layout_marginRightPercent="10%" 35 36 app:layout_marginTopPercent="10%" 37 app:layout_marginBottomPercent="10%" 38 39 app:srcCompat="@drawable/qq" /> 40 41 42 <com.google.android.gms.maps.MapView 43 android:id="@+id/mapView" 44 android:background="#d3a16c" 45 46 app:layout_widthPercent="100%" 47 app:layout_heightPercent="50%" 48 49 app:layout_marginLeftPercent="10%" 50 app:layout_marginRightPercent="10%" 51 52 app:layout_marginStartPercent="3%" 53 app:layout_marginEndPercent="3%" 54 55 app:layout_marginTopPercent="5%" 56 app:layout_marginBottomPercent="5%" 57 58 android:layout_alignParentBottom="true" /> 59 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 --> 8 9 <TextView 10 android:id="@+id/textView" 11 12 android:text="hello" 13 android:textAlignment="center" 14 15 app:layout_widthPercent="60%" 16 app:layout_heightPercent="60%" 17 18 app:layout_marginStartPercent="20%" 19 app:layout_marginEndPercent="20%" 20 21 app:layout_marginTopPercent="10%" 22 app:layout_marginBottomPercent="10%" 23 24 android:background="#f5a61e"/> 25 26 </android.support.percent.PercentFrameLayout>
8.线性百分比布局
把PercentLinearLayout.java加入到源码中:
1 package com.example.tt.percent; 2 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; 9 10 public class PercentLinearLayout extends LinearLayout 11 { 12 13 private PercentLayoutHelper mPercentLayoutHelper; 14 15 public PercentLinearLayout(Context context, AttributeSet attrs) 16 { 17 super(context, attrs); 18 19 mPercentLayoutHelper = new PercentLayoutHelper(this); 20 } 21 22 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 } 33 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 } 40 41 @Override 42 public LayoutParams generateLayoutParams(AttributeSet attrs) 43 { 44 return new LayoutParams(getContext(), attrs); 45 } 46 47 48 public static class LayoutParams extends LinearLayout.LayoutParams 49 implements PercentLayoutHelper.PercentLayoutParams 50 { 51 private PercentLayoutHelper.PercentLayoutInfo mPercentLayoutInfo; 52 53 public LayoutParams(Context c, AttributeSet attrs) 54 { 55 super(c, attrs); 56 mPercentLayoutInfo = PercentLayoutHelper.getPercentLayoutInfo(c, attrs); 57 } 58 59 @Override 60 public PercentLayoutHelper.PercentLayoutInfo getPercentLayoutInfo() 61 { 62 return mPercentLayoutInfo; 63 } 64 65 @Override 66 protected void setBaseAttributes(TypedArray a, int widthAttr, int heightAttr) 67 { 68 PercentLayoutHelper.fetchWidthAndHeight(this, a, widthAttr, heightAttr); 69 } 70 71 public LayoutParams(int width, int height) { 72 super(width, height); 73 } 74 75 76 public LayoutParams(ViewGroup.LayoutParams source) { 77 super(source); 78 } 79 80 public LayoutParams(MarginLayoutParams source) { 81 super(source); 82 } 83 84 } 85 86 }
使用相对布局时注意: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%"/> 14 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%"/> 21 22 </com.example.tt.percent.PercentLinearLayout>
9.复合使用百分比布局
1 <?xml version="1.0" encoding="utf-8"?> 2 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"> 9 10 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" 21 > 22 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" /> 36 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%" 49 50 app:srcCompat="@drawable/qq" /> 51 52 </com.example.tt.percent.PercentLinearLayout> 53 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%" 63 > 64 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"> 74 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%"/> 85 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%"/> 96 97 </com.example.tt.percent.PercentLinearLayout> 98 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%" 107 108 android:id="@+id/percentFrameLayout"> 109 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 /> 121 122 </android.support.percent.PercentFrameLayout> 123 </android.support.percent.PercentRelativeLayout> 124 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%" 130 131 app:layout_marginTopPercent="60%" 132 app:layout_marginBottomPercent="1%" 133 android:background="@color/colorChildLayout" 134 > 135 136 <ImageView 137 android:id="@+id/mapView" 138 139 android:contentDescription="w=48%,h=98%" 140 android:background="#555555" 141 android:layout_alignParentBottom="true" 142 143 app:layout_widthPercent="98%" 144 app:layout_heightPercent="48%" 145 146 app:layout_marginStartPercent="1%" 147 app:layout_marginEndPercent="1%" 148 149 app:layout_marginTopPercent="5%" 150 app:layout_marginBottomPercent="1%" 151 152 app:srcCompat="@drawable/google" /> 153 154 <Button 155 android:id="@+id/btn_bottom" 156 app:layout_widthPercent="98%" 157 app:layout_heightPercent="40%" 158 159 app:layout_marginStartPercent="1%" 160 app:layout_marginEndPercent="1%" 161 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%" /> 167 168 </android.support.percent.PercentFrameLayout> 169 170 171 </android.support.percent.PercentRelativeLayout>
10.下载示例
https://git.oschina.net/xi/PercentLayout.git