Android适配—百分比布局库(android-percent-support-lib-sample)

    xiaoxiao2021-03-26  9

    1、概述

          最近在总结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:用来表示宽高比例,当我们指定宽或者高的任一边的长度或者百分比,其就能够自动地计算出来另外一边的长度。

    2、用法

    (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>

    用法简单直接。

    3、源码分析

    我们先来看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为布局文件中编写的值

    4、实现PercentLinearLayout

    package com.juliengenoud.percentsamples; 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); } } }

    想要详细了解理论原理,请参考: http://blog.csdn.net/lmj623565791/article/details/46695347

    转载请注明原文地址: https://ju.6miu.com/read-650213.html

    最新回复(0)