百分比佈局
分析一下:只要子View在xml文件指定percentX percentY屬性和並分配屬性值給他們,父容器就可以算出座標給子View佈局, 這種佈局對座標很精確,而且不涉及適配問題,不會像絕對佈局那樣因爲適配問被拋棄掉了。但是絕對佈局有個問題,就是必須指定佈局的大小,也就是說在寫佈局的時候指定android:layout_width/height 屬性的時候,屬性值必須是明確的 如:**dp,MATH_PARENT ,爲什麼呢, 這是代碼設計有關哦,詳細請看下面.
<pre name="code" class="java" style="font-size: 13.3333px;"><span style="font-size: 18px;">package com.example.just_android_percent_layout_custom;
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
public class PercentLayout extends ViewGroup{
private int mScreenWidth;
private int mScreenHeight;
public PercentLayout(Context context) {
this(context,null);
}
public PercentLayout(Context context, AttributeSet attrs) {
this(context, attrs,0);
}
public PercentLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context);
}
private void init(Context context) {
mScreenWidth = context.getResources().getDisplayMetrics().widthPixels;
mScreenHeight = context.getResources().getDisplayMetrics().heightPixels;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int widthMode=MeasureSpec.getMode(widthMeasureSpec);
int heightMode=MeasureSpec.getMode(heightMeasureSpec);
int resultWidth=0;
int resultHeight=0;
int parentWidth=MeasureSpec.getSize(widthMeasureSpec);
int parentHeight=MeasureSpec.getSize(heightMeasureSpec);
int widthMeasured=0;
int heightMeasured=0;
float childPercentX=0;
float childPercentY=0;
if(widthMode==MeasureSpec.AT_MOST||MeasureSpec.UNSPECIFIED==widthMode){
throw new RuntimeException("PercentLayout layout_width android layout_height must more than 0 dp");
// /**
// * 測量子view
// */
// int childCount=this.getChildCount();
// for(int i=0;i<childCount;i++){
// View child=this.getChildAt(i);
// if(child.getVisibility()==View.GONE){
// continue;
// }
// PercentLayoutParams mPercentLayoutParams=(PercentLayoutParams) child.getLayoutParams();
// if(mPercentLayoutParams==null)
// continue;
// int childWidth=mPercentLayoutParams.width;
// if(childWidth>0){
//
// widthMeasured=MeasureSpec.makeMeasureSpec(childWidth, MeasureSpec.EXACTLY);
//
// }else if(childWidth==LayoutParams.WRAP_CONTENT){
//
// widthMeasured=MeasureSpec.makeMeasureSpec(parentWidth, MeasureSpec.AT_MOST);
// }else if(childWidth==LayoutParams.MATCH_PARENT){
// widthMeasured=MeasureSpec.makeMeasureSpec(parentWidth, MeasureSpec.EXACTLY);
// }
//
// int childHeight=mPercentLayoutParams.height;
// if(childHeight>0){
// heightMeasured=MeasureSpec.makeMeasureSpec(childHeight, MeasureSpec.EXACTLY);
// }else if (childHeight==-1){
// heightMeasured=MeasureSpec.makeMeasureSpec(parentHeight, MeasureSpec.EXACTLY);
// }else if(childHeight==-2){
// heightMeasured=MeasureSpec.makeMeasureSpec(parentHeight, MeasureSpec.AT_MOST);
// }
//
// child.measure(widthMeasured, heightMeasured);
// //這裏不考慮padding和margin
// resultWidth=Math.max(child.getMeasuredWidth()+(int)(mPercentLayoutParams.percentX*mScreenWidth), resultWidth);
// resultHeight=Math.max(child.getMeasuredHeight()+(int)(mPercentLayoutParams.percentY*mScreenHeight), resultHeight);
// }//測量完成
}else{
resultWidth=parentWidth;//如果爲EXACTY 直接把父view傳過來期望的大小賦值給其
resultHeight=parentHeight;
//不考慮padding 和margin的測量子view
int viewCount=this.getChildCount();
PercentLayoutParams mParams;
for(int i=0;i<viewCount;i++){
View child=this.getChildAt(i);
mParams=(PercentLayoutParams) child.getLayoutParams();
if(mParams==null)
continue;
int viewWidth=mParams.width;
int viewHeight=mParams.height;
int viewMeasuredWidth=this.getChildMeasureSpec(widthMeasureSpec, 0, viewWidth);
int viewMeasuredHeight=this.getChildMeasureSpec(heightMeasureSpec, 0, viewHeight);
this.measureChild(child, viewMeasuredWidth, viewMeasuredHeight);
}
}
this.setMeasuredDimension(resultWidth, resultHeight);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
int childCount=this.getChildCount();
for(int i=0;i<childCount;i++){
View child=this.getChildAt(i);
PercentLayoutParams mParams=(PercentLayoutParams) child.getLayoutParams();
if(mParams==null)
continue;
float percentX=mParams.percentX;
float percentY=mParams.percentY;
l=(int)((percentX*this.getMeasuredWidth())-child.getMeasuredWidth()/2);
t=(int) ((percentY*this.getMeasuredHeight())-child.getMeasuredHeight()/2);
if(l<0){
l=0;
}
if(t<0){
t=0;
}
r= l+child.getMeasuredWidth();
b=t+child.getMeasuredHeight();
child.layout(l, t,r,b );
}
}
@Override
public LayoutParams generateLayoutParams(AttributeSet p) {
return new PercentLayoutParams(getContext(),p);
}
class PercentLayoutParams extends ViewGroup.LayoutParams{
public float percentX;
public float percentY;
public PercentLayoutParams(Context context, AttributeSet attr) {
super(context, attr);
TypedArray ta=context.getResources().obtainAttributes(attr, R.styleable.PercentLayout);
int count=ta.getIndexCount();
for(int i=0;i<count;i++){
switch (ta.getIndex(i)) {
case R.styleable.PercentLayout_percentX:
percentX=ta.getFloat(ta.getIndex(i), -1f);
if(percentX>1||percentX<0){
percentX=0;
}
break;
case R.styleable.PercentLayout_percentY:
percentY=ta.getFloat(ta.getIndex(i), -1f);
if(percentY>1||percentY<0){
percentY=0;
}
break;
}
}
}
public PercentLayoutParams(int arg0, int arg1) {
super(arg0, arg1);
}
public PercentLayoutParams(LayoutParams l) {
super(l);
}
}
}</span>
自定義屬性:
<<span style="font-size:24px;color:#000099;">?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="PercentLayout" >
<attr name="percentX" format="float"></attr>
<attr name="percentY" format="float"></attr>
</declare-styleable>
</resources></span>
佈局:
<span style="font-size:24px;color:#3333ff;"><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:justson="http://schemas.android.com/apk/res/com.example.just_android_percent_layout_custom" >
<com.example.just_android_percent_layout_custom.PercentLayout
android:background="#3d77c0"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/percentLayout">
<Button
android:layout_width="100dp"
android:layout_height="100dp"
android:id="@+id/button"
android:background="#ff0000"
justson:percentX="0.8"
justson:percentY="0.6"
android:gravity="center"
android:text="justson"/>
<Button
android:layout_width="100dp"
android:layout_height="100dp"
android:background="#ff0000"
justson:percentX="0.2"
justson:percentY="0.3"
android:gravity="center"
android:text="justson"/>
</com.example.just_android_percent_layout_custom.PercentLayout>
</RelativeLayout></span>
效果圖
<span style="font-size:24px;color:#3333ff;"><img src="https://img-blog.csdn.net/20160518230504716?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" /></span>