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

原创 2015年11月17日 17:44:44
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();
        }
    }
}
版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

安卓开发:仿微博自定义带进度条和vip标识功能的圆形头像IdentityImageView

最近产品增加了两个小功能,一个是头像加一个进度条,用于升级提示,一个是身份标识功能,也就是标识Vip的功能,如图: ,很多朋友看见这个小功能,肯定觉得特简单,就是两张图片叠在一起嘛,用个Rela...

自定义ImageView实现圆形头像

java代码如下: package com.yan.view; import android.content.Context; import android.graphics.Bitmap; ...

androidの自定义ImageView圆形头像

androidの自定义ImageView圆形头像 1.自定义圆形控件    CircleImageView.java 主要自定义的类package de.hdodenhof.circleimage...

圆形头像以及一些常见需求形状自定义ImageView组件

在实际开发中,我们经常会遇到这样的需求,就是无论图片长啥样,我们都要其显示成圆形、圆形加一个边框、矩形加边框,带圆角的矩形等等,我已把自己平常用的组件和demo上传到了github(https://g...

自定义ImageView实现圆形头像 利用Xferomede实现

不说废话,直接上代码,用的话直接把代码拷过去就行,不用别的配置import android.content.Context; import android.graphics.Bitmap; impor...

自定义圆形ImageView(仿QQ头像)

我们可以发现,现在的app对圆形图片的使用越来越普遍,特别是用户的头像等。圆形图片外观柔和、友好、饱满,能大大提升用户的视觉体验。所以今天我们就来看看 怎样自定义圆形的ImageView(一些说明与应...

安卓开发之自定义View------> 圆形头像ImageView

安卓小白学习笔记,欢迎大家来一起交流,转载请注明出处~安卓开发之自定义View——> 圆形头像ImageView,先贴效果图↓ 一般自己写自定义View有两种方式 1、新建class继承View...

android 自定义ImageView控件实现圆形图片-适用于用户头像

android开发中常常涉及到一种情况,就是将用户上传的图片以圆形样式显示,但是用户上传的图片可以有直角、圆角、正方形等多种不确定样式,这时就用到了自定义ImageView控件,在安卓客户端使接收到的...

Android中使用自定义ImageView实现圆形头像

第一步:创建一个自定义MyImageView类继承ImageViewpackage com.sx.happytoplay.ui; import android.content.Context; i...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)