Scratch card effect is popular in shopping applications. Moreover, it can be used for proving user are not a robot in some security requirements. In Android, there is no default widget in SDK which help us to build this layout easily, developer must build it yourself. Fortunately, by search on Internet, there are a lot of external libraries that making this type of view very well. Through this post, I would like to introduce one of them, called ScratchView. Maybe it's not very popular but still quite usable!
Like description in the library Github page, in order to use it, please add this dependency to your
Use it like a normal
Activity layout:
Absolutely with above, in this activity, I use a
The xml layout:
The most popular external libraries in creating scratch view may be WSScratchView (developed by winstan520), you can take a glance, it's better than the library which using in this post. But if you would like to make a simple view to quick resolved this problem, ScratchView is still useful and can deal with all your requirements.
Thank for reading this tip and finally, you can view my full project on @Github.
Import library
app/build.gradle:
compile 'com.github.cooltechworks:ScratchView:v1.0'
It's provide us two types of scratch view:ScratchImageView: A subclass ofImageViewwhich conceals the image. Scratching over the view will reveal the hidden image.ScratchTextView: A subclass ofTextViewwhich conceals the text. Scratching over the view will reveal the hidden text.
Using ScratchTextView
TextView and specially, it has setRevealListener(IRevealListener), a callback listener interface which gets called back when user reveals the text/image through onReveal() method.Activity layout:
activity_text.xml
And it's simple programmatically code:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".TextViewActivity">
<com.cooltechworks.views.ScratchTextView
android:id="@+id/text"
android:padding="@dimen/activity_horizontal_margin"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="gghghjgjgj"
android:textSize="15sp"
android:textStyle="bold" />
</RelativeLayout>
TextViewActivity.java
Running this application, we'll have this output:
package info.devexchanges.scratchview;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Toast;
import com.cooltechworks.views.ScratchTextView;
public class TextViewActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_text);
ScratchTextView scratchTextView = (ScratchTextView)findViewById(R.id.text);
assert scratchTextView != null;
scratchTextView.setRevealListener(new ScratchTextView.IRevealListener() {
@Override
public void onRevealed(ScratchTextView tv) {
Toast.makeText(TextViewActivity.this, "Revealed!", Toast.LENGTH_SHORT).show();
}
});
}
}
ScratchImageView
ScratchImageView to proving user is not a robot. The xml layout:
activity_image.xml
A simple code to confirm user action:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="@dimen/activity_horizontal_margin">
<com.cooltechworks.views.ScratchImageView
android:id="@+id/sample_image"
android:layout_width="150dp"
android:layout_height="150dp"
android:background="@android:color/white"
android:src="@drawable/nexus_6p" />
<RadioGroup
android:id="@+id/group"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<RadioButton
android:id="@+id/ip"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Iphone 6s" />
<RadioButton
android:id="@+id/nexus"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Nexus 6P" />
<RadioButton
android:id="@+id/pp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Blackberry Passport" />
<RadioButton
android:id="@+id/lu"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Nokia Lumia 930" />
</RadioGroup>
<Button
android:id="@+id/btn_confirm"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#F88A00"
android:text="Confirm"
android:textColor="@android:color/white" />
</LinearLayout>
ScratchImageActivity.java
This is output:
package info.devexchanges.scratchview;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.RadioGroup;
import android.widget.Toast;
import com.cooltechworks.views.ScratchImageView;
public class ScratchImageActivity extends AppCompatActivity {
private ScratchImageView scratchImageView;
private RadioGroup radioGroup;
private Button btnConfirm;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_image);
btnConfirm = (Button) findViewById(R.id.btn_confirm);
radioGroup = (RadioGroup) findViewById(R.id.group);
scratchImageView = (ScratchImageView) findViewById(R.id.sample_image);
//You must have this listener
scratchImageView.setRevealListener(new ScratchImageView.IRevealListener() {
@Override
public void onRevealed(ScratchImageView scratchImageView) {
Log.i("Main", "onRevealed");
}
});
btnConfirm.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (!scratchImageView.isRevealed()) {
Toast.makeText(ScratchImageActivity.this, "You mus scratch image first", Toast.LENGTH_SHORT).show();
} else if (radioGroup.getCheckedRadioButtonId() == R.id.nexus) {
Toast.makeText(ScratchImageActivity.this, "Confirmed!", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(ScratchImageActivity.this, "Failed!", Toast.LENGTH_SHORT).show();
}
}
});
}
}
Other libraries?
Thank for reading this tip and finally, you can view my full project on @Github.