Scratch card like google pay reward card in android application

Hi Guys, Welcome to Proto Coders Point, In this Android Tutorial we will implement Scratch Card in android studio,  an android app same like Google Pay(Tez app) reward scratch card in our android application.

I found the Source code in GitHub developed by Shubham Mahalkar, Credit to him

Result of the Final built app

scratch card reward google pay android studio

Scratch Card like google pay reward card in android studio

Step 1 : Create a new android project in android studio

offcourse you need to create a new android project or open any of your existing android project where you want to add Scratch card reward.

Give a name to your android project as “Scratch Card Google Pay” or anything as per you choice.

Step 2 : create a attrs xml file in values folder

go to res->values-> and create new file name it as attrs.xml

then copy paste below lines of code

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <declare-styleable name="ScratchCard">
        <attr
            name="scratchDrawable"
            format="reference|color" />
        <attr
            name="scratchWidth"
            format="dimension" />
    </declare-styleable>

</resources>

Step 3 : Create a java class ScratchCard.java

This class is used to create Graphical objects in xml layout. Even this class will keep track of any event happens such as user scratch the card to check his reward points.

We will implement this class in xml file to display a square box which we will be able to check the google pay reward point after the card is been scratched.

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

class ScratchCard extends View {
    private Drawable mDrawable;
    private float mScratchWidth;
    private Bitmap mBitmap;
    private Canvas mCanvas;
    private Path mPath;
    private Paint mInnerPaint;
    private Paint mOuterPaint;
    private OnScratchListener mListener;

    public interface OnScratchListener {
        void onScratch(ScratchCard scratchCard, float visiblePercent);
    }

    public ScratchCard(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        resolveAttr(context, attrs);
    }

    public ScratchCard(Context context, AttributeSet attrs) {
        super(context, attrs);
        resolveAttr(context, attrs);
    }

    public ScratchCard(Context context) {
        super(context);
        resolveAttr(context, null);
    }

    private void resolveAttr(Context context, AttributeSet attrs) {
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.ScratchCard);
        mDrawable = typedArray.getDrawable(R.styleable.ScratchCard_scratchDrawable);
        mScratchWidth = typedArray.getDimension(R.styleable.ScratchCard_scratchWidth, Utils.dipToPx(context, 70));
        typedArray.recycle();
    }

    public void setOnScratchListener(OnScratchListener listener) {
        mListener = listener;
    }

    @Override
    protected void onSizeChanged(int width, int height, int oldWidth, int oldHeight) {
        super.onSizeChanged(width, height, oldWidth, oldHeight);

        if (mBitmap != null)
            mBitmap.recycle();

        mBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        mCanvas = new Canvas(mBitmap);

        if (mDrawable != null) {
            mDrawable.setBounds(0, 0, mBitmap.getWidth(), mBitmap.getHeight());
            mDrawable.draw(mCanvas);
        } else {
            mCanvas.drawColor(0xFFEC7063);
        }

        if (mPath == null) {
            mPath = new Path();
        }

        if (mInnerPaint == null) {
            mInnerPaint = new Paint();
            mInnerPaint.setAntiAlias(true);
            mInnerPaint.setDither(true);
            mInnerPaint.setStyle(Paint.Style.STROKE);
            mInnerPaint.setFilterBitmap(true);
            mInnerPaint.setStrokeJoin(Paint.Join.ROUND);
            mInnerPaint.setStrokeCap(Paint.Cap.ROUND);
            mInnerPaint.setStrokeWidth(mScratchWidth);
            mInnerPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
        }

        if (mOuterPaint == null) {
            mOuterPaint = new Paint();
        }
    }

    private float mLastTouchX;
    private float mLastTouchY;

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        float currentTouchX = event.getX();
        float currentTouchY = event.getY();

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                mPath.reset();
                mPath.moveTo(event.getX(), event.getY());
                break;
            case MotionEvent.ACTION_MOVE:
                float dx = Math.abs(currentTouchX - mLastTouchX);
                float dy = Math.abs(currentTouchY - mLastTouchY);
                if (dx >= 4 || dy >= 4) {
                    float x1 = mLastTouchX;
                    float y1 = mLastTouchY;
                    float x2 = (currentTouchX + mLastTouchX) / 2;
                    float y2 = (currentTouchY + mLastTouchY) / 2;
                    mPath.quadTo(x1, y1, x2, y2);
                }
                break;
            case MotionEvent.ACTION_UP:
                mPath.lineTo(currentTouchX, currentTouchY);
                if (mListener != null) {
                    int width = mBitmap.getWidth();
                    int height = mBitmap.getHeight();
                    int total = width * height;
                    int count = 0;
                    for (int i = 0; i < width; i += 3) {
                        for (int j = 0; j < height; j += 3) {
                            if (mBitmap.getPixel(i, j) == 0x00000000)
                                count++;
                        }
                    }
                    mListener.onScratch(this, ((float) count) / total * 9);
                }
                break;
        }

        mCanvas.drawPath(mPath, mInnerPaint);
        mLastTouchX = currentTouchX;
        mLastTouchY = currentTouchY;

        invalidate();
        return true;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        canvas.drawBitmap(mBitmap, 0, 0, mOuterPaint);
        super.onDraw(canvas);
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        if (mBitmap != null) {
            mBitmap.recycle();
            mBitmap = null;
        }
    }
}

STEP 4 : Create a new Utils.java file

Utils.java this class will help you randomly generate as number from 1 – 100 and we will be able to display in a form of rewards point some like google Play app.

Utils.java

import android.content.Context;

import java.util.Random;

public class Utils {
    static Random random = new Random();

    public static float dipToPx(Context context, float dipValue) {
        float density = context.getResources().getDisplayMetrics().density;
        return dipValue * density;
    }


    //Generate random number(Prize)
    private static String generateCodePart(int min, int max) {
        int minNumber = 1;
        int maxNumber = 100;
        return String.valueOf((random.nextInt((maxNumber - minNumber) + 1) + minNumber));
    }

    public static String generateNewCode() {
        String firstCodePart = generateCodePart(1000, 9999);
        return "You Won\nRs." + firstCodePart;
    }
}

Step 5: Now Open activity_main.xml file and add the below lines of code

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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">

    <View
        android:id="@+id/view"
        android:layout_width="300dp"
        android:layout_height="300dp"
        android:layout_gravity="center"
        android:background="@color/colorPrimaryDark"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <LinearLayout
        android:layout_width="300dp"
        android:layout_height="300dp"
        android:gravity="center"
        android:orientation="vertical"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <ImageView
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:layout_gravity="center"
            android:background="@drawable/ic_launcher_background" />

        <TextView
            android:id="@+id/codeTxt"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="15dp"
            android:gravity="center"
            android:textColor="@android:color/white"
            android:textSize="30sp" />

    </LinearLayout>

    <com.example.androidscratchcard.ScratchCard
        android:id="@+id/scratchCard"
        android:layout_width="300dp"
        android:layout_height="300dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/btnScratchAgain"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="scratch again to get reward"
        android:textColor="@android:color/black"
        android:textSize="18sp"
        android:textStyle="bold"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/view" />

</androidx.constraintlayout.widget.ConstraintLayout>

” you just need to replace with package name with your android project package name” as shown below

scratchcard android studio

Step 6 : The Final Step add code in MainActivity.java

Then Now open MainActivity.java and add the below lines of code

package com.example.androidscratchcard;

import android.os.Bundle;
import android.view.View;
import android.widget.TextView;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {

    private ScratchCard mScratchCard;
    TextView codeTxt;
    String number;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mScratchCard = findViewById(R.id.scratchCard);
        codeTxt = findViewById(R.id.codeTxt);
        number = codeTxt.getText().toString();
        codeTxt.setText(number);
        codeTxt.setText(Utils.generateNewCode());

        findViewById(R.id.btnScratchAgain).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
                startActivity(getIntent());
            }
        });
    }

    private void scratch(boolean isScratched) {
        if (isScratched) {
            mScratchCard.setVisibility(View.INVISIBLE);
        } else {
            mScratchCard.setVisibility(View.VISIBLE);
        }
    }

    private void handleListeners() {
        mScratchCard.setOnScratchListener(new ScratchCard.OnScratchListener() {
            @Override
            public void onScratch(ScratchCard scratchCard, float visiblePercent) {
                if (visiblePercent > 0.8) {
                    scratch(true);
                }
            }
        });
    }
}

You are all set to run your application, Kindly feel free to ask questions in comments  section.