Android开发分享系列-12宫格抽奖盘

118 阅读4分钟
Android开发分享系列-12宫格抽奖盘

Android12宫格抽奖盘,也可以是9宫格。不过一般这功能都是给web做的。

一、思路:

自定义控件NineLuckPan

二、效果图:

在这里插入图片描述

三、关键代码:
public class NineLuckPan extends View {
    private Paint mPaint;
    private ArrayList<RectF> mRects;//存储矩形的集合
    private float mStrokWidth = 5;//矩形的描边宽度
    private int[] mItemColor = {Color.GREEN, Color.YELLOW};//矩形的颜色
    private int mRectSize;//矩形的宽和高(矩形为正方形)
    private boolean mClickStartFlag = false;//是否点击中间矩形的标记
    private int mRepeatCount = 3;//转的圈数
    private int mLuckNum = 2;//最终中奖位置
    private int mPosition = -1;//抽奖块的位置
    private int mStartLuckPosition = 0;//开始抽奖的位置
    private int[] mImgs = {R.drawable.ic_df, R.drawable.ic_df, R.drawable.ic_df, R.drawable.ic_df, R.drawable.ic_df, R.drawable.ic_df, R.drawable.ic_df, R.drawable.ic_df, R.drawable.ic_df, R.drawable.ic_df, R.drawable.ic_df, R.drawable.ic_df};
    private String[] mLuckStr = {"豆腐", "鸡腿", "米饭", "卷心菜", "南瓜", "糖葫芦", "大虾", "香肠", "南瓜", "糖葫芦", "大虾", "香肠"};
    private OnLuckPanAnimEndListener onLuckPanAnimEndListener;

    private int mOuterCircleWidth;  // 最外边圆环
    private Paint mOuterCirclePaint;
    private int mOuterCircleBackgroundColor;

    private int mSmallCircleRadius;  // 小圆圈半径
    private Paint mSmallCirclePaint;
    private int mSmallCircleBlueColor;
    private int mSmallCircleYellowColor;

    private Paint mInnerPaint;
    private int mInnerCircleBackgroundColor;

    private List<Bitmap> bitmaps;
    private List<String> titles;
    private int padding;

    public OnLuckPanAnimEndListener getOnLuckPanAnimEndListener() {
        return onLuckPanAnimEndListener;
    }

    public void setOnLuckPanAnimEndListener(OnLuckPanAnimEndListener onLuckPanAnimEndListener) {
        this.onLuckPanAnimEndListener = onLuckPanAnimEndListener;
    }

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

    public NineLuckPan(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public NineLuckPan(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context);
    }

    public int getmLuckNum() {
        return mLuckNum;
    }

    public void setmLuckNum(int mLuckNum) {
        this.mLuckNum = mLuckNum;
    }

    public int[] getmImgs() {
        return mImgs;
    }

    public void setmImgs(int[] mImgs) {
        this.mImgs = mImgs;
        invalidate();
    }

    public String[] getmLuckStr() {
        return mLuckStr;
    }

    public void setmLuckStr(String[] mLuckStr) {
        this.mLuckStr = mLuckStr;
        invalidate();
    }

    public List<Bitmap> getBitmaps() {
        return bitmaps;
    }

    public void setBitmaps(List<Bitmap> bitmaps) {
        this.bitmaps = bitmaps;
        invalidate();
    }

    public List<String> getTitles() {
        return titles;
    }

    public void setTitles(List<String> titles) {
        this.titles = titles;
    }

    /**
     * 初始化数据
     */
    private void init(Context context) {

        mOuterCircleWidth = (int) context.getResources().getDimension(R.dimen.lotteryview_outer_circle_width);
        mOuterCircleBackgroundColor = context.getResources().getColor(R.color.color_table_text);
        mOuterCirclePaint = new Paint();
        mOuterCirclePaint.setColor(mOuterCircleBackgroundColor);
        mOuterCirclePaint.setAntiAlias(true);
        mOuterCirclePaint.setStrokeWidth(mOuterCircleWidth);
        mOuterCirclePaint.setStyle(Paint.Style.FILL);

        mSmallCircleRadius = (int) context.getResources().getDimension(R.dimen.lotteryview_outer_small_circle_radius);
        mSmallCircleBlueColor = mSmallCircleBlueColor != 0 ? mSmallCircleBlueColor : context.getResources().getColor(R.color.small_circle_color_blue);
        mSmallCircleYellowColor = mSmallCircleYellowColor != 0 ? mSmallCircleYellowColor : context.getResources().getColor(R.color.small_circle_color_yellow);
        mSmallCirclePaint = new Paint();
        mSmallCirclePaint.setColor(mSmallCircleBlueColor);
        mSmallCirclePaint.setAntiAlias(true);

        mInnerCircleBackgroundColor = context.getResources().getColor(R.color.colorPrimary);
        mInnerPaint = new Paint();
        mInnerPaint.setAntiAlias(true);
        mInnerPaint.setColor(mInnerCircleBackgroundColor);
        mInnerPaint.setStyle(Paint.Style.FILL);

        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaint.setStyle(Paint.Style.FILL);
        mPaint.setStrokeWidth(mStrokWidth);

        mRects = new ArrayList<>();

        padding = dp2px(getContext(), 10);
    }

    /**
     * 外层带圆角矩形圆环
     */
    private void drawOuterRoundCircle(Canvas canvas) {
        canvas.save();
        canvas.clipRect(
                mOuterCircleWidth + getPaddingLeft(),
                mOuterCircleWidth + getPaddingTop(),
                getWidth() - mOuterCircleWidth - getPaddingRight(),
                getWidth() - mOuterCircleWidth - getPaddingBottom(),
                Region.Op.DIFFERENCE);

        canvas.drawRoundRect(
                getPaddingLeft(),
                getPaddingTop(),
                getWidth() - getPaddingRight(),
                getWidth() - getPaddingBottom(),
                18, 18, mOuterCirclePaint);
        canvas.restore();
    }

    private void drawOuterDecorateSmallCircle(Canvas canvas) {
        int result = 0;

        // top
        int x = 0, y = 0;
        int sideSize = getWidth() - mOuterCircleWidth * 2 - getPaddingLeft() - getPaddingRight(); // 除去最外边圆环后的边长
        for (int i = 0; i < 10; i++) {
            mSmallCirclePaint.setColor(i % 2 == result ? mSmallCircleYellowColor : mSmallCircleBlueColor);
            x = mOuterCircleWidth + (sideSize - mSmallCircleRadius * 2 * 9) / 9 * i + mSmallCircleRadius * 2 * i + getPaddingLeft();
            y = (mOuterCircleWidth - mSmallCircleRadius * 2) / 2 + mSmallCircleRadius + getPaddingTop();
            canvas.drawCircle(x, y, mSmallCircleRadius, mSmallCirclePaint);
        }

        // bottom
        for (int i = 0; i < 10; i++) {
            mSmallCirclePaint.setColor(i % 2 == result ? mSmallCircleYellowColor : mSmallCircleBlueColor);
            x = mOuterCircleWidth + (sideSize - mSmallCircleRadius * 2 * 9) / 9 * i + mSmallCircleRadius * 2 * i + getPaddingLeft();
            y = getWidth() - mOuterCircleWidth + (mOuterCircleWidth - mSmallCircleRadius * 2) / 2 + mSmallCircleRadius - getPaddingBottom();
            canvas.drawCircle(x, y, mSmallCircleRadius, mSmallCirclePaint);
        }

        // left
        for (int i = 0; i < 9; i++) {
            mSmallCirclePaint.setColor(i % 2 == (result == 0 ? 1 : 0) ? mSmallCircleYellowColor : mSmallCircleBlueColor);
            x = mOuterCircleWidth / 2 + getPaddingLeft();
            y = mOuterCircleWidth * 2 + (sideSize - mSmallCircleRadius * 2 * 9) / 9 * i + mSmallCircleRadius * 2 * i + getPaddingTop();
            canvas.drawCircle(x, y, mSmallCircleRadius, mSmallCirclePaint);
        }

        // right
        for (int i = 0; i < 9; i++) {
            mSmallCirclePaint.setColor(i % 2 == result ? mSmallCircleYellowColor : mSmallCircleBlueColor);
            x = getWidth() - mOuterCircleWidth / 2 - getPaddingRight();
            y = mOuterCircleWidth * 2 + (sideSize - mSmallCircleRadius * 2 * 9) / 9 * i + mSmallCircleRadius * 2 * i + getPaddingTop();
            canvas.drawCircle(x, y, mSmallCircleRadius, mSmallCirclePaint);
        }
    }

    private void drawInnerBackground(Canvas canvas) {
        canvas.drawRect(mOuterCircleWidth + getPaddingLeft(), mOuterCircleWidth + getPaddingTop(),
                getWidth() - mOuterCircleWidth - getPaddingRight(),
                getWidth() - mOuterCircleWidth - getPaddingBottom(), mInnerPaint);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mRectSize = (Math.min(w, h) - mOuterCircleWidth * 2 - padding * 5) / 4;//获取矩形的宽和高
        mRects.clear();//当控件大小改变的时候清空数据
        initRect();//重新加载矩形数据
    }

    /**
     * 加载矩形数据
     */
    private void initRect() {


        //加载前三个矩形

        int itemWidth = getWidth() - mOuterCircleWidth * 2;

        //加载第1个
        mRects.add(new RectF(0 + mOuterCircleWidth + padding, mOuterCircleWidth + padding, mRectSize + mOuterCircleWidth + padding, mRectSize + mOuterCircleWidth + padding));
        //加载第2个
        mRects.add(new RectF(mRectSize + mOuterCircleWidth + padding * 2, mOuterCircleWidth + padding, mRectSize * 2 + mOuterCircleWidth + padding * 2, mRectSize + mOuterCircleWidth + padding));
        //加载第3个
        mRects.add(new RectF(mRectSize * 2 + mOuterCircleWidth + padding * 3, mOuterCircleWidth + padding, mRectSize * 3 + mOuterCircleWidth + padding * 3, mRectSize + mOuterCircleWidth + padding));
        //加载第4个
        mRects.add(new RectF(mRectSize * 3 + mOuterCircleWidth + padding * 4, mOuterCircleWidth + padding, mRectSize * 4 + mOuterCircleWidth + padding * 4, mRectSize + mOuterCircleWidth + padding));
        //加载第5个
        mRects.add(new RectF(mRectSize * 3 + mOuterCircleWidth + padding * 4, mRectSize + mOuterCircleWidth + padding * 2, mRectSize * 4 + mOuterCircleWidth + padding * 4, mRectSize * 2 + mOuterCircleWidth + padding * 2));
        //加载第6个
        mRects.add(new RectF(mRectSize * 3 + mOuterCircleWidth + padding * 4, mRectSize * 2 + mOuterCircleWidth + padding * 3, mRectSize * 4 + mOuterCircleWidth + padding * 4, mRectSize * 3 + mOuterCircleWidth + padding * 3));
        //加载第7个
        mRects.add(new RectF(mRectSize * 3 + mOuterCircleWidth + padding * 4, mRectSize * 3 + mOuterCircleWidth + padding * 4, mRectSize * 4 + mOuterCircleWidth + padding * 4, mRectSize * 4 + mOuterCircleWidth + padding * 4));
        //加载第8个
        mRects.add(new RectF(mRectSize * 2 + mOuterCircleWidth + padding * 3, mRectSize * 3 + mOuterCircleWidth + padding * 4, mRectSize * 3 + mOuterCircleWidth + padding * 3, mRectSize * 4 + mOuterCircleWidth + padding * 4));
        //加载第9个
        mRects.add(new RectF(mRectSize + mOuterCircleWidth + padding * 2, mRectSize * 3 + mOuterCircleWidth + padding * 4, mRectSize * 2 + mOuterCircleWidth + padding * 2, mRectSize * 4 + mOuterCircleWidth + padding * 4));
        //加载第10个
        mRects.add(new RectF(0 + mOuterCircleWidth + padding, mRectSize * 3 + mOuterCircleWidth + padding * 4, mRectSize + mOuterCircleWidth + padding, mRectSize * 4 + mOuterCircleWidth + padding * 4));
        //加载第11个
        mRects.add(new RectF(0 + mOuterCircleWidth + padding, mRectSize * 2 + mOuterCircleWidth + padding * 3, mRectSize + mOuterCircleWidth + padding, mRectSize * 3 + mOuterCircleWidth + padding * 3));
        //加载第12个
        mRects.add(new RectF(0 + mOuterCircleWidth + padding, mRectSize + mOuterCircleWidth + padding * 2, mRectSize + mOuterCircleWidth + padding, mRectSize * 2 + mOuterCircleWidth + padding * 2));

    }
        @Override
        protected void onDraw (Canvas canvas){
            super.onDraw(canvas);
            drawOuterRoundCircle(canvas);
            drawOuterDecorateSmallCircle(canvas);
            drawInnerBackground(canvas);
            drawRects(canvas);
            drawImages(canvas);
        }

/**
 * 画图片
 * @param canvas
 */
        private void drawImages (Canvas canvas){
            for (int x = 0; x < mRects.size(); x++) {
                RectF rectF = mRects.get(x);
                float left = rectF.centerX() - mRectSize / 4;
                float top = rectF.centerY() - mRectSize / 4;
                if (bitmaps != null && bitmaps.size() > 0) {
                    canvas.drawBitmap(Bitmap.createScaledBitmap(bitmaps.get(x), mRectSize / 2, mRectSize / 2, false), left, top - mRectSize / 8, null);

                }
                if (titles != null && titles.size() > 0) {
                    mInnerPaint.setTextSize(getContext().getResources().getDimension(R.dimen.lotteryview_inner_card_text_size));
                    String title = titles.get(x);
                    if (title.length() > 5) {
                        title = title.substring(0, 5);
                        title = title + "...";
                    }


                    canvas.drawText(title, left - mRectSize / 8, top + mRectSize * 3 / 4 - 20, mInnerPaint);
                }
                //
            }
        }

        private int getTextWidth (Paint paint, String text){
            int iRet = 0;
            if (text != null && text.length() > 0) {
                int len = text.length();
                float[] widths = new float[len];
                paint.getTextWidths(text, widths);
                for (int j = 0; j < len; j++) {
                    iRet += (int) Math.ceil(widths[j]);
                }
            }
            return iRet;
        }
四、项目demo源码结构图:

在这里插入图片描述
有问题或者需要完整源码demo的可以看简介联系我,也可以私信我,我每天都看私信的