自己设置Viewgroup机制
在我们做的项目中,假如需要做某些定制性高的自己设置ViewGroup,假如有不错的Viewgroup机制功底,那做起来就会有奇效。富有创造性的viewgroup会让人看得瞠目结舌,所以从肯定程度上说,写viewgroup的水平很看出一个开发人员的技术如何。比方Android自带的RelativeLayout、LinearLayout、FrameLayout、Viewpager等都是继承自ViewGroup类。
ViewGroup层级图:
Viewgroup绘制流程:
会通过onMeasure、onLayout、onDraw顺序的流程方法进行绘制。
onMeasure
ViewGroup的测量需要遍历所有子view,对所有子view进行测量。
@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int childCount = this.getChildCount(); for (int i = 0; i < childCount; i++) { View child = this.getChildAt(i); this.measureChild(child, widthMeasureSpec, heightMeasureSpec); int cw = child.getMeasuredWidth(); int ch = child.getMeasuredHeight(); }}
onLayout
自己设置viewgroup必需要实现onLayout方法,在其中需要遍历所有子view对其调用layout方法,设置各个子view的左上右下坐标。而viewgroup的宽高则会根据所有子view所需最大的宽高来设置自己的宽高。
protected void onLayout(boolean arg0, int arg1, int arg2, int arg3, int arg4) { int childCount = this.getChildCount(); for (int i = 0; i < childCount; i++) { View child = this.getChildAt(i); LayoutParams lParams = (LayoutParams) child.getLayoutParams(); child.layout(lParams.left, lParams.top, lParams.left + childWidth, lParams.top + childHeight); }}
onDraw
viewgroup会按照子类的排列顺序,调用子类的onDraw方法分别进行绘制。
示例:写一个水平的LinearLayout的功能。
public class MyLinearLayout extends ViewGroup { public MyLinearLayout(Context context) { super(context); } public MyLinearLayout(Context context, AttributeSet attrs) { super(context, attrs); } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { View childView; int startLeft = l; //父view当前的左边距位置,这里只每一个子view的起始左边距位置 for (int i = 0; i < getChildCount(); i++) { childView = getChildAt(i); int width = childView.getMeasuredWidth(); //当前子view的宽 int height = childView.getMeasuredHeight(); //当前子view的高 childView.layout(startLeft, t, startLeft + width, height); startLeft += width; } } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); measureChildren(widthMeasureSpec, heightMeasureSpec); //对所有子view进行测量 int widthMode = MeasureSpec.getMode(widthMeasureSpec); int heigthMode = MeasureSpec.getMode(heightMeasureSpec); int widthSize = MeasureSpec.getSize(widthMeasureSpec); int heightSize = MeasureSpec.getSize(heightMeasureSpec); if (widthMode == MeasureSpec.AT_MOST && heigthMode == MeasureSpec.AT_MOST) { //宽高都为wrapcontent,则设置尺寸为子view所需宽高的最大值 setMeasuredDimension(totalWidth(), totalHeight()); } else if (widthMode == MeasureSpec.AT_MOST) { setMeasuredDimension(totalWidth(), heightSize); } else if (heigthMode == MeasureSpec.AT_MOST) { setMeasuredDimension(widthSize, totalHeight()); } } /** * 计算子view所需最大宽度,宽度为所有子view之和 * @return */ private int totalWidth() { int totalWidth = 0; for (int i = 0; i < getChildCount(); i++) { totalWidth += getChildAt(i).getMeasuredWidth(); } return totalWidth; } /** * 计算子view所需最大高度,为子view中最大高度 * @return */ private int totalHeight() { int maxHeight = 0; for (int i = 0; i < getChildCount(); i++) { if (getChildAt(i).getMeasuredHeight() > maxHeight) { maxHeight = getChildAt(i).getMeasuredHeight(); } } return maxHeight; }}
布局代码:
<com.example.apple.viewgroupuse.MyLinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content"> <View android:layout_width="80dp" android:layout_height="80dp" android:background="#00BC1B"/> <View android:layout_width="80dp" android:layout_height="80dp" android:background="#12B7F5"/> <View android:layout_width="80dp" android:layout_height="80dp" android:background="#FF9F00"/> <View android:layout_width="80dp" android:layout_height="80dp" android:background="#EF1200"/> </com.example.apple.viewgroupuse.MyLinearLayout>
运行结果:
增加子view会水平线性摆放
上一篇 目录 已是最后
说明
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » 自己设置Viewgroup机制
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » 自己设置Viewgroup机制