轉載請标明出處:
http://blog.csdn.net/lmj623565791/article/details/46695347;
本文出自:【張鴻洋的部落格】
一、概述
周末遊戲打得過猛,于是周天熬夜碼代碼,周一早上渾渾噩噩的發現android-percent-support-lib-sample這個項目,Google終于開始支援百分比的方式布局了,瞬間脈動回來,啊咧咧。對于這種曆史性的時刻,不出篇部落格難以表達我内心的激動。
還記得不久前,發了篇部落格:Android 螢幕适配方案,這篇部落格以Web頁面設計引出一種适配方案,最終的目的就是可以通過百分比控制控件的大小。當然了,存在一些問題,比如:
- 對于沒有考慮到螢幕尺寸,可能會出現意外的情況;
- apk的大小會增加;
當然了android-percent-support這個庫,基本可以解決上述問題,是不是有點小激動,稍等,我們先描述下這個support-lib。
這個庫提供了:
- 兩種布局供大家使用:
、PercentRelativeLayout
,通過名字就可以看出,這是繼承自PercentFrameLayout
和FrameLayout
兩個容器類;RelativeLayout
- 支援的屬性有:
layout_widthPercent
、
layout_heightPercent
、
layout_marginPercent
、
layout_marginLeftPercent
、
layout_marginTopPercent
、
layout_marginRightPercent
、
layout_marginBottomPercent
、
layout_marginStartPercent
、
layout_marginEndPercent
。
可以看到支援寬高,以及margin。
也就是說,大家隻要在開發過程中使用
PercentRelativeLayout
、
PercentFrameLayout
替換
FrameLayout
、
RelativeLayout
即可。
是不是很簡單,不過貌似沒有LinearLayout,有人會說LinearLayout有weight屬性呀。但是,weight屬性隻能支援一個方向呀~~哈,沒事,剛好給我們一個機會去自定義一個
PercentLinearLayout
。
好了,本文分為3個部分:
-
、PercentRelativeLayout
的使用PercentFrameLayout
- 對上述控件源碼分析
- 自定義
PercentLinearLayout
二、使用
關于使用,其實及其簡單,并且github上也有例子,android-percent-support-lib-sample。我們就簡單過一下:
首先記得在build.gradle添加:
compile 'com.android.support:percent:22.2.0'
(一)PercentFrameLayout
<?xml version="1.0" encoding="utf-8"?>
<android.support.percent.PercentFrameLayout
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">
<TextView
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_gravity="left|top"
android:background="#44ff0000"
android:text="width:30%,height:20%"
app:layout_heightPercent="20%"
android:gravity="center"
app:layout_widthPercent="30%"/>
<TextView
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_gravity="right|top"
android:gravity="center"
android:background="#4400ff00"
android:text="width:70%,height:20%"
app:layout_heightPercent="20%"
app:layout_widthPercent="70%"/>
<TextView
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_gravity="bottom"
android:background="#770000ff"
android:text="width:100%,height:10%"
android:gravity="center"
app:layout_heightPercent="10%"
app:layout_widthPercent="100%"/>
</android.support.percent.PercentFrameLayout>
3個TextView,很簡單,直接看效果圖:
(二) PercentRelativeLayout
<?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"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="true">
<TextView
android:id="@+id/row_one_item_one"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_alignParentTop="true"
android:background="#7700ff00"
android:text="w:70%,h:20%"
android:gravity="center"
app:layout_heightPercent="20%"
app:layout_widthPercent="70%"/>
<TextView
android:id="@+id/row_one_item_two"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_toRightOf="@+id/row_one_item_one"
android:background="#396190"
android:text="w:30%,h:20%"
app:layout_heightPercent="20%"
android:gravity="center"
app:layout_widthPercent="30%"/>
<ImageView
android:id="@+id/row_two_item_one"
android:layout_width="match_parent"
android:layout_height="0dp"
android:src="@drawable/tangyan"
android:scaleType="centerCrop"
android:layout_below="@+id/row_one_item_one"
android:background="#d89695"
app:layout_heightPercent="70%"/>
<TextView
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_below="@id/row_two_item_one"
android:background="#770000ff"
android:gravity="center"
android:text="width:100%,height:10%"
app:layout_heightPercent="10%"
app:layout_widthPercent="100%"/>
</android.support.percent.PercentRelativeLayout>
ok,依然是直接看效果圖:
使用沒什麼好說的,就是直覺的看一下。
三、源碼分析
其實細想一下,Google隻是對我們原本熟悉的RelativeLayout和FrameLayout進行的功能的擴充,使其支援了percent相關的屬性。
那麼,我們考慮下,如果是我們添加這種擴充,我們會怎麼做:
- 通過LayoutParams擷取child設定的percent相關屬性的值
- onMeasure的時候,将child的width,height的值,通過擷取的自定義屬性的值進行計算(eg:容器的寬 * fraction ),計算後傳入給child.measure(w,h);
ok,有了上面的猜想,我們直接看
PercentFrameLayout
的源碼。
public class PercentFrameLayout extends FrameLayout {
private final PercentLayoutHelper mHelper = new PercentLayoutHelper(this);
//省略了,兩個構造方法
public PercentFrameLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
@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 FrameLayout.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);
}
}
}
代碼是相當的短,可以看到
PercentFrameLayout
裡面首先重寫了generateLayoutParams方法,當然了,由于支援了一些新的layout_屬性,那麼肯定需要定義對應的LayoutParams。
(一)percent相關屬性的擷取
可以看到PercentFrameLayout.LayoutParams在原有的FrameLayout.LayoutParams基礎上,實作了PercentLayoutHelper.PercentLayoutParams接口。
這個接口很簡單,隻有一個方法:
public interface PercentLayoutParams {
PercentLayoutInfo getPercentLayoutInfo();
}
而,這個方法的實作呢,也隻有一行:
return mPercentLayoutInfo;
,那麼這個mPercentLayoutInfo在哪完成指派呢?
看PercentFrameLayout.LayoutParams的構造方法:
public LayoutParams(Context c, AttributeSet attrs) {
super(c, attrs);
mPercentLayoutInfo = PercentLayoutHelper.getPercentLayoutInfo(c, attrs);
}
可以看到,将attrs傳入給getPercentLayoutInfo方法,那麼不用說,這個方法的内部,肯定是擷取自定義屬性的值,然後将其封裝到PercentLayoutInfo對象中,最後傳回。
代碼如下:
public static PercentLayoutInfo getPercentLayoutInfo(Context context,
AttributeSet attrs) {
PercentLayoutInfo info = null;
TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.PercentLayout_Layout);
float value = array.getFraction(R.styleable.PercentLayout_Layout_layout_widthPercent, , ,
-f);
if (value != -f) {
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "percent width: " + value);
}
info = info != null ? info : new PercentLayoutInfo();
info.widthPercent = value;
}
value = array.getFraction(R.styleable.PercentLayout_Layout_layout_heightPercent, , , -f);
if (value != -f) {
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "percent height: " + value);
}
info = info != null ? info : new PercentLayoutInfo();
info.heightPercent = value;
}
value = array.getFraction(R.styleable.PercentLayout_Layout_layout_marginPercent, , , -f);
if (value != -f) {
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "percent margin: " + value);
}
info = info != null ? info : new PercentLayoutInfo();
info.leftMarginPercent = value;
info.topMarginPercent = value;
info.rightMarginPercent = value;
info.bottomMarginPercent = value;
}
value = array.getFraction(R.styleable.PercentLayout_Layout_layout_marginLeftPercent, , ,
-f);
if (value != -f) {
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "percent left margin: " + value);
}
info = info != null ? info : new PercentLayoutInfo();
info.leftMarginPercent = value;
}
value = array.getFraction(R.styleable.PercentLayout_Layout_layout_marginTopPercent, , ,
-f);
if (value != -f) {
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "percent top margin: " + value);
}
info = info != null ? info : new PercentLayoutInfo();
info.topMarginPercent = value;
}
value = array.getFraction(R.styleable.PercentLayout_Layout_layout_marginRightPercent, , ,
-f);
if (value != -f) {
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "percent right margin: " + value);
}
info = info != null ? info : new PercentLayoutInfo();
info.rightMarginPercent = value;
}
value = array.getFraction(R.styleable.PercentLayout_Layout_layout_marginBottomPercent, , ,
-f);
if (value != -f) {
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "percent bottom margin: " + value);
}
info = info != null ? info : new PercentLayoutInfo();
info.bottomMarginPercent = value;
}
value = array.getFraction(R.styleable.PercentLayout_Layout_layout_marginStartPercent, , ,
-f);
if (value != -f) {
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "percent start margin: " + value);
}
info = info != null ? info : new PercentLayoutInfo();
info.startMarginPercent = value;
}
value = array.getFraction(R.styleable.PercentLayout_Layout_layout_marginEndPercent, , ,
-f);
if (value != -f) {
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "percent end margin: " + value);
}
info = info != null ? info : new PercentLayoutInfo();
info.endMarginPercent = value;
}
array.recycle();
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, "constructed: " + info);
}
return info;
}
是不是和我們平時的取值很類似,所有的值最終封裝到PercentLayoutInfo對象中。
ok,到此我們的屬性擷取就介紹完成,有了這些屬性,是不是onMeasure裡面要進行使用呢?
(二) onMeasue中重新計算child的尺寸
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
mHelper.adjustChildren(widthMeasureSpec, heightMeasureSpec);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if (mHelper.handleMeasuredStateTooSmall()) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
可以看到onMeasure中的代碼頁很少,看來核心的代碼都被封裝在mHelper的方法中,我們直接看mHelper.adjustChildren方法。
/**
* Iterates over children and changes their width and height to one calculated from percentage
* values.
* @param widthMeasureSpec Width MeasureSpec of the parent ViewGroup.
* @param heightMeasureSpec Height MeasureSpec of the parent ViewGroup.
*/
public void adjustChildren(int widthMeasureSpec, int heightMeasureSpec) {
//...
int widthHint = View.MeasureSpec.getSize(widthMeasureSpec);
int heightHint = View.MeasureSpec.getSize(heightMeasureSpec);
for (int i = , N = mHost.getChildCount(); i < N; i++) {
View view = mHost.getChildAt(i);
ViewGroup.LayoutParams params = view.getLayoutParams();
if (params instanceof PercentLayoutParams) {
PercentLayoutInfo info =
((PercentLayoutParams) params).getPercentLayoutInfo();
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, "using " + info);
}
if (info != null) {
if (params instanceof ViewGroup.MarginLayoutParams) {
info.fillMarginLayoutParams((ViewGroup.MarginLayoutParams) params,
widthHint, heightHint);
} else {
info.fillLayoutParams(params, widthHint, heightHint);
}
}
}
}
}
通過注釋也能看出,此方法中周遊所有的孩子,通過百分比的屬性重新設定其寬度和高度。
首先在widthHint、heightHint儲存容器的寬、高,然後周遊所有的孩子,判斷其LayoutParams是否是PercentLayoutParams類型,如果是,通過params.getPercentLayoutInfo拿出info對象。
是否還記得,上面的分析中,PercentLayoutInfo儲存了percent相關屬性的值。
如果info不為null,則判斷是否需要處理margin;我們直接看fillLayoutParams方法(處理margin也是類似的)。
/**
* Fills {@code ViewGroup.LayoutParams} dimensions based on percentage values.
*/
public void fillLayoutParams(ViewGroup.LayoutParams params, int widthHint,
int heightHint) {
// Preserve the original layout params, so we can restore them after the measure step.
mPreservedParams.width = params.width;
mPreservedParams.height = params.height;
if (widthPercent >= ) {
params.width = (int) (widthHint * widthPercent);
}
if (heightPercent >= ) {
params.height = (int) (heightHint * heightPercent);
}
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, "after fillLayoutParams: (" + params.width + ", " + params.height + ")");
}
}
首先儲存原本的width和height,然後重置params的width和height為
(int) (widthHint * widthPercent)
和
(int) (heightHint * heightPercent);
。
到此,其實我們的百分比轉換就結束了,理論上就已經實作了對于百分比的支援,不過Google還考慮了一些細節。
我們回到onMeasure方法:
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
mHelper.adjustChildren(widthMeasureSpec, heightMeasureSpec);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if (mHelper.handleMeasuredStateTooSmall()) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
下面還有個mHelper.handleMeasuredStateTooSmall的判斷,也就是說,如果你設定的百分比,最終計算出來的MeasuredSize過小的話,會進行一些操作。
代碼如下:
public boolean handleMeasuredStateTooSmall() {
boolean needsSecondMeasure = false;
for (int i = , N = mHost.getChildCount(); i < N; i++) {
View view = mHost.getChildAt(i);
ViewGroup.LayoutParams params = view.getLayoutParams();
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, "should handle measured state too small " + view + " " + params);
}
if (params instanceof PercentLayoutParams) {
PercentLayoutInfo info =
((PercentLayoutParams) params).getPercentLayoutInfo();
if (info != null) {
if (shouldHandleMeasuredWidthTooSmall(view, info)) {
needsSecondMeasure = true;
params.width = ViewGroup.LayoutParams.WRAP_CONTENT;
}
if (shouldHandleMeasuredHeightTooSmall(view, info)) {
needsSecondMeasure = true;
params.height = ViewGroup.LayoutParams.WRAP_CONTENT;
}
}
}
}
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, "should trigger second measure pass: " + needsSecondMeasure);
}
return needsSecondMeasure;
}
首先周遊所有的孩子,拿出孩子的layoutparams,如果是PercentLayoutParams執行個體,則取出info。如果info不為null,調用
shouldHandleMeasuredWidthTooSmall
判斷:
private static boolean shouldHandleMeasuredWidthTooSmall(View view, PercentLayoutInfo info) {
int state = ViewCompat.getMeasuredWidthAndState(view) & ViewCompat.MEASURED_STATE_MASK;
return state == ViewCompat.MEASURED_STATE_TOO_SMALL && info.widthPercent >= &&
info.mPreservedParams.width == ViewGroup.LayoutParams.WRAP_CONTENT;
}
這裡就是判斷,如果你設定的measuredWidth或者measureHeight過小的話,并且你在布局檔案中layout_w/h 設定的是WRAP_CONTENT的話,将params.width / height= ViewGroup.LayoutParams.WRAP_CONTENT,然後重新測量。
哈,onMeasure終于結束了~~~現在我覺得應該代碼結束了吧,尺寸都設定好了,還需要幹嘛麼,but,你會發現onLayout也重寫了,我們又不改變layout規則,在onLayout裡面幹什麼毛線:
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
mHelper.restoreOriginalParams();
}
繼續看
mHelper.restoreOriginalParams
/**
* Iterates over children and restores their original dimensions that were changed for
* percentage values. Calling this method only makes sense if you previously called
* {@link PercentLayoutHelper#adjustChildren(int, int)}.
*/
public void restoreOriginalParams() {
for (int i = , N = mHost.getChildCount(); i < N; i++) {
View view = mHost.getChildAt(i);
ViewGroup.LayoutParams params = view.getLayoutParams();
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, "should restore " + view + " " + params);
}
if (params instanceof PercentLayoutParams) {
PercentLayoutInfo info =
((PercentLayoutParams) params).getPercentLayoutInfo();
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, "using " + info);
}
if (info != null) {
if (params instanceof ViewGroup.MarginLayoutParams) {
info.restoreMarginLayoutParams((ViewGroup.MarginLayoutParams) params);
} else {
info.restoreLayoutParams(params);
}
}
}
}
}
噗,原來是重新恢複原本的尺寸值,也就是說onMeasure裡面的對值進行了改變,測量完成後。在這個地方,将值又恢複成如果布局檔案中的值,上面寫的都是0。恢複很簡單:
public void restoreLayoutParams(ViewGroup.LayoutParams params) {
params.width = mPreservedParams.width;
params.height = mPreservedParams.height;
}
你應該沒有忘在哪存的把~忘了的話,麻煩Ctrl+F ‘mPreservedParams.width’ 。
也就是說,你去列印上面寫法,布局檔案中view的
v.getLayoutParams().width
,這個值應該是0。
這裡感覺略微不爽~這個0沒撒用處呀,還不如不重置~~
好了,到此就分析完了,其實主要就幾個步驟:
- LayoutParams中屬性的擷取
- onMeasure中,改變params.width為百分比計算結果,測量
- 如果測量值過小且設定的w/h是wrap_content,重新測量
- onLayout中,重置params.w/h為布局檔案中編寫的值
可以看到,有了RelativeLayout、FrameLayout的擴充,竟然沒有LinearLayout幾個意思。好在,我們的核心代碼都由
PercentLayoutHelper
封裝了,自己擴充下LinearLayout也不複雜。
三、實作PercentLinearlayout
可能有人會說,有了weight呀,但是weight能做到寬、高同時百分比指派嘛?
好了,代碼很簡單,如下:
(一)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;
/**
* Created by zhy on 15/6/30.
*/
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);
}
}
}
如果你詳細看了上面的源碼分析,這個代碼是不是沒撒解釋的了~
(二)測試布局
<?xml version="1.0" encoding="utf-8"?>
<com.juliengenoud.percentsamples.PercentLinearLayout
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"
android:orientation="vertical">
<TextView
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#ff44aacc"
android:text="width:60%,height:5%"
android:textColor="#ffffff"
app:layout_heightPercent="5%"
app:layout_marginBottomPercent="5%"
app:layout_widthPercent="60%"/>
<TextView
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#ff4400cc"
android:gravity="center"
android:textColor="#ffffff"
android:text="width:70%,height:10%"
app:layout_heightPercent="10%"
app:layout_marginBottomPercent="5%"
app:layout_widthPercent="70%"/>
<TextView
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#ff44aacc"
android:gravity="center"
android:text="width:80%,height:15%"
android:textColor="#ffffff"
app:layout_heightPercent="15%"
app:layout_marginBottomPercent="5%"
app:layout_widthPercent="80%"/>
<TextView
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#ff4400cc"
android:gravity="center"
android:text="width:90%,height:5%"
android:textColor="#ffffff"
app:layout_heightPercent="20%"
app:layout_marginBottomPercent="10%"
app:layout_widthPercent="90%"/>
<TextView
android:layout_width="match_parent"
android:layout_height="0dp"
android:background="#ff44aacc"
android:gravity="center"
android:text="width:100%,height:25%"
android:textColor="#ffffff"
app:layout_heightPercent="25%"
app:layout_marginBottomPercent="5%"
/>
</com.juliengenoud.percentsamples.PercentLinearLayout>
我們縱向排列的幾個TextView,分别設定寬/高都為百分比,且之間的間隔為5%p。
(三)效果圖
ok,到此,我們使用、源碼分析、擴充PercentLinearLayout就結束了。
添加PercentLinearLayout後的位址:點選檢視
擴充下載下傳:android-percent-support-extend 包含android studio, eclipse項目,以及上述源碼。
~~have a nice day ~~
新浪微網誌
群号:463081660
微信公衆号:hongyangAndroid
(歡迎關注,第一時間推送博文資訊)