由于上一篇框架需要控件重新渲染一次,对于大型项目性能方面运行不够快,针对该问题进行优化
核心思想:自定义组件,在组件的onMeasure中就改变控件的长宽等属性
实现方法:自定义百分比组件,使用该组件自动适配该组件下所有子view,以下例子以针对Linearlayout为基础
在attrs.xml中加入如下属性
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="percentlayout">
<attr name="width_percent" format="float"></attr>
<attr name="height_percent" format="float"></attr>
</declare-styleable>
</resources>
自定义LayoutParams
public static class PercentLinearLayoutParams extends LinearLayoutCompat.LayoutParams implements IGetPercent {
private float widthPercent;
private float heightPercent;
public PercentLinearLayoutParams(Context c, AttributeSet attrs) {
super(c, attrs);
TypedArray typedArray = c.obtainStyledAttributes(attrs, R.styleable.percentlayout);
widthPercent = typedArray.getFloat(R.styleable.percentlayout_width_percent, 0);
heightPercent = typedArray.getFloat(R.styleable.percentlayout_height_percent, 0);
}
public float getWidthPercent() {
return widthPercent;
}
public void setWidthPercent(float widthPercent) {
this.widthPercent = widthPercent;
}
public float getHeightPercent() {
return heightPercent;
}
public void setHeightPercent(float heightPercent) {
this.heightPercent = heightPercent;
}
}
自定义IGetPercent接口利于封装,代码如下:
public interface IGetPercent {
float getHeightPercent();
float getWidthPercent();
}
自定义组件继承LinearLayoutCompat
public class PercentLinearLayout extends LinearLayoutCompat
给childView使用自己定义的LayoutParams,只需要改写generateLayoutParams方法
/**
* 生成自己定义的LayoutParams
*
* @param attrs
* @return
*/
@Override
public LayoutParams generateLayoutParams(AttributeSet attrs) {
return new PercentLinearLayout.PercentLinearLayoutParams(context, attrs);
}
核心代码:改写onMeasure方法,遍历childView并改变他们的LayoutParams中的属性
/**
* 子控件逻辑处理操作
*
* @param widthMeasureSpec
* @param heightMeasureSpec
*/
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//获取当前组件的长宽
int width = View.MeasureSpec.getSize(widthMeasureSpec);
int height = View.MeasureSpec.getSize(heightMeasureSpec);
//遍历子view
for (int i = 0; i < viewGroup.getChildCount(); i++) {
View view = viewGroup.getChildAt(i);
ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
if (layoutParams instanceof IGetPercent) {
//获取百分比
float widthPercent = ((IGetPercent) layoutParams).getWidthPercent();
float heightPercent = ((IGetPercent) layoutParams).getHeightPercent();
//适配不同屏幕
ViewsParseUtil.catchChildView(view);
//设置子view的长宽,优先使用自定义的百分比,会将上一行代码中对长宽的设置覆盖
if (widthPercent > 0) {
layoutParams.width = (int) (width * widthPercent);
}
if (heightPercent > 0) {
layoutParams.height = (int) (height * heightPercent);
}
}
}
}
xml中使用自定义的组件,并在子控件中使用自定义属性就能实现百分比布局
<?xml version="1.0" encoding="utf-8"?>
<com.aruba.screenlibrary.layout.PercentLinearLayout 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=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="100px"
android:layout_marginLeft="30px"
android:background="@android:color/darker_gray"
android:text="Hello World!"
app:height_percent="0.5"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:width_percent="0.5" />
</com.aruba.screenlibrary.layout.PercentLinearLayout>
结论:在测量方法onMeasure中就完成对控件的适配,不需要重新渲染,提高了性能