版本号: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. listbox横向排列

    在Listbox中横向显示CheckBox 前台代码 <ListBox Height=" > <StackPanel x:Name="sp" Orien ...

  2. MYSQL 引擎的情况

    方法 1: show engine innodb status; ------------------------------------------------------------------- ...

  3. (11)Xamarin.iOS - 新增iPhone storyboard

    原文 Xamarin.iOS - 新增iPhone storyboard 1. 开启Xamarin Studio 并建立新项目 专案类型为 iOS=>iPhone Storyboard => ...

  4. Unix/Linux环境C编程入门教程(3) Oracle Linux 环境搭建

    Unix/Linux版本众多,我们推荐Unix/Linux初学者选用几款典型的Unix/Linux操作系统进行学习. 2010年9月,Oracle Enterprise Linux发布新版内核--Un ...

  5. linux下修改.bash_profile立即生效的三种方法

    1 . .bash_profile 2 source .bash_profile 3 exec bash --login

  6. E=MC2 - 搜搜百科

    E=MC2 - 搜搜百科 1 E=MC2 质能等价理论是爱因斯坦狭义相对论的最重要的推论,即著名的方程式E=mC^2,式中E为能量,m为质量,C为光速:也就是说,一切物质都潜藏着质量乘于光速平方的能量 ...

  7. linux 查看信息命令

    # uname -a # 查看内核/操作系统/CPU信息# head -n 1 /etc/issue # 查看操作系统版本# cat /proc/cpuinfo # 查看CPU信息# hostname ...

  8. 在OC项目工程中混编Swift

    1.创建一个OC项目工程,然后在Build Settings中找到如下字段,修改. 2.然后在项目中创建swift文件,如果系统提示是否需要创建桥接文件的时候,点击确定. 然后在Build Setti ...

  9. android退出activity的方式总结(一)

    在android中使用:[activityname].this.finish();  只是退出了activity的堆栈中,要真正的退出程序在手机cpu中的运行,当应用不再使用时,通常需要关闭应用,可以 ...

  10. [C#参考]利用Socket连续发送数据

    这个例子只是一个简单的连续发送数据,接收数据的DEMO.因为最近做一个项目,要求robot连续的通过Socket传回自己的当前的位置坐标,然后客户端接收到坐标信息,在本地绘制地图,实时显示robot的 ...