Android Custom View And OnTouchListener Example – Move View On Touch Move

android.view.View component acts like JPanel in Swing programming. It’s just a rectangular blank area, the android.view.View component doesn’t have any content.

For built-in UI components of Android applications, they all inherit the class android.view.Viewand then render the appearance on the blank areas provided by the View component.

If you find all built-in UI components can not fit your needs, you can customize your own View component, this example will show you how to achieve this.

1. Custom View Example File Structure.

  1. This example mainly consist of three core files, they are :
  2. DrawBallView.java
  3. CustomViewActivity.java
  4. activity_custom_view.xml

    D:\WORK\DEV2QA.COM-EXAMPLE-CODE\ANDROIDEXAMPLEPROJECT\EXAMPLE
    ├─app
    │  │  .gitignore
    │  │  build.gradle
    │  │  proguard-rules.pro
    │  │
    │  └─src
    │      │
    │      ├─main
    │      │  │  AndroidManifest.xml
    │      │  │
    │      │  ├─java
    │      │  │  └─com
    │      │  │      └─dev2qa
    │      │  │          └─example
    │      │  │              │  CustomViewActivity.java
    │      │  │              │
    │      │  │              ├─view
    │      │  │              │  │  DrawBallView.java
    │      │  │
    │      │  └─res
    │      │      ├─layout
    │      │      │      activity_custom_view.xml

2. Create Custom View Component.

  1. In this example, we create a custom view which name is DrawBallView.
  2. DrawBallView can be used to draw a color ball on the screen.
  3. When your finger touches the screen and moves, the color ball will follow your finger’s move.
  4. DrawBallView class must extend android.view.View.
  5. It must override android.view.View‘s onDraw(Canvas canvas) method, and write code in this method to render a color ball.

2.1 DrawBallView.java

  1. DrawBallView.java
    package com.dev2qa.example.view;
    
    import android.content.Context;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.Paint;
    import android.view.View;
    
    import com.dev2qa.example.R;
    
    public class DrawBallView extends View {
    
        // Record current ball horizontal ordinate.
        private float currX = 100;
    
        // Record current ball vertical ordinate
        private float currY = 100;
    
        // This is the ball color.
        private int ballColor = Color.GREEN;
    
        public int getBallColor() {
            return ballColor;
        }
    
        public void setBallColor(int ballColor) {
            this.ballColor = ballColor;
        }
    
        // getter and setter method for currX and currY.
        public float getCurrX() {
            return currX;
        }
    
        public float getCurrY() {
            return currY;
        }
    
        public void setCurrX(float currX) {
            this.currX = currX;
        }
    
        public void setCurrY(float currY) {
            this.currY = currY;
        }
    
        // DrawBallView constructor.
        public DrawBallView(Context context) {
            super(context);
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
    
            // Create a new Paint object.
            Paint paint = new Paint();
    
            // Set paint color.
            paint.setColor(this.getBallColor());
    
            // Draw a circle in the canvas.
            canvas.drawCircle(currX, currY, 35, paint);
        }
    }

3. Use The Custom View Component.

  1. CustomViewActivity.java uses the DrawBallView component to render the color ball that follows the user finger touch and move.
  2. CustomViewActivity.java
    package com.dev2qa.example;
    
    import android.graphics.Color;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.view.MotionEvent;
    import android.view.View;
    import android.widget.LinearLayout;
    
    import com.dev2qa.example.view.DrawBallView;
    
    public class CustomViewActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_custom_view);
    
            // Get the root Linearlayout object.
            LinearLayout rootLayout = (LinearLayout)findViewById(R.id.idDrawBallView);
    
            // Create the DrawBallView custom view object.
            final DrawBallView drawBallView = new DrawBallView(this);
    
            //set min width and height.
            drawBallView.setMinimumWidth(500);
            drawBallView.setMinimumHeight(800);
    
            // Create a ontouch listener object.
            View.OnTouchListener onTouchListener = new View.OnTouchListener() {
                @Override
                public boolean onTouch(View view, MotionEvent motionEvent) {
    
                    // Set drawBallView currX and currY value to user finger x y ordinate value..
                    drawBallView.setCurrX(motionEvent.getX());
                    drawBallView.setCurrY(motionEvent.getY());
    
                    // Set ball color to blue.
                    drawBallView.setBallColor(Color.BLUE);
    
                    // Notify drawBallView to redraw. This will invoke DrawBallView's onDraw() method.
                    drawBallView.invalidate();
    
                    // Return true means this listener has complete process this event successfully.
                    return true;
                }
            };
    
            // Register onTouchListener object to drawBallView.
            drawBallView.setOnTouchListener(onTouchListener);
    
            // Add drawBallView object in root LinearLayout object.
            rootLayout.addView(drawBallView);
        }
    }

4. activity_custom_view.xml.

  1. The layout XML file is not complex, there is only one LinearLayout view component in it.
  2. This layout component is used to contain the DrawBallView component.
    <?xml version="1.0" encoding="utf-8"?>
    <android.support.constraint.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="com.dev2qa.example.CustomViewActivity">
    
        <LinearLayout
            android:id="@+id/idDrawBallView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="horizontal"
            tools:layout_editor_absoluteX="8dp"
            tools:layout_editor_absoluteY="8dp"></LinearLayout>
    </android.support.constraint.ConstraintLayout>

5. Run Above Example.

  1. When you execute CustomViewActivity, you may encounter the below error messages.
    Error running CustomViewActivity: The activity must be exported or contain an intent-filter.
  2. To resolve this error, you should add the intent-filter sub XML element under CustomViewActivity in the AndroidManifest.xml file as below.
    <activity android:name=".CustomViewActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
    
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

Below is the example demo video when the app runs.

If you can not watch the above video, you can see it on the youtube URL https://youtu.be/c-mxKUVozZA.

Leave a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.