百分比布局 (翻译,体验)解决布局问题,又一种体验

转载请注明出处:王亟亟的大牛之路

我们过去经常使用传统的RelativeLayout,LinearLayout,FrameLayout.以及一些较新的诸如可拉伸的CollapsingToolbarLayout等等都已经多多少少的在项目中使用,早前就已经知晓了百分比布局percent,但是一直没想到去看,去试验相关的内容,正好今天想到了就写一篇关于他的(貌似是本周的第一篇)

安利下自己的整合库:https://github.com/ddwhan0123/Useful-Open-Source-Android,快来fork,star!!!

废话不多,先贴一下试验的效果:(看上去比传统的样子差不多,别心急,看下去)

在具体贴代码之前,先加以解释,毕竟是官方控件,例子都不需要加太多,让大家理解更重要

这篇主要讲的是RelativeLayout的演化版 PercentRelativeLayout 再顺道提一提一个自定义的PercentLinearLayout

看字面意思大家就很容易理解,一个是百分比的相对布局,一个就是百分比的线性布局。(接下来的例子我们拿的是官方的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">
     <ImageView
         app:layout_widthPercent="50%"
         app:layout_heightPercent="50%"
         app:layout_marginTopPercent="25%"
         app:layout_marginLeftPercent="25%"/>
 </android.support.percent.PercentFrameLayout>

直接像引用正常RelativeLayout控件一样往里面一丢,具体的百分比行为在子控件里操作。乍一看就比较清楚,和通常的配置的区别在于 layout_width或者layout_height来控制空间的尺寸而是使用 app:layout_widthPercent=”50%”和 app:layout_heightPercent=”50%”这样的标签来控制大小,大小的具体数值由%决定,当然这里的占比取决于容器父控件的%大小。

那么既然有新标签,那就来介绍下

//长度和宽度在上面已经做出了解释,这里补充一句,如果百分比设定的值太小,并且你仍然设置了layout_width/height="wrap_content"的话,他的尺寸会变成"wrap_content"大小

app:layout_widthPercent

app:layout_heightPercent

//下面这些就是一些间距的设置,跟RelativeLayout类似只是用%作为尺寸大小,其他并没有区别
app:layout_marginPercent

app:layout_marginLeftPercent

app:layout_marginTopPercent

app:layout_marginRightPercent

app:layout_marginBottomPercent

app:layout_marginStartPercent

app:layout_marginEndPercent

//如果你想让你的控件成一定比例的形式诸如16:9你可以设置如下,这将使画面比例16:9(1.78:1)
 app:layout_aspectRatio="178%"

详细内容可以看:https://developer.android.com/reference/android/support/percent/PercentRelativeLayout.html

OK,我们来简单的读下源码,再贴例子代码就收工!

整个类本身代码并不太多,也就100行不到,读起来还算轻松,Go

public class PercentRelativeLayout extends RelativeLayout

跟之前预想的一样他是继承于RelativeLayout

在文章的一开始官方有介绍到

If a layout wants to support percentage based dimensions and use this helper class, its LayoutParams subclass must implement this interface.

所以PercentRelativeLayout的一系列实现都与PercentLayoutHelper相关

 private final PercentLayoutHelper mHelper = new PercentLayoutHelper(this);

在源码的开始,就获取了这个Helper的实例用于调用。

//返回默认的布局参数
 @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);
        }
    }

//位置操作,都是mHelper给与相应实现
    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
        mHelper.restoreOriginalParams();
    }

内部类,用于给PercentRelativeLayout做布局实现,因为单继承多实现的原则,只能构建一个LayoutParams作为PercentRelativeLayout的实现。

  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);
        }
    }

我们再贴下实现的XML

<?xml version="1.0" encoding="utf-8"?>
<android.support.percent.PercentRelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="wjj.com.percentdemo.MainActivity">

    <ImageView  android:id="@+id/a1" android:layout_width="0dp" android:layout_height="0dp" android:layout_alignParentTop="true" android:background="@drawable/a1" app:layout_heightPercent="30%" app:layout_widthPercent="70%" />
    <ImageView  android:id="@+id/a3" android:layout_width="0dp" android:layout_height="0dp" android:layout_below="@id/a1" android:background="@drawable/a3" app:layout_heightPercent="28%" app:layout_widthPercent="60%" />

    <ImageView  android:id="@+id/a2" android:layout_width="0dp" android:layout_height="0dp" android:layout_below="@id/a1" android:layout_toRightOf="@+id/a3" android:background="@drawable/a2" app:layout_heightPercent="28%" app:layout_widthPercent="40%" />

    <ImageView  android:id="@+id/a4" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_alignParentTop="true" android:background="@drawable/a4" app:layout_heightPercent="25%" app:layout_widthPercent="25%" />

  <ImageView  android:layout_below="@id/a2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/a5" app:layout_heightPercent="35%" android:layout_centerHorizontal="true" app:layout_widthPercent="35%" android:layout_alignParentBottom="true"/>

</android.support.percent.PercentRelativeLayout>

这里再补充下:

最低版本android 2.1 也就是 7 (现在4.0以下的还有吗?再退一步,4.3以下的还有吗?)

源码地址:https://github.com/ddwhan0123/BlogSample/tree/master/PercentDemo

下载地址:https://github.com/ddwhan0123/BlogSample/blob/master/PercentDemo/PercentDemo.zip?raw=true

PercentLinearLayout,这个类,网上抠来的不知道作者,这里也声明下0,0

你可能感兴趣的:(android,git,百分比,布局,RelativeLayout)