文件名: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();
            }
        }
    }

}

 

posted on 2016-06-07 09:39  灯火、阑珊处  阅读(306)  评论(0编辑  收藏  举报