Android 标签控件

Android 标签控件

大家好,又见面了,我是全栈君,祝每个程序员都可以多学几门语言。

版本号: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" />
显演示样例如以下:
Android 标签控件
 

 在github上有一个
android-flowlayout
控件,它是依据子视图的大小来动态包裹视图,如图:
Android 标签控件
 

  因此,控制换行就能够利用这个控件去实现,无需反复发明轮子。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);
          }
     }
}
真机显示效果例如以下:
Android 标签控件
  

  当然,这个TagView的外观还是能够自己设置的,包含字体、背景等等。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/118521.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • redis 密码_商用密码知识

    redis 密码_商用密码知识Redis可以设置密码,设置密码后如果不用密码登录,执行命令时会提示错误:下面列举一下Redis密码相关知识。1,在配置文件中设置密码在Redis的配置文件中,可以用requirepass参数配置密码,比如这样:requirepassthisispassword那么密码就是thisispassword。配置文件中设置的密码在启动Redis时就会生效。…

    2025年9月17日
    5
  • css css样式表 选择器 声明「建议收藏」

    css css样式表 选择器 声明「建议收藏」css部分css指层叠样式表(cascadingstylesheets),它们控制网页内容的外观。使用css设置页面样式时,可以将内容与表现形式分开。网页内容(HTML代码)驻留在HTML文件自身中,而css驻留在另一个文件中(外部样式表*.css)或HTML文档的另一部分(通常为文件头部分)中。写页面时要做到结构(HTML)、样式(css)、行为(js)相分离,

    2022年7月14日
    27
  • 最短路径算法——Dijkstra算法——python3实现

    最短路径算法——Dijkstra算法——python3实现本文参考来自数据结构与算法分析java语言描述。问题描述问题分析实现过程如何使用数据变化表问题描述现有一个有向赋权图。如下图所示:问题:根据每条边的权值,求出从起点s到其他每个顶点的最短路径和最短路径的长度。说明:不考虑权值为负的情况,否则会出现负值圈问题。s:起点v:算法当前分析处理的顶点w:与v邻接的顶点dvdvd_v:从s到v的距离…

    2022年5月4日
    71
  • UFT使用技巧

    UFT使用技巧1 UFT基本功能的使用         UFT的基本功能包括两大部分:一部分是提供给初级用户使用的关键字视图;另一部分是提供给熟悉VBScript脚本编写的自动化测试工程师使用的专家视图。但是,并没有严格的区分,在实际的自动化测试项目中完全可以两者结合着使用。 1.1 UFT自动化测试的基本过程          使用UFT进行自动化测试的基本过程与使用其他自动化测试工具进行自动化功能测试的过…

    2022年5月26日
    192
  • js 判断是否字符串_js字符串查找

    js 判断是否字符串_js字符串查找整理js中可以用到的判断一个字符串中是否包含另外一个字符的方法String对象方法1、indexOfindexOf返回指定字符串在该字符中首次出现的位置,如果没有找到,则返回-1indexOf接收两个参数,第一是需要搜索的字符串,第二个参数是检索的位置,默认为0letstr=’abcde’;//例如,从str第三位开始搜索’a’console.log(str.indexOf(‘a’,2));//-1console.log(str.indexOf(‘a’))//02、

    2022年10月6日
    2
  • 几款移动跨平台App开发框架比较[通俗易懂]

    几款移动跨平台App开发框架比较[通俗易懂]整理目前流行的跨平台WebApp开发技术的特点,仅供参考。每个框架几乎都包含以下特性:使用HTML5+CSS+JavaScript开发; 跨平台重用代码; 丰富的UI库; 提供访问设备原生API的JavaScriptAPI包装器; 解决原生开发中机型适配的难题; 提供打包、部署的工具或服务; 都需要学习自身封装的JavaScriptAPI;筛选框架的要求…

    2022年5月3日
    722

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号