之前项目遇到需要自动换行的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); } }
需要的朋友自己下载
相关推荐
"AndroidAutoLayout"是一个专为Android平台设计的自定义ViewGroup,它提供了自动换行的功能,使得在有限的屏幕空间内展示多个元素变得更加灵活和便捷。这个组件特别适合用于创建多标签选择界面,无论是单选还是多选...
总之,"Android 标签,可以自动换行的ViewGroup"是Android UI设计中一个重要的概念,它通过自动换行的能力提高了界面的适应性和用户体验。开发者可以利用现有的开源库或自定义ViewGroup来实现这一功能,以创建更加...
标题"android 自动换行的自定义viewgroup"所指的,就是创建一个能够根据子视图的数量和大小自动调整布局,实现自动换行效果的自定义 ViewGroup 类。这样的组件通常用于展示网格或者流式布局,例如商品列表、图片墙等...
在这个场景中,我们关注的是一个名为"Android自动换行标签控件(二)"的主题,它涉及到如何利用`ViewGroup`来实现一个可以自动换行的标签控件。这样的控件通常用于展示多条分类标签,例如新闻类别或者产品属性,当...
"自动换行的ViewGroup",如其名所示,是一种特殊的LinearLayout,它具有自动将子视图在达到容器边界时换行的功能,类似于常见的网格或流式布局。这个特性使得在不预先确定子视图数量和大小的情况下,仍然可以创建...
总的来说,创建一个多标签自动换行的`ViewGroup`需要理解Android布局系统的底层工作原理,以及如何通过自定义`ViewGroup`来实现特定的布局需求。通过这样的实践,开发者可以更灵活地控制界面的布局,以适应各种屏幕...
总之,“多个view自动换行”是Android布局设计中的一个重要特性,它涉及到对`ViewGroup`和布局管理器的深入理解。通过自定义`ViewGroup`,我们可以实现更复杂的布局逻辑,比如自动换行,以满足各种UI设计需求。在...
在Android开发中,创建自定义ViewGroup以实现自动换行的功能是一个常见的需求,尤其是在构建复杂的用户界面时。这个场景特别适用于邮件应用中的收件人输入框,用户可以连续添加多个收件人,而这些收件人的显示需要...
本项目是一个年前的Android应用源码示例,专为学生毕业设计学习而准备,旨在教授如何让TextView根据文本长度自动换行,以适应不同屏幕尺寸和用户需求。 在Android中,TextView默认情况下会自动换行,当一行文本无法...
Android LinearLayout 实现自动换行 Android LinearLayout 实现自动换行是 Android 开发中常见的需求。LinearLayout 是 Android 中最常用的布局控件之一,但它有一个缺陷,就是不能自动换行。今天,我们将详细介绍...
本示例“Android实现View的排列自动换行”着重讲解如何在自定义View中实现视图元素的自动布局,即当一行无法容纳所有视图时,自动将超出的视图换行到下一行,并保持适当的间距。 首先,我们需要创建一个新的...
在Android TV开发中,"焦点自动换行"是一个重要的功能,它涉及到用户界面(UI)的交互性和可访问性。在Android TV系统上,用户通常通过遥控器进行操作,焦点管理是用户导航应用界面的关键。当用户按下遥控器的箭头键时...
在Android开发中,...总之,实现一个自定义的自动换行控件,需要理解Android布局机制,熟练掌握ViewGroup的测量和布局过程。通过自定义ViewGroup,我们可以灵活地创建满足特定需求的复杂布局,提高应用的用户体验。
在这个场景中,提到的"添加标签,自动换行,并可以多选,单选"是一个对FlowLayout的增强,使得开发者能够更灵活地构建UI,特别是处理大量可选择的项目时。 1. **FlowLayout**: FlowLayout是Java Swing或Android中的...
`AutoLineLayoutManager`将接管ViewGroup的布局过程,通过计算每个子View的尺寸和位置,确保它们在达到边界时自动换行。这样的类可能需要重写`onLayout()`方法,以实现自定义的换行逻辑。 这三种自定义类提供了不同...
这个压缩包"安卓Android源码——textView根据长度自动换行.zip"很可能包含了一个示例项目或代码片段,演示了如何在TextView中实现根据文本长度自动换行的功能。 在Android的TextView中,自动换行是默认开启的。当你...
本项目“Android自定义标签view——可自动换行”提供了一种解决方案,使得在界面上显示的标签可以按照屏幕大小自动换行,从而避免了内容溢出的问题。下面将详细介绍这个项目及其相关知识点。 1. 自定义View:在...
本教程将探讨如何实现一个自定义控件,它具有自动换行的效果,使得在有限的屏幕空间内,元素能够整齐地排列成多行。参考链接为:。 首先,我们需要创建一个新的`ViewGroup`子类,例如`AutoWrapLayout`。这个自定义...
本篇将详细探讨如何实现一个根据控件长度自动换行的功能,尤其在ListView的item中动态添加布局。 首先,我们需要理解ListView的工作原理。ListView通过复用convertView来提高性能,即当一个item滚动出屏幕时,它的...