九宫格抽奖实现 [复制链接]

2019-11-22 16:13
疯子来过 阅读:65 评论:0 赞:0
Tag:  
1.今天有这么一个需求我就是九宫格抽奖我想了一回,回去自定义画了一个,然后飘到上面来回转,就是一直画,俩层嵌套,已经实现了。
2.睡了一觉第二天我觉得不合适太消耗内存了,性能了怎么办呢,我就用移动布局的办法实现了一个。
3.到了周六日没事了,我说在改改吧,后来我用动画实现了一拨。当然下面肯定也是几个texview没有自定义,因为消耗性能。
我在网上找了半天都是直接自定义画的,要么性能卡的,要么大家可以自己看看都不太行,
package com.aquarius.customview;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.Pair;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;

import java.util.ArrayList;
import java.util.Random;

/**
 * Created by aquarius on 17-4-11.
 */
public class LotteryView extends View {

    private int mScreenWidth;   // 屏幕宽度
    private int mScreenHeight;  // 屏幕高度

    private int mSelfTotalWidth;    // 自身最大的宽度

    private static float DEFAULT_SIZE_FACTOR = 0.85f;   // 自身占用屏幕宽度的比例

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

    private Paint mInnerPaint;
    private int mInnerCircleBackgroundColor;

    private Paint mSmallCirclePaint;
    private int mSmallCircleBlueColor;
    private int mSmallCircleYellowColor;
    private int mInnerCardTextColor;


    private int mInnerCardWidth;    // 卡片宽度
    private int mInnerCardSpace;    // 卡片间隔


    private boolean mHadInitial = false;
    private ArrayList<Pair<Pair<Integer, Integer>,Pair<Integer, Integer>>> mCardPositionInfoList;
    private Context mContext;
    private AlertDialog mAlertDialog;

    private int[] mPicResId;
    private String[] mInfoResArray;
    private Rect mBounds = new Rect();
    private float mSmallInfoTextSize;
    private float mBigInfoTextSize;

    private boolean mNeedRandomTimes = false;
    private int mInvalidateInnerCardCount;
    private int mLotteryInvalidateTimes;

    private boolean mStartAnimation = false; // not real animation
    private boolean mLastEndSelected = false;
    private boolean mStartflag;
    private String  mFlag;

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

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

    public LotteryView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, attrs);
    }

    private void init(Context context, AttributeSet attrs) {
        mContext = context;
        acquireCustomAttValues(context, attrs);

        WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        DisplayMetrics dm = new DisplayMetrics();
        wm.getDefaultDisplay().getMetrics(dm);
        mScreenWidth = dm.widthPixels;
        mScreenHeight = dm.heightPixels;
        mSelfTotalWidth = mScreenWidth < mScreenHeight ?
                (int)(mScreenWidth ) : (int)(mScreenHeight);

        mSmallInfoTextSize = context.getResources().getDimension(R.dimen.lotteryview_inner_card_text_size);
        mBigInfoTextSize = context.getResources().getDimension(R.dimen.lotteryview_inner_card_big_text_size);
        mOuterCircleWidth = (int) context.getResources().getDimension(R.dimen.lotteryview_outer_circle_width);
        mInnerCardSpace   =4;//(int) context.getResources().getDimension(R.dimen.lotteryview_inner_card_blank);//卡片之间距离
        mInnerCardWidth   = (mSelfTotalWidth- getPaddingLeft() -getPaddingRight() - mOuterCircleWidth * 2 -  mInnerCardSpace * 4) / 3;

        mInnerCardTextColor = context.getResources().getColor(R.color.inner_card_text_color);

        mOuterCircleBackgroundColor = context.getResources().getColor(R.color.outer_circle_bg_color);
        mOuterCirclePaint = new Paint();
        mOuterCirclePaint.setColor(mOuterCircleBackgroundColor);
        mOuterCirclePaint.setAntiAlias(true);
        mOuterCirclePaint.setStrokeWidth(mOuterCircleWidth);
        mOuterCirclePaint.setStyle(Paint.Style.FILL);

        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);
        mOuterCirclePaint.setStyle(Paint.Style.FILL);


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

        mCardPositionInfoList = new ArrayList<>();
        initResId();
    }

    private void acquireCustomAttValues(Context context, AttributeSet attrs) {
        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.LotteryView);
        mSmallCircleBlueColor   = ta.getColor(R.styleable.LotteryView_outer_small_circle_color_default, 0);
        mSmallCircleYellowColor = ta.getColor(R.styleable.LotteryView_outer_small_circle_color_active, 0);
        mLotteryInvalidateTimes = ta.getInt(R.styleable.LotteryView_lottery_invalidate_times, 0);
        DEFAULT_SIZE_FACTOR     = ta.getFloat(R.styleable.LotteryView_self_width_size_factor, DEFAULT_SIZE_FACTOR);
        ta.recycle();
    }

    /**
     * 绘制图片
     */
    private void initResId() {
        mPicResId = new int[]{
                R.mipmap.icon_yifudaipicutbt, R.mipmap.icon_yifudaipicutbt, R.mipmap.icon_yifudaipicutbt,
                R.mipmap.icon_yifudaipicutbt, 0, R.mipmap.icon_yifudaipicutbt,
                R.mipmap.icon_yifudaipicutbt, R.mipmap.icon_yifudaipicutbt, R.mipmap.icon_yifudaipicutbt
        };

        mInfoResArray = mContext.getResources().getStringArray(R.array.jifeng_array_info);
    }


    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        //super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        setMeasuredDimension(mSelfTotalWidth, mSelfTotalWidth);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        drawInnerBackground(canvas);
        drawInnerCards(canvas);
        if ("1".equals(mFlag)){
            Log.d("otouzi","什么值:"+mStartAnimation);
            mStartAnimation=mStartflag;
            loopInnerRoundCardAnimation();
        }
    }




    /**
     *绘制背景
     * @param canvas
     */
    private void drawInnerBackground(Canvas canvas) {
        mInnerPaint.setColor(Color.parseColor("#FF5047"));
        canvas.drawRect(mOuterCircleWidth + getPaddingLeft(), mOuterCircleWidth + getPaddingTop(),
                mSelfTotalWidth - mOuterCircleWidth - getPaddingRight(),
                mSelfTotalWidth - mOuterCircleWidth - getPaddingBottom(), mInnerPaint);
    }

    private void drawInnerCards(Canvas canvas) {
        int left = 0, top = 0, right = 0, bottom = 0;
        int spaceNum = 0;
        for(int i = 0 ; i < 9 ; i++) {
            spaceNum = i % 3 + 1;
            left = mOuterCircleWidth + mInnerCardWidth * (i%3) + mInnerCardSpace * spaceNum + getPaddingLeft();
            top = mOuterCircleWidth + mInnerCardWidth * (i/3) +mInnerCardSpace * (i/3 + 1) + getPaddingTop();
            right = left + mInnerCardWidth;
            bottom = top + mInnerCardWidth;
            if(!mHadInitial) {
                mCardPositionInfoList.add(new Pair(new Pair(left, right), new Pair(top, bottom)));
            }
            drawInnerRoundCard(canvas, left, top, right, bottom, i);
        }
        mHadInitial = true;
    }

    private void drawInnerRoundCard(Canvas canvas, int left, int top, int right, int bottom, int index) {

        boolean need = switchCardColorIfNeed(index);
        //没有选中的时候

        mInnerPaint.setColor(Color.parseColor("#D8D8D8"));

        //选中的时候
        if(mStartAnimation && need) {
            mInnerPaint.setColor(mOuterCircleBackgroundColor);
            Bitmap mBitmap=BitmapFactory.decodeResource(getResources(),R.mipmap.icon_yifudaicheckbt);
     //       canvas.drawBitmap(mBitmap,left,top,mInnerPaint);
            if (index==0){
                  canvas.drawBitmap(mBitmap,left+1,top+91,mInnerPaint);
            }else if (index==1){
               canvas.drawBitmap(mBitmap,left+1,top+91,mInnerPaint);
            } else if (index==2){
               canvas.drawBitmap(mBitmap,left+1,top+91,mInnerPaint);
            } else if (index==3){
                  canvas.drawBitmap(mBitmap,left+1,top+10,mInnerPaint);
            } else if (index==5){
                  canvas.drawBitmap(mBitmap,left+1,top+10,mInnerPaint);
            }  else if (index==6){
                  canvas.drawBitmap(mBitmap,left+1,top-58,mInnerPaint);
            } else if (index==7){
                  canvas.drawBitmap(mBitmap,left+1,top-58,mInnerPaint);
            } else if (index==8){
                   canvas.drawBitmap(mBitmap,left+1,top-58,mInnerPaint);
            }


        }

        // 绘制内部小卡片
        if(index == 4) {
            mInnerPaint.setColor(Color.parseColor("#FF5047"));
        }


        if(index ==4) {
            mInnerPaint.setColor(Color.parseColor("#FF5047"));
            Bitmap bitmap=BitmapFactory.decodeResource(getResources(),R.mipmap.icon_yifudaiopen);
            int space = mInnerCardWidth / 9;
        //    canvas.drawRoundRect(left + space, top + space, right - space, bottom - space, 12, 12, mInnerPaint);
            canvas.drawBitmap(bitmap,left ,top+20,mInnerPaint);
        }
        // 绘制卡片中的图片
        int picHeight = 0;
        if (mPicResId != null && mPicResId[index] != 0) {
            Bitmap bitmap = BitmapFactory.decodeResource(mContext.getResources(),mPicResId[index]);

           if (index==0){
            canvas.drawBitmap(bitmap,left+10,top+100,mInnerPaint);
           }else if (index==1){
                     canvas.drawBitmap(bitmap,left+10,top+100,mInnerPaint);
           }else if (index==2){
                                canvas.drawBitmap(bitmap,left+10,top+100,mInnerPaint);
           }else if (index==3){
                         canvas.drawBitmap(bitmap,left+10,top+20,mInnerPaint);
           }else if (index==5){
                     canvas.drawBitmap(bitmap,left+10,top+20,mInnerPaint);
           }  else {
                canvas.drawBitmap(bitmap,left+10,top-50,mInnerPaint);
           }


        }

    }


    private boolean switchCardColorIfNeed(int index) {
        int result = mInvalidateInnerCardCount % 9;
        if((result == 0 && index == 0) || (result == 1 && index == 1) || (result == 2 && index == 2)
                || (result == 6 && index == 6)) {
            return true;
        }
        if((result == 3 && index == 5) || (result == 4 && index == 8) || (result == 5 && index == 7)
                || (result == 7 && index == 3)) {
            return true;
        }
        return false;
    }

    /**
     * 抽奖动画
     */

    private void loopInnerRoundCardAnimation() {
        if(!mStartAnimation || mLastEndSelected){
            return;
        }

        if(mInvalidateInnerCardCount == mLotteryInvalidateTimes){
            //mStartAnimation = false;
            mLastEndSelected = true;
            postInvalidate();
            postDelayed(new ResultTask(mLotteryInvalidateTimes), 200);
            return;
        }

        mInvalidateInnerCardCount++;
        postInvalidateDelayed(20);

    }

    private class ResultTask implements Runnable{
        int times;
        public ResultTask(int times) {
            this.times = times;
        }
        @Override
        public void run() {
            mInvalidateInnerCardCount = 0;//没有用
            mLastEndSelected = false;//重新开始抽奖判断
            String info = "";
            int i = times % 9;
            info = mInfoResArray[i];
            if(i == 3) info = mInfoResArray[5];
            if(i == 4) info = mInfoResArray[8];
            if(i == 5) info = mInfoResArray[7];
            if(i == 7) info = mInfoResArray[3];
            showResultDialog(mContext, info);
        }
    }



    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int x = (int) event.getX();
        int y = (int) event.getY();

        int action = event.getAction();
        switch (action) {
            case MotionEvent.ACTION_DOWN:
            break;

            case MotionEvent.ACTION_UP:
                int index = getTouchPositionInCardList(x, y);
                if(index == 5) {
                    if(mNeedRandomTimes || mLotteryInvalidateTimes == 0) {
                        mLotteryInvalidateTimes =  (new Random().nextInt(3) + 1) * 9 + new Random().nextInt(8);
                        mNeedRandomTimes = true;
                    }
                    //提示谈款
                    showReminderDialog(mContext);
                }
                break;
        }

        return true;
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        mStartAnimation = false;
        mInvalidateInnerCardCount = 0;
        mNeedRandomTimes = false;

    }

    private void showResultDialog(Context context, String result) {
        final AlertDialog.Builder builder = new AlertDialog.Builder(context);
        builder.setTitle(R.string.result_title)
                .setMessage(context.getString(R.string.result_message, result))
                .setCancelable(true)
                .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss();
                    }
                });
       builder.create().show();
    }

    private void showReminderDialog(Context context) {
        setStart("1",true);
        mStartAnimation = true;
        invalidate();
    }

    private int getTouchPositionInCardList(int x, int y) {
        if(mCardPositionInfoList != null) {
            int index = 1;
            for (Pair<Pair<Integer, Integer>,Pair<Integer, Integer>> pair : mCardPositionInfoList) {
                if(x > pair.first.first && x < pair.first.second && y > pair.second.first && y < pair.second.second) {
                    return index;
                }
                index++;
            }
        }
        return 0;
    }



    /**
     * 空间开始
     */
    public void setStart(String flag,boolean staranflag){
        mFlag=flag;
        mStartflag=staranflag;
    }


}
第二种:方式
package com.aquarius.customview;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

/**
 * 俩种实现抽奖功能,可以自己切换,这种是我喜欢的方式,其实还有第三种就是动画实现,这个比较简单
 */
public class OterActivity extends Activity {
    private TextView move;
    private TextView tvOnclik;
    private int wiht=0;
    private int height=0;
    private int spect=0;
    private int size=0;
    private int spectsize=0;
    private Handler handler=new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if (msg.what!=0){
                setMove(size);
                Toast.makeText(OterActivity.this,msg.what+":第几个",Toast.LENGTH_LONG).show();
                size++;
                if (size==8){
                    size=0;
                }
            }

        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_oter);
        move=findViewById(R.id.move);
        tvOnclik=findViewById(R.id.tv_onclick);
        wiht= (int) getResources().getDimension(R.dimen.allwitht);
        height=(int) getResources().getDimension(R.dimen.allheight);
        spect=(int) getResources().getDimension(R.dimen.spect);
        spectsize=(int) getResources().getDimension(R.dimen.spectsize);
        tvOnclik.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                new Thread(new ResultTask(12)).start();


            }
        });


    }
    private void setMove(int size){
        RelativeLayout.LayoutParams layoutParams= (RelativeLayout.LayoutParams) move.getLayoutParams();
        if (size==0){
            layoutParams.setMargins(wiht+2*spect,spect,0,0);
        }else if (size==1){
            layoutParams.setMargins(2*wiht+3*spect,spect,0,0);
        }else if (size==2){
            layoutParams.setMargins(2*wiht+3*spect,height+2*spectsize,0,0);
        }else if (size==3){
            layoutParams.setMargins(2*wiht+3*spect,2*height+3*spectsize-2,0,0);
        }else if (size==4){
            layoutParams.setMargins(wiht+2*spect,2*height+3*spectsize,0,0);
        }else if (size==5){
            layoutParams.setMargins(spect,2*height+3*spectsize,0,0);
        }else if (size==6){
            layoutParams.setMargins(spect,height+2*spectsize,0,0);
        }else if (size==7){
            layoutParams.setMargins(spect,spect,0,0);
        }

        move.requestLayout();
    }

    private class ResultTask implements Runnable{
        int times;
        public ResultTask(int times) {
            this.times = times;
        }
        @Override
        public void run() {
            for (int b=0;b<times;b++){
                try {
                    Thread.sleep(200);
                    handler.sendEmptyMessage(b);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }

        }
    }


}
最后我会一回上传demo到安卓巴士

我来说两句
您需要登录后才可以评论 登录 | 立即注册
facelist
所有评论(0)
领先的中文移动开发者社区
18620764416
7*24全天服务
意见反馈:1294855032@qq.com

扫一扫关注我们

Powered by Discuz! X3.2© 2001-2019 Comsenz Inc.( 粤ICP备15117877号 )