android自定义view之自定义容器
来源:互联网 发布:程序员去金融公司 编辑:程序博客网 时间:2024/06/05 22:41
1、容器中的控件高度相同,一行一行往下放,一个控件放不下时,则换行
package com.example.huanghaiyan.mjtestactivity;import android.content.Context;import android.util.AttributeSet;import android.util.Log;import android.view.View;import android.view.ViewGroup;import java.util.ArrayList;import java.util.List;/** * Created by huanghaiyan on 16/3/22. */public class MyGroupView extends ViewGroup { public MyGroupView(Context context) { super(context); } public MyGroupView(Context context, AttributeSet attrs) { super(context, attrs); } public MyGroupView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) { return new MarginLayoutParams(getContext(), attrs); } protected void onMeasure(int w,int h) { super.onMeasure(w, h); //获得它的父容器为它设置的测量模式和大小 int sizeWidth = MeasureSpec.getSize(w); int sizeHeight = MeasureSpec.getSize(h); int modeWidth = MeasureSpec.getMode(w); int modeHeight = MeasureSpec.getMode(h); //如果是wrap_content情况下,记录宽和高 int width = 0; int height = 0; /** * 记录每一行的宽度,width不断取最大宽度 */ int lineWidth = 0; /** * 记录每一行的高度,累加只height */ int lineHeight = 0; int mCount = getChildCount(); //遍历每个子元素 for (int i = 0;i < mCount; i++) { View child = getChildAt(i); //测量每一个child的宽和高 measureChild(child, w, h); //得到child的lp MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams(); //当前子空间的实际占据的宽度 int childWidth = child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin; //...的高度 int childHeight = child.getMeasuredHeight() + lp.topMargin + lp.bottomMargin; /** * 如果加入当前child,超出最大宽度,则将目前最大宽度给width;累加height,开启新行 */ if (lineWidth + childWidth > sizeWidth) { width = Math.max(lineWidth, childWidth); //width = Math.max(lineWidth, width); lineWidth = childWidth; //重新开启新行,开始记录 //叠加当前高度 height += lineHeight; Log.i("myTag", "lineH:" + lineHeight + " height:" + height); //开启记录下一行的高度 lineHeight = Math.max(lineHeight, childHeight); } else { lineWidth += childWidth; lineHeight = Math.max(lineHeight, childHeight); } //如果是最后一个,则将当前记录的最大宽度和当前lineWidth作比较 if (i == mCount - 1) { width = Math.max(width, lineWidth); height += lineHeight; Log.i("myTag", "lineH:" + lineHeight + " height:" + height); } } Log.i("myTag", width + "and" + height); setMeasuredDimension((modeWidth == MeasureSpec.EXACTLY) ? sizeWidth : width, (modeHeight == MeasureSpec.EXACTLY) ? sizeHeight : height); } /** * 存储所有的view,按行记录 */ private List<List<View>> mAllView = new ArrayList<List<View>>(); /** * 记录每一行的最大高度 */ private List<Integer> mLineHeight = new ArrayList<Integer>(); @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { mAllView.clear(); mLineHeight.clear(); int width = getWidth(); int lineWidth = 0; int lineHeight = 0; //存储每一行所有的childview List<View> lineView = new ArrayList<View>(); int mCount = getChildCount(); //遍历所有的子控件 for (int i = 0;i < mCount; i++) { View child = getChildAt(i); MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams(); int childWidth = child.getMeasuredWidth(); int childHeight = child.getMeasuredHeight(); //如果已经需要换行 if (childWidth + lp.leftMargin + lp.rightMargin + lineWidth > width) { //记录这一行所有的View以及最大高度 mLineHeight.add(lineHeight); //将当前行的childView保存,然后开启新的ArrayList保存下一行的childView mAllView.add(lineView); lineWidth = 0; //重置行宽 lineView = new ArrayList<View>(); } /** * 如果不需要换行,则累加 */ lineWidth += childWidth + lp.leftMargin + lp.rightMargin; lineHeight = Math.max(lineHeight, childHeight + lp.topMargin + lp.bottomMargin); //lineHeight = childHeight + lp.topMargin + lp.bottomMargin; lineView.add(child); } //记录最后一行 mLineHeight.add(lineHeight); mAllView.add(lineView); int left = 0; int top = 0; //得到总行数 int lineNums = mAllView.size(); for (int i = 0;i < lineNums; i++) { //每一行的所有的views lineView = mAllView.get(i); //当前行的最大高度 lineHeight = mLineHeight.get(i); Log.i("myTag", i + " " + lineHeight); //遍历当前所有的view for (int j = 0;j < lineView.size(); j++) { View child = lineView.get(j); if (child.getVisibility() == View.GONE) { continue; } MarginLayoutParams lp = (MarginLayoutParams)child.getLayoutParams(); //计算childView的left,top,right,bottom int cl = left + lp.leftMargin; int ct = top + lp.topMargin; int cr = cl + child.getMeasuredWidth(); int cb = ct + child.getMeasuredHeight(); child.layout(cl, ct, cr, cb); left += child.getMeasuredWidth() + lp.rightMargin + lp.leftMargin; } left = 0; top += lineHeight; } }}2、容器规定了控件的高度和宽度
package com.example.huanghaiyan.mjtestactivity;import android.content.Context;import android.util.AttributeSet;import android.util.Log;import android.view.View;import android.view.ViewGroup;import java.util.ArrayList;import java.util.List;/** * Created by Alex on 16/3/22. */public class MyLayout extends ViewGroup { double childWidth; double childHeight; double childMagin; public MyLayout(Context context) { super(context); } public MyLayout(Context context, AttributeSet attrs) { super(context, attrs); } public MyLayout(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) { return new MarginLayoutParams(getContext(), attrs); } /*假设每行四个*/ protected void onMeasure(int w,int h) { super.onMeasure(w, h); //获得它的父容器为它设置的测量模式和大小 int sizeWidth = MeasureSpec.getSize(w); int sizeHeight = MeasureSpec.getSize(h); Log.i("myTag", sizeWidth + ""); //计算控件长宽与magin double mwidth = sizeWidth / 4; childMagin = mwidth / 5; childWidth = mwidth - 2*childMagin; childHeight = childWidth; setMeasuredDimension(sizeWidth, sizeHeight); } /** * 存储所有的view,按行记录 */ private List<List<View>> mAllView = new ArrayList<List<View>>(); /** * 记录每一行的最大高度 */ private List<Integer> mLineHeight = new ArrayList<Integer>(); @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { mAllView.clear(); mLineHeight.clear(); int width = getWidth(); int lineWidth = 0; int lineHeight = 0; //存储每一行所有的childview List<View> lineView = new ArrayList<View>(); int mCount = getChildCount(); //遍历所有的子控件 double left = 0; double top = 0; for (int i = 0;i < mCount; i++) { View child = getChildAt(i); if (i != 0 && i % 4 == 0) { left = 0; top += childHeight + childMagin * 2; } if (child.getVisibility() == View.GONE) { continue; } //计算childView的left,top,right,bottom double cl = left + childMagin; double ct = top + childMagin; double cr = cl + childWidth; double cb = ct + childHeight; child.layout((int) cl, (int) ct, (int) cr, (int) cb); left += childWidth + childMagin + childMagin; Log.i("myTag", "left:" + left); } }}
布局文件都是相似的:
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:custom="http://schemas.android.com/apk/res/com.example.huanghaiyan.mjtestactivity" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.example.huanghaiyan.mjtestactivity.MainActivity"> <com.example.huanghaiyan.mjtestactivity.MyLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <ImageView android:layout_width="match_parent" android:layout_height="100dp" android:src="@drawable/example"/> <TextView android:textColor="#000000" android:text="block1" android:layout_height="wrap_content" android:layout_width="wrap_content"/> <TextView android:textColor="#000000" android:text="block2" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <TextView android:textColor="#000000" android:text="block3" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <TextView android:textColor="#000000" android:text="block4" android:layout_height="wrap_content" android:layout_width="wrap_content"/> <TextView android:textColor="#000000" android:text="block5" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <TextView android:textColor="#000000" android:text="block6" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <TextView android:textColor="#000000" android:text="block7" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <TextView android:textColor="#000000" android:text="block8" android:layout_height="wrap_content" android:layout_width="wrap_content"/> <TextView android:textColor="#000000" android:text="block9" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <TextView android:textColor="#000000" android:text="block10" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <TextView android:textColor="#000000" android:text="block11" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <TextView android:textColor="#000000" android:text="block12" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <TextView android:textColor="#000000" android:text="block13" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <TextView android:textColor="#000000" android:text="block14" android:layout_height="wrap_content" android:layout_width="wrap_content"/> <TextView android:textColor="#000000" android:text="block15" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </com.example.huanghaiyan.mjtestactivity.MyLayout></RelativeLayout>
0 0
- android自定义view之自定义容器
- Android 自定义滑动容器View
- Android之自定义View
- android 之自定义View
- Android之自定义View
- Android之自定义View
- Android之自定义View
- Android 之 自定义View
- Android 自定义View 之 自定义View属性
- Android 自定义滑动容器View(2)
- Android自定义View之自定义“更多”界面
- Android自定义View之自定义开关按钮
- Android之自定义view及自定义属性
- android自定义view之自定义RatingBar
- android自定义view之自定义卫星menu
- android自定义view之自定义imageview
- android自定义view之自定义时钟wacthview
- Android自定义控件之自定义View(一)
- FreeMarker模板使用方法讲解
- 快速排序, 堆排序,归并排序【N*logN】
- Andoird Studio 错误: 非法字符: '\ufeff' 解决方案。
- java 1.8 ArrayList容量增长方式
- dubbo + zookeeper + spring
- android自定义view之自定义容器
- 内存存储格式打印
- android 4.4 系统永不休眠
- 编译 Linux 3.5 内核烧写 Android 到tiny4412
- SpringMVC+spring-security+sitemesh+hibernate+freemarker整合
- 信号(SIGNAL)与槽(SLOT)
- HBase基础讲解
- zend debugger图文教程
- 可编辑模型model