自定义viewgroup实现自动换行的布局,同时解决自定义布局在wrapc

一.基础知识在这里首先介绍一下Android下自定义Component的一些基础知识,已经了解或者心急的同学可以直接跳到第二章看代码。说到自定义Component,我想在没有什么比Google自家的SDK document解释的来的全面和准确的了,下面我们就来看看官方是怎么说的:在SDK->API Guides->UserInterface->Custom Components一章中官方是这么说的. To start with, the platform includes a variety of prebuilt View and ViewGroup subclasses — called widgets and layouts, respectively — that you can use to construct your UI.也就是说,基本所有我们使用的UI控件都是继承自View和ViewGroup这两个基类的,比如我们常用的布局(Linerlayout,,RelativeLayout等),和一些widgets(Button,TextView等)。我们自己想要自定义控件也必须继承这两个基类(当然,你也可以直接继承已有的Layouts和widgets)。重写ViewGroup需要注意的事项:1.必须要重写onLayout方法,并且需要实现三个默认的构造函数,不然会加载布局时出错。2.重写onMeasure方法。onMeasure方法,该方法指定控件在屏幕上的大小,方法的原型: onMeasure(int widthMeasureSpec heightMeasureSpeconMeasure传入的widthMeasureSpec和heightMeasureSpec不是一般的尺寸数值,而是将模式和尺寸组合在一起的数值。我们需要通过int mode = MeasureSpec.getMode(widthMeasureSpecmode共有三种情况,取值分别为MeasureSpec.UNSPECIFIED, MeasureSpec.EXACTLY, MeasureSpec.AT_MOST。MeasureSpec.EXACTLY是精确尺寸,当我们将控件的layout_width或layout_height指定为具体数值时如andorid:layout_width="50dip",或者为FILL_PARENT是,都是控件大小已经确定的情况,都是精确尺寸。MeasureSpec.AT_MOST是最大尺寸,当控件的layout_width或layout_height指定为WRAP_CONTENT时,控件大小一般随着控件的子空间或内容进行变化,此时控件尺寸只要不超过父控件允许的最大尺寸即可。因此,此时的mode是AT_MOST,size给出了父控件允许的最大尺寸。 MeasureSpec.UNSPECIFIED是未指定尺寸,这种情况不多,一般都是父控件是AdapterView,通过measure方法传入的模式。 onLayout方法,该方法通过拿到childView的getMeasuredWidth() andgetMeasuredHeight(),用来布局所有的childView。二.自动换行的布局(通过自定义ViewGroup实现)废话不多说,直接上代码:

package com.example.hyydatalist.view;import com.example.hyydatalist.constants.HyyConstants;import android.content.Context;import android.util.AttributeSet;import android.util.Log;import android.view.View;import android.view.ViewGroup;public class AutoExtViewGroup extends ViewGroup {public AutoExtViewGroup(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);// TODO Auto-generated constructor stub}public AutoExtViewGroup(Context context, AttributeSet attrs) {super(context, attrs);// TODO Auto-generated constructor stub}public AutoExtViewGroup(Context context) {super(context);// TODO Auto-generated constructor stub}private final static int VIEW_MARGIN = 10;@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {// TODO Auto-generated method stubLog.d(HyyConstants.HYY_TAG, "widthMeasureSpec=" + widthMeasureSpec+ "heightMeasureSpec=" + heightMeasureSpec);int stages = 1;int stageHeight = 0;int stageWidth = 0;int wholeWidth = MeasureSpec.getSize(widthMeasureSpec);for (int i = 0; i < getChildCount(); i++) {final View child = getChildAt(i);// measuremeasureChild(child, widthMeasureSpec, heightMeasureSpec);stageWidth += (child.getMeasuredWidth() + VIEW_MARGIN);stageHeight = child.getMeasuredHeight();if (stageWidth >= wholeWidth) {stages++;//reset stageWidthstageWidth = child.getMeasuredWidth();}Log.i(HyyConstants.HYY_TAG, "i:" + i + ",wholeWidth:" + wholeWidth+ ",stageWidth:" + stageWidth+",stageHeight:"+stageHeight+",stage:"+stages);}Log.i(HyyConstants.HYY_TAG, "stages:" + stages);int wholeHeight = (stageHeight + VIEW_MARGIN) * stages;// report this final dimensionsetMeasuredDimension(resolveSize(wholeWidth, widthMeasureSpec),resolveSize(wholeHeight, heightMeasureSpec));}@Overrideprotected void onLayout(boolean changed, int l, int t, int r, int b) {// TODO Auto-generated method stubfinal int count = getChildCount();int row = 0; // which row lay your view relative to parentint lengthX = l; // right position of child relative to parentint lengthY = t; // bottom position of child relative to parentfor (int i = 0; i < count; i++) {final View child = this.getChildAt(i);int width = child.getMeasuredWidth();int height = child.getMeasuredHeight();lengthX += width + VIEW_MARGIN;lengthY = row * (height + VIEW_MARGIN) + VIEW_MARGIN + height + t;// if it cant't draw in a same line ,skip it to next lineif (lengthX > r) {lengthX = width + VIEW_MARGIN + l;row++;lengthY = row * (height + VIEW_MARGIN) + VIEW_MARGIN + height+ t;}child.layout(lengthX – width, lengthY – height, lengthX, lengthY);}}}

版权声明:本文为博主原创文章,未经博主允许不得转载。

却还是,会愚蠢的选择相互敌视的方式。即使背脊相抵,

自定义viewgroup实现自动换行的布局,同时解决自定义布局在wrapc

相关文章:

你感兴趣的文章:

标签云: