Also known as Digital Rain Effect, the Matrix Effect is a classic effect featured in the Matrix series films. A green code is falling and represents the activity of the virtual reality environment of the Matrix on screen. On Android, Matrix Effect has been implemented in various applications often as a Live Wallpaper. In that tutorial, you are going to learn how to create a simple Matrix Effect.

You can discover this tutorial directly in video on Youtube :

 

1. Create a Matrix Effect custom View

First, you need to create a custom view named MatrixEffect :


package com.ssaurel.digitalraineffect;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;

import java.util.Random;

public class MatrixEffect extends View {

    private static final Random RANDOM = new Random();
    private int width, height;
    private Canvas canvas;
    private Bitmap canvasBmp;
    private int fontSize = 40;
    private int columnSize;
    private char[] cars = "+-*/!^'([])#@&?,=$€°|%".toCharArray();
    private int[] txtPosByColumn;
    private Paint paintTxt, paintBg, paintBgBmp, paintInitBg;

    public MatrixEffect(Context context, AttributeSet attrs) {
        super(context, attrs);
        paintTxt = new Paint();
        paintTxt.setStyle(Paint.Style.FILL);
        paintTxt.setColor(Color.GREEN);
        paintTxt.setTextSize(fontSize);

        paintBg = new Paint();
        paintBg.setColor(Color.BLACK);
        paintBg.setAlpha(5);
        paintBg.setStyle(Paint.Style.FILL);

        paintBgBmp = new Paint();
        paintBgBmp.setColor(Color.BLACK);

        paintInitBg = new Paint();
        paintInitBg.setColor(Color.BLACK);
        paintInitBg.setAlpha(255);
        paintInitBg.setStyle(Paint.Style.FILL);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        width = w;
        height = h;

        canvasBmp = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        canvas = new Canvas(canvasBmp);
        canvas.drawRect(0, 0, width, height, paintInitBg);
        columnSize = width / fontSize;

        txtPosByColumn = new int[columnSize + 1];

        for (int x = 0; x < columnSize; x++) {
            txtPosByColumn[x] = RANDOM.nextInt(height / 2) + 1;
        }
    }

    private void drawText() {
        for (int i = 0; i < txtPosByColumn.length; i++) {
            canvas.drawText("" + cars[RANDOM.nextInt(cars.length)], i * fontSize, txtPosByColumn[i] * fontSize, paintTxt);

            if (txtPosByColumn[i] * fontSize > height && Math.random() > 0.975) {
                txtPosByColumn[i] = 0;
            }

            txtPosByColumn[i]++;
        }
    }

    private void drawCanvas() {
        canvas.drawRect(0, 0, width, height, paintBg);
        drawText();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawBitmap(canvasBmp, 0, 0, paintBgBmp);
        drawCanvas();
        invalidate();
    }
}

First, we define the variables for the Matrix Effect with the size of the code, the size of a column, the position of the bottom text for each column and then the caracters that will be used for the code. Note that you can put the caracters you want here or why not a custom font.

In the constructor, we initialize the paint objects. To get view width and height, we override the onSizeChanged method of the View. We initialize the position of the first caracter for each column. We use a random position between the top of the screen and the middle of the screen.

Then, we define a draw text method used to draw a random caracter for each column at the position indicated by txtPosByColumn variable.

The drawCanvas method is used to draw the background of our view and then the code.

Finally, we override the onDraw method of our custom view to call the drawCanvas method and invalidate the view to force a redraw. With that call, the Matrix Effect could progress from top to bottom in infinite mode. Note that it is not the most optimized way to manage a Matrix Effect, but for a tutorial it’s sufficient.

 

2. Define the MatrixEffect View on the Layout

Now, we can define the MatrixEffect View on the layout of the Main Activity.


<!--?xml version="1.0" encoding="utf-8"?--><?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"
 tools:context="com.ssaurel.digitalraineffect.MainActivity">

 <com.ssaurel.digitalraineffect.MatrixEffect
 android:layout_width="match_parent"
 android:layout_height="match_parent" />

</RelativeLayout>

 

3. Set the layout on the Main Activity

Last step is to set the layout as content view for the Main Activity.


package com.ssaurel.digitalraineffect;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

public class MainActivity extends AppCompatActivity {

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

 

4. Demo

To enjoy the Matrix Effect, you have just to launch the application on an Android device and you should see the following effect :