自定义带 vip 标识的 圆形头像(圆形ImageView)

简介: 自定义带 vip 标识的 圆形头像(圆形ImageView)
import java.lang.ref.WeakReference;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.RectF;
import android.graphics.Xfermode;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.widget.ImageView;
import com.ccvideo.R;
public class RoundImageView extends ImageView {
    private Paint mPaint;
    private Xfermode mXfermode = new PorterDuffXfermode(PorterDuff.Mode.DST_IN);
    private WeakReference<Bitmap> mWeakBitmap;
    private WeakReference<Bitmap> mMaskWeakBitmap;
    private WeakReference<Canvas> mWeakCanvas;
    public static final int TYPE_CIRCLE = 0;
    public static final int TYPE_ROUND = 1;
    private static final int BORDER_RADIUS_DEFAULT = 10;
    private static final int BORDER_WIDTH_DEFAULT = 0;
    private static final int BORDER_COLOR_DEFAULT = R.color.black_alpha_percent_10;
    private int mShapeType;
    private int mBorderRadius;
    private int mBorderWidth;
    private int mBorderColor;
    private int mOverLayColor;
    public RoundImageView(Context context, int BorderWidth, int BorderColor) {
        this(context, null);
        this.mBorderWidth = BorderWidth;
        this.mBorderColor = BorderColor;
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
    }
    public RoundImageView(Context context, AttributeSet attrs) {
        super(context, attrs);
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RoundImageView);
        mBorderRadius = a.getDimensionPixelSize(R.styleable.RoundImageView_border_radius,
                (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
                        BORDER_RADIUS_DEFAULT, getResources().getDisplayMetrics()));// Default 10dp
        mShapeType = a.getInt(R.styleable.RoundImageView_type, TYPE_CIRCLE);
        mBorderWidth = a.getDimensionPixelSize(R.styleable.RoundImageView_border_width,
                (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
                        BORDER_WIDTH_DEFAULT, getResources().getDisplayMetrics()));
        mBorderColor = a.getColor(R.styleable.RoundImageView_border_color, BORDER_COLOR_DEFAULT);
        mOverLayColor = a.getColor(R.styleable.RoundImageView_overlay, android.R.color.transparent);
        a.recycle();
    }
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        if (mShapeType == TYPE_CIRCLE) {
            int width = Math.min(getMeasuredWidth(), getMeasuredHeight());
            // setMeasuredDimension(width, width);
        }
    }
    @Override
    public void invalidate() {
        mWeakBitmap = null;
        mMaskWeakBitmap = null;
        mWeakCanvas = null;
        super.invalidate();
    }
    @Override
    protected void onDraw(Canvas canvas) {
        Drawable drawable = getDrawable();
        if (drawable == null || getWidth() == 0 || getHeight() == 0) {
            return;
        }
        Bitmap bitmap = mWeakBitmap == null ? null : mWeakBitmap.get();
        if (bitmap == null || bitmap.isRecycled()) {
            bitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
        }
        Canvas drawCanvas = mWeakCanvas == null ? null : mWeakCanvas.get();
        if (drawCanvas == null) {
            drawCanvas = new Canvas(bitmap);
        }
        float scale = 1.0f;
        int drawableWidth = drawable.getIntrinsicWidth();
        int drawableHeight = drawable.getIntrinsicHeight();
        if (mShapeType == TYPE_ROUND) {
            scale = Math.max(getWidth() * 1.0f / drawableWidth, getHeight() * 1.0f / drawableHeight);
        } else {
            scale = getWidth() * 1.0f / Math.min(drawableWidth, drawableHeight);
        }
        drawable.setBounds(0, 0, (int) (scale * drawableWidth), (int) (scale * drawableHeight));
        drawable.draw(drawCanvas);
        mPaint.reset();
        mPaint.setColor(mOverLayColor);
        drawCanvas.drawColor(mOverLayColor);
        mPaint.reset();
        mPaint.setFilterBitmap(false);
        mPaint.setXfermode(mXfermode);
        Bitmap maskBitmap = mMaskWeakBitmap == null ? null : mMaskWeakBitmap.get();
        if (maskBitmap == null || maskBitmap.isRecycled()) {
            maskBitmap = getBitmap();
            mMaskWeakBitmap = new WeakReference<Bitmap>(maskBitmap);
        }
        drawCanvas.drawBitmap(maskBitmap, 0, 0, mPaint);
        mPaint.setXfermode(null);
        if (mBorderWidth > 0) {
            drawCircleBorder(drawCanvas);
        }
        canvas.drawBitmap(bitmap, 0, 0, null);
    }
    private Bitmap getBitmap() {
        Bitmap bitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);
        Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setColor(Color.BLACK);
        if (mShapeType == TYPE_ROUND) {
            canvas.drawRoundRect(new RectF(0, 0, getWidth(), getHeight()),
                    mBorderRadius, mBorderRadius, paint);
        } else {
            canvas.drawCircle(getWidth() / 2, getWidth() / 2, getWidth() / 2 - mBorderWidth, paint);
        }
        return bitmap;
    }
    private void drawCircleBorder(Canvas canvas) {
        Paint paint = new Paint();
        paint.setAntiAlias(true);
        paint.setFilterBitmap(true);
        paint.setDither(true);
        paint.setColor(mBorderColor);
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(mBorderWidth);
        if (mShapeType == TYPE_ROUND) {
            canvas.drawRoundRect(new RectF(0, 0, getWidth(), getHeight()),
                    mBorderRadius, mBorderRadius, paint);
        } else {
            canvas.drawCircle(getWidth() / 2, getWidth() / 2, (getWidth() - mBorderWidth) / 2, paint);
        }
    }
    public void setBorderWidth(int borderWidth) {
        this.mBorderWidth = mBorderWidth;
    }
    public void setBorderColor(int borderColor) {
        this.mBorderColor = mBorderColor;
    }
}
package com.yizhibo.video.view;
import java.lang.ref.WeakReference;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Xfermode;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.widget.ImageView;
import com.ccvideo.R;
public class MyUserPhoto extends ImageView {
    private static final int BORDER_SMALL_WIDTH_DEFAULT = 10;
    private static final int BORDER_SMALL_HEIGHT_DEFAULT = 10;
    private static final int IS_VIP = 1;
    private static final int BORDER_WIDTH_DEFAULT = 0;
    private static final int BORDER_COLOR_DEFAULT = R.color.black_alpha_percent_10;
    private int mSmallImageWidth;
    private int mSmallImageHeight;
    private int mIsVip;
    private int mBorderWidth;
    private int mBorderColor;
    private int mSmallIconResId;
    private Paint mPaint;
    private Xfermode mXfermode = new PorterDuffXfermode(PorterDuff.Mode.DST_IN);
    private WeakReference<Bitmap> mWeakBitmap;
    private WeakReference<Bitmap> mMaskWeakBitmap;
    private WeakReference<Canvas> mWeakCanvas;
    public MyUserPhoto(Context context) {
        super(context);
    }
    public MyUserPhoto(Context context, AttributeSet attrs) {
        super(context, attrs);
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.MyUserPhoto);
        mSmallImageHeight = a.getDimensionPixelSize(R.styleable.MyUserPhoto_small_height,
                BORDER_SMALL_HEIGHT_DEFAULT);
        mSmallImageWidth = a.getDimensionPixelSize(R.styleable.MyUserPhoto_small_width,
                BORDER_SMALL_WIDTH_DEFAULT);
        mIsVip = a.getInt(R.styleable.MyUserPhoto_is_vip, 0);
        mSmallIconResId = a.getResourceId(R.styleable.MyUserPhoto_small_icon,
                R.drawable.floating_screen_v);
        mBorderWidth = a.getDimensionPixelSize(R.styleable.MyUserPhoto_border_width,
                (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
                        BORDER_WIDTH_DEFAULT, getResources().getDisplayMetrics()));
        mBorderColor = a.getColor(R.styleable.MyUserPhoto_border_color, BORDER_COLOR_DEFAULT);
        setWillNotDraw(false);
        a.recycle();
    }
    @Override
    public void invalidate() {
        mWeakBitmap = null;
        mMaskWeakBitmap = null;
        mWeakCanvas = null;
        super.invalidate();
    }
    @Override
    protected void onDraw(Canvas canvas) {
        Drawable drawable = getDrawable();
        if (drawable == null || getWidth() == 0 || getHeight() == 0) {
            return;
        }
        Bitmap bitmap = mWeakBitmap == null ? null : mWeakBitmap.get();
        if (bitmap == null || bitmap.isRecycled()) {
            bitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
            mWeakBitmap = new WeakReference<Bitmap>(bitmap);
        }
        Canvas drawCanvas = mWeakCanvas == null ? null : mWeakCanvas.get();
        if (drawCanvas == null) {
            drawCanvas = new Canvas(bitmap);
            mWeakCanvas = new WeakReference<Canvas>(drawCanvas);
        }
        float scale = 1.0f;
        int drawableWidth = drawable.getIntrinsicWidth();
        int drawableHeight = drawable.getIntrinsicHeight();
        scale = getWidth() * 1.0f / Math.min(drawableWidth, drawableHeight);
        drawable.setBounds(0, 0, (int) (scale * drawableWidth), (int) (scale * drawableHeight));
        drawable.draw(drawCanvas);
        mPaint.reset();
        mPaint.setFilterBitmap(false);
        mPaint.setXfermode(mXfermode);
        Bitmap maskBitmap = mMaskWeakBitmap == null ? null : mMaskWeakBitmap.get();
        if (maskBitmap == null || maskBitmap.isRecycled()) {
            maskBitmap = getMaskBitmap();
            mMaskWeakBitmap = new WeakReference<Bitmap>(maskBitmap);
        }
        drawCanvas.drawBitmap(maskBitmap, 0, 0, mPaint);
        mPaint.setXfermode(null);
        if (mBorderWidth > 0) {
            drawCircleBorder(drawCanvas);
        }
        if (mIsVip == IS_VIP && (mSmallImageWidth > 0 || mSmallImageHeight > 0)) {
            drawSmallIcon(drawCanvas);
        }
        canvas.drawBitmap(bitmap, 0, 0, null);
    }
    private Bitmap getMaskBitmap() {
        Bitmap bitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);
        Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setColor(Color.BLACK);
        canvas.drawCircle(getWidth() / 2, getWidth() / 2, getWidth() / 2 - mBorderWidth, paint);
        return bitmap;
    }
    private void drawCircleBorder(Canvas canvas) {
        Paint paint = new Paint();
        paint.setAntiAlias(true);
        paint.setFilterBitmap(true);
        paint.setDither(true);
        paint.setColor(mBorderColor);
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(mBorderWidth);
        canvas.drawCircle(getWidth() / 2, getWidth() / 2, (getWidth() - mBorderWidth) / 2, paint);
    }
    private void drawSmallIcon(Canvas canvas) {
        int smallIconSize = mSmallImageWidth;
        Bitmap smallIconBitmap = BitmapFactory.decodeResource(getResources(), mSmallIconResId);
        smallIconBitmap = scaleImage(smallIconBitmap, smallIconSize, smallIconSize);
        float marginTop = getWidth() / 2.0f + (float)Math.sqrt(2) * (getHeight() / 2.0f) / 2.0f
                - smallIconSize / 2.0f;
        float marginLeft = marginTop;
        canvas.drawBitmap(smallIconBitmap, marginLeft, marginTop, null);
        smallIconBitmap.recycle();
    }
    private Bitmap scaleImage(Bitmap bitmap, float newWidth, float newHeight) {
        float width = bitmap.getWidth();
        float height = bitmap.getHeight();
        Matrix matrix = new Matrix();
        float scaleWidth = newWidth / width;
        float scaleHeight = newHeight / height;
        matrix.postScale(scaleWidth, scaleHeight);
        return Bitmap.createBitmap(bitmap, 0, 0, (int) width, (int) height, matrix, true);
    }
    public ImageView getRoundImageView() {
        return this;
    }
    public void setIsVip(int isVip) {
        if (mIsVip != isVip) {
            mIsVip = isVip;
            invalidate();
        }
    }
}


相关文章
|
6月前
|
Android开发
ImageView设置tint ,修改图标颜色
ImageView设置tint ,修改图标颜色
85 0
|
XML 数据格式
超简单的自定义ImageView,支持圆角和直角
需求:ImageView显示的图片,上方的两个角是圆角,下方的两个角是直角。 ![需求图](https://img-blog.csdn.net/20180125151146126?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXFfMjYyODc0MzU=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
|
前端开发 Android开发
圆形头像的7种显示方法
牙叔教程 简单易懂
248 0
|
Android开发
TextView未绘制情况下获取其宽高
/** * 注:StaticLayout是android中处理文字换行的一个类,TextView源码中也是通过这个类实现换行的,使用这个类可以 * 在不进行TextView绘制的前提下得到TextView的宽高,这里我们只需要获取到高度即可,这个高度当然也可以通过post * 在run中获取,但是这样做会有一个问题,界面是先绘制显示然后再计算高度根据我们的逻辑来收缩TextView的高度,在列表中 * 会出现闪烁的问题。
2611 0
|
前端开发 Android开发
Android 自定义垂直,旋转,圆形进度提示 自定义Seekbar
SeekBar是用来调节参数值的,系统默认的一般都不太适合我们,需要我们自定义, 里面也有一个RxJava背压的具体应用 废话不多说,看图   package com.
2379 0
|
Android开发
android:elevation属性,控制View底部渐变阴影
android:elevation属性,控制View底部渐变阴影 android:elevation这一属性,可以控制View底部渐变阴影,给一个View在其底部增加一定的灰度渐变阴影效果,如图: 上图是一个简单的TextView,TextView底部阴影渐变。
2711 0
|
Android开发
Android代码设置TextView的顶部图及设置图与字体之间距离
终于建了一个自己个人小站:https://huangtianyu.gitee.io,以后优先更新小站博客,欢迎进站,O(∩_∩)O~~ 现在很多的设计底部都是几个Tab标签,每个标签都是上边是图片,下边是文字。
2500 0