轉載:http://blog.csdn.net/wangjinyu501/article/details/38089061
在有的應用中可能需要設定一些标簽來友善用去去查詢某些資訊,比如手機助手或者購物軟體之類都會有一些标簽。對于軟體開發初期來說,直接使用textview、button實作是最為簡單的一種方式。但是這種方法也有其局限性,比如不能控制換行、耦合性低等缺點。是以除了解決這些問題之外,最好能夠封裝一個類庫出來,友善以後使用。
首先建立一個tag類,
[html] view
plaincopy
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) {
public void setleftdrawableresid( int paramint) {
this .leftdrawableresid = paramint;
public void setrightdrawableresid( int paramint) {
this .rightdrawableresid = paramint;
public void settitle(string 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);
public tagview(context paramcontext, attributeset paramattributeset,
int paramint) {
super (paramcontext, paramattributeset, 0);
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);
}
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 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
* @param attributeset
public taglistview(context context, attributeset attributeset) {
super(context, attributeset);
* @param defstyle
public taglistview(context context, attributeset attributeset, int defstyle) {
super(context, attributeset, defstyle);
@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();
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 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 string[] titles = { "安全必備", "音樂", "父母學", "上班族必備",
"360手機衛士", "qq","輸入法", "微信", "最美應用", "andevui", "蘑菇街" };
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的外觀還是可以自己設定的,包括字型、背景等等。
項目代碼下載下傳位址:http://download.csdn.net/detail/jdsjlzx/9417250