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 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
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.