前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >自定义带 vip 标识的 圆形头像(圆形ImageView)

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

作者头像
再见孙悟空_
发布于 2023-02-10 10:55:37
发布于 2023-02-10 10:55:37
1.9K00
代码可运行
举报
运行总次数:0
代码可运行
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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;
    }
}

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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();
        }
    }
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-08-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
面试题:非对称加密和对称加密的区别以及优缺点
在计算机安全领域,加密是一种常用的手段来保护数据的安全性。对称加密和非对称加密是两种常见的加密方式,它们在Java中都有相应的实现。
GeekLiHua
2025/01/21
1430
java之jce「建议收藏」
Java Cryptography Extension(JCE)是一组包,它们提供用于加密、密钥生成和协商以及 Message Authentication Code(MAC)算法的框架和实现。它提供对对称、不对称、块和流密码的加密支持,它还支持安全流和密封的对象。它不对外出口,用它开发完成封装后将无法调用。
全栈程序员站长
2022/07/05
2.5K0
SpringCloud-数据认证加密总结
在当今分布式系统的日益复杂和信息传递的广泛网络化环境中,确保通信的安全性至关重要。数据的加密和认证作为保障信息传递安全的关键手段,在分布式系统中扮演着不可或缺的角色。Spring Cloud,作为一套构建微服务架构的强大框架,提供了多种灵活而强大的数据加密和认证方式。从传统的 MD5 散列算法到现代的 OAuth 2.0 和 JWT(JSON Web Token)标准,每种加密和认证方式都针对不同的应用场景和安全需求提供了特定的解决方案。
Damon小智
2024/03/06
2160
SpringCloud-数据认证加密总结
Java安全之安全加密算法
本篇文来谈谈关于常见的一些加密算法,其实在此之前,对算法的了解并不是太多。了解的层次只是基于加密算法的一些应用上。也来浅谈一下加密算法在安全领域中的作用。写本篇文也是基于算法的应用和实现,也是我的基本原则,能用就行。
全栈程序员站长
2021/04/07
1.4K0
Java安全之安全加密算法
Java技术专题:「入门到精通系列」深入探索常用的六种加密技术和实现
随着信息安全的日益重要,加密技术在软件开发领域中扮演着关键的角色。Java作为一门广泛应用的编程语言,提供了丰富的加密库和API,使得开发者可以轻松实现各种加密算法。本文将深入探索Java技术中常用到的六种加密技术,包括对称加密、非对称加密、哈希算法、消息摘要、数字签名和数字证书,并通过具体的实现代码帮助读者更好地理解和应用这些加密技术。
IT_陈寒
2024/01/08
3170
Java技术专题:「入门到精通系列」深入探索常用的六种加密技术和实现
关于加解密、加签验签的那些事 | 得物技术
面对MD5、SHA、DES、AES、RSA等等这些名词你是否有很多问号?这些名词都是什么?还有什么公钥加密、私钥解密、私钥加签、公钥验签。这些都什么鬼?或许在你日常工作没有听说过这些名词,但是一旦你要设计一个对外访问的接口,或者安全性要求高的系统,那么必然会接触到这些名词。所以加解密、加签验签对于一个合格的程序员来说是必须要掌握的一个概念。接下来我们就一文彻底搞懂这些概念。
用户10346649
2023/03/10
1K0
关于加解密、加签验签的那些事 | 得物技术
支付项目中常用的加密解密算法一文讲透
作为支付机构,传输的数据大多是非常隐私的,比如身份证号、银行卡号、银行卡密码等。一旦这些信息被不法分子截获,就可能直接被盗刷银行卡,给消费者造成巨大损失。如果不法分子获取的信息是加密的,且没有解密的秘钥,那么对于不法分子来说这些信息就是一堆乱码,这就是加码最重要的意义。
用户3587585
2024/04/30
1.2K0
支付项目中常用的加密解密算法一文讲透
面试官:如何设计一个对外的安全接口?
哈喽,我是狗哥。最近在跟业务方对接需要我这边出个接口给到他们调用,这种涉及外部调用的接口设计,一般都涉及很多方面,比如:
JavaFish
2022/01/17
5850
面试官:如何设计一个对外的安全接口?
[Java 安全]加密算法
Base64编码 算法简述 定义 Base64内容传送编码是一种以任意8位字节序列组合的描述形式,这种形式不易被人直接识别。 Base64是一种很常见的编码规范,其作用是将二进制序列转换为人类可读的A
静默虚空
2018/01/05
3.9K0
[Java 安全]加密算法
对称加密与非对称加密
优点:速度快,对称性加密通常在消息发送方需要加密大量数据时使用,算法公开、计算量小、加密速度快、加密效率高。
lyb-geek
2022/03/09
2.5K0
加密与安全_探索非对称加密算法_RSA算法
加密与安全_探索密钥交换算法(Diffie-Hellman算法) 中我们可以看到,公钥-私钥组成的密钥对是非常有用的加密方式,因为公钥是可以公开的,而私钥是完全保密的,由此奠定了非对称加密的基础。
小小工匠
2024/05/26
1950
每日一博 - 对称加密算法 vs 非对称加密算法
我们今天来梳理一下将分别介绍这两种加密算法的优缺点,并通过Java代码实现和测试结果来验证其效果。
小小工匠
2023/05/29
4770
加密-解密详解
参考视频: https://www.bilibili.com/video/BV1tz4y197hm
用户5927264
2020/07/30
2.8K0
SpringBoot 实现 RAS+AES 自动接口解密
目前常用的加密方式就对称性加密和非对称性加密,加密解密的操作的肯定是大家知道的,最重要的使用什么加密解密方式,制定什么样的加密策略;考虑到我技术水平和接口的速度,采用的是RAS非对称加密和AES对称加密一起用!!!!
程序员蜗牛
2024/05/10
1620
SpringBoot 实现 RAS+AES 自动接口解密
JAVA中的加密算法之双向加密(二)
本节主要讲述Java双向加密算法中的非对称加密算法实现。 (二)、非对称加密 1976年,美国学者Dime和Henman为解决信息公开传送和密钥管理问题,提出一种新的密钥交换协议,允许在不安全的媒体上的通讯双方交换信息,安全地达成一致的密钥,这就是“公开密钥系统”。相对于“对称加密算法”这种方法也叫做“非对称加密算法”。 与对称加密算法不同,非对称加密算法需要两个密钥:公开密钥(publickey)和私有密钥 (privatekey)。公开密钥与私有密钥是一对,如果用公开密钥对数据进行加密,只有用对应的私有密钥才能解密;如果用私有密钥对数据进行加密,那么只有用对应的公开密钥才能解密。因为加密和解密使用的是两个不同的密钥,所以这种算法叫作非对称加密算法。 1. RSA 公钥加密算法是1977年由Ron Rivest、Adi Shamirh和LenAdleman在(美国麻省理工学院)开发的。RSA取名来自开发他们三者的名字。RSA是目前最有影响力的公钥加密算法,它能够抵抗到目前为止已知的所有密码攻击,已被ISO推荐为公钥数据加密标准。RSA算法基于一个十分简单的数论事实:将两个大素数相乘十分容易,但那时想要对其乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥。
幽鸿
2020/04/02
1.6K0
JAVA使用几种非对称加密
DH: package com.fengyunhe.asymmetric; import com.sun.org.apache.xerces.internal.impl.dv.util.HexBin; import javax.crypto.*; import javax.crypto.interfaces.DHPublicKey; import javax.crypto.spec.DHParameterSpec; import java.security.*; import java.security
前Thoughtworks-杨焱
2021/12/08
4510
如何使用Java进行加密和解密
在Java中,我们可以使用许多不同的加密和解密技术来保护数据。这些技术可以用于加密密码、保护敏感数据、网络通信等。下面将介绍Java中常用的加密和解密技术和实现方法。
用户1289394
2023/09/22
7190
如何使用Java进行加密和解密
哈希算法是对称算法还是非对称算法_对称加密和非对称加密原理
作用:对任意一组输入数据进行计算,得到一个固定长度的输出摘要。 哈希算法的目的:为了验证原始数据是否被篡改。 哈希算法最重要的特点就是: 相同的输入一定得到相同的输出; 不同的输入大概率得到不同的输出。
全栈程序员站长
2022/11/01
1.2K0
Java中的加密和解密是什么,提供一个使用加密和解密的实际案例
在Java中,加密和解密是信息安全领域中非常重要的概念,它们用于保护数据的机密性和完整性。加密是指将明文转换为密文的过程,而解密则是将密文还原为明文的过程。在实际应用中,我们通常使用一些加密算法来对数据进行加密,以保护数据的安全性。
用户1289394
2024/05/29
1940
Java中的加密和解密是什么,提供一个使用加密和解密的实际案例
深入解析ECC(椭圆曲线密码学)加解密算法
随着互联网的普及和信息安全需求的不断提高,密码学在保护数据安全方面发挥着越来越重要的作用。公钥密码体制作为一种常见的加密方式,为数据安全提供了可靠的保障。ECC(椭圆曲线密码学)是一种新型的公钥密码体制,相比传统的RSA算法,在相同安全性要求下,ECC所需的密钥长度更短,运算效率更高,因此在现代密码学领域得到了广泛应用。
公众号:码到三十五
2024/05/24
1.4K0
深入解析ECC(椭圆曲线密码学)加解密算法
推荐阅读
相关推荐
面试题:非对称加密和对称加密的区别以及优缺点
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验