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

来源:互联网 发布:生命一个数组 编辑:程序博客网 时间:2024/06/05 17:17

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

0 0