Skip to content Skip to sidebar Skip to footer

Ontouchlistener For Entire Screen

I have a screen filled with buttons, but want the onTouch-method to use the entire screen's coordinates. I first tried using a RelativeLayout with an onTouchListener, but never man

Solution 1:

Sorry if I'm wrong, but I believe I've just had a similar problem. I wanted a title screen that displayed a picture and on the picture words that say "Click to go on" or something similar. I messed around for a bit and found that you can make a layout clickable.

    android:focusable="true" 
    android:id="@+id/titlescreenframe">

is in my xml file for my layout. The background image is simply in the background attribute (I realize you aren't using images)

Anyway, back in my activity

private FrameLayout fl;
    ...
    fl = (FrameLayout)findViewById(R.id.titlescreenframe);
    fl.setOnClickListener(this);

And then I use a switch statement to handle that and the buttons that are on the next layout. Here if you need it: Using Switch Statement to Handle Button Clicks

Seems this should work with other layouts as well, and I don't have literally any views on my main layout. (unless the layout itself counts as one?)

Ha! Just realized you said you found the solution. Silly timing. I'll post on the off-chance this helps someone, happy coding everyone. :)

Solution 2:

Have you tried onInterceptTouchEvent on the layout?

Solution 3:

I used dispatchTouchEvent for a similar problem. You could consider it a drop-in replacement for onTouchEvent, except that it always sends you an event, even if it's over an existing view.

Return true if you're handling the event, otherwise, be sure to call super.dispatchTouchEvent() and return its result.

As for getting screen coordinates - simply call the MotionEvent's getRawX() and getRawY() rather than getX() and getY(). Those are the absolute screen coordinates, including the action bar and all. If you want to cross-reference those with views, getLocationOnScreen is probably the easiest solution.

Solution 4:

touch event return's to child views first. and if you define onClick or onTouch listener for them, parnt view (for example fragment) will not receive any touch listener. So if you want define swipe listener for fragment in this situation, you must implement it in a new class:

package com.neganet.QRelations.fragments;

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.FrameLayout;

publicclassSwipeListenerFragmentextendsFrameLayout {
    privatefloat x1,x2;
    staticfinalint MIN_DISTANCE=150;
    private onSwipeEventDetected mSwipeDetectedListener;


    publicSwipeListenerFragment(Context context) {
        super(context);
    }

    publicSwipeListenerFragment(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    publicSwipeListenerFragment(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @OverridepublicbooleanonInterceptTouchEvent(MotionEvent ev) {
        boolean result=false;
        switch(ev.getAction())
        {
            case MotionEvent.ACTION_DOWN:
                x1 = ev.getX();
                break;
            case MotionEvent.ACTION_UP:
                x2 = ev.getX();
                floatdeltaX= x2 - x1;
                if (Math.abs(deltaX) > MIN_DISTANCE)
                {
                    if(deltaX<0)
                    {
                        result=true;
                        if(mSwipeDetectedListener!=null)
                            mSwipeDetectedListener.swipeLeftDetected();

                    }elseif(deltaX>0){
                        result=true;
                        if(mSwipeDetectedListener!=null)
                            mSwipeDetectedListener.swipeRightDetected();
                    }
                }
                break;
        }
        return result;
    }

    publicinterfaceonSwipeEventDetected
    {
        publicvoidswipeLeftDetected();
        publicvoidswipeRightDetected();

    }

    publicvoidregisterToSwipeEvents(onSwipeEventDetected listener)
    {
        this.mSwipeDetectedListener=listener;
    }
}

you can make implements for other types of Layouts completely like this. this class can detect both right and left swipe and specially it returns onInterceptTouchEvent true after detect. its important because if we don't do it some times child views maybe receive event and both of Swipe for fragment and onClick for child view (for example) runs and cause some issues. after making this class, you must change your fragment xml file:

<com.neganet.QRelations.fragments.SwipeListenerFragmentxmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:id="@+id/main_list_layout"android:clickable="true"android:focusable="true"android:focusableInTouchMode="true"android:layout_height="match_parent"tools:context="com.neganet.QRelations.fragments.mainList"android:background="@color/main_frag_back"><!-- TODO: Update blank fragment layout --><android.support.v7.widget.RecyclerViewandroid:id="@+id/farazList"android:scrollbars="horizontal"android:layout_width="match_parent"android:layout_height="match_parent"android:layout_gravity="left|center_vertical" /></com.neganet.QRelations.fragments.SwipeListenerFragment>

you see that begin tag is the class that we made. now in fragment class:

View view=inflater.inflate(R.layout.fragment_main_list, container, false);
        SwipeListenerFragment tdView=(SwipeListenerFragment) view;
        tdView.registerToSwipeEvents(this);


and then ImplementSwipeListenerFragment.onSwipeEventDetectedinit:

        @OverridepublicvoidswipeLeftDetected() {
        Toast.makeText(getActivity(), "left", Toast.LENGTH_SHORT).show();
    }

    @OverridepublicvoidswipeRightDetected() {
        Toast.makeText(getActivity(), "right", Toast.LENGTH_SHORT).show();
    }

It's a little complicated but works perfect :)

Post a Comment for "Ontouchlistener For Entire Screen"