之前项目遇到需要自动换行的linearlayout,当时没有实现出来,现在已经搞定,把它分享出来。
我用的是viewgroup写的,其实也可以用其他容器控件写,有需要的同学自己去扩展。
package com.example.test.auto.change.lines; import android.content.Context; import android.util.AttributeSet; import android.util.Log; import android.view.View; import android.view.ViewGroup; /** * 自动换行ViewGroup */ public class AutoChangeLinesViewGroup extends ViewGroup { private final String TAG = "AutoChangeLinesViewGroup"; private final static int VIEW_MARGIN = 2; public AutoChangeLinesViewGroup(Context context) { super(context); // TODO Auto-generated constructor stub } public AutoChangeLinesViewGroup(Context context, AttributeSet attrs) { super(context, attrs); // TODO Auto-generated constructor stub } public AutoChangeLinesViewGroup(Context context, AttributeSet attrs,int defStyle) { super(context, attrs, defStyle); // TODO Auto-generated constructor stub } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { // TODO Auto-generated method stub Log.d(TAG, "changed ==== " + changed + " l == " + l + " t === " + t + " r == " + r + " b== " + b); int row = 0; int width = 0; int height = 0; if(changed){ final int count = getChildCount(); for(int i = 0; i < count; i++){ final View child = this.getChildAt(i); int measuredWidth = child.getMeasuredWidth(); int measuredHeight = child.getMeasuredHeight(); width += measuredWidth + VIEW_MARGIN; height = row * ( measuredHeight + VIEW_MARGIN ) + VIEW_MARGIN + measuredHeight; if(width > r){ width = measuredWidth + VIEW_MARGIN; if(width > r){ width = r - l ; } row ++; height = row * ( measuredHeight + VIEW_MARGIN ) + VIEW_MARGIN + measuredHeight; // 超出最大范围之后不绘制 child.layout(0, height - measuredHeight, width, height); }else { child.layout(width - measuredWidth, height - measuredHeight, width, height); } } } } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { // TODO Auto-generated method stub for(int i = 0 ; i < getChildCount() ; i ++){ final View childView = getChildAt(i); childView.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED); } super.onMeasure(widthMeasureSpec, heightMeasureSpec); } }
此控件有一个问题,如果它外层有Viewgroup,那么此控件不能计算本身高度,导致没法看到期望的效果,下面我再次贴出完美解决此问题的代码
package com.app.widget; import android.content.Context; import android.util.AttributeSet; import android.view.View; import android.view.ViewGroup; import com.app.R; public class AutoChangeLinesViewGroup extends ViewGroup { // 横向间距 private static int VIEW_WIDTH_MARGIN = 10; // 纵向间距 private static int VIEW_HEIGHT_MARGIN = 10; public AutoChangeLinesViewGroup(Context context) { super(context); // TODO Auto-generated constructor stub init(context); } public AutoChangeLinesViewGroup(Context context, AttributeSet attrs) { super(context, attrs); // TODO Auto-generated constructor stub init(context); } public AutoChangeLinesViewGroup(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); // TODO Auto-generated constructor stub init(context); } private void init(Context context){ VIEW_WIDTH_MARGIN = (int) context.getResources().getDimension(R.dimen.nearby_releasse_thtem_tag_height); VIEW_HEIGHT_MARGIN = (int) context.getResources().getDimension(R.dimen.nearby_releasse_thtem_tag_width); } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { // TODO Auto-generated method stub int width = 0; int height = 0; int row = 0 ; if(changed){ final int count = getChildCount(); for(int i = 0; i < count; i++){ final View child = this.getChildAt(i); int measuredWidth = child.getMeasuredWidth(); int measuredHeight = child.getMeasuredHeight(); width += measuredWidth + VIEW_WIDTH_MARGIN; height = row * ( measuredHeight + VIEW_HEIGHT_MARGIN ) + VIEW_HEIGHT_MARGIN + measuredHeight; if(width > getWidth()){ width = measuredWidth + VIEW_WIDTH_MARGIN; if(width > getWidth()){ width = getWidth() ; } row ++; height = row * ( measuredHeight + VIEW_HEIGHT_MARGIN ) + VIEW_HEIGHT_MARGIN + measuredHeight; // 超出最大范围之后不绘制 child.layout(0, height - measuredHeight, width - VIEW_WIDTH_MARGIN, height); }else { child.layout(width - measuredWidth - VIEW_WIDTH_MARGIN, height - measuredHeight, width - VIEW_WIDTH_MARGIN, height); } } } } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { // TODO Auto-generated method stub super.onMeasure(widthMeasureSpec, heightMeasureSpec); // 获取系统自动测量的该ViewGroup的大小 int widthSize = MeasureSpec.getSize(widthMeasureSpec); int heightSize = MeasureSpec.getSize(heightMeasureSpec); if(heightSize > 0 && widthSize > 0){ setMeasuredDimension(widthSize, heightSize); return ; } // 我们也可调用setMeasuredDimension()重新设置测量结果 // 修改了系统自动测量的子View的大小 int childCount = this.getChildCount(); int width = 0; int height = 0; int row = 0 ; for (int i = 0; i < childCount; i++) { View childView = getChildAt(i); int w = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); int h = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); childView.measure(w, h); // 获取每个子View测量所得的宽和高 int childMeasuredWidth = childView.getMeasuredWidth(); int childMeasuredHeight = childView.getMeasuredHeight(); width += childMeasuredWidth + VIEW_WIDTH_MARGIN; height = row * ( childMeasuredHeight + VIEW_HEIGHT_MARGIN ) + VIEW_HEIGHT_MARGIN + childMeasuredHeight; if(width > widthSize){ width = childMeasuredWidth + VIEW_WIDTH_MARGIN; if(width > widthSize){ width = widthSize ; } row ++; height = row * ( childMeasuredHeight + VIEW_HEIGHT_MARGIN ) + VIEW_HEIGHT_MARGIN + childMeasuredHeight; } } setMeasuredDimension(widthSize, height); } }
需要的朋友自己下载
相关推荐
可自动换行效果的viewgroup,支持一键多选,单选,绝对是多标签选择的不二选择
Android 标签,可以自动换行的ViewGroup
可以自动换行,如果一行放不下,可换行,还可以支持滚动布局。
Android基于ViewGroup实现自动换行标签控件。
多标签自动换行的控件ViewGroup ;
自定义ViewGroup实现自动换行功能,一行控件填充满以后自动换到下一行。
android 通过自定义ViewGroup实现自动换行的流布局,支持padding与margin
首先需要继承ViewGroup, 在这里我们需要重写它的onMeasure和onLayout方法。本项目中它的子View有两种填充方式,一种是Fill_PARENT,一种是WRAP_CONTENT,看名字应该能知道是什么意思吧。
一些搜索软件下面一般都会提供一些关键字供用户参考,该控件可以根据关键字多少实现自动换行
在我们开发过程中会经常遇见一些客户要求但是Android系统又不提供的效果,这时我们只能自己动手去实现它,或者从网络上借鉴他人的资源,本着用别人不如自己会做的心态,在此我总结了一下Android中如何实现自动换行的...
AndroidTagGroup实现云标签效果,各种背景效果的标签,并且支持添加, 大体实现:有一个TagsManager管理TagGroup,自定义TagGroup...TagGroup extends ViewGroup,TagGroup 由多个TagView组成,TagView继承TextView 。
自定义ViewGroup 实现类似于电商平台上的商品属性显示效果
自动换行布局,水平排列子项,并自动换行,支持不等长不等宽子项,且可以设置垂直间距与水平间距及子项对齐模式。要求minSdkVersion 4引用dependencies { ⋯ compile 'am.widget:wraplayout:1.1.0' ⋯ }...
最近,Google开源了一个流式排版库“FlexboxLayout”,功能强大,支持多种排版方式,如各种方向的自动换行等,具体资料各位可搜索学习^_^。 由于我的项目中,只需要从左到右S型的自动换行,需求效果图如下: 使用...
自定义viewgroup自动换行layout, 看效果图 Series of entrance animation effects just like ppt in Android. There are effects of Blinds,Wipe,Box,Strips,Diamond,Wheel,Split,Checkerboard,Peek In,Wedge,Plus...
本篇文章讲的是Android 自定义ViewGroup之实现标签流式布局-FlowLayout,开发中我们会经常需要实现类似于热门标签等自动换行的流式布局的功能,网上也有很多这样的FlowLayout,但不影响我对其的学习。和往常一样,...
android ui 流式布局,实现自定义viewgroup flowlayout,实现子view的自动换行。对viewgroup wrap_content的处理等。
自定义ViewGroup实现view自动换行
在日常的app使用中,我们会在android 的app中看见 热门标签等自动换行的流式布局,今天,我们就来看看如何 自定义一个类似热门标签那样的流式布局吧(源码下载在下面最后给出) 类似的自定义布局。下面我们就来详细...