Search code examples
androidtouchandroid-touch-event

Android - What happens when the ontouch() method of a radio button is set to true


I am trying to wrap my head around how Android handles touch events and I got confused at this. From what I know, if the onTouch() event of a view element is set to true, it means that the element is ready to handle that touch event, i.e. it consumes the touch event.
If that is so, in the code snippet below, after running, the lock, when it returned true, did not allow us to change the selection of the radio group
I'm sure its because I am not too familiar with how android touch events work. Can someone please summarize it properly for me. And explain why returning true for onTouch() events prevented us from selecting a new item.

package com.examples.customtouch;

import android.app.Activity;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.widget.CheckBox;

/**
 * Created by Dave Smith
 * Double Encore, Inc.
 * Date: 9/25/12
 * TouchListenerActivity
 */

public class TouchListenerActivity extends Activity implements View.OnTouchListener {

    /* Views to display last seen touch event */
    CheckBox mLockBox;

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

        mLockBox = (CheckBox) findViewById(R.id.checkbox_lock);

        findViewById(R.id.selection_first).setOnTouchListener(this);
        findViewById(R.id.selection_second).setOnTouchListener(this);
        findViewById(R.id.selection_third).setOnTouchListener(this);
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        /*
         * Consume the events here so the buttons cannot process them
         * if the CheckBox in the UI is checked
         */
        return mLockBox.isChecked();
    }

    private String getNameForEvent(MotionEvent event) {
        String action = "";
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                action = "ACTION_DOWN";
                break;
            case MotionEvent.ACTION_CANCEL:
                action = "ACTION_CANCEL";
                break;
            case MotionEvent.ACTION_MOVE:
                action = "ACTION_MOVE";
                break;
            case MotionEvent.ACTION_UP:
                action = "ACTION_UP";
                break;
            default:
                return null;
        }

        return String.format("%s\n%.1f, %.1f", action, event.getX(), event.getY());
    }
}

The activity's XML file

<?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="10dp">

    <CheckBox
        android:id="@+id/checkbox_lock"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Lock Selection" />

    <RadioGroup
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
        <RadioButton
            android:id="@+id/selection_first"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="First"/>
        <RadioButton
            android:id="@+id/selection_second"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="Second"/>
        <RadioButton
            android:id="@+id/selection_third"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="Third"/>
    </RadioGroup>
</LinearLayout>

Please note that this code snippet is from a project by Dave Smith called Custom Touch Examples


Solution

  • From the documentation at https://developer.android.com/reference/android/view/View.OnTouchListener.html, returning true from onTouch indicates that the event has been consumed. While I am not 100% certain, my take away is that it should not be propagated through to other elements in the hierarchy, and so the event won't be passed on to the three RadioButtons in the layout, meaning that they will not be notified of any touches.

    The onTouch method serves two purposes, to allow you to perform custom logic on that event, and to indicate whether to pass the event on to other handlers through the return value.