0

Note: This specific problem is solved, but there are serious follow-up problems. Have a look at GestureDetector - Detect double click in GridView item's although returning false in onTouchEvent()

I want to detect double clicks on distinct items in a GridView of images. Therefore I assigned a separate OnTouchListener to each item-imageView in the getView() method of the adapter. The gestureDetector is a member variable of the adapter-class.

private GestureDetectorCompat gestureDetector;

public ImageGridViewAdapter(Context c, ArrayList<UriWrapper> startUpImages)     {
    mContext = c;
    uriManager  = new UriManager(startUpImages);
    gestureDetector = new GestureDetectorCompat(mContext, new SingleTapConfirm());
}

public View getView(final int position, View recycled, ViewGroup parent) {

    ViewHolder holder;
    if (recycled == null) {
       ..... find items by id
    } else{
        holder = (ViewHolder) recycled.getTag();
    }

    // Set listener to item image
    holder.image.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            // Always returns false, the gestureDetector does not detect anything
            boolean ret = gestureDetector.onTouchEvent(event);
            // At least the onTouch-callback gets called with the correct position
            Log.e(TAG, "onTouch returned " + ret + " at position " + position);
            return true;
        }
    });

    // Use glide library to load images into the image views
    Glide.with(mContext)....into(holder.image);
    return recycled;
}

private class SingleTapConfirm extends GestureDetector.SimpleOnGestureListener {

    @Override
    public boolean onSingleTapConfirmed(MotionEvent event) {
        Log.e(TAG, "onSingleTapConfirmed"); // never called..
        return true;
    }

    @Override
    public boolean onDoubleTap(MotionEvent e) {
        Log.e(TAG, "onDoubleTap"); // never called..
        return super.onDoubleTap(e);
    }
}

The OnTouchListener's work and get called with the correct position. However, no matter what I am doing, the methods of the GestureDetector are never called. What seems to be the issue with this code?

Update: The onTouch-callback needs to return true, now at least the GestureDetector works. However, returning true breaks the rest of the functionality, since I have a long-click-selection-mode and a global OnTouchListener for my GridView.

Second Update: Merging the item-specific OnTouchListener and the global OnTouchListener did not work properly. (swipe gestures only recognized on certain items) I hope that I can work around these two problems by creating a custom View extending ImageView and assigning the item-specific OnTouchListener there.

Community
  • 1
  • 1
Mike76
  • 899
  • 1
  • 9
  • 31

1 Answers1

1
 private GestureDetectorCompat gestureDetector;

    // in your adapter constructor
    gestureDetector = new GestureDetector(context, new SingleTapConfirm());

    public View getView(final int position, View recycled, ViewGroup parent) {

        ViewHolder holder;
        if (recycled == null) {
            .....find items by id
        } else {
            holder = (ViewHolder) recycled.getTag();
        }

        // Set listener to item image
        holder.image.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                // Use lazy initialization for the gestureDetector
                gestureDetector.onTouchEvent(event);
                // At least the onTouch-callback gets called with the correct position
                return true;
            }
        });

        // Use glide library to load images into the image views
        Glide.with(mContext)....into(holder.image);
        return recycled;
    }

    private class SingleTapConfirm extends GestureDetector.SimpleOnGestureListener {

        @Override
        public boolean onSingleTapConfirmed(MotionEvent event) {
            Log.e(TAG, "onSingleTapConfirmed"); // never called..
            return true;
        }

        @Override
        public boolean onDoubleTap(MotionEvent e) {
            Log.e(TAG, "onDoubleTap"); // never called..
            return super.onDoubleTap(e);
        }
    }

Update:

        @Override
        public boolean onTouch(View v, MotionEvent event) {anything
            gestureDetector.onTouchEvent(event);
            return true;
        }
Sohail Zahid
  • 8,099
  • 2
  • 25
  • 41
  • thanks I changed it to use this inner class and removed the lazy initialization, but it still does not detect any gestures – Mike76 Aug 23 '16 at 12:22
  • 1
    can you post the updated code in your question with constructor. – Sohail Zahid Aug 23 '16 at 12:23
  • Thanks now the gesture detector is finally working with returning true! But I still have to check out if this breaks the rest of my code – Mike76 Aug 23 '16 at 12:38
  • 1
    @Mike76 show some gratitude with tick mark and vote up. – Sohail Zahid Aug 23 '16 at 12:44
  • Now I have the problem that I already have another TouchListener over the whole GridView, that is now broken since I have to return true in the item-TouchListeners. I try to merge these two listeners somehow – Mike76 Aug 23 '16 at 12:52
  • 1
    you can post a new question with new issue but try your best first then post new question with full details and you can also send its link here as a refer Happy coding :) if you tick it will not consider in unanswered question then it could here other newbies too. – Sohail Zahid Aug 23 '16 at 12:56
  • alright I still have two issues, I can not merge the item-specific and the global TouchListener properly, and the MultiChoiceMode for the GridView is also broken – Mike76 Aug 23 '16 at 13:15
  • I might make a new issue for that and accept this, but for now I am still trying to solve these two problems and share the solution here – Mike76 Aug 23 '16 at 13:16
  • Since most people who use double click on a gridView will probably also use long click selection and swipe gestures, I want to solve this question with this fact in mind – Mike76 Aug 23 '16 at 13:19
  • I updated my question. Since multiple OnTouchListeners overlaying are not possible, I will try to extend the ImageView class to make this working without breaking the other functionality. – Mike76 Aug 23 '16 at 13:43
  • Again thank you for your help, I am still trying to solve this problem, please have a look at the new issue. that I created: http://stackoverflow.com/questions/39107566/detect-double-click-on-imageview-works-only-when-ontouchevent-returns-truemaybe – Mike76 Aug 23 '16 at 17:40