这个功能可以很方便的为一张图片设置一个标记,这在促销的时候很是有效
- <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