Search code examples
javaandroidandroid-fragmentsandroid-viewpagerdrawerlayout

onSwipe Event is not Triggered inside a ViewPager


Please see update below I have a ViewPager, the first page(fragment) of it has a DrawerLayout that implements a SimpleOnGestureListener that listens to onSwipe event. The purpose of the onSwipe event inside the DrawerLayout(fragment) is to listen if the user swipes to left and right which triggers the opening and closing of the drawer. enter image description here

The problem is by the time, I swipe to left or right the ViewPager's page changes instead of triggering the opening and closing of the Drawer.

Is there a way to disable temporarily the swiping of the ViewPager, while its current view is on DrawerLayout so that it can listen to the left and right event?

If the Drawer is opened and If I swipe the screen to the right then that's the time the page changes. I've been struggling with this for a couple of days now.

I this possible inside the DrawerLayoutFragment?

if(MainClass_ViewPager.getView == getActivity().getView)
MainClass_ViewPager.isEnabled(false)

onSwipe of `DrawerLayoutFragment`  is triggered

Drawer

public class DrawerLayoutFragment extends Fragment implements SimpleGestureListener{

   private SimpleGestureFilter detector; 

    private DrawerLayout mDrawerLayout;

    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    public void onCreate (Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);


    }

    @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        return rootView;
    }

     public boolean onCreateOptionsMenu(Menu menu) {
            MenuInflater inflater = getActivity().getMenuInflater();
           inflater.inflate(R.menu.main_menu, menu);
            return getActivity().onCreateOptionsMenu(menu);
        }

     @Override
        public boolean onOptionsItemSelected(MenuItem item) {

             // The action bar home/u p action should open or close the drawer.
             // ActionBarDrawerToggle will take care of this.
            if (mDrawerToggle.onOptionsItemSelected(item)) {

                return true;
            }
            // Handle action buttons
            switch(item.getItemId()) {
            default:
                Log.d("onOptionsItemSelected", "inside");
                return super.onOptionsItemSelected(item);
            }
        }


     protected void onPostCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            // Sync the toggle state after onRestoreInstanceState has occurred.
            mDrawerToggle.syncState();
        }

     @Override
        public void onConfigurationChanged(Configuration newConfig) {
            super.onConfigurationChanged(newConfig);
            // Pass any configuration change to the drawer toggls
            mDrawerToggle.onConfigurationChanged(newConfig);
        }



    /* The click listner for ListView in the navigation drawer */
    private class DrawerItemClickListener implements ListView.OnItemClickListener {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            selectItem(position);

            Log.d("DrawerItemClickListener", "inside");
        }
    }

    private void selectItem(int position) {

   }

    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    public void setTitle(CharSequence title) {
        mTitle = title;
        getActivity().getActionBar().setTitle(mTitle);
    }


    //Simple Gesture
    public boolean dispatchTouchEvent(MotionEvent me){ 
      this.detector.onTouchEvent(me);
     return getActivity().dispatchTouchEvent(me); 
    }

    @Override
    public void onSwipe(int direction) {
        Log.d("onSwipe", "onSwipe");

    }

    @Override
    public void onDoubleTap() {
        // TODO Auto-generated method stub
        Log.d("onDoubleTap", "onDoubleTap");

    }

}

UPDATE - this is what I got so far. I have a parent ViewPager that has a child ViewPager(fragment), I can't handle the swiping of the child ViewPager because the parent one is always got swiped not giving any chance for the child one. The drawer is working, as along as I hold the left side of the screen for a sec then drag it to the right. As shown in the image above.

private void selectItem(int position) {
     Log.d("selectItem", "inside");
       // update the main content by replacing fragments
       ViewPagerConnect fragment = new ViewPagerConnect();
       Bundle args = new Bundle();
       args.putInt("position", position);
       fragment.setArguments(args);

       FragmentTransaction ft = getChildFragmentManager().beginTransaction();
                 ft.add(R.id.content_frame, fragment);
         ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
         ft.commit();

       // update selected item and title, then close the drawer
       mDrawerList.setItemChecked(position, true);
       setTitle(mPlanetTitles[position]);
       mDrawerLayout.closeDrawer(mDrawerList);
   }

---------------------------------------


public class ViewPagerConnect extends SherlockFragment{

    AppSectionsPagerAdapter mAppSectionsPagerAdapter;
     ViewPager mViewPager;
     static int position;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {

        mAppSectionsPagerAdapter = new AppSectionsPagerAdapter(getChildFragmentManager());

        position = getArguments().getInt("position");

         View rootView = inflater.inflate(R.layout.viewpager_connect, container, false);
        mViewPager = (ViewPager) rootView.findViewById(R.id.pager);
        mViewPager.setAdapter(mAppSectionsPagerAdapter);


                return rootView;

    }

    public static class AppSectionsPagerAdapter extends FragmentPagerAdapter {

        public AppSectionsPagerAdapter(FragmentManager fm) {
            super(fm);
        }


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

        @Override
        public CharSequence getPageTitle(int position) {
            return "Section: " + (position + 1);
        }


        @Override
        public Fragment getItem(int arg0) {
             switch(arg0){
             case 0:
                 PlanetFragment fragment = new PlanetFragment();
                 Bundle args = new Bundle();
                 args.putInt(PlanetFragment.ARG_PLANET_NUMBER, position);
                 fragment.setArguments(args);
                 return fragment;

             }
            return null;

        }
    }

}
----------------------------------------------
public class PlanetFragment extends SherlockFragment {

     ViewPager mViewPager;
    public static final String ARG_PLANET_NUMBER = "planet_number";

    public PlanetFragment() {
        // Empty constructor required for fragment subclasses
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_planet, container, false);
        int i = getArguments().getInt(ARG_PLANET_NUMBER);
        String planet = getResources().getStringArray(R.array.planets_array)[i];

        int imageId = getResources().getIdentifier(planet.toLowerCase(Locale.getDefault()),
                        "drawable", getActivity().getPackageName());
        ((ImageView) rootView.findViewById(R.id.image)).setImageResource(imageId);
        getActivity().setTitle(planet);
        return rootView;
    }
}
---------------------------
viewpager_connect.xml

<?xml version="1.0" encoding="utf-8"?>
  <android.support.v4.view.ViewPager
      xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/pager"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

-----------------------------------------------
fragment_planet.xml

<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/image"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#000000"
    android:gravity="center"
    android:padding="32dp" />

Solution

  • Get the demo NavDrawer here

    If you swap in a ViewPager implementation for the Planet Selection frame given in the sample code, it will work fine.

    Details:

    in 'selectItem' just get a ViewPager in the 'fragment' object that is the target of the FragmentManager transaction. That will do it and you will have the NavDrawer along with the ViewPager. Dont disable anything because it will just work.

    see the 'planetfragement' below - just swap in your ViewPager class and it will all work. Remove the planetfragment. Add your ViewPager in its place. that is all u have to do. Your 'viewpager' should be a Fragment that gets a ViewPager and hooks it up to an adapter. It implements the same interface as the Planets in the current sample. just swap it in.

    private void selectItem(int position) {
        // update the main content by replacing fragments
        Fragment fragment = new PlanetFragment();
        Bundle args = new Bundle();
        args.putInt(PlanetFragment.ARG_PLANET_NUMBER, position);
        fragment.setArguments(args);
    
        FragmentManager fragmentManager = getFragmentManager();
        fragmentManager.beginTransaction().replace(R.id.content_frame, fragment).commit();
    
        // update selected item and title, then close the drawer
        mDrawerList.setItemChecked(position, true);
        setTitle(mPlanetTitles[position]);
        mDrawerLayout.closeDrawer(mDrawerList);
    }