自定义view之图片放入圆环中间随记

关于drawBitmap

1、基本的绘制图片方法
//Bitmap:图片对象,left:偏移左边的位置,top: 偏移顶部的位置
drawBitmap(Bitmap bitmap, float left, float top, Paint paint)
2、对图片剪接和限定显示区域
drawBitmap(Bitmap bitmap, Rect src, RectF dst, Paint paint);
Rect src: 是对图片进行裁截,若是空null则显示整个图片
RectF dst:是图片在Canvas画布中显示的区域,大于src则把src的裁截区放大,小于src则把src的裁截区缩小

如何将图片放到自定义view圆环的中间

//获取圆心坐标x,y分别减去图片宽高的1/2;和加上1/2;设为左、上、右、下就可以把图片放到中间了
det = new Rect(x-bitmap.getWidth()/2,y-mBitmap.getHeight()/2,
x+bitmap.getWidth(),y+mBitmap.getHeight()/2)


中间图像为图片圆环和背景为自定义

具体代码如下

public class MaskView extends View {

    private static final String TAG = "MaskView";

    private int mLeft;
    private int mTop;
    private int mRight;
    private int mBottom;
    private int mProgress=0; // 进度

    private Paint mClearPaint;
    private Paint mCirclePaint;
    private Paint mSmallCirclePaint;
    private Paint mfuzzyCirclePaint;
    private Rect mMaskRect;
    private boolean mIsFirstScale = true;
    private Bitmap mBitmap;
    private Bitmap mDoneBimap;
    private Rect mSrc;
    private Rect mDst;
    private Rect mDoneSrc;
    private Rect mDoneDst;

    public MaskView(Context context) {
        super(context);
        init();
    }

    public MaskView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    private void init() {
        mClearPaint = new Paint();
        mClearPaint.setAntiAlias(true);
//设置圆内部为空
        mClearPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
        mCirclePaint = new Paint();
        mCirclePaint.setAntiAlias(true);
        mCirclePaint.setStyle(Paint.Style.STROKE);
        mCirclePaint.setStrokeWidth(CommonUtil.dip2px(getContext(), 3));

        mSmallCirclePaint = new Paint();
        mSmallCirclePaint.setAntiAlias(true);
        mSmallCirclePaint.setStyle(Paint.Style.STROKE);
        mSmallCirclePaint.setStrokeWidth(CommonUtil.dip2px(getContext(), 5));

        mfuzzyCirclePaint = new Paint();
        mfuzzyCirclePaint.setAntiAlias(true);


        mMaskRect = new Rect();

        mBitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.face_entry);
        mDoneBimap = BitmapFactory.decodeResource(getResources(), R.mipmap.face_dong);

    }
//设置不同时期进度
    public void setProgress(int progress) {
        this.mProgress = progress;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            invalidate();
        }
    }

    public Rect getMaskRect(float scaleX, float scaleY) {
        if (mIsFirstScale) {
            int left = (int) (this.mLeft / scaleX);
            int top = (int) (this.mTop / scaleY);
            int right = (int) (this.mRight / scaleX);
            int bottom = (int) (this.mBottom / scaleY);
            mMaskRect.set(left, top, right, bottom);
            mIsFirstScale = false;
            Log.d(TAG, "scaleX : " + scaleX);
            Log.d(TAG, "scaleY : " + scaleY);
            Log.d(TAG, "mMaskRect : " + mMaskRect.toShortString());
        }
        return mMaskRect;
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
        if (changed)
            initMaskArea();
    }

    private void initMaskArea() {
        int width = getWidth();
        int length = width / 6;
        mLeft = length;
        mTop = length; // 上下蒙板区域固定
        mRight = length * 5;
        mBottom = length * 5;

        int centerButmap = width >> 1;
        mSrc = new Rect(0,0,mBitmap.getWidth(),mBitmap.getHeight());
        mDst = new Rect(centerButmap-mBitmap.getWidth()/2,centerButmap-mBitmap.getHeight()/2,
                centerButmap+mBitmap.getWidth()/2,centerButmap+mBitmap.getHeight()/2);

        mDoneSrc = new Rect(0,0,mDoneBimap.getWidth(),mDoneBimap.getHeight());
//获取圆心坐标x,y分别减去图片宽高的1/2;和加上1/2;设为左、上、右、下就可以把图片放到中间了
        mDoneDst = new Rect(centerButmap-mDoneBimap.getWidth()/2,centerButmap-mDoneBimap.getHeight()/2,
                centerButmap+mDoneBimap.getWidth()/2,centerButmap+mDoneBimap.getHeight()/2);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        float cx = (mLeft + mRight) >> 1;
        float cy = (mTop + mBottom) >> 1;
        float radius = (mRight - mLeft) >> 1;
        if (mProgress==0) {
            canvas.drawBitmap(mBitmap, mSrc, mDst, null);
        }else {
            canvas.drawCircle(cx, cy, radius, mClearPaint);
        }

        if (mProgress == 100) {
            canvas.drawBitmap(mDoneBimap, mDoneSrc, mDoneDst, null);
            mfuzzyCirclePaint.setColor(0x37fbfbfb);
            canvas.drawCircle(cx, cy, radius-CommonUtil.dip2px(getContext(), 2), mfuzzyCirclePaint);
        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            mSmallCirclePaint.setColor(0xfffbfbfb);
            canvas.drawCircle(cx, cy, radius-CommonUtil.dip2px(getContext(), 2), mSmallCirclePaint);
            mCirclePaint.setColor(0xFFD9D9D9);
            canvas.drawCircle(cx, cy, radius+CommonUtil.dip2px(getContext(), 2), mCirclePaint);
            mCirclePaint.setColor(0xFF15af97);
            float sweepAngle = mProgress * 360 / 100.0f;
            Log.d(TAG, "sweepAngle: " + sweepAngle);
            canvas.drawArc(mLeft-CommonUtil.dip2px(getContext(), 2), mTop-CommonUtil.dip2px(getContext(), 2),
                    mRight+CommonUtil.dip2px(getContext(), 2),
                    mBottom+CommonUtil.dip2px(getContext(), CommonUtil.dip2px(getContext(), 1)),
                    -90, sweepAngle, false, mCirclePaint);
        }
    }
}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350

推荐阅读更多精彩内容