Android 標簽控件
轉載:https://blog.csdn.net/wangjinyu501/article/details/38089061
在有的應用中可能需要設置一些標簽來方便用去去查詢某些信息,比如手機助手或者購物軟件之類都會有一些標簽。對於軟件開發初期來說,直接使用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);
- }
- }
- }
- <? xml version= "1.0" encoding = "utf-8"?>
- < com.niceapp.lib.tagview.widget.TagView xmlns:android ="https://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" />
顯示如下:


因此,控製換行就可以利用這個控件去實現,無需重複發明輪子。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的外觀還是可以自己設置的,包括字體、背景等等。
最後更新:2017-04-03 05:39:33