`

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

阅读更多
先看图



这个功能可以很方便的为一张图片设置一个标记,这在促销的时候很是有效
<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
  • 大小: 24.6 KB
分享到:
评论

相关推荐

    android ImageView动态设置尺寸、圆角(绝对好用)

    综上所述,Android中的ImageView是一个强大的组件,可以通过编程方式动态设置其尺寸和实现圆角效果,同时利用第三方库如Glide轻松加载网络图片。这些技术的应用,能帮助开发者实现更加丰富和个性化的UI设计。

    imageview图片圆角方法

    ### 图片圆角方法 在Android中,可以通过多种方式来实现图片的圆角效果,其中一种常用的方法是通过自定义Bitmap,并结合Canvas和Paint对象来进行图形绘制。以下代码示例展示了如何创建一个具有圆角的Bitmap: ```...

    圆形,圆角,带边框的圆形imageView

    当我们需要创建特定形状的ImageView,比如圆形、圆角或带有边框的圆形ImageView时,通常需要自定义View或者使用一些库来实现。本篇将深入探讨如何实现这些效果,特别是在描述中提到的"圆形,圆角,带边框的圆形...

    android ImageView网络图片加载、动态设置尺寸、圆角(绝对好用)

    在实际应用中,我们不仅需要显示本地资源中的图像,还经常需要从网络上加载图片,同时可能还需要根据界面需求动态设置ImageView的尺寸以及实现圆角效果。下面将详细讲解这些知识点。 1. **网络图片加载** Android...

    Android-RCImageView自定义圆角ImageView带边框效果

    在布局XML文件中,我们可以像使用普通ImageView一样使用RCImageView,并通过属性来设置圆角和边框效果。 ```xml android:id="@+id/rounded_image" android:layout_width="wrap_content" android:layout_height...

    Android高级应用源码-ImageView 自定义控件,实现圆角控件图片功能.zip

    然而,原生的`ImageView`并不直接支持创建带有圆角的图片效果。为了实现这个效果,开发者通常需要自定义`ImageView`类,通过重写其绘制方法。 在`RoundedImageView-master`这个项目中,我们可以预期找到一个名为`...

    ImageView 自定义控件,实现圆角控件图片功能

    `ImageView`作为显示图像的常用组件,有时我们需要让它展示为圆角或带有特定形状的效果,以满足更丰富的设计需求。本文将深入探讨如何自定义一个`ImageView`控件,使其能够实现圆角图片的功能。 首先,要实现圆角...

    Android实现imageView显示圆角图片、描边图片效果.rar

    Android实现imageView显示圆角图片、描边图片效果,具体效果请...这个例子主要是让大家熟悉imageView控件的用法技巧,除了可以实现圆形图片、圆角图片、为图片增加各种颜色大小的边框外,还有很多功能,敬请下载源码。

    圆形、圆角ImageView

    自定义ImageView还可以添加额外的属性,如圆角半径(用于圆角图片),以允许在XML布局文件中动态设置。这可以通过定义自定义属性并在代码中解析它们来实现。 6. **使用自定义ImageView** 在XML布局文件中,你可以...

    自定义ImageView,实现指定任意角为圆角

    本篇文章将详细介绍如何通过自定义ImageView类来实现这一功能,并结合Glide库加载网络图片,使得顶部两个角为圆角,底部两个角为直角。 首先,我们要创建一个新的自定义ImageView类。这个类需要继承自Android的...

    Android ImageView圆角图片 + 剪切

    通过以上方法,我们不仅可以实现`ImageView`的圆角显示,还可以提供用户友好的图片剪切功能,使应用具有更丰富的交互体验。在实际项目中,根据需求选择合适的方法,既考虑性能,也要注重用户体验。

    一个可指定任意角为圆角的ImageView

    在实际应用中,这样的自定义ImageView可以提供更大的灵活性,比如用于用户头像显示,或者卡片样式的界面设计,可以轻松调整每个角的圆润程度,以适应不同的设计需求。此外,为了提高性能,开发者还可以考虑使用硬件...

    ImageView 不同方向的圆角

    对于压缩包中的文件名“SelectableRoundedImageView-master”,可以推测这是一个开源项目,名为“可选择的圆角ImageView”。通常,这类项目会提供更丰富的功能,比如是否选中时改变圆角效果、点击反馈等。我们可以...

    imageView 圆角图片 描边效果

    可以创建一个自定义的`ImageView`子类,并在`onDraw()`方法中重写绘图逻辑,使用`Canvas`的`drawRoundRect()`方法绘制带有圆角的矩形,然后调用`super.onDraw()`绘制实际的图片。 2. **XML Shape Drawable**: 在...

    圆角矩形和圆形ImageView的实现

    对于圆角矩形ImageView,我们可以创建一个新的类继承自ImageView,并在onDraw()方法中使用Canvas的drawRoundRect()方法。这个方法接受六个参数:矩形的左上角坐标、宽度、高度以及四个圆角的半径。通过设置合适的...

    Android-一个Kotlin实现的简单小巧支持圆形和圆角定制化的ImageView

    这个开源项目的目标是提供一个轻量级且易于定制的ImageView组件,可以方便地将方形图片转换为圆形或带有指定圆角的图片。在Android原生的ImageView组件中,实现这样的效果通常需要自定义视图或者使用额外的图片处理...

    安卓源码圆角ImageView.zip

    圆角ImageView是继承自ImageView的基本控件,其主要特点是允许设置图片的四个角落为圆形或者指定的半径,从而使得图片看起来更具视觉吸引力。在Android中,为了实现这种效果,通常通过改变View的`background`属性...

    自定义imageview显示圆角图片

    4. 在布局文件中使用:在XML布局文件中,我们可以像普通ImageView一样使用RoundedImageView,并设置圆角半径属性。 ```xml android:id="@+id/rounded_image_view" android:layout_width="wrap_content" android...

    圆角ImageView

    圆角ImageView允许我们显示带有圆角的图片,这可以提升应用程序的用户界面设计,使其看起来更加精致和专业。 首先,`RoundAngleImageView2.java` 是一个自定义的ImageView子类,它扩展了Android原生的ImageView组件...

    android自定义ImageView圆角和圆形抗锯齿

    android自定义ImageView,圆角和圆形,抗锯齿.亲测可用。直接拷贝代码就行。

Global site tag (gtag.js) - Google Analytics