setOnTouchListener not working for android Fragment
Asked Answered
T

4

5

I am using TabView and in it, I am using Fragment to load each tab. I want to get the Touch event when the user touches any of the fragments.

Fragment Code

 public MobileBankingFragment() {
    // Required empty public constructor
}


@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    context = (FragmentActivity) super.getActivity();
    view = inflater.inflate(R.layout.fragment_mobile_banking, container, false);
    alarm = new TimerReceiver();
    init(view);
    touchListener(view);
    return view;
}

private void touchListener(View view) {
    layout= (FrameLayout) view.findViewById(R.id.fragmentMobileBanking);
    layout.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            Toast.makeText(context, "you just touch the screen :-)", Toast.LENGTH_SHORT).show();
            return true;
        }
    });


    view.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            Toast.makeText(context, "you just touch the screen :-)", Toast.LENGTH_SHORT).show();
            startTheTimerForTenSecond();
            return true;
        }
    });
}

Here I try to get the touch event in two ways, one by event, another by the id of the layout, but I have had no luck. This code gives no errors, but no output either.

Tomboy answered 9/4, 2015 at 10:26 Comment(1)
Why not using OnClickListener?Ragin
C
6

It works on me:

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_take_attendance, container, false);
    touchListener(view);
    ..
}
 private void touchListener(View view) {
        view.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if (event.getActionMasked() == MotionEvent.ACTION_DOWN){
                    Toast.makeText(getActivity(), "you just touch the screen :-)", Toast.LENGTH_SHORT).show();
                }
                return true;
            }
        });
    }

It listens when you touch whole fragment

Century answered 9/4, 2015 at 11:7 Comment(13)
If I send wrong view, then application must show error or crashTomboy
@ShafiqUllahShohag i tried this code in Fragment, clicking TextView, it works. Delete first layout.setOnTouchListener() in methodCentury
lskenderov , I want to take touch event for the whole layout, like user may touch where there is no button, or text, How can I do that?Tomboy
@ShafiqUllahShohag i changed, in my case, i defined View view inside my onCreateViewCentury
@ShafiqUllahShohag changed a bit, now it is called once when touch is happenedCentury
I think the problem may be on other side, I am looking on the wrong direction . All your code is logical and it should work, but it's not working for me. Why Android Studio or App is not giving any error while it's not working ? Thanks for your time. Can you help me little more, How can i get onResume() for fragment. I see onResume() work for activity.Tomboy
onResume() has in Fragment!Century
Thanks , first fragment resume is not working, any way I did not need that.Tomboy
Hi , 2015 not work, I don't know if the fault of the material designAlfy
@user1007522 check other answer, your fragment implementation may be differentCentury
I think I found the problem. The whole fragment is a recyclerview so maybe the recyclerview is consuming the touch?Ninetieth
@Ninetieth yes, so do whatever you want to do in onclick of every item of recyclerviewCentury
but I need to know even when the user scrolls or even touches the screenNinetieth
R
3

You have to subclass ViewPager and override interceptTouchEvent() and onTouchEvent() to distinguish swipe gestures from touch fragment event. https://developer.android.com/training/gestures/viewgroup.html

Ragin answered 9/4, 2015 at 11:13 Comment(4)
It create problem when tab swipe , again it can't take touch event, It take touch when pager swiped ...Tomboy
You are right, I can get it for button click. But In my issue , I have to set a timer not only for button click , but also for other elements touch . So my logic is to getting any kind of touch in the layout to set the timer .Tomboy
Simply add an OnClickListener to the layout. OnClickListener can be set on any view (layout is a view as well) on android, not only on Buttons.Ragin
I try it, but no luck. can you give me a sample code which worked for you?Tomboy
L
0

All you need is, add ``focusable="true" and clicable="true" in your fragments xml.

Lysander answered 3/11, 2019 at 15:55 Comment(0)
B
0

Similar answer to what @sockeqwe gave, but with more details. You probably add you Fragment into some fragment container in your Application class. Say you use FrameLayout (which is derived from ViewGroup) for this purpose. Then you need to derive your own class from FrameLayout. This will do the whole job:

public static class YourOwnFrameLayout extends FrameLayout {
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        // Catch all touch events
        // You can also distinguish which event to catch (return true) or ignore (return false) 
        // using "switch" or "if" statement on ev.getActionMasked() or ev.getAction()
        return true;
    }

    @SuppressLint("ClickableViewAccessibility")
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        // Define your OnTouchEvent actions here
        // Use "switch" or "if" statement on ev.getActionMasked() or ev.getAction()

        // Dispatch event to the children
        for (int i = 0; i < getChildCount(); i++) {
            getChildAt(i).dispatchTouchEvent(event);
        }
        return true;
    }

    // Standard constructors — just pass everything
    public YourOwnFrameLayout (final Context context) {
        super(context);
    }

    public YourOwnFrameLayout (final Context context, final AttributeSet attrs) {
        super(context, attrs);
    }

    public YourOwnFrameLayout (final Context context, final AttributeSet attrs, final int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public YourOwnFrameLayout (Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

}

Then use this Customized FrameLayout (or any other Fragment container) in your Application xml (not in Fragment xml).

Buccaneer answered 12/4, 2022 at 5:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.