IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> Andoid-----抽奖转盘----12宫格----实用性商业化 -> 正文阅读

[Java知识库]Andoid-----抽奖转盘----12宫格----实用性商业化

简述:

差不多一年半没有更新文章了,这段时间发生很多事情,一直在处理。博客还是正常在维护,有技术咨询和期望代做毕设或者商业洽谈的可以私信我。我基本每天都会看。

这篇文章的内容适用于安卓常用的抽奖效果,参照网络上九宫格抽奖特效进行了修改。

效果图:

实际效果:

点击盲盒领取,奖品上增加一个蒙层,开始转动,当倒计时结束(自己设定时长),抽奖成功,蒙层停到你指定的坐标下。

使用步骤:

1.自定义控件:

/**
 * ================================================
 * <p>
 * 作    者:Vip 版    本:V 1.0.0
 * 创建日期:2018/6/29
 * 描    述:盲盒抽奖
 * 修订历史:
 * ================================================
 */
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 = 3;//最终中奖位置
    private int mPosition = -1;//抽奖块的位置
    private int mStartLuckPosition = 0;//开始抽奖的位置
    private int[] mImgs = {
            R.drawable.icon,
            R.drawable.icon,
            R.drawable.icon,
            R.drawable.icon,
            R.drawable.icon,
            R.drawable.icon,
            R.drawable.icon,
            R.drawable.icon,
            R.drawable.icon,
            R.drawable.icon,
            R.drawable.icon,
            R.drawable.icon};
    private String[] mLuckStr = {"子鼠", "丑牛", "萝卜", "刺猬", "北极虾", "糖葫芦", "钝角", "香肠", "南瓜", "IP地址", "安装", "土狗"};
    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;
    private float left;
    private float top;

    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.dp_10);
        mOuterCircleBackgroundColor = context.getResources().getColor(R.color.load_red);
        mOuterCirclePaint = new Paint();
        mOuterCirclePaint.setColor(mOuterCircleBackgroundColor);
        mOuterCirclePaint.setAntiAlias(true);
        mOuterCirclePaint.setStrokeWidth(mOuterCircleWidth);
        mOuterCirclePaint.setStyle(Paint.Style.FILL);

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

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

        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);
        //下列三个方法去掉,内容为外框,不符合UI设计,不用调用。
//        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.ds_9sp));
                //文字加粗
                mInnerPaint.setStrokeWidth(1);
                String title = titles.get(x);
                if (title.length() > 5) {
                    title = title.substring(0, 5);
                    title = title + "...";
                }
                canvas.drawText(title, left - mRectSize/30 , 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;
    }

    /**
     * 画矩形
     *
     * @param canvas
     */
    private void drawRects(Canvas canvas) {
        for (int x = 0; x < mRects.size(); x++) {
            RectF rectF = mRects.get(x);

            mPaint.setColor(getContext().getResources().getColor(R.color.cs_ffe9c6));
            if (mPosition == x) {
                //动画的转动框
                mPaint.setColor(getContext().getResources().getColor(R.color.cs_f8de9b));
            }
            canvas.drawRoundRect(rectF, 10, 10, mPaint);
            if (mPosition == x) {
                //转动框底色
                mPaint.setColor(getContext().getResources().getColor(R.color.load_purple));
                RectF rectF1 = new RectF();
                rectF1.left = rectF.left + 10;
                rectF1.top = rectF.top + 10;
                rectF1.right = rectF.right - 10;
                rectF1.bottom = rectF.bottom - 10;
                canvas.drawRect(rectF1, mPaint);
            }
        }
    }

    public void setPosition(int position) {
        mPosition = position;
        invalidate();
    }
    ValueAnimator valueAnimator = ValueAnimator.ofInt(mStartLuckPosition, mRepeatCount * 12 + mLuckNum).setDuration(5000);
    /**
     * 开始动画
     */
    public void startAnim() {


        if (!mClickStartFlag) {
            mClickStartFlag = true;

            valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator animation) {
                    int position = (int) animation.getAnimatedValue();
                    setPosition(position % 12);
                }
            });
            valueAnimator.addListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    mClickStartFlag = false;
                    mStartLuckPosition = mLuckNum;
                    if (onLuckPanAnimEndListener != null) {
                        onLuckPanAnimEndListener.onAnimEnd(mPosition, mLuckStr[mPosition]);
                    }
                }
            });
            valueAnimator.start();
        }

    }
    /**结束动画**/

    public void endAnim(int mEndPosition){
        valueAnimator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                mClickStartFlag = false;
                mStartLuckPosition = mLuckNum;
                if (onLuckPanAnimEndListener != null) {
                    onLuckPanAnimEndListener.onAnimEnd(mEndPosition, mLuckStr[mEndPosition]);
                }
            }
        });
    }

    public interface OnLuckPanAnimEndListener {
        void onAnimEnd(int position, String msg);
    }

    public int dp2px(Context context, float dpValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }


}

2.对应布局:

              <!--十二宫格-->
                    <com.android.lingtu.view.NineLuckPan
                        android:id="@+id/luck_view"
                        android:layout_width="320dp"
                        android:layout_height="320dp"
                        android:layout_centerInParent="true"
                        android:layout_centerHorizontal="true" />

3.Java代码调用:

1.在对应Activity内进行FindViewById
    @BindView(R.id.luck_view)
    NineLuckPan luckView;

2.获取奖品数据源,进行赋值,这里模拟是从服务器获取的数据
    
   if(StringUtils.stringThreeNotEmpty(response.body())){
        BoxLIstBean bean = JSON.parseObject(response.body(), BoxLIstBean.class);
        if (NumberConstant.TWO_HUNDRED.equals(StringUtils.NullToStr(bean.getCode()))) {
            if (bean.getRows() != null && bean.getRows().size() > 0) {
                //盲盒奖品
                new Thread() {
                    public void run() {
                        List<Bitmap> bitmaps = new ArrayList<>();
                        List<String> list = new ArrayList<>();
                        try {
                            for (int i = 0; i < bean.getRows().get(0).getGoodsList().size(); i++) {
                                happyList.clear();
                                happyList.addAll(bean.getRows().get(0).getGoodsList());
                                Bitmap myBitmap = Glide.with(mContext).asBitmap().load(RequestApi.ROOT_URL + bean.getRows().get(0).getGoodsList().get(i).getImage()).submit(100, 100).get();
                                Bitmap bitmap = Bitmap.createBitmap(myBitmap, 0, 0, myBitmap.getWidth(), myBitmap.getHeight());
                                bitmaps.add(bitmap);
                                list.add(bean.getRows().get(0).getGoodsList().get(i).getName());
                            }
                            luckView.setTitles(list);
                            luckView.setBitmaps(bitmaps);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }

                }.start();


            }
        } else {
            Tt.showShort(mContext, StringUtils.NullToStr(bean.getMsg()));
        }
    }
3.获取抽奖结果,然后开启转盘动画,进行延迟操作显示中奖记录,并重置。

   if (StringUtils.stringThreeNotEmpty(response.body())) {
                            BoxRandomBean bean = JSON.parseObject(response.body(), BoxRandomBean.class);
                            if (NumberConstant.TWO_HUNDRED.equals(StringUtils.NullToStr(bean.getCode()))) {
                                luckView.startAnim();
                                if (bean.getData() != null) {
                                    new Handler().postDelayed(new Runnable() {
                                        @Override
                                        public void run() {
                                            if (StringUtils.stringThreeNotEmpty(bean.getData().getGoodsIds())) {
                                                // 抽中
                                                for (int i = 0; i < happyList.size(); i++) {
                                                    if ((happyList.get(i).getId() + "").equals(bean.getData().getGoodsIds())) {
                                                        showBoxYes(happyList.get(i).getName());
                                                        luckView.endAnim(i);
                                                    }
                                                }
                                              }
                                            } else {
                                                //未抽中
                                                showBoxNo();
                                            }
                                        }
                                    }, 6000);
                                } else {
                                    //未抽中
                                    new Handler().postDelayed(new Runnable() {
                                        @Override
                                        public void run() {
                                            //回零
                                            luckView.setPosition(0);
                                            showBoxNo();

                                        }
                                    }, 8000);

                                }


                            } else {
                                //没积分或者请求失败
                                Tt.showShort(mContext, StringUtils.NullToStr(bean.getMsg()));
                            }

                        }
  

总结:

通过以上方式,即可实现。

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-05-10 11:43:27  更:2022-05-10 11:47:03 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 23:38:45-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码