带标记的ImageView,图片可以设置成圆角

来源:互联网 发布:中国新歌声网络直播权 编辑:程序博客网 时间:2024/04/25 08:08
先看图



这个功能可以很方便的为一张图片设置一个标记,这在促销的时候很是有效
<com.mb.bgfitting.view.SimpleTagImageView        xmlns:app="http://schemas.android.com/apk/res-auto"        android:id="@+id/item_0"        android:layout_width="80dp"        android:layout_height="80dp"         android:contentDescription="@null"        app:simple_tag_textSize="@dimen/font_middle"        app:simple_corner_distance="20dp"        app:simple_tag_text="50%off"        app:simple_tag_background_color="#AA27CDC0"        app:simple_tag_orientation="left_top"        app:simple_tag_width="16dip"        app:simple_tag_textColor="@android:color/white"        app:simple_tag_enable="true"        app:simple_tag_round_radius="8dp"        />


源码:
import android.content.Context;import android.content.res.TypedArray;import android.graphics.Bitmap;import android.graphics.BitmapShader;import android.graphics.Canvas;import android.graphics.Matrix;import android.graphics.Paint;import android.graphics.Path;import android.graphics.Rect;import android.graphics.RectF;import android.graphics.Shader;import android.graphics.drawable.BitmapDrawable;import android.graphics.drawable.Drawable;import android.text.TextUtils;import android.util.AttributeSet;import android.util.Log;import android.widget.ImageView;public class SimpleTagImageView extends ImageView {    public static final String TAG = "SimpleTagImageView";    public  static final byte LEFT_TOP = 0x00;    public  static final byte RIGHT_TOP = 0x01;    public  static final byte LEFT_BOTTOM = 0x02;    public  static final byte RIGHT_BOTTOM = 0x03;    private static final float THE_SQUARE_ROOT_OF_2 = (float) Math.sqrt(2);    private static final int DEFAULT_TAG_WIDTH = 20;    private static final int DEFAULT_CORNER_DISTANCE = 20;    private static final int DEFAULT_TAG_BACKGROUND_COLOR = 0x9F27CDC0;    private static final int DEFAULT_TAG_TEXT_SIZE = 15;    private static final int DEFAULT_TAG_TEXT_COLOR = 0xFFFFFFFF;    private float mCornerDistance;    private float mTagWidth;    private int mTagBackgroundColor;    private Path mPath;    private Paint mPaint;    private String mTagText;    private int mTagTextSize;    private Paint mTextPaint;    private Rect mTagTextBound;    private int mTagTextColor;    private float mDensity;    private int mTagOrientation;    private MyPoint startPoint;    private MyPoint endPoint;    private Paint mBitmapPaint;    private RectF mRoundRect;    private boolean mTagEnable;    private int mRoundRadius;    public SimpleTagImageView(Context context) {        this(context, null);    }    public SimpleTagImageView(Context context, AttributeSet attrs) {        this(context, attrs, 0);    }    public SimpleTagImageView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        mDensity = context.getResources().getDisplayMetrics().density;        TypedArray a = context.obtainStyledAttributes(attrs,R.styleable.SimpleTagImageView,defStyleAttr,0);        mTagOrientation = a.getInteger(R.styleable.SimpleTagImageView_simple_tag_orientation,0);        mTagWidth = a.getDimensionPixelSize(R.styleable.SimpleTagImageView_simple_tag_width, dip2px(DEFAULT_TAG_WIDTH));        mCornerDistance = a.getDimensionPixelSize(R.styleable.SimpleTagImageView_simple_corner_distance,dip2px(DEFAULT_CORNER_DISTANCE));        mTagBackgroundColor = a.getColor(R.styleable.SimpleTagImageView_simple_tag_background_color,DEFAULT_TAG_BACKGROUND_COLOR);        mTagText = a.getString(R.styleable.SimpleTagImageView_simple_tag_text);        mTagTextSize = a.getDimensionPixelSize(R.styleable.SimpleTagImageView_simple_tag_textSize, dip2px(DEFAULT_TAG_TEXT_SIZE));        mTagTextColor = a.getColor(R.styleable.SimpleTagImageView_simple_tag_textColor, DEFAULT_TAG_TEXT_COLOR);        mTagEnable = a.getBoolean(R.styleable.SimpleTagImageView_simple_tag_enable,true);        mRoundRadius = a.getDimensionPixelSize(R.styleable.SimpleTagImageView_simple_tag_round_radius,0);        a.recycle();        if(TextUtils.isEmpty(mTagText))mTagText = "";        mPaint = new Paint();        mPath = new Path();        mTextPaint = new Paint();        mTagTextBound = new Rect();        startPoint = new MyPoint();        endPoint = new MyPoint();        mRoundRect = new RectF();    }    /**     *     * @param textSize unit:dip     */    public void setTagTextSize(int textSize) {        this.mTagTextSize = dip2px(textSize);        invalidate();    }    public int getTagTextSize(){        return mTagTextSize;    }    /**     *     * @param cornerDistance unit:dip     */    public void setCornerDistance(int cornerDistance) {        if(this.mCornerDistance == cornerDistance)return;        this.mCornerDistance = dip2px(cornerDistance);        invalidate();    }    /**     *     * @return unit:dip     */    public int getCornerDistance() {        return px2dip(this.mCornerDistance);    }    public int getTagTextColor() {        return this.mTagTextColor;    }    public void setTagTextColor(int tagTextColor) {        if(this.mTagTextColor == tagTextColor)return;        this.mTagTextColor = tagTextColor;        invalidate();    }    public String getTagText() {        return this.mTagText;    }    public void setTagText(String tagText){        if(tagText.equals(this.mTagText))return;        this.mTagText = tagText;        invalidate();    }    public void setTagBackgroundColor(int tagBackgroundColor) {        if(this.mTagBackgroundColor == tagBackgroundColor)return;        this.mTagBackgroundColor = tagBackgroundColor;        invalidate();    }    public int getTagBackgroundColor() {        return this.mTagBackgroundColor;    }    /**     * @return unit:dip     */    public int getTagWidth() {        return px2dip(this.mTagWidth);    }    /**     *     * @param tagWidth unit:dip     */    public void setTagWidth(int tagWidth) {        this.mTagWidth = dip2px(tagWidth);        invalidate();    }    /**     * @return  0 : left_top     *          1 : right_top     *          2 : left_bottom     *          3 : right_bottom     */    public int getTagOrientation() {        return mTagOrientation;    }    /**     *     * @param tagOrientation {@link #LEFT_TOP} or     *                       {@link #LEFT_BOTTOM} or     *                       {@link #RIGHT_TOP} or     *                       {@link #RIGHT_BOTTOM}     */    public void setTagOrientation(int tagOrientation) {        if(tagOrientation == this.mTagOrientation)return;        this.mTagOrientation = tagOrientation;        invalidate();    }    public void setTagEnable(boolean tagEnable) {        if(this.mTagEnable == tagEnable) return ;        this.mTagEnable = tagEnable;        invalidate();    }    public boolean getTagEnable() {        return this.mTagEnable;    }    public  int getTagRoundRadius() {        return this.mRoundRadius;    }    public void setTagRoundRadius(int roundRadius) {        if(this.mRoundRadius == roundRadius) return;        this.mRoundRadius = roundRadius;        invalidate();    }    @Override    protected void onDraw(@SuppressWarnings("NullableProblems") Canvas mCanvas) {        if(mRoundRadius == 0) {            super.onDraw(mCanvas);        }else {            Drawable d = getDrawable();            if(d == null) return;            if(d.getIntrinsicWidth() == 0 || d.getIntrinsicHeight() == 0) return;            setupBitmapPaint();            mRoundRect.set(getPaddingLeft(),getPaddingTop(),getMeasuredWidth() - getPaddingRight(),getMeasuredHeight() - getPaddingBottom());            mCanvas.drawRoundRect(mRoundRect, mRoundRadius, mRoundRadius, mBitmapPaint);        }        if(mTagWidth > 0 && mTagEnable) {            float rDistance = mCornerDistance + mTagWidth/2;            chooseTagOrientation(rDistance);            mTextPaint.setTextSize(mTagTextSize);            mTextPaint.getTextBounds(mTagText,0,mTagText.length(),mTagTextBound);            mPaint.setDither(true);            mPaint.setAntiAlias(true);            mPaint.setColor(mTagBackgroundColor);            mPaint.setStyle(Paint.Style.STROKE);            mPaint.setStrokeJoin(Paint.Join.ROUND);            mPaint.setStrokeCap(Paint.Cap.SQUARE);            mPaint.setStrokeWidth(mTagWidth);            mPath.reset();            mPath.moveTo(startPoint.x, startPoint.y);            mPath.lineTo(endPoint.x, endPoint.y);            mCanvas.drawPath(mPath, mPaint);            mTextPaint.setColor(mTagTextColor);            mTextPaint.setTextSize(mTagTextSize);            mTextPaint.setAntiAlias(true);//          斜边长度            float hypotenuse = THE_SQUARE_ROOT_OF_2 * rDistance;            mCanvas.drawTextOnPath(mTagText, mPath, hypotenuse / 2 - mTagTextBound.width() / 2,                    mTagTextBound.height() / 2, mTextPaint);        }    }    private void chooseTagOrientation(float rDistance) {        int mWidth = getMeasuredWidth();        int mHeight = getMeasuredHeight();        switch (mTagOrientation) {            case 0:                startPoint.x = 0;                startPoint.y = rDistance;                endPoint.x = rDistance;                endPoint.y = 0;                break;            case 1:                startPoint.x = mWidth - rDistance;                startPoint.y = 0;                endPoint.x = mWidth;                endPoint.y = rDistance;                break;            case 2:                startPoint.x = 0;                startPoint.y = mHeight - rDistance;                endPoint.x = rDistance;                endPoint.y = mHeight;                break;            case 3:                startPoint.x = mWidth - rDistance;                startPoint.y = mHeight;                endPoint.x = mWidth;                endPoint.y = mHeight - rDistance;                break;        }    }    private void setupBitmapPaint() {        Drawable drawable = getDrawable();        if (drawable == null) {            return;        }        Bitmap mBitmap = drawableToBitmap(drawable);        BitmapShader mBitmapShader = new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);        if(getScaleType() != ScaleType.FIT_XY){            Log.w(TAG,String.format("Now scale type just support fitXY,other type invalid"));        }        //now scale type just support fitXY        //todo support all scale type        Matrix mMatrix = new Matrix();        mMatrix.setScale(getWidth() * 1.0f / mBitmap.getWidth(), getHeight() * 1.0f / mBitmap.getHeight());        mBitmapShader.setLocalMatrix(mMatrix);        if(mBitmapPaint == null) {            mBitmapPaint = new Paint();            mBitmapPaint.setDither(false);            mBitmapPaint.setAntiAlias(true);            mBitmapPaint.setShader(mBitmapShader);        }    }    private int dip2px(int dip) {        return (int)(mDensity * dip + 0.5f);    }    private int px2dip(float px) {        return (int)(px/mDensity + 0.5f);    }    private Bitmap drawableToBitmap(Drawable drawable) {        if (drawable instanceof BitmapDrawable) {            BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;            return bitmapDrawable.getBitmap();        }        int w = drawable.getIntrinsicWidth();        int h = drawable.getIntrinsicHeight();        Bitmap bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);        Canvas canvas = new Canvas(bitmap);        drawable.setBounds(0, 0, w, h);        drawable.draw(canvas);        return bitmap;    }    static class MyPoint {        float x;        float y;    }}


属性:
<?xml version="1.0" encoding="utf-8"?><resources>    <declare-styleable name="SimpleTagImageView">        <attr name="simple_corner_distance" format="dimension" />        <attr name="simple_tag_width" format="dimension"/>        <attr name="simple_tag_background_color" format="color"/>        <attr name="simple_tag_text" format="string"/>        <attr name="simple_tag_textSize" format="dimension" />        <attr name="simple_tag_textColor" format="color"/>        <attr name="simple_tag_orientation" format="enum">            <enum name="left_top" value="0"/>            <enum name="right_top" value="1"/>            <enum name="left_bottom" value="2"/>            <enum name="right_bottom" value="3"/>        </attr>        <attr name="simple_tag_enable" format="boolean"/>        <attr name="simple_tag_round_radius" format="dimension"/>    </declare-styleable></resources>




一个为ImageView添加徽章,标记(badge)的库
http://www.jcodecraeer.com/a/opensource/2015/1125/3720.html
Android标签控件
https://github.com/H07000223/FlycoLabelView

使用 supportV4 的 RoundedBitmapDrawable 实现圆角
http://blog.csdn.net/ys743276112/article/details/52316588

可配置的迷你版轻量级 Label 辅助类
https://github.com/yanbober/AvatarLabelView