androi自定义自动换行的View(类似网页的标签Tag)

看来只有礼拜天才有时间写点博客啊,平时只能埋头苦干了。今天在公司加班,遇到一个需求,就是自动换行的TextView,有点像网页的tag标签,点击一下,就自动加上去了,不过这个是根据后台拿来的数据来显示多少个View,在网上找找,看见了许多,我自己也封装写一个吧,以便以后需要...开工

package com.woyou.ui.component;

import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import com.citaq.ideliver.R;

/**
 * 自动换行的View
 *
 * @author shenzhou	2015年1月11日
 */
public class WordWrapView extends ViewGroup {
	private static final int PADDING_HOR = 10;// 水平方向padding
	private static final int PADDING_VERTICAL = 15;// 垂直方向padding
	private static final int SIDE_MARGIN = 10;// 左右间距
	private static final int TEXT_MARGIN = 10;

	public WordWrapView(Context context) {
		super(context);
	}

	public WordWrapView(Context context, AttributeSet attrs) {
		super(context, attrs);
	}

	public WordWrapView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
	}

	@Override
	protected void onLayout(boolean changed, int l, int t, int r, int b) {
		int childCount = getChildCount();
		int autualWidth = r - l;
		int x = SIDE_MARGIN;// 横坐标开始
		int y = 0;// 纵坐标开始
		int rows = 1;
		for (int i = 0; i < childCount; i++) {
			View view = getChildAt(i);
			view.setBackgroundResource(R.drawable.shopdetail_keytag_bg);
			int width = view.getMeasuredWidth();
			int height = view.getMeasuredHeight();
			x += width + TEXT_MARGIN;
			if (x > autualWidth) {
				x = width + SIDE_MARGIN;
				rows++;
			}
			y = rows * (height + TEXT_MARGIN);
			if (i == 0) {
				view.layout(x - width - TEXT_MARGIN, y - height, x
						- TEXT_MARGIN, y);
			} else {
				view.layout(x - width, y - height, x, y);
			}
		}

	}

	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		int x = 0;// 横坐标
		int y = 0;// 纵坐标
		int rows = 1;// 总行数
		int specWidth = MeasureSpec.getSize(widthMeasureSpec);
		int actualWidth = specWidth - SIDE_MARGIN * 2;// 实际宽度
		int childCount = getChildCount();
		for (int index = 0; index < childCount; index++) {
			View child = (TextView) getChildAt(index);
			child.setPadding(PADDING_HOR, PADDING_VERTICAL, PADDING_HOR,
					PADDING_VERTICAL);
			child.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
			int width = child.getMeasuredWidth();
			int height = child.getMeasuredHeight();
			x += width + TEXT_MARGIN;
			if (x > actualWidth) {// 换行
				x = width;
				rows++;
			}
			y = rows * (height + TEXT_MARGIN);
		}
		setMeasuredDimension(actualWidth, y);
	}

}

具体使用:

我的项目的布局文件太长了,我就说了

<com.woyou.ui.component.WordWrapView
	               style="@style/shopDetailTextStyle"
	               android:id="@+id/shopdetail_container"
	               android:layout_width="match_parent"
	               android:layout_height="wrap_content"
	               android:orientation="vertical"
	               android:paddingLeft="@dimen/dp20"
	               android:paddingRight="@dimen/dp20"
	               android:paddingTop="@dimen/dp10" />

把这段布局文件加到你要把文字自动换行的地方。java文件中的使用:

if ( !TextUtils.isEmpty(shopDetail.getInfo()) ) {
					infoLin.setVisibility(View.VISIBLE);
					//店铺关键字
					String key = shopDetail.getKey();
					strs = key.split("\\|");
					for (int i = 0; i < strs.length; i++) {
					      TextView textview = new TextView(mActivity);
					      textview.setText(strs[i]);
					      wordWrapView.addView(textview);
					}
					LogUtil.i(TAG, "tags:" + strs.toString());

前面还有找到控件什么的,我相信大家都是知道的。这只是核心代码,效果图如下:

****************************************************************************************************************************

**********************介绍另外一种方法,是某个大神写的,不过没封装,供大家参考***********************************

****************************************************************************************************************************

 /** 标签之间的间距 px */
    private final int itemMargins = (int) getContext().getResources().getDimension(R.dimen.dp15);
    /** 标签的行间距 px */
    private final int lineMargins = (int) getContext().getResources().getDimension(R.dimen.dp10);  
/**
	 * 加载店铺关键字
	 * @param tags
	 */
	private void loadShopKeys (String[] tags) {
		if ( tags == null )
			return;
		final int containerWidth = container.getMeasuredWidth() - container.getPaddingRight()  - container.getPaddingLeft();
        final LayoutInflater inflater = mActivity.getLayoutInflater();  

        /** 用来测量字符的宽度 */
        final Paint paint = new Paint();
        final TextView textView = (TextView) inflater.inflate(R.layout.item_textviewtag_lv, null);
        final int itemPadding = textView.getCompoundPaddingLeft() + textView.getCompoundPaddingRight();
        final LinearLayout.LayoutParams tvParams = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT,  LayoutParams.WRAP_CONTENT);
        tvParams.setMargins(0, 0, itemMargins, 0);  

        paint.setTextSize(textView.getTextSize());
        LinearLayout layout = new LinearLayout(getContext());
        layout.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
        layout.setOrientation(LinearLayout.HORIZONTAL);
        container.addView(layout);  

        final LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
        params.setMargins(0, lineMargins, 0, 0);  

        /** 一行剩下的空间 **/
        int remainWidth = containerWidth;  

        for (int i = 0; i < tags.length; ++i) {
            final String text = tags[i];
            final float itemWidth = paint.measureText(text) + itemPadding;
            if (remainWidth > itemWidth) {
                addItemView(inflater, layout, tvParams, text);
            } else {
                resetTextViewMarginsRight(layout);
                layout = new LinearLayout(getContext());
                layout.setLayoutParams(params);
                layout.setOrientation(LinearLayout.HORIZONTAL);  

                /** 将前面那一个textview加入新的一行 */
                addItemView(inflater, layout, tvParams, text);
                container.addView(layout);
                remainWidth = containerWidth;
            }
            remainWidth = (int) (remainWidth - itemWidth + 0.5f) - itemMargins;
        }
        resetTextViewMarginsRight(layout);
    }  

	/***************** 将每行最后一个textview的MarginsRight去掉 *********************************/
    private void resetTextViewMarginsRight(ViewGroup viewGroup) {
        final TextView tempTx = (TextView) viewGroup.getChildAt(viewGroup.getChildCount() - 1);
        tempTx.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
    }  

    private void addItemView(LayoutInflater inflater, ViewGroup viewGroup, android.widget.LinearLayout.LayoutParams tvParams, String text) {
        final TextView itemTx = (TextView) inflater.inflate(R.layout.item_textviewtag_lv, null);
        itemTx.setText(text);
        viewGroup.addView(itemTx, tvParams);
    }

好了,到此结束了,屌丝要继续加班了,话说都好几天没打LoL,有点怀念了,等这段时间过了,本吊要撸到天明...

时间: 01-11

androi自定义自动换行的View(类似网页的标签Tag)的相关文章

C#自定义双向链表,功能类似C++中的CList

参照博客: http://www.cnblogs.com/linzheng/news/2011/07/14/2106530.html. http://blog.csdn.net/dongxinxi/article/details/6303421 C#自定义双向链表,功能类似C++中的CList,布布扣,bubuko.com

自定义控件(视图)2期笔记14:自定义视图之View事件分发 dispatchTouchEvent,onTouch,onTouchEvent,onClick逻辑顺序过程

1. 这里我们先从案例角度说明dispatchTouchEvent,onTouch,onTouchEvent,onClick逻辑顺序过程: (1)首先我们重写一个MyButton 继承自 Button,代码如下: 1 package com.himi.eventdemo; 2 3 import android.content.Context; 4 import android.util.AttributeSet; 5 import android.util.Log; 6 import andro

浅析网页meta标签中X-UA-Compatible属性的使用

今天有一个做开发的朋友突然问你知道很多网站上面加入的X-UA-Compatible属性的意义么?其实这个在以前还专门花了一点时间来验证我自己的想法,结果也确实如自己所预想的那样,八九不离十,当然有一点点的偏差.我做的项目中也并不是每个项目中都使用该属性.那么我们首先来看看几个知名站点,他们也使用了这个 上面时淘宝的,下面是百度的. 都可以发现在head中又一个meta,里面有一个X-UA-Compatible的属性,而且确实非常多的网站中在使用.当然也有很多网站是在开发的时候不管三七二十一给加上

网页编辑标签及属性

网页是通过编辑不同的标签来完成的.大多数的标签通常由两个组成,开始跟结束,如<html>...</html>.每个标签都能够添加属性,属性通常编辑在开始标签里.<body bgcolor="  ">...</body>,其中bgcolor编辑的是body 的属性,是背景颜色.body编辑属性还有:text 文字颜色,topmargin 上页边距  leftmargin.rightmargin.bottomargin,background

JSP自定义分页标签TAG

首先我们需要在WEB-INF/tld/目录下创建page.tld文件 <?xml version="1.0" encoding="ISO-8859-1"?> <taglib> <tlib-version>1.0</tlib-version> <jsp-version>1.2</jsp-version> <short-name>page</short-name> <u

Android自定义Viewgroup切换View带有吸附效果

1.概述 先上效果图 大概就是这个效果,先说说实现思路 1.首先我们要拿到图片的url(网络)或id.路径(本地),将View与数据进行绑定,写我们自己的Adapter 2.自定义Viewgroup将要显示的view进行布局,以及处理触摸事件进行逻辑处理 3.写切换回调 2.实现 1)自定义Adapter 这里我下载的网络图片,同样可以将图片放到res下设置ImageView的内容 public class DragPageViewAdapter { private static final S

Android自定义View4——统计图View

1.介绍 周末在逛慕课网的时候,看到了一张学习计划报告图,详细记录了自己一周的学习情况,天天都是0节课啊!正好在学习Android自定义View,于是就想着自己去写了一个,这里先给出一张慕课网的图,和自己的效果图. yissan的博客,未经允许严禁转载 http://blog.csdn.net/yissan 2.实现分析 我们要实现这样一个折线统计图,必要的信息主要有下面几个 先看纵轴,纵轴需要的信息有最大值,还有用来确定每个间距代表的单位,比如最大值是100,我们还要有一个将值分为几份的数据.

iOS 自定义UITableView 删除View

替朋友解决的问题: 需要修改左拉,删除的按钮 查看SDK,系统自带的,只能修改NSStrin 那么问题来了...他急!!! 所以,我就只好用第三方快速开发. 使用SWTableViewCell来解决这个 pod 'SWTableViewCell', '~> 0.3.6' 具体访问GitHub上查看具体内容  地址链接 ==================================== 使用三方类库有风险,如若使用,风险由个人承担.

HTML静态网页(标签、表格)

HTML静态网页: 打开DREAMWEAVER,新建HTML,如下图: body的属性: bgcolor 页面背景色 background  背景壁纸.图片 text  文字颜色 topmargin  上边距 leftmargin   左边距 rightmargin 右边距 bottommargin  下边距 body属性用法示例: 格式控制标签: <font color="" face="" size=""></font>

类似小红书标签效果(补间动画)

昨天老大给布置个任务,为我们的app做下调研,app中有标签的存在,类似小红书和nice的添加标签模式,于是我就试着做出那个一闪一闪的标注点~   仔细看了看小红书的闪闪的标签,得出一个结论: 它是个动画   好吧,这简直是废话. 其实一开始我的思路是拿来主义,去网上找了找类似的“小红书标签效果”等等,然后我发现他们用自定义控件完成了一个这样的动画..就这样,我华丽丽的跑偏了呃呃呃..   自定义控件我不熟啊!! 学. 花了半个下午研究自定义控件,好不容易写出了动画效果. 这个效果的原理是这个样