网上的都是自己绘制的或者图片,我的需求是可以随意的自定义底部和顶部的布局。所以自己重写一个,原理就是直接继承 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;
}
}
|