[Android] Implement onClick, onLongClick, and onTouch at the same time.

Asked 2 years ago, Updated 2 years ago, 123 views

I studied Android Studio with a basic book, but when I tried to make an application, there were many things I didn't know just with the basic book, so I'm practicing using a basic application and applying steps. I'm making a simple notepad application with a basic application Here, I'm using listview to show you what I added as a memo.

The contents of the list view will include an item class that inherits Linear Layout. This item class contains notes in the text view.

What I want to implement here is to make the item view (note content) appear when you click (on-click), the correction window appears when you click (on LongClick), or when you slide (onTouch) to the side (swipe).

Currently, onTouchEvent is in the item class that inherited the linear layout, and onClick or onLongClick is implemented as listview.setOnClickListener, listview.setLongClickListener in MainActivity, which has listview.

After some googling, I saw onTouchEvent that the return value is [True ends the current event, False ends the current event, and then moves on to the next event]. When set to True, onTouch works, but when set to True, onClick or onLongClick does not work, and onTouch does not work.

Is it because you put touch, click, and long click separately?

android-listview android

2022-09-21 20:49

1 Answers

It is correct to return false in the onTouch event. I can't give you an exact answer because I haven't seen the source, but I think it's a good idea

I don't think I received any other events because you handled touch, click, and long-click events respectively.

I will explain based on the code I wrote. Create a class for swipe processing once touched.

package com.example.user.malendar;

import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

public class SwipeDetector implements View.OnTouchListener {
    public final int HORIZONTAL_MIN_DISTANCE = 40; 
    public final int VERTICAL_MIN_DISTANCE = 80;

    public static enum Action {
        LR, // Left to Right
        RL, // Right to Left
        TB, // Top to bottom
        BT, // Bottom to Top
        None // when no action was detected
    }

    private static final String logTag = "SwipeDetector";
    private static final int MIN_DISTANCE = 100;
    private float downX, downY, upX, upY;
    private Action mSwipeDetected = Action.None;

    public boolean swipeDetected() {
        return mSwipeDetected != Action.None;
    }

    public Action getAction() {
        return mSwipeDetected;
    }

    public boolean onTouch(View v, MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN: {
                downX = event.getX();
                downY = event.getY();
                mSwipeDetected = Action.None;
                return false; // allow other events like Click to be processed
            }
            case MotionEvent.ACTION_MOVE: {
                upX = event.getX();
                upY = event.getY();

                float deltaX = downX - upX;
                float deltaY = downY - upY;

                // // horizontal swipe detection
                if (Math.abs(deltaX) > HORIZONTAL_MIN_DISTANCE) {
                    // // left or right
                    if (deltaX < 0) {
                        Log.i(logTag, "Swipe Left to Right");
                        mSwipeDetected = Action.LR;
                        return true;
                    }
                    if (deltaX > 0) {
                        Log.i(logTag, "Swipe Right to Left");
                        mSwipeDetected = Action.RL;
                        return true;
                    }
                } } else

                    // // vertical swipe detection
                    if (Math.abs(deltaY) > VERTICAL_MIN_DISTANCE) {
                        // // top or down
                        if (deltaY < 0) {
                            Log.i(logTag, "Swipe Top to Bottom");
                            mSwipeDetected = Action.TB;
                            return false;
                        }
                        if (deltaY > 0) {
                            Log.i(logTag, "Swipe Bottom to Top");
                            mSwipeDetected = Action.BT;
                            return false;
                        }
                    }
                return true;
            }
        }
        return false;
    }
}

On Android, you receive events first in the order of touch->click, so if it was a simple touch, you can return false so that you can receive a click event. And I tried to do something when I swipe left and right, so I don't need to process the click when I swipe left and right, so I return true.

And register touch listener in list view and item click listener and item long click listener. At this time, the item click listener and the long click listener must handle the touch event respectively.

final SwipeDetector swipeDetector = new SwipeDetector();
lv.setOnTouchListener(swipeDetector);
        lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                if (swipeDetector.swipeDetected()){
                    //Swipe processing 
                } } else {
                    // Click Processing
                    Log.i("Swipe","SHOOOOOORT");
                }
            }
        });
        lv.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
            @Override
            public boolean onItemLongClick(AdapterView<?> parent, View view,int position, long id) {
                if (swipeDetector.swipeDetected()){
                    // Swipe processing 
                } } else {
                    //Long-click processing 
                    Log.i("Swipe","LOOOONG");
                }
                return true;
            }
        });
    ```




2022-09-21 20:49

If you have any answers or tips


© 2024 OneMinuteCode. All rights reserved.