Android 九宫格抽奖RaffleView

本文介绍如何在Android中实现一个九宫格抽奖视图,包括绘制外边框、九宫格布局和抽奖动效。难点在于绘制带有闪光效果的外框,以及实现点击中间按钮的缩放动画。代码已开源。
摘要由CSDN通过智能技术生成

Android 九宫格抽奖View

最近在项目中要实现一个九宫格抽奖view 。中间是抽奖按钮,八个格子是奖品。效果图如下:

在这里插入图片描述
接下来我就分析一下实现这个View的步骤:
1.绘制出外框(此处难点是绘制闪光点的效果);
2.绘制九个格子,这个就是计算均分的逻辑,比较简单。
3.实现抽奖动效,以及点击中间start按钮有个缩放效果的实现。
我一一分析一下。

1.绘制外边框:

见代码:核心是使用 canvas.drawRoundRect(rectF, radiusBg, radiusBg, bgPaint);方法绘制圆角边框矩形,绘制内外两个边框矩形,重叠在一起(此处起初想使用画笔画边框,但实现起来只能内边框才有圆角,外边框是直角)。

接下来就是绘制四个角上的小原点(原点是图片),这样做是保证四个角的图片一致,此处逻辑就是计算四个角上的位置稍微麻烦点;然后计算四条边上的点。最后,使用postDelayed重复绘制,达到闪烁的效果。

public class LuckyDrawLayout extends RelativeLayout {
   
    private static final String TAG = "LuckyDrawLayout";
    private Paint bgPaint;
    private int mWidth, mHeight;
    private int radiusBg;
    private RectF rectF = new RectF();
    private Bitmap smallGreenBitmap;
    private Bitmap smallRedBitmap;
    private int ballWidth, ballHeight;
    private int redBallWidth, redBallHeight;
    private RectF ballRectf;
    private int innerPadding = dip2px(15);
    private boolean isChanged = true;
    private int eachRow = 13;

    public LuckyDrawLayout(Context context) {
   
        this(context, null);
    }

    public LuckyDrawLayout(Context context, AttributeSet attrs) {
   
        this(context, attrs, 0);
    }

    public LuckyDrawLayout(Context context, AttributeSet attrs, int defStyle) {
   
        super(context, attrs, defStyle);

        bgPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        bgPaint.setStyle(Paint.Style.FILL);
        bgPaint.setStrokeCap(Paint.Cap.ROUND);
        bgPaint.setStrokeJoin(Paint.Join.ROUND);
        bgPaint.setAntiAlias(true);
        bgPaint.setDither(true);
        bgPaint.setColor(0xFFFF356B);

        smallGreenBitmap = BitmapFactory.decodeResource(getContext().getResources(), R.mipmap.ic_small_green);
        smallRedBitmap = BitmapFactory.decodeResource(getContext().getResources(), R.mipmap.ic_small_red);
        ballWidth = smallGreenBitmap.getWidth();
        ballHeight = smallGreenBitmap.getHeight();
        redBallWidth = smallRedBitmap.getWidth();
        redBallHeight = smallRedBitmap.getHeight();
        ballRectf = new RectF();

        setWillNotDraw(false);
        changeBall();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
   
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int mWidth = MeasureSpec.getSize(widthMeasureSpec);
        int mHeight = MeasureSpec.getSize(heightMeasureSpec);
        int size = Math.min(mWidth, mHeight);
        setMeasuredDimension(size, size);
    }

    @Override
    protected void onDraw(Canvas canvas) {
   
        super.onDraw(canvas);
        mWidth = getWidth();
        mHeight = getHeight();

        radiusBg = mWidth / 40;
        rectF.set(0, 0, mWidth, mHeight);
        bgPaint.setColor(0xFFFF356B);
        canvas.drawRoundRect(rectF, radiusBg, radiusBg, bgPaint);

        rectF.set(innerPadding, innerPadding, mWidth - innerPadding, mHeight - innerPadding);
        bgPaint.setColor(0xFFCE0037);
        canvas.drawRoundRect(rectF, radiusBg, radiusBg, bgPaint);

        drawFourCorner(canvas);
        int ballGapDp = (mWidth - innerPadding * 2) / eachRow;
        for (int i = 0; i < eachRow; i++) {
   
            if (getGreen(i)) {
   
                //上
                ballRectf.set(innerPadding * 2 + i * ballGapDp - ballWidth / 2, innerPadding / 2 - ballHeight / 2, innerPadding * 2 + ballWidth / 2 + i * ballGapDp, innerPadding / 2 + ballHeight / 2);
                canvas.drawBitmap(smallGreenBitmap, null, ballRectf, null);
                //下
                ballRectf.set(innerPadding * 2 + i * ballGapDp - ballWidth / 2, mHeight - (innerPadding / 2 + ballHeight / 2), innerPadding * 2 + ballWidth / 2 + i * ballGapDp, mHeight - (innerPadding / 2 - ballHeight / 2));
                canvas.drawBitmap(smallGreenBitmap, null, ballRectf, null);
                //左
                ballRectf.set(innerPadding / 2 - ballWidth / 2, innerPadding * 2 + i * ballGapDp 
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值