`
夏文权
  • 浏览: 242249 次
  • 性别: Icon_minigender_1
  • 来自: 贵州
社区版块
存档分类
最新评论

Android 自动换行的ViewGroup

 
阅读更多

之前项目遇到需要自动换行的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);
	}
}

 

 

需要的朋友自己下载

 

 

 

  • 大小: 98.8 KB
分享到:
评论

相关推荐

    AndroidAutoLayout自动换行viewgroup

    "AndroidAutoLayout"是一个专为Android平台设计的自定义ViewGroup,它提供了自动换行的功能,使得在有限的屏幕空间内展示多个元素变得更加灵活和便捷。这个组件特别适合用于创建多标签选择界面,无论是单选还是多选...

    Android 标签,可以自动换行的ViewGroup

    总之,"Android 标签,可以自动换行的ViewGroup"是Android UI设计中一个重要的概念,它通过自动换行的能力提高了界面的适应性和用户体验。开发者可以利用现有的开源库或自定义ViewGroup来实现这一功能,以创建更加...

    android 自动换行的自定义viewgroup

    标题"android 自动换行的自定义viewgroup"所指的,就是创建一个能够根据子视图的数量和大小自动调整布局,实现自动换行效果的自定义 ViewGroup 类。这样的组件通常用于展示网格或者流式布局,例如商品列表、图片墙等...

    Android自动换行标签控件(二)

    在这个场景中,我们关注的是一个名为"Android自动换行标签控件(二)"的主题,它涉及到如何利用`ViewGroup`来实现一个可以自动换行的标签控件。这样的控件通常用于展示多条分类标签,例如新闻类别或者产品属性,当...

    自动换行的ViewGroup

    "自动换行的ViewGroup",如其名所示,是一种特殊的LinearLayout,它具有自动将子视图在达到容器边界时换行的功能,类似于常见的网格或流式布局。这个特性使得在不预先确定子视图数量和大小的情况下,仍然可以创建...

    多标签自动换行的控件ViewGroup

    总的来说,创建一个多标签自动换行的`ViewGroup`需要理解Android布局系统的底层工作原理,以及如何通过自定义`ViewGroup`来实现特定的布局需求。通过这样的实践,开发者可以更灵活地控制界面的布局,以适应各种屏幕...

    多个view自动换行

    总之,“多个view自动换行”是Android布局设计中的一个重要特性,它涉及到对`ViewGroup`和布局管理器的深入理解。通过自定义`ViewGroup`,我们可以实现更复杂的布局逻辑,比如自动换行,以满足各种UI设计需求。在...

    Android自动换行控件,邮件收件人

    在Android开发中,创建自定义ViewGroup以实现自动换行的功能是一个常见的需求,尤其是在构建复杂的用户界面时。这个场景特别适用于邮件应用中的收件人输入框,用户可以连续添加多个收件人,而这些收件人的显示需要...

    Android textView根据长度自动换行-IT计算机-毕业设计.zip

    本项目是一个年前的Android应用源码示例,专为学生毕业设计学习而准备,旨在教授如何让TextView根据文本长度自动换行,以适应不同屏幕尺寸和用户需求。 在Android中,TextView默认情况下会自动换行,当一行文本无法...

    Android LinearLayout实现自动换行

    Android LinearLayout 实现自动换行 Android LinearLayout 实现自动换行是 Android 开发中常见的需求。LinearLayout 是 Android 中最常用的布局控件之一,但它有一个缺陷,就是不能自动换行。今天,我们将详细介绍...

    Android 实现View的排列自动换行

    本示例“Android实现View的排列自动换行”着重讲解如何在自定义View中实现视图元素的自动布局,即当一行无法容纳所有视图时,自动将超出的视图换行到下一行,并保持适当的间距。 首先,我们需要创建一个新的...

    android TV 焦点自动换行

    在Android TV开发中,"焦点自动换行"是一个重要的功能,它涉及到用户界面(UI)的交互性和可访问性。在Android TV系统上,用户通常通过遥控器进行操作,焦点管理是用户导航应用界面的关键。当用户按下遥控器的箭头键时...

    android自定义控件自动换行效果实现 简化版demo

    在Android开发中,...总之,实现一个自定义的自动换行控件,需要理解Android布局机制,熟练掌握ViewGroup的测量和布局过程。通过自定义ViewGroup,我们可以灵活地创建满足特定需求的复杂布局,提高应用的用户体验。

    添加标签,自动换行,并可以多选,单选

    在这个场景中,提到的"添加标签,自动换行,并可以多选,单选"是一个对FlowLayout的增强,使得开发者能够更灵活地构建UI,特别是处理大量可选择的项目时。 1. **FlowLayout**: FlowLayout是Java Swing或Android中的...

    android 自动换行

    `AutoLineLayoutManager`将接管ViewGroup的布局过程,通过计算每个子View的尺寸和位置,确保它们在达到边界时自动换行。这样的类可能需要重写`onLayout()`方法,以实现自定义的换行逻辑。 这三种自定义类提供了不同...

    安卓Android源码——textView根据长度自动换行.zip

    这个压缩包"安卓Android源码——textView根据长度自动换行.zip"很可能包含了一个示例项目或代码片段,演示了如何在TextView中实现根据文本长度自动换行的功能。 在Android的TextView中,自动换行是默认开启的。当你...

    Android自定义标签view——可自动换行

    本项目“Android自定义标签view——可自动换行”提供了一种解决方案,使得在界面上显示的标签可以按照屏幕大小自动换行,从而避免了内容溢出的问题。下面将详细介绍这个项目及其相关知识点。 1. 自定义View:在...

    android自定义控件自动换行效果实现

    本教程将探讨如何实现一个自定义控件,它具有自动换行的效果,使得在有限的屏幕空间内,元素能够整齐地排列成多行。参考链接为:。 首先,我们需要创建一个新的`ViewGroup`子类,例如`AutoWrapLayout`。这个自定义...

    Android 控件可以根据长度自动换行

    本篇将详细探讨如何实现一个根据控件长度自动换行的功能,尤其在ListView的item中动态添加布局。 首先,我们需要理解ListView的工作原理。ListView通过复用convertView来提高性能,即当一个item滚动出屏幕时,它的...

Global site tag (gtag.js) - Google Analytics