版本号:1.0
日期:2014.7.24
版权:© 2014 kince 转载注明出处
  
  在有的应用中可能须要设置一些标签来方便用去去查询某些信息,比方手机助手或者购物软件之类都会有一些标签。对于软件开发初期来说,直接使用TextView、Button实现是最为简单的一种方式。可是这样的方法也有其局限性,比方不能控制换行、耦合性低等缺点。所以除了解决这些问题之外,最好能够封装一个类库出来,方便以后使用。
  首先新建一个Tag类,
import java.io.Serializable;

public class Tag implements Serializable {

      /**
*
*/
private static final long serialVersionUID = 2684657309332033242L; private int backgroundResId ;
private int id ;
private boolean isChecked ;
private int leftDrawableResId ;
private int rightDrawableResId ;
private String title; public Tag() { } public Tag( int paramInt, String paramString) {
this .id = paramInt;
this .title = paramString;
} public int getBackgroundResId() {
return this .backgroundResId ;
} public int getId() {
return this .id ;
} public int getLeftDrawableResId() {
return this .leftDrawableResId ;
} public int getRightDrawableResId() {
return this .rightDrawableResId ;
} public String getTitle() {
return this .title ;
} public boolean isChecked() {
return this .isChecked ;
} public void setBackgroundResId( int paramInt) {
this .backgroundResId = paramInt;
} public void setChecked( boolean paramBoolean) {
this .isChecked = paramBoolean;
} public void setId(int paramInt) {
this .id = paramInt;
} public void setLeftDrawableResId( int paramInt) {
this .leftDrawableResId = paramInt;
} public void setRightDrawableResId( int paramInt) {
this .rightDrawableResId = paramInt;
} public void setTitle(String paramString) {
this .title = paramString;
}
}
  这个类封装了标签视图的背景图片资源、id、是否check等。
  然后新建TagView类,继承自ToggleButton,
import com.niceapp.lib.tagview.R;

import android.content.Context;
import android.util.AttributeSet;
import android.widget.ToggleButton; public class TagView extends ToggleButton { private boolean mCheckEnable = true; public TagView(Context paramContext) {
super (paramContext);
init();
} public TagView(Context paramContext, AttributeSet paramAttributeSet) {
super (paramContext, paramAttributeSet);
init();
} public TagView(Context paramContext, AttributeSet paramAttributeSet,
int paramInt) {
super (paramContext, paramAttributeSet, 0);
init();
} private void init() {
setTextOn( null );
setTextOff( null );
setText( "" );
setBackgroundResource(R.drawable. tag_bg );
} public void setCheckEnable( boolean paramBoolean) {
this .mCheckEnable = paramBoolean;
if (!this .mCheckEnable ) {
super .setChecked( false);
}
} public void setChecked( boolean paramBoolean) {
if (this .mCheckEnable ) {
super .setChecked(paramBoolean);
}
}
}

这个TagView就是标签视图,标签信息由他来显示。对应的xml文件例如以下,tag.xml:

<? xml version= "1.0" encoding = "utf-8"?>
< com.niceapp.lib.tagview.widget.TagView xmlns:android ="http://schemas.android.com/apk/res/android"
android:layout_width= "wrap_content"
android:layout_height= "wrap_content"
android:drawablePadding= "5.0dip"
android:minHeight= "0.0dip"
android:paddingBottom= "4.5dip"
android:paddingLeft= "20.0dip"
android:paddingRight= "20.0dip"
android:paddingTop= "4.5dip"
android:textColor= "#ff000000"
android:textSize= "16.0sp" />
显演示样例如以下:
 
 在github上有一个android-flowlayout控件,它是依据子视图的大小来动态包裹视图,如图:
 
  因此,控制换行就能够利用这个控件去实现,无需反复发明轮子。android-flowlayout功能实现的类是FlowLayout,所以通过继承这个类来完毕标签控件的实现。
import java.util.ArrayList;
import java.util.List;
import com.niceapp.lib.tagview.R;
import android.content.Context;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.CompoundButton; /**
* @author kince
*
*/
public class TagListView extends FlowLayout implements OnClickListener { private boolean mIsDeleteMode;
private OnTagCheckedChangedListener mOnTagCheckedChangedListener;
private OnTagClickListener mOnTagClickListener;
private int mTagViewBackgroundResId;
private int mTagViewTextColorResId;
private final List<Tag> mTags = new ArrayList<Tag>(); /**
* @param context
*/
public TagListView(Context context) {
super(context);
// TODO Auto-generated constructor stub
init();
} /**
* @param context
* @param attributeSet
*/
public TagListView(Context context, AttributeSet attributeSet) {
super(context, attributeSet);
// TODO Auto-generated constructor stub
init();
} /**
* @param context
* @param attributeSet
* @param defStyle
*/
public TagListView(Context context, AttributeSet attributeSet, int defStyle) {
super(context, attributeSet, defStyle);
// TODO Auto-generated constructor stub
init();
} @Override
public void onClick(View v) {
if ((v instanceof TagView)) {
Tag localTag = (Tag) v.getTag();
if (this.mOnTagClickListener != null) {
this.mOnTagClickListener.onTagClick((TagView) v, localTag);
}
}
} private void init() { } private void inflateTagView(final Tag t, boolean b) { TagView localTagView = (TagView) View.inflate(getContext(),
R.layout.tag, null);
localTagView.setText(t.getTitle());
localTagView.setTag(t); if (mTagViewTextColorResId <= 0) {
int c = getResources().getColor(R.color.blue);
localTagView.setTextColor(c); } if (mTagViewBackgroundResId <= 0) {
mTagViewBackgroundResId = R.drawable.tag_bg;
localTagView.setBackgroundResource(mTagViewBackgroundResId);
} localTagView.setChecked(t.isChecked());
localTagView.setCheckEnable(b);
if (mIsDeleteMode) {
int k = (int) TypedValue.applyDimension(1, 5.0F, getContext()
.getResources().getDisplayMetrics());
localTagView.setPadding(localTagView.getPaddingLeft(),
localTagView.getPaddingTop(), k,
localTagView.getPaddingBottom());
localTagView.setCompoundDrawablesWithIntrinsicBounds(0, 0,
R.drawable.forum_tag_close, 0);
}
if (t.getBackgroundResId() > 0) {
localTagView.setBackgroundResource(t.getBackgroundResId());
}
if ((t.getLeftDrawableResId() > 0) || (t.getRightDrawableResId() > 0)) {
localTagView.setCompoundDrawablesWithIntrinsicBounds(
t.getLeftDrawableResId(), 0, t.getRightDrawableResId(), 0);
}
localTagView.setOnClickListener(this);
localTagView
.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
public void onCheckedChanged(
CompoundButton paramAnonymousCompoundButton,
boolean paramAnonymousBoolean) {
t.setChecked(paramAnonymousBoolean);
if (TagListView.this.mOnTagCheckedChangedListener != null) {
TagListView.this.mOnTagCheckedChangedListener
.onTagCheckedChanged(
(TagView) paramAnonymousCompoundButton,
t);
}
}
});
addView(localTagView);
} public void addTag(int i, String s) {
addTag(i, s, false);
} public void addTag(int i, String s, boolean b) {
addTag(new Tag(i, s), b);
} public void addTag(Tag tag) {
addTag(tag, false);
} public void addTag(Tag tag, boolean b) {
mTags.add(tag);
inflateTagView(tag, b);
} public void addTags(List<Tag> lists) {
addTags(lists, false);
} public void addTags(List<Tag> lists, boolean b) {
for (int i = 0; i < lists.size(); i++) {
addTag((Tag) lists.get(i), b);
}
} public List<Tag> getTags() {
return mTags;
} public View getViewByTag(Tag tag) {
return findViewWithTag(tag);
} public void removeTag(Tag tag) {
mTags.remove(tag);
removeView(getViewByTag(tag));
} public void setDeleteMode(boolean b) {
mIsDeleteMode = b;
} public void setOnTagCheckedChangedListener(
OnTagCheckedChangedListener onTagCheckedChangedListener) {
mOnTagCheckedChangedListener = onTagCheckedChangedListener;
} public void setOnTagClickListener(OnTagClickListener onTagClickListener) {
mOnTagClickListener = onTagClickListener;
} public void setTagViewBackgroundRes(int res) {
mTagViewBackgroundResId = res;
} public void setTagViewTextColorRes(int res) {
mTagViewTextColorResId = res;
} public void setTags(List<? extends Tag> lists) {
setTags(lists, false);
} public void setTags(List<? extends Tag> lists, boolean b) {
removeAllViews();
mTags.clear();
for (int i = 0; i < lists.size(); i++) {
addTag((Tag) lists.get(i), b);
}
} public static abstract interface OnTagCheckedChangedListener {
public abstract void onTagCheckedChanged(TagView tagView, Tag tag);
} public static abstract interface OnTagClickListener {
public abstract void onTagClick(TagView tagView, Tag tag);
} }
  这个类最要的部分还是inflateTagView这种方法,它将TagView解析出来出来,然后显示出TagListView所要显示的标签。
  最后Activity的代码例如以下:
import java.util.ArrayList;
import java.util.List;
import com.niceapp.lib.tagview.widget.Tag;
import com.niceapp.lib.tagview.widget.TagListView;
import android.app.Activity;
import android.os.Bundle; public class MainActivity extends Activity { private TagListView mTagListView;
private final List<Tag> mTags = new ArrayList<Tag>();
private final String[] titles = { "安全必备", "音乐", "父母学", "上班族必备",
"360手机卫士", "QQ","输入法", "微信", "最美应用", "AndevUI", "蘑菇街" }; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.select_tag_activity); mTagListView = (TagListView) findViewById(R.id.tagview);
setUpData();
mTagListView.setTags(mTags);
} private void setUpData() {
for (int i = 0; i < 10; i++) {
Tag tag = new Tag();
tag.setId(i);
tag.setChecked(true);
tag.setTitle(titles[i]);
mTags.add(tag);
}
}
}
真机显示效果例如以下:
  
  当然,这个TagView的外观还是能够自己设置的,包含字体、背景等等。

Android 标签控件的更多相关文章

  1. Android控件进阶-自定义流式布局和热门标签控件

    技术:Android+java   概述 在日常的app使用中,我们会在android 的app中看见 热门标签等自动换行的流式布局,今天,我们就来看看如何 自定义一个类似热门标签那样的流式布局吧,类 ...

  2. Android基本控件之Menus

    在我们的手机中有很多样式的菜单,比如:我们的短信界面,每条短信,我们长按都会出现一个菜单,还有很多的种类.那么现在,我们就来详细的讨论一下安卓中的菜单 Android的控件中就有这么一个,叫做Menu ...

  3. VS2010/MFC编程入门之三十三(常用控件:标签控件Tab Control 下)

    上一节中鸡啄米讲了标签控件知识的上半部分,本节继续讲下半部分. 标签控件的创建 MFC为标签控件的操作提供了CTabCtrl类. 与之前的控件类似,创建标签控件可以在对话框模板中直接拖入Tab Con ...

  4. Kotlin 第一弹:自定义 ViewGroup 实现流式标签控件

    古人学问无遗力, 少壮工夫老始成.纸上得来终觉浅, 绝知此事要躬行. – 陆游 <冬夜读书示子聿> 上周 Google I/O 大会的召开,宣布了 Kotlin 语言正式成为了官方开发语言 ...

  5. 一个Demo让你掌握Android所有控件

    原文:一个Demo让你掌握Android所有控件 本文是转载收藏,侵删,出处:"安卓巴士"      下面给出实现各个组件的源代码: 1.下拉框实现--Spinner packag ...

  6. Android UI控件常用库汇总

    现在App的开发已经是非常成熟,涌现了一大批开源的工具.这些项目能够提高我们的搬砖效率.以下是一些在开发中比较常使用的控件和库. ListView WaveSwipeRefreshLayout 水滴效 ...

  7. Android 开源控件与常用开发框架开发工具类

    Android的加载动画AVLoadingIndicatorView 项目地址: https://github.com/81813780/AVLoadingIndicatorView 首先,在 bui ...

  8. VS2010-MFC(常用控件:标签控件Tab Control 下)

    转自:http://www.jizhuomi.com/software/207.html 上一节讲了标签控件知识的上半部分,本节继续讲下半部分. 标签控件的创建 MFC为标签控件的操作提供了CTabC ...

  9. android 基础控件(EditView、SeekBar等)的属性及使用方法

        android提供了大量的UI控件,本文将介绍TextView.ImageView.Button.EditView.ProgressBar.SeekBar.ScrollView.WebView ...

随机推荐

  1. mysql函数操作(3)

    <?php $dbh = new PDO('mysql:dbname=testdb;host=localhost', 'mysql_user', 'mysql_pwd'); $dbh->s ...

  2. struts2笔记05-ServletActionContext

    1.ServletActionContext ServletActionContext, 这个类继承自ActionContext, 所以它具有ActionContext的很多功能,不过更重要的是它提供 ...

  3. 初识C(2)---从printf函数开始

    继承[K&R]的传统,我们的第一个C语言程序也是“Hello, World.”. 书写C语言程序的大前提:C语言中的语法符号必须都是英文字符,即在中文输入法关闭状态下输入的字符. 例 1. H ...

  4. JS知识点摘记(一)

    JavaScript:基于对象和事件的脚本语言 特点: 安全性:不允许直接访问本地硬盘,可做的就是信息的动态交互 跨平台性:只要可以解析JS的浏览器就可执行,与平台无关 JavaScript与Java ...

  5. 用“U盘”重新安装(MSDN)原版Windows XP sp3操作系统(图文)

    安装微软(MSDN)原版Windows XP sp3系统的方法不少,可以说是很多,但是我就用“U盘”安装.用“U盘”装XP系统也不是什么稀罕事,不会的,就按照下面我常用的“U盘”装原版Windows ...

  6. Golang网络库中socket阻塞调度源码剖析

    本文分析了Golang的socket文件描述符和goroutine阻塞调度的原理.代码中大部分是Go代码,小部分是汇编代码.完整理解本文需要Go语言知识,并且用Golang写过网络程序.更重要的是,需 ...

  7. 点击按钮改变标签内容(采用lambda函数方式)

    from Tkinter import* window=Tk() counter=IntVar() counter.set(0) def click(variable,value): variable ...

  8. 美国TJX公司 - MBA智库百科

    美国TJX公司 - MBA智库百科 TJX公司总部设在美国波士顿,在北美地区和许多欧洲国家开有连锁分店,仅在美国就有2500多家分店. TJX Companies, Inc. 是美国和全世界的服装和家 ...

  9. ios开发之再谈设计模式

    子曰:设计模式这东西,没有好坏之分,只有合适于不合适 天去面试很有意思,技术考官指着最后一道二选一的编程题说,这是昨天晚上专门为你新加的.当时我听后倍感惭愧. 虽然当时在纸上把大概思路和设计说了下.为 ...

  10. 关于 FPGA 和 外部芯片接口时序设计

    在看这篇文章之前, 建议先好好读下这篇文章.http://download.csdn.net/detail/angelbosj/8013827. 因为我不太会用 VISio.要是哪位网友能告诉我.怎么 ...