【Android】自定义ViewGroup(1)
2016-12-23 00:00
405 查看
摘要: 每个高级程序员必须要会的东西就是自定义布局,自定义控件,那么我也是作为一个学习的态度来写这篇文章,在这条长长的路上慢慢的走。在这边也是自己作为一个记录的笔记,以后自己想看的时候也能翻出来查看。
前言
主要介绍的是ViewGroup的自定义,ViewGroup相当于一个放置View的容器,并且我们在写布局xml的时候,会告诉容器(凡是以layout为开头的属性,都是为用于告诉容器的),我们的宽度(layout_width)、高度(layout_height)、对齐方式(layout_gravity)等;当然还有margin等;于是乎,ViewGroup的职能为:给childView计算出建议的宽和高和测量模式 ;决定childView的位置;为什么只是建议的宽和高,而不是直接确定呢,别忘了childView宽和高可以设置为wrap_content,这样只有childView才能计算出自己的宽和高。
那么直接上代码:
CustomImgContainer.java
以上就是所有的代码,要是有什么好的建议个意见请留言关注交流。
前言
主要介绍的是ViewGroup的自定义,ViewGroup相当于一个放置View的容器,并且我们在写布局xml的时候,会告诉容器(凡是以layout为开头的属性,都是为用于告诉容器的),我们的宽度(layout_width)、高度(layout_height)、对齐方式(layout_gravity)等;当然还有margin等;于是乎,ViewGroup的职能为:给childView计算出建议的宽和高和测量模式 ;决定childView的位置;为什么只是建议的宽和高,而不是直接确定呢,别忘了childView宽和高可以设置为wrap_content,这样只有childView才能计算出自己的宽和高。
那么直接上代码:
<?xml version="1.0" encoding="utf-8"?> <com.zhjy.hxf.hznestedsroll.view.CustomImgContainer xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#AA333333"> <TextView android:layout_width="150dp" android:layout_height="150dp" android:background="#E5ED05" android:gravity="center" android:text="0" android:textColor="#FFFFFF" android:textSize="22sp" android:textStyle="bold" /> <TextView android:layout_width="50dp" android:layout_height="50dp" android:background="#00ff00" android:gravity="center" android:text="1" android:textColor="#FFFFFF" android:textSize="22sp" android:textStyle="bold" /> <TextView android:layout_width="50dp" android:layout_height="50dp" android:background="#ff0000" android:gravity="center" android:text="2" android:textColor="#FFFFFF" android:textSize="22sp" android:textStyle="bold" /> <TextView android:layout_width="50dp" android:layout_height="50dp" android:background="#0000ff" android:gravity="center" android:text="3" android:textColor="#FFFFFF" android:textSize="22sp" android:textStyle="bold" /> </com.zhjy.hxf.hznestedsroll.view.CustomImgContainer>
CustomImgContainer.java
package com.zhjy.hxf.hznestedsroll.view; import android.content.Context; import android.util.AttributeSet; import android.util.Log; import android.view.View; import android.view.ViewGroup; /** * @author :huangxianfeng on 2016/12/23. * 自定义ViewGroup学习demo */ public class CustomImgContainer extends ViewGroup { private static final String TAG = "CustomImgContainer"; public CustomImgContainer(Context context) { super(context); } public CustomImgContainer(Context context, AttributeSet attrs) { super(context, attrs); } public CustomImgContainer(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } /** * 计算所有ChildView的宽度和高度 然后根据ChildView的计算结果,设置自己的宽和高 */ @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); /** * 获得此ViewGroup上级容器为其推荐的宽和高,以及计算模式 */ //得到的是计算的模式 int widthMode = MeasureSpec.getMode(widthMeasureSpec); int hightMode = MeasureSpec.getMode(heightMeasureSpec); //得到的是上级其为计算的宽度和高度 int sizeWidth = MeasureSpec.getSize(widthMeasureSpec); int sizeHight = MeasureSpec.getSize(heightMeasureSpec); Log.e(TAG, (hightMode == MeasureSpec.UNSPECIFIED) + "," + sizeHight + "," + getLayoutParams().height); //计算出所有的childView的宽度和高度 measureChildren(widthMeasureSpec, heightMeasureSpec); //记录如果是warp_content是设置的宽度和高度 int width = 0; int height = 0; int cCount = getChildCount(); int cWidth = 0; int cHeight = 0; MarginLayoutParams cParams = null; //用于计算左边两个childView的高度 int lHeight = 0; //用于计算右面两个childView的高度。最终高度取二者之间的大值 int rHeight = 0; // 用于计算上边两个childView的宽度 int tWidth = 0; // 用于计算下面两个childiew的宽度,最终宽度取二者之间大值 int bWidth = 0; //根据childView计算出的宽和高,以及设置的Margin计算容器的宽和高,主要用于容器是warp_content时 for (int i = 0; i < cCount; i++) { View childView = getChildAt(i); cWidth = childView.getMeasuredWidth(); cHeight = childView.getMeasuredHeight(); cParams = (MarginLayoutParams) childView.getLayoutParams(); //上面两个childView if (i == 0 || i == 1) { tWidth += cWidth + cParams.leftMargin + cParams.rightMargin; } if (i == 2 || i == 3) { bWidth += cWidth + cParams.leftMargin + cParams.rightMargin; } if (i == 0 || i == 2) { lHeight += cHeight + cParams.topMargin + cParams.bottomMargin; } if (i == 1 || i == 3) { rHeight += cHeight + cParams.topMargin + cParams.bottomMargin; } } width = Math.max(tWidth, bWidth); height = Math.max(lHeight, rHeight); /** * 如果是wrap_content设置为我们计算的值 * 否则:直接设置为父容器计算的值 */ setMeasuredDimension((widthMode == MeasureSpec.EXACTLY) ? sizeWidth : width, (hightMode == MeasureSpec.EXACTLY) ? sizeHight : height); } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { int cCount = getChildCount(); int cWidth = 0; int cHeight = 0; MarginLayoutParams cParams = null; /** * 遍历所有的childView的根据其宽和高度,以及margin进行布局 */ for (int i = 0; i < cCount; i++) { View childView = getChildAt(i); cWidth = childView.getMeasuredWidth(); cHeight = childView.getMeasuredHeight(); cParams = (MarginLayoutParams) childView.getLayoutParams(); int c1 = 0, ct = 0, cr = 0, cb = 0; switch (i) { case 0: c1 = cParams.leftMargin; ct = cParams.topMargin; break; case 1: c1 = getWidth() - cWidth - cParams.leftMargin - cParams.rightMargin; ct = cParams.topMargin; break; case 2: c1 = cParams.leftMargin; ct = getHeight() - cHeight - cParams.leftMargin; break; case 3: c1 = getWidth() - cWidth - cParams.leftMargin - cParams.rightMargin; ct = getHeight() - cHeight - cParams.bottomMargin; break; } cr = c1 + cWidth; cb = cHeight + ct; childView.layout(c1, ct, cr, cb); } } @Override public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) { return new MarginLayoutParams(getContext(), attrs); } @Override protected ViewGroup.LayoutParams generateDefaultLayoutParams() { Log.e(TAG, "generateDefaultLayoutParams"); return new MarginLayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); } @Override protected ViewGroup.LayoutParams generateLayoutParams( ViewGroup.LayoutParams p) { Log.e(TAG, "generateLayoutParams p"); return new MarginLayoutParams(p); } }
以上就是所有的代码,要是有什么好的建议个意见请留言关注交流。
相关文章推荐
- android之自定义ViewGroup
- android之自定义ViewGroup和自动换行的布局的实现
- android之自定义ViewGroup和自动换行的布局的实现
- Android中自定义ViewGroup
- android之自定义ViewGroup和自动换行的布局的实现
- 在Android中,可以自定义类,继承ViewGroup等容器类,以实现自己需要的布局显示。
- (转)android 自定义ViewGroup和对view进行切图动画实现滑动菜单SlidingMenu
- android之自定义ViewGroup和自动换行的布局的实现
- android之自定义ViewGroup和自动换行的布局的实现
- Android开发教程:自定义ViewGroup方法总结
- android:自定义viewgroup,并实现滚动条和换行。
- Android中自定义ViewGroup
- android 自定义ViewGroup和对view进行切图动画实现滑动菜单SlidingMenu
- Android自定义ViewGroup自动换行实现滑动任意布局及事件处理效果
- android之自定义ViewGroup和自动换行的布局的实现
- android:自定义viewgroup,并实现滚动条和换行
- android 自定义ViewGroup和对view进行切图动画实现滑动菜单SlidingMenu
- Android学习:自定义ViewGroup方法总结
- android 自定义ViewGroup和对view进行切图动画实现滑动菜单SlidingMenu[转]
- Android 学习之--自定义ViewGroup