1. 程式人生 > >關於使用PorterDuff.Mode.CLEAR實現喪心病狂的高亮效果

關於使用PorterDuff.Mode.CLEAR實現喪心病狂的高亮效果

最近專案裡面要做引導頁,然後美工出圖了,看到效果圖的第一眼我覺得還是很容易的這裡寫圖片描述

抱著試一試的態度,我去看了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); }

說下原始碼的思路吧:

  1. 先把當前的View也就是ShowTipsView新增到ActivityDecorView裡面去
  2. 根據一系列條件去生成需要的showhintPoints,具體邏輯請看程式碼
  3. 最主要的使用了PorterDuff.Mode.CLEAR,實現了高亮的效果;從onDraw的原始碼可以看出,先生成一個bitmap,在拿到他的Canvas即是裡面變數temp,重要的是temp.drawCircle(x, y, radius, transparentPaint);這裡使用了CLEAR,清除畫布,如果吧這裡註釋掉之後就沒有高亮的效果了;看了感覺原來原理還是很簡單的啊!!!!
    好了原理之後了,剩下的就是Enjoy yourself !!!