最近在总结android屏幕适配,发现LinearLayout有android:layout_weight这个属性,可以控制各个内部控件的占比。如果任何布局引入百分比形式的布局方式那么适配效果会很不错,也简单。 通过查找发现,谷歌官方在2年前就发布了百分比布局库,android-percent-support-lib-sample。
GitHub链接: https://github.com/JulienGenoud/android-percent-support-lib-sample
API链接: https://developer.android.com/reference/android/support/percent/package-summary.html
百分比软件包提供的 API 支持向应用中添加基于百分比的尺寸并对其进行管理。
两种布局提供使用: PercentRelativeLayout、PercentFrameLayout LinearLayout布局通过weight属性控制百分比
支持属性: layout_widthPercent layout_heightPercent layout_marginPercent layout_marginLeftPercent layout_marginTopPercent layout_marginRightPercent layout_marginBottomPercent layout_marginStartPercent layout_marginEndPercent layout_aspectRatio:用来表示宽高比例,当我们指定宽或者高的任一边的长度或者百分比,其就能够自动地计算出来另外一边的长度。
(1)添加依赖库
dependencies { compile 'com.android.support:percent:24.2.0' }(2)PercentRelativeLayout 效果图:
<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"> <View android:id="@+id/top_left" android:layout_width="0dp" android:layout_height="0dp" android:layout_alignParentTop="true" android:background="#ff44aacc" app:layout_heightPercent="20%" app:layout_widthPercent="70%" /> <View android:id="@+id/top_right" android:layout_width="0dp" android:layout_height="0dp" android:layout_alignParentTop="true" android:layout_toRightOf="@+id/top_left" android:background="#ffe40000" app:layout_heightPercent="20%" app:layout_widthPercent="30%" /> <View android:id="@+id/bottom" android:layout_width="match_parent" android:layout_height="0dp" android:layout_below="@+id/top_left" android:background="#ff00ff22" app:layout_heightPercent="80%" /> </android.support.percent.PercentRelativeLayout>(3)PercentFrameLayout 效果图:
<android.support.percent.PercentFrameLayout android:layout_width="match_parent" android:layout_height="match_parent" android:layout_alignParentTop="true" android:layout_alignParentLeft="true" android:layout_alignParentStart="true"> <ImageView app:layout_widthPercent="50%" app:layout_heightPercent="50%" android:background="@color/colorPrimary" app:layout_marginTopPercent="25%" app:layout_marginLeftPercent="25%"/> </android.support.percent.PercentFrameLayout>用法简单直接。
我们先来看PercentRelativeLayout的源码,源码很短:
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); } @Override protected LayoutParams generateDefaultLayoutParams() { return new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); } @Override public LayoutParams generateLayoutParams(AttributeSet attrs) { return new LayoutParams(getContext(), attrs); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { mHelper.adjustChildren(widthMeasureSpec, heightMeasureSpec); super.onMeasure(widthMeasureSpec, heightMeasureSpec); if (mHelper.handleMeasuredStateTooSmall()) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); } } @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); mHelper.restoreOriginalParams(); } public static class LayoutParams extends RelativeLayout.LayoutParams implements PercentLayoutHelper.PercentLayoutParams { private PercentLayoutHelper.PercentLayoutInfo mPercentLayoutInfo; public LayoutParams(Context c, AttributeSet attrs) { super(c, attrs); mPercentLayoutInfo = PercentLayoutHelper.getPercentLayoutInfo(c, attrs); } public LayoutParams(int width, int height) { super(width, height); } public LayoutParams(ViewGroup.LayoutParams source) { super(source); } public LayoutParams(MarginLayoutParams source) { super(source); } @Override public PercentLayoutHelper.PercentLayoutInfo getPercentLayoutInfo() { if (mPercentLayoutInfo == null) { mPercentLayoutInfo = new PercentLayoutHelper.PercentLayoutInfo(); } return mPercentLayoutInfo; } @Override protected void setBaseAttributes(TypedArray a, int widthAttr, int heightAttr) { PercentLayoutHelper.fetchWidthAndHeight(this, a, widthAttr, heightAttr); } } }首先重写了generateLayoutParams方法,当然了,由于为了支持了新的layout_属性,那么肯定需要定义对应的LayoutParams。主要是以下几步:
LayoutParams中属性的获取onMeasure中,改变params.width为百分比计算结果,测量如果测量值过小且设置的w/h是wrap_content,重新测量onLayout中,重置params.w/h为布局文件中编写的值想要详细了解理论原理,请参考: http://blog.csdn.net/lmj623565791/article/details/46695347