Creating a Custom View in Android: A Step-by-Step Guide

Adi Mizrahi
CodeX
Published in
3 min readMay 6, 2024

Introduction

Are you a junior Android developer looking to level up your skills and add some custom flair to your projects? In this tutorial, we’ll walk through the process of creating a custom view in Android from scratch. Specifically, we’ll dive into creating a “Reveal Image View,” where users can slide between two images to reveal one or the other. Let’s get started!

Step 1: Setting up the Project

Before diving into coding, let’s set up our Android project. Open Android Studio and create a new project with an empty activity. We’ll name our project “CustomRevealImageView.”

Step 2: Creating the Custom View Class

In Android, custom views are subclasses of existing view classes. To create our Reveal Image View, we’ll create a new Java class called RevealImageView. This class will extend AppCompatImageView, providing us with the necessary functionality for displaying images.

// RevealImageView.java

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.MotionEvent;
import androidx.appcompat.widget.AppCompatImageView;

public class RevealImageView extends AppCompatImageView {

// Member variables
private Bitmap leftImage;
private Bitmap rightImage;
private Paint paint;
private float pct = 0.5f;

// Constructors
public RevealImageView(Context context) {
super(context);
init();
}

public RevealImageView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}

public RevealImageView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}

// Initialization method
private void init() {
paint = new Paint();
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
}

// Setters for left and right images
public void setLeftImage(Bitmap bitmap) {
this.leftImage = bitmap;
invalidate();
}

public void setRightImage(Bitmap bitmap) {
this.rightImage = bitmap;
invalidate();
}

// Touch event handling
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_MOVE:
float x = event.getX();
pct = x / getWidth();
invalidate();
return true;
}
return super.onTouchEvent(event);
}

// Drawing the images and slider
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);

if (leftImage != null && rightImage != null) {
int width = getWidth();
int height = getHeight();

// Draw left image
Rect leftSrc = new Rect(0, 0, (int) (width * pct), height);
Rect leftDst = new Rect(0, 0, (int) (width * pct), height);
canvas.drawBitmap(leftImage, leftSrc, leftDst, null);

// Draw right image
Rect rightSrc = new Rect((int) (width * pct), 0, width, height);
Rect rightDst = new Rect((int) (width * pct), 0, width, height);
canvas.drawBitmap(rightImage, rightSrc, rightDst, null);

// Draw the slider line
paint.setXfermode(null);
paint.setColor(0xFFFFFFFF);
paint.setAlpha(128);
canvas.drawRect(width * pct - 2, 0, width * pct + 2, height, paint);
}
}
}

Step 3: Integrating the Custom View into XML Layout

Now that we have our RevealImageView class ready, let's integrate it into our XML layout file.

<!-- activity_main.xml -->
<?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"
android:layout_width="match_parent"
android:layout_height="match_parent">

<com.cloudinary.cloudinarysampleapp.helpers.views.RevealImageView
android:id="@+id/revealImageView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/black"
android:layout_margin="16dp"/>

</androidx.constraintlayout.widget.ConstraintLayout>

Step 4: Using the Custom View in Java Code

Let’s now use our custom RevealImageView in our Java code. We'll load two images and set them to the RevealImageView.

// MainActivity.java

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {

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

RevealImageView revealImageView = findViewById(R.id.revealImageView);

// Load left and right images
Bitmap leftBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.left_image);
Bitmap rightBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.right_image);

// Set images to RevealImageView
revealImageView.setLeftImage(leftBitmap);
revealImageView.setRightImage(rightBitmap);
}
}

Step 5: Testing

Before we conclude, let’s run the app and ensure our custom RevealImageView works as expected. Slide your finger horizontally on the view to reveal one image over the other.

Conclusion

Congratulations! You’ve successfully created a custom Reveal Image View in Android. You’ve learned how to create a custom view class, integrate it into XML layout files, and use it in your Java code. Custom views like these can add unique and interactive elements to your Android apps, enhancing the user experience.

--

--