美文网首页
使用PorterDuffXfermode实现刮刮卡效果

使用PorterDuffXfermode实现刮刮卡效果

作者: duoduo7628 | 来源:发表于2021-02-05 20:34 被阅读0次
PorterDuff其实来自两个人名:Tomas Porter和Tom Duff。利用PorterDuff.Mode,我们可以实现图片的任意叠加混合。

先画圆,在画矩形,代码中间设置Xfermode。圆在下,矩形在上。SrcOver是默认状态

全重叠
部分重叠

因为准备画“部分重叠”状态,所以用ClearDstOut都可以,因为矩形即使不重叠的部分也会消失,因为Clean全重叠时会全部消失,所以选择DstOut。

刮刮卡代码

package com.noahedu.currentactivity;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;


public class GuaGuaCard extends View implements View.OnTouchListener {


    private Paint mPaint;
    private Rect mRect;
    //把画的所有点都存起来
    private Path mPath;
    private PorterDuffXfermode mPorterDuffXfermode;


    public GuaGuaCard(Context context) {
        this(context, null);
    }

    public GuaGuaCard(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public GuaGuaCard(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        init();
    }

    private void init() {

        setOnTouchListener(this);
        //关闭硬件加速(遇到显示异常,比如全黑全白时设置)
        setLayerType(LAYER_TYPE_SOFTWARE, null);
        mPorterDuffXfermode = new PorterDuffXfermode(PorterDuff.Mode.DST_OUT);
        mRect = new Rect();
        mPath = new Path();
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeWidth(dp2px(20));
        mPaint.setColor(Color.RED);
    }

    private float dp2px(int dp) {

        float density = getContext().getResources().getDisplayMetrics().density;
        int px = (int) (dp * density + 0.5f);

        return px;
    }


    private static final String TAG = "GuaGuaCard";

    private float startX;
    private float startY;
    private float endX;
    private float endY;

    @Override
    public boolean onTouch(View v, MotionEvent event) {

        int action = event.getAction();

        if (action == MotionEvent.ACTION_DOWN) {

            Log.e(TAG, "onTouch: action = MotionEvent.ACTION_DOWN");
            startX = event.getX();
            startY = event.getY();
            mPath.moveTo(startX, startY);
        } else if (action == MotionEvent.ACTION_MOVE) {

            Log.e(TAG, "onTouch: action = MotionEvent.ACTION_MOVE");

            endX = event.getX();
            endY = event.getY();
            mPath.lineTo(endX, endY);
            invalidate();

        } else if (action == MotionEvent.ACTION_UP) {

            Log.e(TAG, "onTouch: action = MotionEvent.ACTION_UP");
        }

        return true;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        Log.e(TAG, "onDraw: -------------------startX = " + startX + "  endX = " + endX);

        mPaint.setXfermode(null);
        mRect.set(0, 0, canvas.getWidth(), canvas.getHeight());
        mPaint.setColor(Color.parseColor("#FFCEE0E0"));
        mPaint.setStyle(Paint.Style.FILL);
        canvas.drawRect(mRect, mPaint);
        mPaint.setColor(Color.RED);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setXfermode(mPorterDuffXfermode);
        canvas.drawPath(mPath, mPaint);
    }
}

Activity代码

package com.noahedu.currentactivity;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;

public class MainActivity extends AppCompatActivity {

    private TextView textview;
    private Button test_button;
    private Thread thread;
    private GuaGuaCard guaguacard;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        textview = findViewById(R.id.textview);
        test_button = findViewById(R.id.test_button);
        guaguacard = findViewById(R.id.guaguacard);

        textview.setText("世有伯乐,然后有千里马。千里马常有,而伯乐不常有。故虽有名马,祗辱于奴隶人之手,骈死于槽枥之间,不以千里称也。\n" +
                "\n" +
                "马之千里者,一食或尽粟一石。食马者不知其能千里而食也。是马也,虽有千里之能,食不饱,力不足,才美不外见,且欲与常马等不可得,安求其能千里也?\n" +
                "\n" +
                "策之不以其道,食之不能尽其材,鸣之而不能通其意,执策而临之,曰:“天下无马!”呜呼!其真无马邪?其真不知马也!");
    }
}

activity_main.xml代码

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/textview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        android:textSize="16sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/test_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/app_name"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        />

    <com.noahedu.currentactivity.GuaGuaCard
        android:id="@+id/guaguacard"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:visibility="visible"
        />

</android.support.constraint.ConstraintLayout>

实现效果

参考:
Android Paint Xfermode 学习小结
Android PorterDuffXfermode使用中的一些坑

相关文章

网友评论

      本文标题:使用PorterDuffXfermode实现刮刮卡效果

      本文链接:https://www.haomeiwen.com/subject/lpsqzktx.html