網上的都是自己繪製的或者圖片,我的需求是可以隨意的自定義底部和頂部的佈局。所以自己重寫一個,原理就是直接繼承 View 來實現一個刮層,讓這個刮層和圖片以及文字不產生任何依賴,再結合 FrameLayout 將刮層放置最上一層,刮層之下你想放多少圖片文字,圖片文字要怎麼佈局擺放都行。由於是FrameLayout ,刮層的上面想加內容都是可以的。如圖:
原理:刮刮卡無非就是文本,或者圖片,就是我們下邊的佈局,然後在其上繪製刮獎層,設置DST_OUT,然後把用戶觸摸繪製上去;這樣消失以後就能看到背後的獎了。
佈局
1
2
3
4
5
6
7
8
9
10
11
|
<FrameLayout android:layout_width= "350dp" android:layout_centerInParent= "true" android:layout_height= "150dp" > <include layout= "@layout/scratch_view_after" /> <coordemo.ly.com.myapplication.GuaGuaKaView android:layout_width= "match_parent" android:id= "@+id/gg1" android:layout_height= "match_parent"
/> </FrameLayout> |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
|
public
class GuaGuaKaView extends View { /** * 繪製線條的畫筆 */ private
Paint mOutterPaint = new
Paint(); /** * 遮層畫筆 */ private
Paint mMaskPaint = new
Paint(); /** * 最下面畫筆 */ private
Paint mBackPint = new
Paint(); /** * mCanvas繪製內容在其上 */ private
Bitmap mBitmap; /** * 記錄用戶繪製的Path */ private
Path mPath = new
Path(); /** * 內存中創建的Canvas */ private
Canvas mCanvas; private
boolean isComplete; private
Rect mTextBound = new
Rect(); private
String mText = "¥500,0000" ; private
int mLastX; private
int mLastY; private
int measuredWidth; private
int measuredHeight; public
GuaGuaKaView(Context context) { this (context,
null ); } public
GuaGuaKaView(Context context, AttributeSet attrs) { this (context, attrs, 0); } public
GuaGuaKaView(Context context, AttributeSet attrs,
int defStyle) { super(context, attrs, defStyle); init(); } private
void init() { mPath =
new Path(); setUpOutPaint(); setUpBackPaint(); } /** * 初始化canvas的繪製用的畫筆 */ private
void setUpBackPaint() { mBackPint.setStyle(Style.FILL); mBackPint.setTextScaleX(2f); mBackPint.setColor(Color.DKGRAY); mBackPint.setTextSize(32); mBackPint.getTextBounds(mText, 0, mText.length(), mTextBound); } @Override protected
void onDraw(Canvas canvas) { if
(!isComplete) { drawPath(); canvas.drawBitmap(mBitmap, 0, 0,
null ); }
else { this .setVisibility(GONE); } } @Override protected
void onMeasure( int
widthMeasureSpec, int
heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); measuredWidth = getMeasuredWidth(); //寬高和父view的相同 measuredHeight = getMeasuredHeight(); // 初始化bitmap mBitmap = Bitmap.createBitmap(measuredWidth, measuredHeight, Bitmap.Config.ARGB_8888); mCanvas =
new Canvas(mBitmap); mMaskPaint.setColor(Color.parseColor( "#00000000" )); //遮層透明 mMaskPaint.setStyle(Style.FILL); mCanvas.drawRoundRect( new
RectF(0, 0, measuredWidth, measuredHeight), 0, 0, mMaskPaint); mCanvas.drawBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.award_1),
null ,
new RectF(0, 0, measuredWidth, measuredHeight),
null ); //遮層 } /** * 設置畫筆的一些參數 */ private
void setUpOutPaint() { // 設置畫筆 // mOutterPaint.setAlpha(0); mOutterPaint.setColor(Color.parseColor( "#c0c0c0" )); mOutterPaint.setAntiAlias( true ); mOutterPaint.setDither( true ); mOutterPaint.setStyle(Style.STROKE); mOutterPaint.setStrokeJoin(Paint.Join.ROUND);
// 圓角 mOutterPaint.setStrokeCap(Paint.Cap.ROUND);
// 圓角 // 設置畫筆寬度 mOutterPaint.setStrokeWidth(50); } /** * 繪製線條 */ private
void drawPath() { mOutterPaint.setStyle(Style.STROKE); mOutterPaint .setXfermode( new
PorterDuffXfermode(PorterDuff.Mode.DST_OUT)); //取倆者的交集 mCanvas.drawPath(mPath, mOutterPaint); } @Override public
boolean onTouchEvent(MotionEvent event ) { int
action = event .getAction(); int
x = ( int )
event .getX(); int
y = ( int )
event .getY(); switch
(action) { case
MotionEvent.ACTION_DOWN: mLastX = x; mLastY = y; mPath.moveTo(mLastX, mLastY); break ; case
MotionEvent.ACTION_MOVE: int
dx = Math.abs(x - mLastX); int
dy = Math.abs(y - mLastY); if
(dx > 3 || dy > 3) mPath.lineTo(x, y); mLastX = x; mLastY = y; new
Thread(mRunnable).start(); break ; case
MotionEvent.ACTION_UP: new
Thread(mRunnable).start(); break ; } invalidate(); return
true ; } /** * 統計擦除區域任務 */ private
Runnable mRunnable = new
Runnable() { private
int [] mPixels; @Override public
void run() { int
w = getWidth(); int
h = getHeight(); float
wipeArea = 0; float
totalArea = w * h; Bitmap bitmap = mBitmap; mPixels =
new int [w * h]; /** * 拿到所有的像素信息 */ bitmap.getPixels(mPixels, 0, w, 0, 0, w, h); /** * 遍歷統計擦除的區域 */ for
( int
i = 0; i < w; i++) { for
( int
j = 0; j < h; j++) { int
index = i + j * w; if
(mPixels[index] == 0) { wipeArea++; } } } /** * 根據所佔百分比,進行一些操作 */ if
(wipeArea > 0 && totalArea > 0) { int
percent = ( int ) (wipeArea * 100 / totalArea); // Log.e("TAG", percent + ""); if
(percent > 50) { // Log.e("TAG", "清除區域達到50%,下面自動清除"); isComplete =
true ; postInvalidate(); } } } }; /** * 將佈局轉換成bitmap * @param addViewContent * @return */ private
Bitmap getViewBitmap(View addViewContent) { addViewContent.setDrawingCacheEnabled( true ); addViewContent.measure( View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)); addViewContent.layout(0, 0, addViewContent.getMeasuredWidth(), addViewContent.getMeasuredHeight()); addViewContent.buildDrawingCache(); Bitmap cacheBitmap = addViewContent.getDrawingCache(); Bitmap bitmap = Bitmap.createBitmap(cacheBitmap); return
bitmap; } } |