1000字范文,内容丰富有趣,学习的好帮手!
1000字范文 > Android自定义实现九宫格抽奖功能

Android自定义实现九宫格抽奖功能

时间:2022-07-19 21:50:25

相关推荐

Android自定义实现九宫格抽奖功能

最近的功能需求中需要实现用户使用签到获取的积分,可以在九宫格中进行抽奖消耗积分,这里使用的是自定义进行实现抽奖的功能,可以通过设置计算策略,来控制用户 中哪些奖以及中大奖 的概率,话不多说,直接上代码。

1.先看效果图

2.自定义View实现九宫格抽奖功能

public class LuckyView extends View {private Paint mPaint;private float mStrokeWidth = 5;private int mRepeatCount = 5; // 转的圈数private int mRectSize; // 矩形的宽和高(矩形为正方形)private boolean mShouldStartFlag;private boolean mShouldStartNextTurn = true; // 标记是否应该开启下一轮抽奖private int mStartLuckPosition = 0; // 开始抽奖的位置private int mCurrentPosition = -1; // 当前转圈所在的位置private OnLuckAnimationEndListener mLuckAnimationEndListener;/*** 可以通过对 mLuckNum 设置计算策略,来控制用户 中哪些奖 以及 中大奖 的概率*/private int mLuckNum = 3; // 默认最终中奖位置private List<RectF> mRectFs; // 存储矩形的集合private int[] mItemColor = {Color.parseColor("#ffefd6"), Color.parseColor("#ffefd6")}; // 矩形的颜色private String[] mPrizeDescription = {"满20减1元券", "满10减1元券", "满30减2元券", "满5减1元券", "免单", "满300减40元券", "满100减10元券", "满500减50元券", "开始"};private int[] mLuckyPrizes = {R.drawable.aaa, R.drawable.bbb, c, R.drawable.ddd, R.drawable.aaa, R.drawable.bbb, c, R.drawable.ddd, R.drawable.center_lucky};private List<String> lettersBeans;private float left;private float top;private Bitmap[] bitmaps;private String[] luckyName;private String[] id;private int selectPos;public LuckyView(Context context) {this(context, null);}public LuckyView(Context context, @Nullable AttributeSet attrs) {this(context, attrs, 0);}public LuckyView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);init();}private void init() {mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); // 抗锯齿mPaint.setStyle(Paint.Style.FILL);// mPaint.setStyle(Paint.Style.STROKE); // 设置样式为描边mPaint.setStrokeWidth(mStrokeWidth); // 设置描边的宽度mRectFs = new ArrayList<>();}public void setLuckAnimationEndListener(OnLuckAnimationEndListener luckAnimationEndListener) {mLuckAnimationEndListener = luckAnimationEndListener;}public int getLuckNum() {return mLuckNum;}public void setLuckNum(int luckNum) {mLuckNum = luckNum;}public int[] getLuckyPrizes() {return mLuckyPrizes;}public void setLuckyPrizes(int[] luckyPrizes) {mLuckyPrizes = luckyPrizes;}//设置图片,文字数据public void setData(List<String> lettersBeans) {this.lettersBeans = lettersBeans;invalidate();}@Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh) {super.onSizeChanged(w, h, oldw, oldh);// 矩形的宽高mRectSize = (Math.min(w, h)) / 3;// 当控件大小改变的时候清空数据mRectFs.clear();initNineRect();}/*** 初始化 9 个矩形(正方形)的位置信息*/private void initNineRect() {final float width = getWidth();// 加载前三个矩形for (int i = 0; i < 3; i++) {float left = i * mRectSize + 5;float right = (i + 1) * mRectSize;float top = 5;float bottom = mRectSize;RectF rectF = new RectF(left, top, right, bottom);mRectFs.add(rectF);}// 加载第 4 个矩形mRectFs.add(new RectF(width - mRectSize + 5, mRectSize + 5, width, 2 * mRectSize));// 加载第 5~7 个矩形for (int j = 3; j > 0; j--) {float left = width - (4 - j) * mRectSize + 5;float right = width - (3 - j) * mRectSize;float top = 2 * mRectSize + 5;float bottom = 3 * mRectSize;RectF rectF = new RectF(left, top, right, bottom);mRectFs.add(rectF);}// 加载第 8 个矩形mRectFs.add(new RectF(5, mRectSize + 5, mRectSize, 2 * mRectSize));// 加载中心第 9 个矩形mRectFs.add(new RectF(mRectSize + 5, mRectSize + 5, 2 * mRectSize, 2 * mRectSize));}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);//执行真正的绘制矩形操作drawNineRect(canvas);// 填充奖品图片drawNineBitmaps(canvas);// 填充奖品文字drawNineText(canvas);}/*** 在每个矩形中填充奖品图片* left:The position of the left side of the bitmap being drawn* top:The position of the top side of the bitmap being drawn*/private void drawNineBitmaps(final Canvas canvas) {for (int i = 0; i < mRectFs.size(); i++) {RectF rectF = mRectFs.get(i);// 将图片设置在每个矩形中央left = rectF.left + mRectSize / 4;top = rectF.top + mRectSize / 4;canvas.drawBitmap(Bitmap.createScaledBitmap(BitmapFactory.decodeResource(getResources(), mLuckyPrizes[i]), mRectSize / 2, mRectSize / 2, false), left, top, null);}}/*** 在每个矩形中央填充文字,代替抽奖图片* x:he x-coordinate of the origin of the text being drawn* y:The y-coordinate of the baseline of the text being drawn*/private void drawNineText(Canvas canvas) {for (int i = 0; i < mRectFs.size(); i++) {RectF rectF = mRectFs.get(i);float x = rectF.left + mRectSize / 4; // 将文字设置在每个矩形中央float y = rectF.top + mRectSize - 20;mPaint.setColor(Color.parseColor("#5e5448"));mPaint.setStyle(Paint.Style.FILL);mPaint.setTextSize(15); // unit pxif (i == mRectFs.size() - 1) {canvas.drawText("", x, y, mPaint);} else {canvas.drawText(mPrizeDescription[i], x, y, mPaint);}}}/*** 执行真正的绘制矩形操作*/private void drawNineRect(Canvas canvas) {for (int x = 0; x < mRectFs.size(); x++) {RectF rectF = mRectFs.get(x);if (x == 8) {mPaint.setColor(Color.WHITE);} else {if (mCurrentPosition == x) {mPaint.setColor(Color.parseColor("#edcea9"));} else {mPaint.setColor(mItemColor[x % 2]); // 标记当前转盘经过的位置}}canvas.drawRect(rectF, mPaint);}}@SuppressLint("ClickableViewAccessibility")@Overridepublic boolean onTouchEvent(MotionEvent event) {if (event.getAction() == MotionEvent.ACTION_DOWN) {mShouldStartFlag = mRectFs.get(8).contains(event.getX(), event.getY());return true;}if (event.getAction() == MotionEvent.ACTION_UP) {if (mShouldStartFlag) {if (mRectFs.get(8).contains(event.getX(), event.getY())) {// mLuckAnimationEndListener.onClickLuck();startAnim(); // 判断只有手指落下和抬起都在中间的矩形内时才开始执行动画抽奖}mShouldStartFlag = false;}}return super.onTouchEvent(event);}private void startAnim() {if (!mShouldStartNextTurn) {return;}Random random = new Random();setLuckNum(random.nextInt(8)); // 生成 [0,8) 的随机整数ValueAnimator animator = ValueAnimator.ofInt(mStartLuckPosition, mRepeatCount * 8 + mLuckNum).setDuration(5000);animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {@Overridepublic void onAnimationUpdate(ValueAnimator animation) {final int position = (int) animation.getAnimatedValue();setCurrentPosition(position % 8);mShouldStartNextTurn = false;}});animator.addListener(new AnimatorListenerAdapter() {@Overridepublic void onAnimationEnd(Animator animation) {mShouldStartNextTurn = true;mStartLuckPosition = mLuckNum;//最终选中的位置if (mLuckAnimationEndListener != null) {mLuckAnimationEndListener.onLuckAnimationEnd(mCurrentPosition,mPrizeDescription[mCurrentPosition]);}}});animator.start();}private void setCurrentPosition(int position) {mCurrentPosition = position;invalidate(); // 强制刷新,在 UI 线程回调 onDraw()}public void setBitmap(Bitmap[] bitmaps1, String[] name, String[] strings) {bitmaps = bitmaps1;luckyName = name;id = strings;invalidate();}/*** 选中id** @param datas*/public void setSelectId(int datas) {String selectId = datas + "";if (id != null && id.length != 0) {for (int i = 0; i < id.length; i++) {if (id[i].equals(selectId)) {selectPos = i;}}}startAnim();}/*** 用于抽奖结果回调*/public interface OnLuckAnimationEndListener {void onLuckAnimationEnd(int pos, String msg);}}

3.主界面布局文件

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="/apk/res/android"xmlns:app="/apk/res-auto"xmlns:tools="/tools"android:layout_width="match_parent"android:layout_height="wrap_content"android:background="#fff"tools:context=".MainActivity"><com.showly.luckyactivity.view.LuckyViewandroid:id="@+id/lucky_view"android:layout_width="match_parent"android:layout_height="match_parent"android:layout_marginTop="50dp"/></RelativeLayout>

4.主程序

这里比较简单,就是输出抽奖结果

public class MainActivity extends AppCompatActivity {private LuckyView luckyView;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initView();initData();initListener();}private void initView() {luckyView = findViewById(R.id.lucky_view);}private void initData() {}private void initListener() {luckyView.setLuckAnimationEndListener(new LuckyView.OnLuckAnimationEndListener() {@Overridepublic void onLuckAnimationEnd(int pos, String msg) {//打印抽奖结果Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_SHORT).show();}});}}

5,总结

实现九宫格抽奖重点在自定义View的处理,代码中有文字解析,这里就不重复说明了,还有这里抽奖展示的图片及文字是固定的,如果需要动态设置图片及文字数据的话,可以自己更改自定义控件中的逻辑。

需要Demo源码的童鞋可以在底部的公众号回复:"九宫格抽奖"即可获取。

小编整理了一份Android电子书籍,需要的童鞋关注底部公众号(longxuanzhigu)回复:“e_books” 即可获取哦!

以下是个人公众号(longxuanzhigu),之后发布的文章会同步到该公众号,方便交流学习Android知识及分享个人爱好文章:

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。