刮刮乐自定义view

时间:2021-09-13 14:42:57

说明:该代码是参考鸿洋大神的刮刮乐自定义view来写的。

实现:刮刮乐-刮奖的效果,如下效果

刮刮乐自定义view

 

刮刮乐自定义view

下面直接放代码了:只有一个自定义view,要实现真正的功能还需要进一步封装

  1 /**
2 * 自定义view-刮刮乐
3 */
4 public class GuaGuaKaView extends View{
5
6 /**
7 * 记录用户绘制的Path
8 */
9 private Path mPath = new Path();
10
11 /**
12 * mCanvas绘制内容在其上
13 */
14 private Bitmap mBitmap;
15
16 /**
17 * 内存中创建的Canvas
18 */
19 private Canvas mCanvas;
20
21 /**
22 * 绘制线条的Paint,即用户手指绘制Path
23 */
24 private Paint mOutterPaint = new Paint();
25 private int mLastX;
26 private int mLastY;
27 private boolean isComplete=false;
28
29 private int[] mPixels;
30 private Paint mBackPint = new Paint();
31 private Rect mTextBound = new Rect();
32 private String mText = "50,000 元";
33
34
35 public GuaGuaKaView(Context context)
36 {
37 this(context, null);
38 }
39
40 public GuaGuaKaView(Context context, AttributeSet attrs)
41 {
42 this(context, attrs, 0);
43 }
44
45 public GuaGuaKaView(Context context, AttributeSet attrs, int defStyle)
46 {
47 super(context, attrs, defStyle);
48 init();
49 }
50
51 private void init()
52 {
53 mPath = new Path();
54 }
55
56 @Override
57 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
58 super.onMeasure(widthMeasureSpec, heightMeasureSpec);
59 int width=getMeasuredWidth();
60 int height=getMeasuredHeight();
61 mBitmap=Bitmap.createBitmap(width, height, Config.ARGB_8888);
62 mCanvas=new Canvas(mBitmap);
63 setUpBackPaint();
64 setUpOutPaint();
65 mCanvas.drawColor(Color.parseColor("#c0c0c0"));
66 Bitmap bitmap=BitmapFactory.decodeResource(getResources(), R.drawable.s_title);
67 mCanvas.drawBitmap(bitmap, null,new RectF(0, 0, width, height), null);
68 }
69
70 private void setUpOutPaint() {
71 //设置画笔
72 mOutterPaint.setColor(Color.RED);
73 mOutterPaint.setDither(true);//?
74 mOutterPaint.setAntiAlias(true);//设置是否有锯齿
75 mOutterPaint.setStyle(Paint.Style.STROKE);
76 mOutterPaint.setStrokeJoin(Paint.Join.ROUND);//?
77 mOutterPaint.setStrokeCap(Paint.Cap.ROUND);//?
78
79 //设置画笔宽度
80 mOutterPaint.setStrokeWidth(50);
81 }
82
83 /**
84 * 初始化canvas的绘制用的画笔
85 */
86 private void setUpBackPaint()
87 {
88 mBackPint.setStyle(Style.FILL);
89 mBackPint.setTextScaleX(2f);
90 mBackPint.setColor(Color.DKGRAY);
91 mBackPint.setTextSize(50);
92 mBackPint.getTextBounds(mText, 0, mText.length(), mTextBound);
93 }
94
95 @Override
96 protected void onDraw(Canvas canvas) {
97 drawBackText(canvas);
98 if(!isComplete){
99 drawPath();
100 canvas.drawBitmap(mBitmap, 0, 0,null);
101 }
102 }
103
104 private void drawBackText(Canvas canvas) {
105 //绘制奖项
106 canvas.drawText(mText, getWidth() / 2 - mTextBound.width() / 2,
107 getHeight() / 2 + mTextBound.height() / 2, mBackPint);
108 }
109
110 /**
111 * 绘制线头
112 */
113 private void drawPath() {
114 mOutterPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
115 mCanvas.drawPath(mPath, mOutterPaint);
116 }
117
118 @Override
119 public boolean onTouchEvent(MotionEvent event) {
120 int action=event.getAction();
121 int x=(int) event.getX();
122 int y=(int) event.getY();
123 switch (action) {
124 case MotionEvent.ACTION_DOWN:
125 mLastX=x;
126 mLastY=y;
127 mPath.moveTo(mLastX, mLastY);
128 break;
129 case MotionEvent.ACTION_MOVE:
130 int dx=Math.abs(x-mLastX);
131 int dy=Math.abs(y-mLastY);
132 if(dx>3||dy>3){
133 mPath.lineTo(x, y);
134 }
135 mLastX=x;
136 mLastY=y;
137 break;
138 case MotionEvent.ACTION_UP:
139 new Thread(mRunnable).start();
140 break;
141 default:
142 break;
143 }
144 invalidate();
145 return true;
146 }
147
148 /*
149 * 统计擦除区域的面积
150 */
151 private Runnable mRunnable=new Runnable() {
152
153 @Override
154 public void run() {
155 int w=getWidth();
156 int h=getHeight();
157 float wipeArea=0;
158 float totalArea=w*h;//总面积
159 Bitmap bitmap=mBitmap;
160 mPixels=new int[w*h];
161 //拿到所有的像素信息 ?
162 bitmap.getPixels(mPixels, 0, w, 0, 0, w, h);
163
164 //遍历统计擦除的区域
165 for(int i=0;i<w;i++){
166 for(int j=0;j<h;j++){
167 int index=i+j*w;
168 if(mPixels[index]==0){//擦除后,该点像素值为0
169 wipeArea++;
170 }
171 }
172 }
173
174 if(wipeArea>0&&totalArea>0){
175 int percent=(int)(wipeArea*100/totalArea);
176 Log.e("TAG", percent+"");
177 if(percent>70){
178 isComplete=true;
179 postInvalidate();
180 }
181 }
182 }
183 };
184
185 }

至此,完了。