当前位置:   article > 正文

android百分比布局适配,安卓屏幕适配-百分比布局

百分比布局适配

屏幕适配-百分比布局

原理:以父容器尺寸作为参考,在View的加载过程,根据当前父容器实际尺寸换算出目标尺寸,在作用在View上。

百分比布局实际是对容器的一中扩展,扩展的是宽高等比例的设置。

1、自定义属性

attrs.xml

2、对属性进行解析

RelativeLayout为例,看一下它是如何对属性进行解析的?

RelativeLayout的工作原理:在它里面定义了一个LayoutParams静态内部类,在这里面定义了我们的自定义属性,这些属性都是我们这个容器的特有的属性。

9951697bd0c5

解析是在 public LayoutParams(Context c, AttributeSet attrs)构造方法中:

9951697bd0c5

现在我们看一下,这些属性是如何添加到我们的View中的。

我们都知道PhoneWindow是Window的唯一实现类,我们从PhoneWindow的setContentView开始

9951697bd0c5

9951697bd0c5

9951697bd0c5

public View inflate(XmlPullParser parser, @Nullable ViewGroup root, boolean attachToRoot) {

synchronized (mConstructorArgs) {

Trace.traceBegin(Trace.TRACE_TAG_VIEW, "inflate");

final Context inflaterContext = mContext;

final AttributeSet attrs = Xml.asAttributeSet(parser);

Context lastContext = (Context) mConstructorArgs[0];

mConstructorArgs[0] = inflaterContext;

View result = root;

........

if (TAG_MERGE.equals(name)) {

if (root == null || !attachToRoot) {

throw new InflateException(" can be used only with a valid "

+ "ViewGroup root and attachToRoot=true");

}

rInflate(parser, root, inflaterContext, attrs, false);

} else {

// Temp is the root view that was found in the xml 表示我们布局文件的根布局

final View temp = createViewFromTag(root, name, inflaterContext, attrs);

ViewGroup.LayoutParams params = null;

if (root != null) {

if (DEBUG) {

System.out.println("Creating params from root: " +

root);

}

// Create layout params that match root, if supplied

params = root.generateLayoutParams(attrs);

if (!attachToRoot) {

// Set the layout params for temp if we are not

// attaching. (If we are, we use addView, below)

temp.setLayoutParams(params);

}

}

...........

}

我们看到重要的核心代码 params = root.generateLayoutParams(attrs);和

temp.setLayoutParams(params);

如下就是我们自定义的百分不布局:

public class PercentLayout extends RelativeLayout {

public PercentLayout(Context context) {

super(context);

}

public PercentLayout(Context context, AttributeSet attrs) {

super(context, attrs);

}

public PercentLayout(Context context, AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

}

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

//获取父容器的尺寸

int widthSize = MeasureSpec.getSize(widthMeasureSpec);

int heightSize = MeasureSpec.getSize(heightMeasureSpec);

int count = getChildCount();

for (int i = 0; i < count; i++) {

View child = getChildAt(i);//重新设置子View的布局属性,在进行View的测量

ViewGroup.LayoutParams params = child.getLayoutParams();

//如果说是百分比布局属性

if (checkLayoutParams(params)){

LayoutParams lp = (LayoutParams)params;

//自定百分比属性

float widthPercent = lp.widthPercent;

float heightPercent = lp.heightPercent;

float marginLeftPercent = lp.marginLeftPercent;

float marginRightPercent= lp.marginRightPercent;

float marginTopPercent= lp.marginTopPercent;

float marginBottomPercent = lp.marginBottomPercent;

//根据当前父容器实际尺寸换算出目标尺寸

if (widthPercent > 0){

params.width = (int) (widthSize * widthPercent);

}

if (heightPercent > 0){

params.height = (int) (heightSize * heightPercent);

}

if (marginLeftPercent > 0){

((LayoutParams) params).leftMargin = (int) (widthSize * marginLeftPercent);

}

if (marginRightPercent > 0){

((LayoutParams) params).rightMargin = (int) (widthSize * marginRightPercent);

}

if (marginTopPercent > 0){

((LayoutParams) params).topMargin = (int) (heightSize * marginTopPercent);

}

if (marginBottomPercent > 0){

((LayoutParams) params).bottomMargin = (int) (heightSize * marginBottomPercent);

}

}

}

super.onMeasure(widthMeasureSpec, heightMeasureSpec);

}

@Override

protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {

return p instanceof LayoutParams;

}

public LayoutParams generateLayoutParams(AttributeSet attrs){

return new LayoutParams(getContext(), attrs);

}

public static class LayoutParams extends RelativeLayout.LayoutParams{

private float widthPercent;

private float heightPercent;

private float marginLeftPercent;

private float marginRightPercent;

private float marginTopPercent;

private float marginBottomPercent;

public LayoutParams(Context c, AttributeSet attrs) {

super(c, attrs);

//解析自定义属性

TypedArray a = c.obtainStyledAttributes(attrs,R.styleable.PercentLayout);

widthPercent = a.getFloat(R.styleable.PercentLayout_widthPercent, 0);

heightPercent = a.getFloat(R.styleable.PercentLayout_heightPercent, 0);

marginLeftPercent = a.getFloat(R.styleable.PercentLayout_marginLeftPercent, 0);

marginRightPercent = a.getFloat(R.styleable.PercentLayout_marginRightPercent, 0);

marginTopPercent = a.getFloat(R.styleable.PercentLayout_marginTopPercent, 0);

marginBottomPercent = a.getFloat(R.styleable.PercentLayout_marginBottomPercent, 0);

a.recycle();

}

}

}

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Cpp五条/article/detail/270938
推荐阅读
相关标签
  

闽ICP备14008679号