打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
Android ViewGroup介绍+实例,apt编译时期自动生成代码&动态类加载

attrArray.recycle();

}

//此视图是否自行绘制

setWillNotDraw(false);

}

/**

*?负责设置子控件的测量模式和大小?根据所有子控件设置自己的宽和高

*/

@Override

protected?void?onMeasure(int?widthMeasureSpec,?int?heightMeasureSpec)?{

super.onMeasure(widthMeasureSpec,?heightMeasureSpec);

MLog.e(getClass().getName(),"onMeasure");

//?获得它的父容器为它设置的测量模式和大小

int?sizeWidth?=?MeasureSpec.getSize(widthMeasureSpec);

int?sizeHeight?=?MeasureSpec.getSize(heightMeasureSpec);

int?modeWidth?=?MeasureSpec.getMode(widthMeasureSpec);

int?modeHeight?=?MeasureSpec.getMode(heightMeasureSpec);

//?如果是warp_content情况下,记录宽和高

int?width?=?0;

int?height?=?0;

//记录每一行的宽度,width不断取最大宽度

int?lineWidth?=?0;

//每一行的高度,累加至height

int?lineHeight?=?0;

int?count?=?getChildCount();

int?left?=?getPaddingLeft();

int?top?=?getPaddingTop();

//?遍历每个子元素

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

View?child?=?getChildAt(i);

if?(child.getVisibility()?==?GONE)

continue;

//?测量每一个child的宽和高

measureChild(child,?widthMeasureSpec,?heightMeasureSpec);

//?得到child的lp

ViewGroup.LayoutParams?lp?=?child.getLayoutParams();

//?当前子空间实际占据的宽度

int?childWidth?=?child.getMeasuredWidth()?+?childHorizontalSpace;

//?当前子空间实际占据的高度

int?childHeight?=?child.getMeasuredHeight()?+?childVerticalSpace;

if?(lp?!=?null?&&?lp?instanceof?MarginLayoutParams)?{

MarginLayoutParams?params?=?(MarginLayoutParams)?lp;

childWidth?+=?params.leftMargin?+?params.rightMargin;

childHeight?+=?params.topMargin?+?params.bottomMargin;

}

//如果加入当前child,则超出最大宽度,则的到目前最大宽度给width,类加height?然后开启新行

if?(lineWidth?+?childWidth?>?sizeWidth?-?getPaddingLeft()?-?getPaddingRight())?{

width?=?Math.max(lineWidth,?childWidth);//?取最大的

lineWidth?=?childWidth;?//?重新开启新行,开始记录

//?叠加当前高度,

height?+=?lineHeight;

//?开启记录下一行的高度

lineHeight?=?childHeight;

child.setTag(new?Location(left,?top?+?height,?childWidth

《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》

浏览器打开:qq.cn.hn/FTe 开源分享

?+?left?-?childHorizontalSpace,?height?+?child.getMeasuredHeight()?+?top));

}?else?{

//?否则累加值lineWidth,lineHeight取最大高度

child.setTag(new?Location(lineWidth?+?left,?top?+?height,?lineWidth?+?childWidth?-?childHorizontalSpace?+?left,?height?+?child.getMeasuredHeight()?+?top));

lineWidth?+=?childWidth;

lineHeight?=?Math.max(lineHeight,?childHeight);

}

}

width?=?Math.max(width,?lineWidth)?+?getPaddingLeft()?+?getPaddingRight();

height?+=?lineHeight;

sizeHeight?+=?getPaddingTop()?+?getPaddingBottom();

height?+=?getPaddingTop()?+?getPaddingBottom();

setMeasuredDimension((modeWidth??MeasureSpec.EXACTLY)???sizeWidth?:?width,?(modeHeight??MeasureSpec.EXACTLY)???sizeHeight?:?height);

}

/**

*?记录子控件的坐标

*/

public?class?Location?{

public?Location(int?left,?int?top,?int?right,?int?bottom)?{

this.left?=?left;

this.top?=?top;

this.right?=?right;

this.bottom?=?bottom;

}

public?int?left;

public?int?top;

public?int?right;

public?int?bottom;

}

//计算当前View以及子View的位置

@Override

protected?void?onLayout(boolean?changed,?int?l,?int?t,?int?r,?int?b)?{

MLog.e(getClass().getName(),"onLayout");

//获取子View个数

int?count?=?getChildCount();

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

//获取子View

View?child?=?getChildAt(i);

//判断是否显示

if?(child.getVisibility()?==?GONE)

continue;

//获取子View的坐标

Location?location?=?(Location)?child.getTag();

//设置子View位置

child.layout(location.left,?location.top,?location.right,?location.bottom);

}

}

@Override

protected?void?onSizeChanged(int?w,?int?h,?int?oldw,?int?oldh)?{

super.onSizeChanged(w,?h,?oldw,?oldh);

MLog.e(getClass().getName(),"onSizeChanged");

}

@Override

protected?void?onDraw(Canvas?canvas)?{

super.onDraw(canvas);

MLog.e(getClass().getName(),"onDraw");

}

}

2.使用自定义CustomLayout

<com.scc.demo.view.CustomLayout?xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:custom="http://schemas.android.com/apk/res-auto"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:layout_margin="@dimen/dimen_20"

custom:horizontalSpace="10dp"

custom:verticalSpace="20dp">

<TextView

style="@style/TvStyle"

android:text="破阵子·为陈同甫赋壮词以寄"?/>

<TextView

style="@style/TvStyle"

android:text="宋·辛弃疾"?/>

<TextView

style="@style/TvStyle"

android:text="醉里挑灯看剑"?/>

<TextView

style="@style/TvStyle"

android:text="梦回吹角连营"?/>

<TextView

style="@style/TvStyle"

android:text="八百里分麾下炙"?/>

<TextView

style="@style/TvStyle"

android:text="五十弦翻塞外声"?/>

<TextView

style="@style/TvStyle"

android:text="沙场秋点兵"?/>

<TextView

style="@style/TvStyle"

android:text="马作的卢飞快"?/>

<TextView

style="@style/TvStyle"

android:text="弓如霹雳弦惊(增加点长度)"?/>

<TextView

style="@style/TvStyle"

android:text="了却君王天下事"?/>

<TextView

style="@style/TvStyle"

android:text="赢得生前身后名"?/>

<TextView

style="@style/TvStyle"

android:text="可怜白发生!"?/>

</com.scc.demo.view.CustomLayout>

3.自定义属性

在app/src/main/res/values/attrs.xml中添加属性

<declare-styleable?name="CustomLayout">

<attr?name="verticalSpace"?format="dimension"?/>

<attr?name="horizontalSpace"?format="dimension"?/>

4.使用自定义属性

  • 在xml中使用

一定要添加:xmlns:test=”http://schemas.android.com/apk/res-auto”添加之后才能在xml中自定义属性,如下代码:

<com.scc.demo.view.CustomLayout?xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:custom="http://schemas.android.com/apk/res-auto"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:layout_margin="@dimen/dimen_20"

custom:horizontalSpace="10dp"

custom:verticalSpace="20dp">

</com.scc.demo.view.CustomLayout>

  • 在代码中使用

TypedArray?attrArray?=?context.obtainStyledAttributes(attrs,?R.styleable.CustomLayout);

if?(attrArray?!=?null)?{

//参数1:获取xml中设置的参数;参数2:获取失败2使用参数作为默认值

childHorizontalSpace?=?attrArray.getDimensionPixelSize(R.styleable.CustomLayout_horizontalSpace,?12);

childVerticalSpace?=?attrArray.getDimensionPixelSize(R.styleable.CustomLayout_verticalSpace,?12);

MLog.e(getClass().getName(),"HorizontalSpace:"+childHorizontalSpace+"|VerticalSpace:"+childVerticalSpace);

//TypedArray对象池的大小默认为5,使用时记得调用recyle()方法将不用的对象返回至对象池来达到重用的目的。

attrArray.recycle();

}

写到这里自定义ViewGroup基本完成。

ViewGroup属性


本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
Android自定义控件之自定义ViewGroup实现标签云(四)
Android Java 设置 style
Android版手风琴(ExpandableListView)
android 把TextView中的文字添加阴影效果
android edittext 去边框 去下划线
Android API Demo研究(3) - 编程 - goandroid
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服