您的位置:首页 > 其它

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

2016-04-20 16:26 369 查看

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

我们过去经常使用传统的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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: