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