關於使用PorterDuff.Mode.CLEAR實現喪心病狂的高亮效果
阿新 • • 發佈:2019-01-28
最近專案裡面要做引導頁,然後美工出圖了,看到效果圖的第一眼我覺得還是很容易的
抱著試一試的態度,我去看了2個庫;然後發現ShowTipsView
不就有我的想要的效果的麼。
好吧,扯了那麼久,終於要進入主題了(你他麼真是囉嗦的啊)。
要實現這種相交區域高亮的效果,說實話以我作孽的智商是沒有想出來的,不過還有大神的程式碼可以參考,讓我們共同去了解其中的原理吧!!
// ShowTipsView
ShowTipsView showtips = new ShowTipsBuilder(this)
.setTarget(btn_two).setTitle ("A magnific button")
.setDescription("This button do nothing very well")
.setDelay(1000)
.setBackgroundAlpha(128)
.setCloseButtonColor(Color.RED)
.setCloseButtonTextColor(Color.GREEN)
.build();
showtips.show (this);
這裡看到構建ShowTipsView
使用的是Builder
模式,進去看下ShowTipsBuilder
的構造方法,裡面呼叫了
public ShowTipsBuilder(Activity activity) {
this.showtipsView = new ShowTipsView(activity);
}
那麼進去看ShowTipsView
public ShowTipsView(Context context) {
super(context);
init();
}
private void init() {
this.setVisibility(View.GONE);
this.setBackgroundColor(Color.TRANSPARENT);
this.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// DO NOTHING
// HACK TO BLOCK CLICKS
}
});
showTipsStore = new StoreUtils(getContext());
paint = new Paint();
bitmapPaint = new Paint();
circleline = new Paint();
transparentPaint = new Paint();
// it's very important,so highlight cool
porterDuffXfermode = new PorterDuffXfermode(PorterDuff.Mode.CLEAR);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
/*
* Draw circle and transparency background
*/
/*
* Since bitmap needs the canva's size, it wont be load at init()
* To prevent the DrawAllocation issue on low memory devices, the bitmap will be instantiate only when its null
*/
if (bitmap == null) {
bitmap = Bitmap.createBitmap(canvas.getWidth(), canvas.getHeight(), Bitmap.Config.ARGB_8888);
temp = new Canvas(bitmap);
}
if (background_color != 0)
paint.setColor(background_color);
else
paint.setColor(Color.parseColor("#000000"));
paint.setAlpha(background_alpha);
temp.drawRect(0, 0, temp.getWidth(), temp.getHeight(), paint);
transparentPaint.setColor(getResources().getColor(android.R.color.transparent));
transparentPaint.setXfermode(porterDuffXfermode);
int x = showhintPoints.x;
int y = showhintPoints.y;
temp.drawCircle(x, y, radius + 200, transparentPaint);
canvas.drawBitmap(bitmap, 0, 0, bitmapPaint);
circleline.setStyle(Paint.Style.STROKE);
if (circleColor != 0)
circleline.setColor(circleColor);
else
circleline.setColor(Color.RED);
circleline.setAntiAlias(true);
circleline.setStrokeWidth(3);
// canvas.drawCircle(x, y, radius, circleline);
}
說下原始碼的思路吧:
- 先把當前的
View
也就是ShowTipsView
新增到Activity
的DecorView
裡面去 - 根據一系列條件去生成需要的
showhintPoints
,具體邏輯請看程式碼 - 最主要的使用了
PorterDuff.Mode.CLEAR
,實現了高亮的效果;從onDraw
的原始碼可以看出,先生成一個bitmap
,在拿到他的Canvas
即是裡面變數temp
,重要的是temp.drawCircle(x, y, radius, transparentPaint);
這裡使用了CLEAR
,清除畫布,如果吧這裡註釋掉之後就沒有高亮的效果了;看了感覺原來原理還是很簡單的啊!!!!
好了原理之後了,剩下的就是Enjoy yourself !!!