文件名:TagListView4ReportLineLimited.java
效果图:
当宽度满屏,自动换行。
用法:
private TagListView4ReportLineLimited mTagListView; private List<Tag> mTags = new ArrayList<Tag>(); private String[][] filesMessagesString = {{"低头族","久坐","久站","吸烟","饮酒","熬夜","鼠标手","喝水少","饭后卧床","强忍大小便","如厕看书报"}, {"bin"}, {"颅脑手术","颈部手术","胸部手术","腹部手术","背部手术","四肢手术","头部外伤","骨折","烧伤","烫伤","扭伤","肌腱损伤","刀砍伤","刀刺伤","皮肤软组织损伤"}, {"高血压","糖尿病","心脏病","脑梗","脑出血","癌症","哮喘","过敏性疾病","癫痫","白癜风","近视","色盲"}, {"青霉素","头孢类抗生素","破伤风抗霉素","普鲁卡因","地卡因","磺胺类药物","维生素b1","泛影葡胺","阿司匹林"}, {"芒果","牛奶","海鲜","笋","香菇","黄瓜","花粉","油漆","皮毛","化妆品 ","菠萝"}};
private void initFilesLayoutData(int position){ mTags.clear(); mTagListView = (TagListView4ReportLineLimited) this.findViewById(R.id.mTagListView2); mTagListView.setVisibility(View.VISIBLE); mTagListView.removeAllViews(); ArrayList<String> hotChannelList = new ArrayList<String>(); for(int i =0;i<filesMessagesString[position].length;i++){ hotChannelList.add(filesMessagesString[position][i]); } setUpData(hotChannelList); mTagListView.setTags(mTags); mTagListView.setOnTagClickListener(new TagListView4ReportLineLimited.OnTagClickListener() { @Override public void onTagClick(TagView tagView, Tag tag) { } }); }
private void setUpData(ArrayList<String> hotChannelList) { mTags.clear(); FlowLayout4ReportLineLimited.SHOW_LINE_NUM = 12; for (int i = 0; i < hotChannelList.size(); i++) { Tag tag = new Tag(); tag.setId(i); tag.setChecked(true); tag.setBackgroundResId(R.drawable.check_details_rounded_rectangle_bg); tag.setTitle(hotChannelList.get(i)); mTags.add(tag); } }
TagListView4ReportLineLimited.java代码如下:
import java.util.ArrayList; import java.util.List; import com.jianke.doctor.R; import android.content.Context; import android.graphics.Canvas; import android.util.AttributeSet; import android.util.Log; import android.util.TypedValue; import android.view.View; import android.view.View.OnClickListener; import android.widget.CompoundButton; import android.widget.RelativeLayout; /** * @author kince * @category 模仿最美应用底部tagview * */ public class TagListView4ReportLineLimited extends FlowLayout4ReportLineLimited 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 TagListView4ReportLineLimited(Context context) { super(context); // TODO Auto-generated constructor stub init(); } /** * @param context * @param attributeSet */ public TagListView4ReportLineLimited(Context context, AttributeSet attributeSet) { super(context, attributeSet); // TODO Auto-generated constructor stub init(); } /** * @param context * @param attributeSet * @param defStyle */ public TagListView4ReportLineLimited(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.tag4reportlinelimited, 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); } }
FlowLayout4ReportLineLimited.java
package com.jianke.view.widget; import java.util.ArrayList; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Paint; import android.util.AttributeSet; import android.util.Log; import android.view.View; import android.view.ViewGroup; import com.jianke.doctor.R; /** * 在每个页面使用完毕后记得将参数还原 * */ public class FlowLayout4ReportLineLimited extends ViewGroup { public static final int HORIZONTAL = 0; public static final int VERTICAL = 1; private int horizontalSpacing = 0; private int verticalSpacing = 0; private int orientation = 0; private boolean debugDraw = false; /** * 设置显示几排,默认为0.0;<br> * 如若全部显示,则将其赋值为Double.POSITIVE_INFINITY(正无穷) * */ public static double SHOW_LINE_NUM = 0; private int num; private static double lineNum; private static ArrayList<Double> lineNums = new ArrayList<Double>(); /** * 是否控制间距(由于加上背景后Tag之间无间距) * */ public static boolean isControlSpace = false; // public static int leftControlSpace = 0, upControlSpace = 0, // rightControlSpace = 0, downControlSpace = 0; public FlowLayout4ReportLineLimited(Context context) { super(context); this.readStyleParameters(context, null); } public FlowLayout4ReportLineLimited(Context context, AttributeSet attributeSet) { super(context, attributeSet); this.readStyleParameters(context, attributeSet); } public FlowLayout4ReportLineLimited(Context context, AttributeSet attributeSet, int defStyle) { super(context, attributeSet, defStyle); this.readStyleParameters(context, attributeSet); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { lineNum = 1; double line_num = 1; setNum(0); int sizeWidth = MeasureSpec.getSize(widthMeasureSpec) - this.getPaddingRight() - this.getPaddingLeft(); int sizeHeight = MeasureSpec.getSize(heightMeasureSpec) - this.getPaddingTop() - this.getPaddingBottom(); int modeWidth = MeasureSpec.getMode(widthMeasureSpec); int modeHeight = MeasureSpec.getMode(heightMeasureSpec); int size; int mode; if (orientation == HORIZONTAL) { size = sizeWidth; mode = modeWidth; } else { size = sizeHeight; mode = modeHeight; } int lineThicknessWithSpacing = 0; int lineThickness = 0; int lineLengthWithSpacing = 0; int lineLength; int prevLinePosition = 0; int controlMaxLength = 0; int controlMaxThickness = 0; final int count = getChildCount(); for (int i = 0; i < count; i++) { if (line_num <= SHOW_LINE_NUM) { setNum(i + 1); final View child = getChildAt(i); if (child.getVisibility() == GONE) { continue; } LayoutParams lp = (LayoutParams) child.getLayoutParams(); child.measure( getChildMeasureSpec(widthMeasureSpec, this.getPaddingLeft() + this.getPaddingRight(), lp.width), getChildMeasureSpec(heightMeasureSpec, this.getPaddingTop() + this.getPaddingBottom(), lp.height)); int hSpacing = this.getHorizontalSpacing(lp); int vSpacing = this.getVerticalSpacing(lp); int childWidth = child.getMeasuredWidth(); int childHeight = child.getMeasuredHeight(); int childLength; int childThickness; int spacingLength; int spacingThickness; if (orientation == HORIZONTAL) { childLength = childWidth; childThickness = childHeight; spacingLength = hSpacing; spacingThickness = vSpacing; } else { childLength = childHeight; childThickness = childWidth; spacingLength = vSpacing; spacingThickness = hSpacing; } lineLength = lineLengthWithSpacing + childLength + 40; lineLengthWithSpacing = lineLength + spacingLength; boolean newLine = lp.newLine || (mode != MeasureSpec.UNSPECIFIED && lineLength > size); if (newLine) { lineNum++; line_num++; if (line_num > SHOW_LINE_NUM) { setNum(i); break; } prevLinePosition = prevLinePosition + lineThicknessWithSpacing; lineThickness = childThickness; lineLength = childLength; lineThicknessWithSpacing = childThickness + spacingThickness; lineLengthWithSpacing = lineLength + spacingLength; } lineThicknessWithSpacing = Math.max(lineThicknessWithSpacing, childThickness + spacingThickness); lineThickness = Math.max(lineThickness, childThickness); int posX; int posY; if (orientation == HORIZONTAL) { posX = getPaddingLeft() + lineLength - childLength; posY = getPaddingTop() + prevLinePosition; } else { posX = getPaddingLeft() + prevLinePosition; posY = getPaddingTop() + lineLength - childHeight; } lp.setPosition(posX, posY); controlMaxLength = Math.max(controlMaxLength, lineLength); controlMaxThickness = prevLinePosition + lineThickness; } } /* need to take paddings into account */ if (orientation == HORIZONTAL) { controlMaxLength += getPaddingLeft() + getPaddingRight(); controlMaxThickness += getPaddingBottom() + getPaddingTop(); } else { controlMaxLength += getPaddingBottom() + getPaddingTop(); controlMaxThickness += getPaddingLeft() + getPaddingRight(); } if (orientation == HORIZONTAL) { this.setMeasuredDimension( resolveSize(controlMaxLength, widthMeasureSpec), resolveSize(controlMaxThickness, heightMeasureSpec)); } else { this.setMeasuredDimension( resolveSize(controlMaxThickness, widthMeasureSpec), resolveSize(controlMaxLength, heightMeasureSpec)); } lineNums.add(lineNum); } private int getVerticalSpacing(LayoutParams lp) { int vSpacing; if (lp.verticalSpacingSpecified()) { vSpacing = lp.verticalSpacing; } else { vSpacing = this.verticalSpacing; } return vSpacing; } private int getHorizontalSpacing(LayoutParams lp) { int hSpacing; if (lp.horizontalSpacingSpecified()) { hSpacing = lp.horizontalSpacing; } else { hSpacing = this.horizontalSpacing; } return hSpacing; } private int getNum() { return num; } private void setNum(int num) { this.num = num; } public static ArrayList<Double> getLineNums() { return lineNums; } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { int pre_x = 0; for (int i = 0; i < getNum(); i++) { View child = getChildAt(i); LayoutParams lp = (LayoutParams) child.getLayoutParams(); if (lp.x == 0) { child.layout(lp.x, lp.y, lp.x + child.getMeasuredWidth(), lp.y + child.getMeasuredHeight()); pre_x = 0; } else { child.layout(pre_x, lp.y, pre_x + child.getMeasuredWidth(), lp.y + child.getMeasuredHeight()); } pre_x = pre_x + child.getMeasuredWidth() + 40; } } @Override protected boolean drawChild(Canvas canvas, View child, long drawingTime) { boolean more = super.drawChild(canvas, child, drawingTime); this.drawDebugInfo(canvas, child); return more; } @Override protected boolean checkLayoutParams(ViewGroup.LayoutParams p) { return p instanceof LayoutParams; } @Override protected LayoutParams generateDefaultLayoutParams() { return new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); } @Override public LayoutParams generateLayoutParams(AttributeSet attributeSet) { return new LayoutParams(getContext(), attributeSet); } @Override protected LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) { return new LayoutParams(p); } private void readStyleParameters(Context context, AttributeSet attributeSet) { TypedArray a = context.obtainStyledAttributes(attributeSet, R.styleable.FlowLayout); try { horizontalSpacing = a.getDimensionPixelSize( R.styleable.FlowLayout_horizontalSpacing, 0); verticalSpacing = a.getDimensionPixelSize( R.styleable.FlowLayout_verticalSpacing, 0); orientation = a.getInteger(R.styleable.FlowLayout_orientation, HORIZONTAL); debugDraw = a.getBoolean(R.styleable.FlowLayout_debugDraw, false); } finally { a.recycle(); } } private void drawDebugInfo(Canvas canvas, View child) { if (!debugDraw) { return; } Paint childPaint = this.createPaint(0xffffff00); Paint layoutPaint = this.createPaint(0xff00ff00); Paint newLinePaint = this.createPaint(0xffff0000); LayoutParams lp = (LayoutParams) child.getLayoutParams(); if (lp.horizontalSpacing > 0) { float x = child.getRight(); float y = child.getTop() + child.getHeight() / 2.0f; canvas.drawLine(x, y, x + lp.horizontalSpacing, y, childPaint); canvas.drawLine(x + lp.horizontalSpacing - 4.0f, y - 4.0f, x + lp.horizontalSpacing, y, childPaint); canvas.drawLine(x + lp.horizontalSpacing - 4.0f, y + 4.0f, x + lp.horizontalSpacing, y, childPaint); } else if (this.horizontalSpacing > 0) { float x = child.getRight(); float y = child.getTop() + child.getHeight() / 2.0f; canvas.drawLine(x, y, x + this.horizontalSpacing, y, layoutPaint); canvas.drawLine(x + this.horizontalSpacing - 4.0f, y - 4.0f, x + this.horizontalSpacing, y, layoutPaint); canvas.drawLine(x + this.horizontalSpacing - 4.0f, y + 4.0f, x + this.horizontalSpacing, y, layoutPaint); } if (lp.verticalSpacing > 0) { float x = child.getLeft() + child.getWidth() / 2.0f; float y = child.getBottom(); canvas.drawLine(x, y, x, y + lp.verticalSpacing, childPaint); canvas.drawLine(x - 4.0f, y + lp.verticalSpacing - 4.0f, x, y + lp.verticalSpacing, childPaint); canvas.drawLine(x + 4.0f, y + lp.verticalSpacing - 4.0f, x, y + lp.verticalSpacing, childPaint); } else if (this.verticalSpacing > 0) { float x = child.getLeft() + child.getWidth() / 2.0f; float y = child.getBottom(); canvas.drawLine(x, y, x, y + this.verticalSpacing, layoutPaint); canvas.drawLine(x - 4.0f, y + this.verticalSpacing - 4.0f, x, y + this.verticalSpacing, layoutPaint); canvas.drawLine(x + 4.0f, y + this.verticalSpacing - 4.0f, x, y + this.verticalSpacing, layoutPaint); } if (lp.newLine) { if (orientation == HORIZONTAL) { float x = child.getLeft(); float y = child.getTop() + child.getHeight() / 2.0f; canvas.drawLine(x, y - 6.0f, x, y + 6.0f, newLinePaint); } else { float x = child.getLeft() + child.getWidth() / 2.0f; float y = child.getTop(); canvas.drawLine(x - 6.0f, y, x + 6.0f, y, newLinePaint); } } } private Paint createPaint(int color) { Paint paint = new Paint(); paint.setAntiAlias(true); paint.setColor(color); paint.setStrokeWidth(2.0f); return paint; } public static class LayoutParams extends ViewGroup.LayoutParams { private static int NO_SPACING = -1; private int x; private int y; private int horizontalSpacing = NO_SPACING; private int verticalSpacing = NO_SPACING; private boolean newLine = false; public LayoutParams(Context context, AttributeSet attributeSet) { super(context, attributeSet); this.readStyleParameters(context, attributeSet); } public LayoutParams(int width, int height) { super(width, height); } public LayoutParams(ViewGroup.LayoutParams layoutParams) { super(layoutParams); } public boolean horizontalSpacingSpecified() { return horizontalSpacing != NO_SPACING; } public boolean verticalSpacingSpecified() { return verticalSpacing != NO_SPACING; } public void setPosition(int x, int y) { this.x = x; this.y = y; } private void readStyleParameters(Context context, AttributeSet attributeSet) { TypedArray a = context.obtainStyledAttributes(attributeSet, R.styleable.FlowLayout_LayoutParams); try { horizontalSpacing = a .getDimensionPixelSize( R.styleable.FlowLayout_LayoutParams_layout_horizontalSpacing, NO_SPACING); verticalSpacing = a .getDimensionPixelSize( R.styleable.FlowLayout_LayoutParams_layout_verticalSpacing, NO_SPACING); newLine = a.getBoolean( R.styleable.FlowLayout_LayoutParams_layout_newLine, false); } finally { a.recycle(); } } } }