- 在一些應用,比如支付寶、天貓app我們經常能夠看到一些刮獎的功能效果,通過用戶手指滑動模擬出"刮刮樂"刮獎的視覺效果,讓用戶有一種刮彩票時候那種“爽”的感覺。
我們接下來就來用代碼模擬出簡配版“刮刮樂”效果,直接看效果圖先
中了40W??(YY下) 是不是跟外面彩票店的刮刮樂有點相似。其實實現這個效果很簡單,簡單到你覺得不可思議~
1.首先我們創建一個類(TicketView)讓其繼承View,然後實現父類構造方法,代碼就不貼了。
2.接下來我們要說明一個類BitmapShader ,該類是實現該效果的重點。BitmapShader繼承於Shader,其實在上面文章仿華爲手機管家“一鍵優化”Loading加載框 已經有簡單提及過該類,Shader中文翻譯着色器,其實就是給View進行繪製色彩變化的工具(你可以這麼理解。。。)
看一下BitmapShapder的構造器
/**
* Call this to create a new shader that will draw with a bitmap.
*
* @param bitmap The bitmap to use inside the shader
* @param tileX The tiling mode for x to draw the bitmap in.
* @param tileY The tiling mode for y to draw the bitmap in.
*/
public BitmapShader(@NonNull Bitmap bitmap, @NonNull TileMode tileX, @NonNull TileMode tileY) {
this(bitmap, tileX.nativeInt, tileY.nativeInt);
}
我們先寫個demo看下效果先。首先我們申明一個Paint畫筆
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(30);
mPaint.setStrokeCap(Paint.Cap.ROUND);
然後聲明一個Bitmap對象,找個背景圖
調用畫筆setShader將創建的BitmapShader設置進去
bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.ticket);
BitmapShader shader = new BitmapShader(bitmap, Shader.TileMode.CLAMP,Shader.TileMode.CLAMP);
mPaint.setShader(shader);
- 在onDraw方法裏面寫幾個文字
mPaint.setTextSize(180);
mPaint.setStyle(Paint.Style.FILL);
canvas.drawText("看到了裏面", 100, 500, mPaint);
運行後效果
我們看到了文字下面是居然是加載的那張bitmap。這個Paint似乎能夠看穿一切~
BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP)看下後面的那兩個參數。
Shader.TileMode顧名思義肯定是一種模式,到這裏就可以理解爲是一種顯示模式,進入這個類,我們會發現一共有 CLAMP, REPEAT, MIRROR三種顯示模式。方法中的第一個Shader.TileMode是X軸的顯示模式,第二個是Y軸上的顯示模式。
/**
* replicate the edge color if the shader draws outside of its
* original bounds
*/
CLAMP (0),
/**
* repeat the shader's image horizontally and vertically
*/
REPEAT (1),
/**
* repeat the shader's image horizontally and vertically, alternating
* mirror images so that adjacent images always seam
*/
MIRROR (2);
看到上面的效果,我估計很多人對“刮刮樂”效果的實現方法已經很清楚了。是的,我們可以直接使用Path,根據手指滑動來繪製path,從而達到模擬“刮出”的效果,直接看代碼~ (初始化代碼跟上面是一致的)
這裏我們用到貝塞爾曲線來繪製手指滑動軌跡,已達到順滑的目的
private Path path = new Path();
//重寫onTouchEvent
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
float x = event.getX();
float y = event.getY();
mX = x;
mY = y;
path.moveTo(x, y);
break;
case MotionEvent.ACTION_MOVE:
float x1 = event.getX();
float y1 = event.getY();
float preX = mX;
float preY = mY;
float dx = Math.abs(x1 - preX);
float dy = Math.abs(y1 - preY);
if (dx >= offset || dy >= offset) {
// 貝塞爾曲線的控制點爲起點和終點的中點
float cX = (x1 + preX) / 2;
float cY = (y1 + preY) / 2;
path.quadTo(preX, preY, cX, cY);
mX = x1;
mY = y1;
}
}
invalidate();
return true;
}
在onDraw方法裏面將path繪製出來
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawPath(path,mPaint);
}
爲了覆蓋顏色更加逼真,將其設置爲灰色
canvas.drawColor(Color.GRAY);
就能顯示是上面的"刮刮樂"效果了~是不是很簡單- -||