标签:

前言:可以设置标签的选中效果。 可以设置标签的选中类型:不可选中、单选、限数量多选和不限数量多选等, 并支持设置必选项等功能

1、效果图

19320939fa3fe845931036d45928f03e.png

2、关键代码:LabelsView.java

import android.content.Context;

import android.content.res.ColorStateList;

import android.content.res.TypedArray;

import android.graphics.drawable.ColorDrawable;

import android.graphics.drawable.Drawable;

import android.os.Bundle;

import android.os.Parcelable;

import android.util.AttributeSet;

import android.util.TypedValue;

import android.view.View;

import android.view.ViewGroup;

import android.widget.TextView;

import java.util.ArrayList;

import java.util.List;

import word.hello.com.module.R;

/**

* 标签列表

*/

public class LabelsView extends ViewGroup implements View.OnClickListener {

private Context mContext;

private ColorStateList mTextColor;

private float mTextSize;

private Drawable mLabelBg;

private int mTextPaddingLeft;

private int mTextPaddingTop;

private int mTextPaddingRight;

private int mTextPaddingBottom;

private int mWordMargin;

private int mLineMargin;

private SelectType mSelectType;

private int mMaxSelect;

//用于保存label数据的key

private static final int KEY_DATA = R.id.labels_data;

//用于保存label位置的key

private static final int KEY_POSITION = R.id.labels_position;

private ArrayList mLabels = new ArrayList<>();

//保存选中的label的位置

private ArrayList mSelectLabels = new ArrayList<>();

//保存必选项。在多选模式下,可以设置必选项,必选项默认选中,不能反选

private ArrayList mCompulsorys = new ArrayList<>();

private OnLabelClickListener mLabelClickListener;

private OnLabelSelectChangeListener mLabelSelectChangeListener;

/**

* Label的选择类型

*/

public enum SelectType {

//不可选中,也不响应选中事件回调。(默认)

NONE(1),

//单选,可以反选。

SINGLE(2),

//单选,不可以反选。这种模式下,至少有一个是选中的,默认是第一个

SINGLE_IRREVOCABLY(3),

//多选

MULTI(4);

int value;

SelectType(int value) {

this.value = value;

}

static SelectType get(int value) {

switch (value) {

case 1:

return NONE;

case 2:

return SINGLE;

case 3:

return SINGLE_IRREVOCABLY;

case 4:

return MULTI;

}

return NONE;

}

}

public LabelsView(Context context) {

super(context);

mContext = context;

}

public LabelsView(Context context, AttributeSet attrs) {

super(context, attrs);

mContext = context;

getAttrs(context, attrs);

}

public LabelsView(Context context, AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

mContext = context;

getAttrs(context, attrs);

}

private void getAttrs(Context context, AttributeSet attrs) {

if (attrs != null) {

TypedArray mTypedArray = context.obtainStyledAttributes(attrs, R.styleable.labels_view);

int type = mTypedArray.getInt(R.styleable.labels_view_selectType, 1);

mSelectType = SelectType.get(type);

mMaxSelect = mTypedArray.getInteger(R.styleable.labels_view_maxSelect, 0);

mTextColor = mTypedArray.getColorStateList(R.styleable.labels_view_labelTextColor);

mTextSize = mTypedArray.getDimension(R.styleable.labels_view_labelTextSize,

sp2px(context, 14));

mTextPaddingLeft = mTypedArray.getDimensionPixelOffset(

R.styleable.labels_view_labelTextPaddingLeft, 0);

mTextPaddingTop = mTypedArray.getDimensionPixelOffset(

R.styleable.labels_view_labelTextPaddingTop, 0);

mTextPaddingRight = mTypedArray.getDimensionPixelOffset(

R.styleable.labels_view_labelTextPaddingRight, 0);

mTextPaddingBottom = mTypedArray.getDimensionPixelOffset(

R.styleable.labels_view_labelTextPaddingBottom, 0);

mLineMargin = mTypedArray.getDimensionPixelOffset(R.styleable.labels_view_lineMargin, 0);

mWordMargin = mTypedArray.getDimensionPixelOffset(R.styleable.labels_view_wordMargin, 0);

int labelBgResId = mTypedArray.getResourceId(R.styleable.labels_view_labelBackground, 0);

mLabelBg = getResources().getDrawable(labelBgResId);

mTypedArray.recycle();

}

}

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

int count = getChildCount();

int maxWidth = MeasureSpec.getSize(widthMeasureSpec) - getPaddingLeft() - getPaddingRight();

int contentHeight = 0; //记录内容的高度

int lineWidth = 0; //记录行的宽度

int maxLineWidth = 0; //记录最宽的行宽

int maxItemHeight = 0; //记录一行中item高度最大的高度

boolean begin = true; //是否是行的开头

for (int i = 0; i < count; i++) {

View view = getChildAt(i);

measureChild(view, widthMeasureSpec, heightMeasureSpec);

if (!begin) {

lineWidth += mWordMargin;

} else {

begin = false;

}

if (maxWidth <= lineWidth + view.getMeasuredWidth()) {

contentHeight += mLineMargin;

contentHeight += maxItemHeight;

maxItemHeight = 0;

maxLineWidth = Math.max(maxLineWidth, lineWidth);

lineWidth = 0;

begin = true;

}

maxItemHeight = Math.max(maxItemHeight, view.getMeasuredHeight());

lineWidth += view.getMeasuredWidth();

}

contentHeight += maxItemHeight;

maxLineWidth = Math.max(maxLineWidth, lineWidth);

setMeasuredDimension(measureWidth(widthMeasureSpec, maxLineWidth),

measureHeight(heightMeasureSpec, contentHeight));

}

private int measureWidth(int measureSpec, int contentWidth) {

int result = 0;

int specMode = MeasureSpec.getMode(measureSpec);

int specSize = MeasureSpec.getSize(measureSpec);

if (specMode == MeasureSpec.EXACTLY) {

result = specSize;

} else {

result = contentWidth + getPaddingLeft() + getPaddingRight();

if (specMode == MeasureSpec.AT_MOST) {

result = Math.min(result, specSize);

}

}

result = Math.max(result, getSuggestedMinimumWidth());

return result;

}

private int measureHeight(int measureSpec, int contentHeight) {

int result = 0;

int specMode = MeasureSpec.getMode(measureSpec);

int specSize = MeasureSpec.getSize(measureSpec);

if (specMode == MeasureSpec.EXACTLY) {

result = specSize;

} else {

result = contentHeight + getPaddingTop() + getPaddingBottom();

if (specMode == MeasureSpec.AT_MOST) {

result = Math.min(result, specSize);

}

}

result = Math.max(result, getSuggestedMinimumHeight());

return result;

}

@Override

protected void onLayout(boolean changed, int left, int top, int right, int bottom) {

int x = getPaddingLeft();

int y = getPaddingTop();

int contentWidth = right - left;

int maxItemHeight = 0;

int count = getChildCount();

for (int i = 0; i < count; i++) {

View view = getChildAt(i);

if (contentWidth < x + view.getMeasuredWidth() + getPaddingRight()) {

x = getPaddingLeft();

y += mLineMargin;

y += maxItemHeight;

maxItemHeight = 0;

}

view.layout(x, y, x + view.getMeasuredWidth(), y + view.getMeasuredHeight());

x += view.getMeasuredWidth();

x += mWordMargin;

maxItemHeight = Math.max(maxItemHeight, view.getMeasuredHeight());

}

}

/* 用于保存View的信息的key */

private static final String KEY_SUPER_STATE = "key_super_state";

private static final String KEY_TEXT_COLOR_STATE = "key_text_color_state";

private static final String KEY_TEXT_SIZE_STATE = "key_text_size_state";

private static final String KEY_BG_RES_ID_STATE = "key_bg_res_id_state";

private static final String KEY_PADDING_STATE = "key_padding_state";

private static final String KEY_WORD_MARGIN_STATE = "key_word_margin_state";

private static final String KEY_LINE_MARGIN_STATE = "key_line_margin_state";

private static final String KEY_SELECT_TYPE_STATE = "key_select_type_state";

private static final String KEY_MAX_SELECT_STATE = "key_max_select_state";

// 由于新版(1.4.0)的标签列表允许设置任何类型的数据,而不仅仅是String。并且标签显示的内容

// 最终由LabelTextProvider提供,所以LabelsView不再在onSaveInstanceState()和onRestoreInstanceState()

// 中保存和恢复标签列表的数据。

private static final String KEY_LABELS_STATE = "key_labels_state";

private static final String KEY_SELECT_LABELS_STATE = "key_select_labels_state";

private static final String KEY_COMPULSORY_LABELS_STATE = "key_select_compulsory_state";

@Override

protected Parcelable onSaveInstanceState() {

Bundle bundle = new Bundle();

//保存父类的信息

bundle.putParcelable(KEY_SUPER_STATE, super.onSaveInstanceState());

//保存标签文字颜色

if (mTextColor != null) {

bundle.putParcelable(KEY_TEXT_COLOR_STATE, mTextColor);

}

//保存标签文字大小

bundle.putFloat(KEY_TEXT_SIZE_STATE, mTextSize);

//保存标签背景 (由于背景改用Drawable,所以不能自动保存和恢复)

// bundle.putInt(KEY_BG_RES_ID_STATE, mLabelBgResId);

//保存标签内边距

bundle.putIntArray(KEY_PADDING_STATE, new int[]{mTextPaddingLeft, mTextPaddingTop,

mTextPaddingRight, mTextPaddingBottom});

//保存标签间隔

bundle.putInt(KEY_WORD_MARGIN_STATE, mWordMargin);

//保存行间隔

bundle.putInt(KEY_LINE_MARGIN_STATE, mLineMargin);

//保存标签的选择类型

bundle.putInt(KEY_SELECT_TYPE_STATE, mSelectType.value);

//保存标签的最大选择数量

bundle.putInt(KEY_MAX_SELECT_STATE, mMaxSelect);

//保存标签列表

// if (!mLabels.isEmpty()) {

// bundle.putStringArrayList(KEY_LABELS_STATE, mLabels);

// }

//保存已选择的标签列表

if (!mSelectLabels.isEmpty()) {

bundle.putIntegerArrayList(KEY_SELECT_LABELS_STATE, mSelectLabels);

}

//保存必选项列表

if (!mCompulsorys.isEmpty()) {

bundle.putIntegerArrayList(KEY_COMPULSORY_LABELS_STATE, mCompulsorys);

}

return bundle;

}

@Override

protected void onRestoreInstanceState(Parcelable state) {

if (state instanceof Bundle) {

Bundle bundle = (Bundle) state;

//恢复父类信息

super.onRestoreInstanceState(bundle.getParcelable(KEY_SUPER_STATE));

//恢复标签文字颜色

ColorStateList color = bundle.getParcelable(KEY_TEXT_COLOR_STATE);

if (color != null) {

setLabelTextColor(color);

}

//恢复标签文字大小

setLabelTextSize(bundle.getFloat(KEY_TEXT_SIZE_STATE, mTextSize));

// //恢复标签背景 (由于背景改用Drawable,所以不能自动保存和恢复)

// int resId = bundle.getInt(KEY_BG_RES_ID_STATE, mLabelBgResId);

// if (resId != 0) {

// setLabelBackgroundResource(resId);

// }

//恢复标签内边距

int[] padding = bundle.getIntArray(KEY_PADDING_STATE);

if (padding != null && padding.length == 4) {

setLabelTextPadding(padding[0], padding[1], padding[2], padding[3]);

}

//恢复标签间隔

setWordMargin(bundle.getInt(KEY_WORD_MARGIN_STATE, mWordMargin));

//恢复行间隔

setLineMargin(bundle.getInt(KEY_LINE_MARGIN_STATE, mLineMargin));

//恢复标签的选择类型

setSelectType(SelectType.get(bundle.getInt(KEY_SELECT_TYPE_STATE, mSelectType.value)));

//恢复标签的最大选择数量

setMaxSelect(bundle.getInt(KEY_MAX_SELECT_STATE, mMaxSelect));

// //恢复标签列表

// ArrayList labels = bundle.getStringArrayList(KEY_LABELS_STATE);

// if (labels != null && !labels.isEmpty()) {

// setLabels(labels);

// }

//恢复必选项列表

ArrayList compulsory = bundle.getIntegerArrayList(KEY_COMPULSORY_LABELS_STATE);

if (compulsory != null && !compulsory.isEmpty()) {

setCompulsorys(compulsory);

}

//恢复已选择的标签列表

ArrayList selectLabel = bundle.getIntegerArrayList(KEY_SELECT_LABELS_STATE);

if (selectLabel != null && !selectLabel.isEmpty()) {

int size = selectLabel.size();

int[] positions = new int[size];

for (int i = 0; i < size; i++) {

positions[i] = selectLabel.get(i);

}

setSelects(positions);

}

return;

}

super.onRestoreInstanceState(state);

}

/**

* 设置标签列表

*

* @param labels

*/

public void setLabels(List labels) {

setLabels(labels, new LabelTextProvider() {

@Override

public CharSequence getLabelText(TextView label, int position, String data) {

return data.trim();

}

});

}

/**

* 设置标签列表,标签列表的数据可以是任何类型的数据,

* 它最终显示的内容由LabelTextProvider根据标签的数据提供。

*

* @param labels

* @param provider

* @param

*/

public void setLabels(List labels, LabelTextProvider provider) {

//清空原有的标签

innerClearAllSelect();

removeAllViews();

mLabels.clear();

if (labels != null) {

mLabels.addAll(labels);

int size = labels.size();

for (int i = 0; i < size; i++) {

addLabel(labels.get(i), i, provider);

}

}

if (mSelectType == SelectType.SINGLE_IRREVOCABLY) {

setSelects(0);

}

}

/**

* 获取标签列表

*

* @return

*/

public List getLabels() {

return (List) mLabels;

}

private void addLabel(T data, int position, LabelTextProvider provider) {

final TextView label = new TextView(mContext);

label.setPadding(mTextPaddingLeft, mTextPaddingTop, mTextPaddingRight, mTextPaddingBottom);

label.setTextSize(TypedValue.COMPLEX_UNIT_PX, mTextSize);

label.setTextColor(mTextColor != null ? mTextColor : ColorStateList.valueOf(0xFF000000));

//设置给label的背景(Drawable)是一个Drawable对象的拷贝,

// 因为如果所有的标签都共用一个Drawable对象,会引起背景错乱。

label.setBackgroundDrawable(mLabelBg.getConstantState().newDrawable());

//label通过tag保存自己的数据(data)和位置(position)

label.setTag(KEY_DATA, data);

label.setTag(KEY_POSITION, position);

label.setOnClickListener(this);

addView(label);

label.setText(provider.getLabelText(label, position, data));

}

@Override

public void onClick(View v) {

if (v instanceof TextView) {

TextView label = (TextView) v;

if (mSelectType != SelectType.NONE) {

if (label.isSelected()) {

if (mSelectType != SelectType.SINGLE_IRREVOCABLY

&& !mCompulsorys.contains((Integer) label.getTag(KEY_POSITION))) {

setLabelSelect(label, false);

}

} else if (mSelectType == SelectType.SINGLE || mSelectType == SelectType.SINGLE_IRREVOCABLY) {

innerClearAllSelect();

setLabelSelect(label, true);

} else if (mSelectType == SelectType.MULTI

&& (mMaxSelect <= 0 || mMaxSelect > mSelectLabels.size())) {

setLabelSelect(label, true);

}

}

if (mLabelClickListener != null) {

mLabelClickListener.onLabelClick(label, label.getTag(KEY_DATA), (int) label.getTag(KEY_POSITION));

}

}

}

private void setLabelSelect(TextView label, boolean isSelect) {

if (label.isSelected() != isSelect) {

label.setSelected(isSelect);

if (isSelect) {

mSelectLabels.add((Integer) label.getTag(KEY_POSITION));

} else {

mSelectLabels.remove((Integer) label.getTag(KEY_POSITION));

}

if (mLabelSelectChangeListener != null) {

mLabelSelectChangeListener.onLabelSelectChange(label, label.getTag(KEY_DATA),

isSelect, (int) label.getTag(KEY_POSITION));

}

}

}

/**

* 取消所有选中的label

*/

public void clearAllSelect() {

if (mSelectType != SelectType.SINGLE_IRREVOCABLY) {

if (mSelectType == SelectType.MULTI && !mCompulsorys.isEmpty()) {

clearNotCompulsorySelect();

} else {

innerClearAllSelect();

}

}

}

private void innerClearAllSelect() {

int count = getChildCount();

for (int i = 0; i < count; i++) {

setLabelSelect((TextView) getChildAt(i), false);

}

mSelectLabels.clear();

}

private void clearNotCompulsorySelect() {

int count = getChildCount();

List temps = new ArrayList<>();

for (int i = 0; i < count; i++) {

if (!mCompulsorys.contains(i)) {

setLabelSelect((TextView) getChildAt(i), false);

temps.add(i);

}

}

mSelectLabels.removeAll(temps);

}

/**

* 设置选中label

*

* @param positions

*/

public void setSelects(List positions) {

if (positions != null) {

int size = positions.size();

int[] ps = new int[size];

for (int i = 0; i < size; i++) {

ps[i] = positions.get(i);

}

setSelects(ps);

}

}

/**

* 设置选中label

*

* @param positions

*/

public void setSelects(int... positions) {

if (mSelectType != SelectType.NONE) {

ArrayList selectLabels = new ArrayList<>();

int count = getChildCount();

int size = mSelectType == SelectType.SINGLE || mSelectType == SelectType.SINGLE_IRREVOCABLY

? 1 : mMaxSelect;

for (int p : positions) {

if (p < count) {

TextView label = (TextView) getChildAt(p);

if (!selectLabels.contains(label)) {

setLabelSelect(label, true);

selectLabels.add(label);

}

if (size > 0 && selectLabels.size() == size) {

break;

}

}

}

for (int i = 0; i < count; i++) {

TextView label = (TextView) getChildAt(i);

if (!selectLabels.contains(label)) {

setLabelSelect(label, false);

}

}

}

}

/**

* 设置必选项,只有在多项模式下,这个方法才有效

*

* @param positions

*/

public void setCompulsorys(List positions) {

if (mSelectType == SelectType.MULTI && positions != null) {

mCompulsorys.clear();

mCompulsorys.addAll(positions);

//必选项发生改变,就要恢复到初始状态。

innerClearAllSelect();

setSelects(positions);

}

}

/**

* 设置必选项,只有在多项模式下,这个方法才有效

*

* @param positions

*/

public void setCompulsorys(int... positions) {

if (mSelectType == SelectType.MULTI && positions != null) {

List ps = new ArrayList<>(positions.length);

for (int i : positions) {

ps.add(i);

}

setCompulsorys(ps);

}

}

/**

* 获取必选项,

*

* @return

*/

public List getCompulsorys() {

return mCompulsorys;

}

/**

* 清空必选项,只有在多项模式下,这个方法才有效

*/

public void clearCompulsorys() {

if (mSelectType == SelectType.MULTI && !mCompulsorys.isEmpty()) {

mCompulsorys.clear();

//必选项发生改变,就要恢复到初始状态。

innerClearAllSelect();

}

}

/**

* 获取选中的label(返回的是所有选中的标签的位置)

*

* @return

*/

public List getSelectLabels() {

return mSelectLabels;

}

/**

* 获取选中的label(返回的是所头选中的标签的数据)

*

* @param

* @return

*/

public List getSelectLabelDatas() {

List list = new ArrayList<>();

int size = mSelectLabels.size();

for (int i = 0; i < size; i++) {

View label = getChildAt(mSelectLabels.get(i));

Object data = label.getTag(KEY_DATA);

if (data != null) {

list.add((T) data);

}

}

return list;

}

/**

* 设置标签背景

*

* @param resId

*/

public void setLabelBackgroundResource(int resId) {

setLabelBackgroundDrawable(getResources().getDrawable(resId));

}

/**

* 设置标签背景

*

* @param color

*/

public void setLabelBackgroundColor(int color) {

setLabelBackgroundDrawable(new ColorDrawable(color));

}

/**

* 设置标签背景

*

* @param drawable

*/

public void setLabelBackgroundDrawable(Drawable drawable) {

mLabelBg = drawable;

int count = getChildCount();

for (int i = 0; i < count; i++) {

TextView label = (TextView) getChildAt(i);

label.setBackgroundDrawable(mLabelBg.getConstantState().newDrawable());

}

}

/**

* 设置标签内边距

*

* @param left

* @param top

* @param right

* @param bottom

*/

public void setLabelTextPadding(int left, int top, int right, int bottom) {

if (mTextPaddingLeft != left || mTextPaddingTop != top

|| mTextPaddingRight != right || mTextPaddingBottom != bottom) {

mTextPaddingLeft = left;

mTextPaddingTop = top;

mTextPaddingRight = right;

mTextPaddingBottom = bottom;

int count = getChildCount();

for (int i = 0; i < count; i++) {

TextView label = (TextView) getChildAt(i);

label.setPadding(left, top, right, bottom);

}

}

}

public int getTextPaddingLeft() {

return mTextPaddingLeft;

}

public int getTextPaddingTop() {

return mTextPaddingTop;

}

public int getTextPaddingRight() {

return mTextPaddingRight;

}

public int getTextPaddingBottom() {

return mTextPaddingBottom;

}

/**

* 设置标签的文字大小(单位是px)

*

* @param size

*/

public void setLabelTextSize(float size) {

if (mTextSize != size) {

mTextSize = size;

int count = getChildCount();

for (int i = 0; i < count; i++) {

TextView label = (TextView) getChildAt(i);

label.setTextSize(TypedValue.COMPLEX_UNIT_PX, size);

}

}

}

public float getLabelTextSize() {

return mTextSize;

}

/**

* 设置标签的文字颜色

*

* @param color

*/

public void setLabelTextColor(int color) {

setLabelTextColor(ColorStateList.valueOf(color));

}

/**

* 设置标签的文字颜色

*

* @param color

*/

public void setLabelTextColor(ColorStateList color) {

mTextColor = color;

int count = getChildCount();

for (int i = 0; i < count; i++) {

TextView label = (TextView) getChildAt(i);

label.setTextColor(mTextColor != null ? mTextColor : ColorStateList.valueOf(0xFF000000));

}

}

public ColorStateList getLabelTextColor() {

return mTextColor;

}

/**

* 设置行间隔

*/

public void setLineMargin(int margin) {

if (mLineMargin != margin) {

mLineMargin = margin;

requestLayout();

}

}

public int getLineMargin() {

return mLineMargin;

}

/**

* 设置标签的间隔

*/

public void setWordMargin(int margin) {

if (mWordMargin != margin) {

mWordMargin = margin;

requestLayout();

}

}

public int getWordMargin() {

return mWordMargin;

}

/**

* 设置标签的选择类型

*

* @param selectType

*/

public void setSelectType(SelectType selectType) {

if (mSelectType != selectType) {

mSelectType = selectType;

//选择类型发生改变,就要恢复到初始状态。

innerClearAllSelect();

if (mSelectType == SelectType.SINGLE_IRREVOCABLY) {

setSelects(0);

}

if (mSelectType != SelectType.MULTI) {

mCompulsorys.clear();

}

}

}

public SelectType getSelectType() {

return mSelectType;

}

/**

* 设置最大的选择数量

*

* @param maxSelect

*/

public void setMaxSelect(int maxSelect) {

if (mMaxSelect != maxSelect) {

mMaxSelect = maxSelect;

if (mSelectType == SelectType.MULTI) {

//最大选择数量发生改变,就要恢复到初始状态。

innerClearAllSelect();

}

}

}

public int getMaxSelect() {

return mMaxSelect;

}

/**

* 设置标签的点击监听

*

* @param l

*/

public void setOnLabelClickListener(OnLabelClickListener l) {

mLabelClickListener = l;

}

/**

* 设置标签的选择监听

*

* @param l

*/

public void setOnLabelSelectChangeListener(OnLabelSelectChangeListener l) {

mLabelSelectChangeListener = l;

}

/**

* sp转px

*/

public static int sp2px(Context context, float spVal) {

return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,

spVal, context.getResources().getDisplayMetrics());

}

public interface OnLabelClickListener {

/**

* @param label 标签

* @param data 标签对应的数据

* @param position 标签位置

*/

void onLabelClick(TextView label, Object data, int position);

}

public interface OnLabelSelectChangeListener {

/**

* @param label 标签

* @param data 标签对应的数据

* @param isSelect 是否选中

* @param position 标签位置

*/

void onLabelSelectChange(TextView label, Object data, boolean isSelect, int position);

}

/**

* 给标签提供最终需要显示的数据。因为LabelsView的列表可以设置任何类型的数据,而LabelsView里的每个item的是一

* 个TextView,只能显示CharSequence的数据,所以LabelTextProvider需要根据每个item的数据返回item最终要显示

* 的CharSequence。

*

* @param

*/

public interface LabelTextProvider {

/**

* 根据data和position返回label需要需要显示的数据。

*

* @param label

* @param position

* @param data

* @return

*/

CharSequence getLabelText(TextView label, int position, T data);

}

}

对应style:

3、使用方法

public class LabelsViewActivity extends AppCompatActivity implements View.OnClickListener {

private LabelsView labelsView;

private TextView text1;

private List stringList = new ArrayList<>();

private List listData = new ArrayList<>();

private String[] labelsData = {"咖啡", "饮食", "男装", "女装", "眼镜", "内衣配饰", "母婴",

"鞋靴", "运动", "箱包"};

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_labels_view);

labelsView = this.findViewById(R.id.labelsView);

text1 = this.findViewById(R.id.text1);

findViewById(R.id.button1).setOnClickListener(this);

findViewById(R.id.button2).setOnClickListener(this);

findViewById(R.id.button3).setOnClickListener(this);

findViewById(R.id.button4).setOnClickListener(this);

initData();

}

/**

* 初始化数据源

*/

private void initData() {

//①:普通String类型

for (int i = 0; i < labelsData.length; i++) {

stringList.add(labelsData[i]);

}

//②:标签带ID类型等

//标题和id

listData.add(new LabelsDto("近视眼镜", "1"));

listData.add(new LabelsDto("精品男装", "2"));

listData.add(new LabelsDto("女裙", "3"));

listData.add(new LabelsDto("男鞋", "4"));

listData.add(new LabelsDto("笔记本", "5"));

listData.add(new LabelsDto("生活用品", "6"));

listData.add(new LabelsDto("厨房家具", "7"));

listData.add(new LabelsDto("3D数码", "8"));

//第一步:设置数据源

labelsView.setLabels(listData, new LabelsView.LabelTextProvider() {

@Override

public CharSequence getLabelText(TextView label, int position, LabelsDto data) {

return data.getLabelTitle();根据data和position返回label需要显示的数据。

}

});

//第二步:点击事件

labelsView.setOnLabelClickListener(new LabelsView.OnLabelClickListener() {

@Override

public void onLabelClick(TextView label, Object data, int position) {

//label是被点击的标签(例:label.getText().toString()),

// data是标签所对应的数据,position是标签的位置。

text1.setText("点击的标题:" + listData.get(position).getLabelTitle()

+ "\n点击的id:" + listData.get(position).getLabelId());

}

});

//第三步:标签选中事件

labelsView.setOnLabelSelectChangeListener(new LabelsView.OnLabelSelectChangeListener() {

@Override

public void onLabelSelectChange(TextView label, Object data, boolean isSelect, int position) {

//label是被选中的标签,data是标签所对应的数据,isSelect是是否选中,position是标签的位置

}

});

}

@Override

public void onClick(View view) {

switch (view.getId()) {

case R.id.button1:

labelsView.setSelectType(LabelsView.SelectType.NONE);

break;

case R.id.button2:

labelsView.setSelectType(LabelsView.SelectType.SINGLE);

break;

case R.id.button3:

labelsView.setSelectType(LabelsView.SelectType.SINGLE_IRREVOCABLY);

break;

case R.id.button4:

labelsView.setSelectType(LabelsView.SelectType.MULTI);

break;

}

}

}

对应实体类:

public class LabelsDto {

private String labelTitle;//标签标题

private String labelId;//标签id

public String getLabelTitle() {

return labelTitle;

}

public void setLabelTitle(String labelTitle) {

this.labelTitle = labelTitle;

}

public String getLabelId() {

return labelId;

}

public void setLabelId(String labelId) {

this.labelId = labelId;

}

public LabelsDto(String labelTitle, String labelId) {

this.labelTitle = labelTitle;

this.labelId = labelId;

}

}

对应布局文件:

xmlns:app="http://schemas.android.com/apk/res-auto"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:orientation="vertical">

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:gravity="center"

android:orientation="horizontal">

android:id="@+id/button1"

android:layout_width="0dp"

android:layout_height="wrap_content"

android:layout_weight="1"

android:text="不可选中" />

android:id="@+id/button2"

android:layout_width="0dp"

android:layout_height="wrap_content"

android:layout_weight="1"

android:text="单选,可以反选" />

android:id="@+id/button3"

android:layout_width="0dp"

android:layout_height="wrap_content"

android:layout_weight="1"

android:text="单选,不可以反选" />

android:id="@+id/button4"

android:layout_width="0dp"

android:layout_height="wrap_content"

android:layout_weight="1"

android:text="多选" />

android:id="@+id/labelsView"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:layout_margin="15dp"

app:labelBackground="@drawable/label_shape"

app:labelTextColor="@drawable/label_text"

app:labelTextPaddingBottom="5dp"

app:labelTextPaddingLeft="10dp"

app:labelTextPaddingRight="10dp"

app:labelTextPaddingTop="5dp"

app:labelTextSize="16sp"

app:lineMargin="10dp"

app:maxSelect="3"

app:selectType="MULTI"

app:wordMargin="10dp" />

android:id="@+id/text1"

android:layout_width="match_parent"

android:layout_height="wrap_content" />

注意:word.hello.com.module.view.LabelsView(路径更改)

对应两个drawable:label_shape、label_text

颜色值:

#ffffff

#8F40C0

4、常用方法属性图:

界面描述

方法名

标签选中颜色(可单独设置一种颜色)

labelTextColor

标签的背景

labelBackground

字体大小

labelTextSize

标签下边距

labelTextPaddingBottom

标签左边距

labelTextPaddingLeft

标签右边距

labelTextPaddingRight

标签上边距

labelTextPaddingTop

行间距

lineMargin

标签间隔

wordMargin

标签的选择类型 有单选(可反选)、单选(不可反选)、多选、不可选四种类型)

selectType

标签的最大选择数量,(多选的时候才有用),0为不限数量

maxSelect

注意:以上均可在代码中动态进行设置

常用方法

方法名

设置选中标签①(可以多个)

labelsView.setSelects(1,4,7);

设置选中标签②

List integers=new ArrayList<>(); integers.add(1);integers.add(4);integers.add(7);labelsView.setSelects(integers);

获取选中的标签(返回的是所有选中的标签的下标)

labelsView.getSelectLabels();

获取选中的label(返回的是所有选中的标签的数据)

labelsView.getSelectLabelDatas();

取消所有选中的标签

labelsView.clearAllSelect();

设置必选项①,(模式必须为多项模式)

labelsView.setCompulsorys(1,4,7);

设置必选项②

方法同标签②一致

清空必选项(模式必须为多项模式)

labelsView.clearCompulsorys();

注意:所有的set方法都有对应的get方法

标签:

来源: https://blog.csdn.net/qq_34536167/article/details/82829710

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐