11

I'm quite new to android development and at the moment I'm working with a viewpager, trying to understand how I can handle touch/tap events. I've spent all morning searching for answers to this and I can't seem to find anything that helps me.

Basically I have a viewpager with 5 fragments that all use the same layout. All I want to do is be able to detect when there's a tap/touch on the stationary view (I don't want any detection to happen when a view is being dragged).

From what I gather, there seems to be an issue with the ViewPager intercepting all touch events by default. I believe this can be dealt with by using:

myPager.requestDisallowInterceptTouchEvent(true);

At first I dabbled with OnTouchListener and tried to log whether the onTouch method was ever hit - it appeared not. I've also seen the GestureDetector class thrown about a lot as a solution to this problem but frankly I feel overwhelmed and I'm not sure which classes/interfaces I should be using here.

All I'd like to do is pick up simple touch/tap events while using a ViewPager.

At the moment I'm using a modified version of the Animation tutorial code from the android developer site. This is what I have in my MainActivity.java file:

package com.example.pbinteractive;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;

public class MainActivity extends FragmentActivity {
    /**
     * The number of pages (wizard steps) to show in this demo.
     */
    private static final int NUM_PAGES = 5;

    /**
     * The pager widget, which handles animation and allows swiping horizontally to access previous
     * and next wizard steps.
     */
    private ViewPager mPager;

    /**
     * The pager adapter, which provides the pages to the view pager widget.
     */
    private PagerAdapter mPagerAdapter;

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

        // Instantiate a ViewPager and a PagerAdapter.
        mPager = (ViewPager) findViewById(R.id.pager);
        mPagerAdapter = new ScreenSlidePagerAdapter(getSupportFragmentManager());
        mPager.setAdapter(mPagerAdapter);       
    }   

    /**
     * A simple pager adapter that represents 5 {@link ScreenSlidePageFragment} objects, in
     * sequence.
     */
    private class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter {
        public ScreenSlidePagerAdapter(FragmentManager fm) {
            super(fm);
        }        

        @Override
        public Fragment getItem(int position) {
            return MyPageFragment.create(position);
        }

        @Override
        public int getCount() {
            return NUM_PAGES;
        }
    }   
}

And this is what I have in my MyPageFragment.java file:

package com.example.pbinteractive;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;

public class MyPageFragment extends Fragment implements OnTouchListener {
    /**
     * The argument key for the page number this fragment represents.
     */
    public static final String ARG_PAGE = "page";

    /**
     * The fragment's page number, which is set to the argument value for {@link #ARG_PAGE}.
     */
    private int mPageNumber;

    /**
     * Factory method for this fragment class. Constructs a new fragment for the given page number.
     */
    public static MyPageFragment create(int pageNumber) {
        MyPageFragment fragment = new MyPageFragment();
        Bundle args = new Bundle();
        args.putInt(ARG_PAGE, pageNumber);
        fragment.setArguments(args);
        return fragment;
    }

    public MyPageFragment() {
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mPageNumber = getArguments().getInt(ARG_PAGE);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        // Inflate the layout containing a title and body text.
        ViewGroup rootView = (ViewGroup) inflater
                .inflate(R.layout.fragment_slide, container, false);

        // Set the title view to show the page number.
        //((TextView) rootView.findViewById(android.R.id.text1)).setText(
        //        getString(R.string.title_template_step, mPageNumber + 1));

        return rootView;
    }

    /**
     * Returns the page number represented by this fragment object.
     */
    public int getPageNumber() {
        return mPageNumber;
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        // TODO Auto-generated method stub
        return false;
    }   
}

FYI I've checked both of these resources, as they often seem to be cited as the best solution to the problem I'm facing (from what I can gather):

android: ViewPager and HorizontalScrollVIew

Fling gesture detection on grid layout

But I haven't been able to get much help from them. Like I said I'm quite new to working with android so I'd really like to just get familiar with the basics!

Thanks

EDIT: Just to clarify, I'd like to pick up the touch events within each fragment, since once I get past this hurdle I'd like some fragments to have touch events working while others will just display unresponsive content.

Community
  • 1
  • 1
alimac83
  • 2,346
  • 6
  • 34
  • 50

1 Answers1

9
 @Override
 public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
// Inflate the layout containing a title and body text.
ViewGroup rootView = (ViewGroup) inflater
                .inflate(R.layout.fragment_slide, container, false);
LinearLayout layout = (LinearLayout)rootView.findViewById(R.id.layout)// get your root  layout
layout.setOnTouchListener(new OnTouchListener() {

        @Override
        public boolean onTouch(View v, MotionEvent event) {
            Log.v(null, "TOUCH EVENT"); // handle your fragment number here
            return false;
        }
    });
      return rootView;
    }
Yahor10
  • 2,123
  • 1
  • 13
  • 13
  • Thanks Yahor! It's picking up the touch event now but it's also picking it up on the swipe. Is it possible to ignore the touch when the view is being swiped but detect it when the view is stationary? – alimac83 Nov 27 '12 at 12:22
  • 4
    Handle MotionEvent code if(event == MotionEvent.ACTION_DOWN)// handle,if(event == MotionEvent.MOVE) // skip – Yahor10 Nov 27 '12 at 12:24
  • 2
    How can you differentiate different actions for swiping to the right vs left – Lion789 Mar 05 '14 at 20:28
  • Get point and when your x-coordinates increase from this point so it right,otherwise it is left. P.s there are ways to determinate right and left movement – Yahor10 Mar 10 '14 at 10:41
  • @Yahor10 but in onTouch, you get only MotionEvent single object then how can you take difference? – VVB Apr 12 '17 at 07:32