Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can't close NavigationDrawer with right-to-left swipe

Tags:

I have been trying to fix the problem I've got, which is that I'm unable to close the NavigationDrawer by swiping from right-to-left, without success. Opening it by swiping from the left edge of the screen to the right is working as it should. I'm currently just trying to merge the NavigationDrawer sample and the ViewPager sample from the developer.android.com website, and everything is working, but not the closing of the navigation drawer. I hope somebody of you wants to help me.

Here's my code:

package com.example.android.effectivenavigation;  import android.app.ActionBar; import android.app.FragmentTransaction; import android.app.SearchManager; import android.content.Intent; import android.content.res.Configuration; import android.os.Bundle; import android.support.v4.app.ActionBarDrawerToggle; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentActivity; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentPagerAdapter; import android.support.v4.view.GravityCompat; import android.support.v4.view.ViewPager; import android.support.v4.widget.DrawerLayout; import android.util.Log; import android.view.LayoutInflater; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.ListView; import android.widget.TextView; import android.widget.Toast;  public class MainActivity extends FragmentActivity /*implements ActionBar.TabListener*/ {      /**      * The {@link android.support.v4.view.PagerAdapter} that will provide fragments for each of the      * three primary sections of the app. We use a {@link android.support.v4.app.FragmentPagerAdapter}      * derivative, which will keep every loaded fragment in memory. If this becomes too memory      * intensive, it may be best to switch to a {@link android.support.v4.app.FragmentStatePagerAdapter}.      */     AppSectionsPagerAdapter mAppSectionsPagerAdapter;      /**      * The {@link ViewPager} that will display the three primary sections of the app, one at a      * time.      */     private DrawerLayout mDrawerLayout;     private ListView mDrawerList;     private ActionBarDrawerToggle mDrawerToggle;      private CharSequence mDrawerTitle;     private CharSequence mTitle;     private String[] mPlanetTitles;      ViewPager mViewPager;      public void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);         setContentView(R.layout.activity_main);          mTitle = mDrawerTitle = getTitle();         mPlanetTitles = getResources().getStringArray(R.array.planets_array);         mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);         mDrawerList = (ListView) findViewById(R.id.left_drawer);          // set a custom shadow that overlays the main content when the drawer opens         mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);         // set up the drawer's list view with items and click listener         mDrawerList.setAdapter(new ArrayAdapter<String>(this,                 R.layout.drawer_list_item, mPlanetTitles));         mDrawerList.setOnItemClickListener(new DrawerItemClickListener());         // Create the adapter that will return a fragment for each of the three primary sections         // of the app.         mAppSectionsPagerAdapter = new AppSectionsPagerAdapter(getSupportFragmentManager());          // Set up the action bar.         final ActionBar actionBar = getActionBar();          // Specify that the Home/Up button should not be enabled, since there is no hierarchical         // parent.         actionBar.setDisplayHomeAsUpEnabled(true);         actionBar.setHomeButtonEnabled(true);       // ActionBarDrawerToggle ties together the the proper interactions         // between the sliding drawer and the action bar app icon         mDrawerToggle = new ActionBarDrawerToggle(                 this,                  /* host Activity */                 mDrawerLayout,         /* DrawerLayout object */                 R.drawable.ic_drawer,  /* nav drawer image to replace 'Up' caret */                 R.string.drawer_open,  /* "open drawer" description for accessibility */                 R.string.drawer_close  /* "close drawer" description for accessibility */                 ) {             public void onDrawerClosed(View view) {                 getActionBar().setTitle(mTitle);                 invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()                 Log.v("MainActivity", "Closed!");             }              public void onDrawerOpened(View drawerView) {                 getActionBar().setTitle(mDrawerTitle);                 invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()                 Log.v("MainActivity", "Opened!");             }         };         mDrawerLayout.setDrawerListener(mDrawerToggle);          mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);           // Specify that we will be displaying tabs in the action bar.         actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);          // Set up the ViewPager, attaching the adapter and setting up a listener for when the         // user swipes between sections.         mViewPager = (ViewPager) findViewById(R.id.pager);         mViewPager.setAdapter(mAppSectionsPagerAdapter);         mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {             @Override             public void onPageSelected(int position) {                 // When swiping between different app sections, select the corresponding tab.                 // We can also use ActionBar.Tab#select() to do this if we have a reference to the                 // Tab.                 //actionBar.setSelectedNavigationItem(position);             }         });          // For each of the sections in the app, add a tab to the action bar.         /*for (int i = 0; i < mAppSectionsPagerAdapter.getCount(); i++) {             // Create a tab with text corresponding to the page title defined by the adapter.             // Also specify this Activity object, which implements the TabListener interface, as the             // listener for when this tab is selected.             actionBar.addTab(                     actionBar.newTab()                             .setText(mAppSectionsPagerAdapter.getPageTitle(i))                             .setTabListener(this));         }*/     }      @Override     protected void onPostCreate(Bundle savedInstanceState) {         super.onPostCreate(savedInstanceState);         // Sync the toggle state after onRestoreInstanceState has occurred.         mDrawerToggle.syncState();     }      @Override     public void onConfigurationChanged(Configuration newConfig) {         super.onConfigurationChanged(newConfig);         mDrawerToggle.onConfigurationChanged(newConfig);     }       public CharSequence getPageTitle (int position) {         return "Hello";     }      /* 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) {          }     }      /*@Override     public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {     }      @Override     public void onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {         // When the given tab is selected, switch to the corresponding page in the ViewPager.         mViewPager.setCurrentItem(tab.getPosition());     }      @Override     public void onTabReselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {     }*/      @Override     public boolean onOptionsItemSelected(MenuItem item) {          // The action bar home/up action should open or close the drawer.          // ActionBarDrawerToggle will take care of this.         if (mDrawerToggle.onOptionsItemSelected(item)) {             return true;         }         return super.onOptionsItemSelected(item);     }      /**      * A {@link FragmentPagerAdapter} that returns a fragment corresponding to one of the primary      * sections of the app.      */     public static class AppSectionsPagerAdapter extends FragmentPagerAdapter {          public AppSectionsPagerAdapter(FragmentManager fm) {             super(fm);         }          @Override         public Fragment getItem(int i) {             switch (i) {                 case 0:                     // The first section of the app is the most interesting -- it offers                     // a launchpad into the other demonstrations in this example application.                     return new LaunchpadSectionFragment();                  default:                     // The other sections of the app are dummy placeholders.                     Fragment fragment = new DummySectionFragment();                     Bundle args = new Bundle();                     args.putInt(DummySectionFragment.ARG_SECTION_NUMBER, i + 1);                     fragment.setArguments(args);                     return fragment;             }         }          @Override         public int getCount() {             return 3;         }          @Override         public CharSequence getPageTitle(int position) {             return "Section " + (position + 1);         }     }      /**      * A fragment that launches other parts of the demo application.      */     public static class LaunchpadSectionFragment extends Fragment {          @Override         public View onCreateView(LayoutInflater inflater, ViewGroup container,                 Bundle savedInstanceState) {             View rootView = inflater.inflate(R.layout.fragment_section_launchpad, container, false);              // Demonstration of a collection-browsing activity.             rootView.findViewById(R.id.demo_collection_button)                     .setOnClickListener(new View.OnClickListener() {                         @Override                         public void onClick(View view) {                             Intent intent = new Intent(getActivity(), CollectionDemoActivity.class);                             startActivity(intent);                         }                     });              // Demonstration of navigating to external activities.             rootView.findViewById(R.id.demo_external_activity)                     .setOnClickListener(new View.OnClickListener() {                         @Override                         public void onClick(View view) {                             // Create an intent that asks the user to pick a photo, but using                             // FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET, ensures that relaunching                             // the application from the device home screen does not return                             // to the external activity.                             Intent externalActivityIntent = new Intent(Intent.ACTION_PICK);                             externalActivityIntent.setType("image/*");                             externalActivityIntent.addFlags(                                     Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);                             startActivity(externalActivityIntent);                         }                     });              return rootView;         }     }      /**      * A dummy fragment representing a section of the app, but that simply displays dummy text.      */     public static class DummySectionFragment extends Fragment {          public static final String ARG_SECTION_NUMBER = "section_number";          @Override         public View onCreateView(LayoutInflater inflater, ViewGroup container,                 Bundle savedInstanceState) {             View rootView = inflater.inflate(R.layout.fragment_section_dummy, container, false);             Bundle args = getArguments();             ((TextView) rootView.findViewById(android.R.id.text1)).setText(                     getString(R.string.dummy_section_text, args.getInt(ARG_SECTION_NUMBER)));             return rootView;         }     } } 

And my XML:

<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/drawer_layout" android:layout_width="match_parent" android:layout_height="match_parent"> <!-- As the main content view, the view below consumes the entire      space available using match_parent in both dimensions. --> <FrameLayout     android:id="@+id/content_frame"     android:layout_width="match_parent"     android:layout_height="match_parent" />  <!-- android:layout_gravity="start" tells DrawerLayout to treat      this as a sliding drawer on the left side for left-to-right      languages and on the right side for right-to-left languages.      The drawer is given a fixed width in dp and extends the full height of      the container. A solid background is used for contrast      with the content view. --> <ListView     android:id="@+id/left_drawer"     android:layout_width="240dp"     android:layout_height="match_parent"     android:layout_gravity="start"     android:choiceMode="singleChoice"     android:divider="@android:color/transparent"     android:dividerHeight="0dp"     android:background="#111"/>  <android.support.v4.view.ViewPager android:id="@+id/pager" android:layout_width="match_parent" android:layout_height="match_parent" >  <android.support.v4.view.PagerTitleStrip     android:id="@+id/pager_title_strip"     android:layout_width="match_parent"     android:layout_height="wrap_content"     android:layout_gravity="top"     android:background="#33b5e5"     android:textColor="#fff"     android:paddingTop="4dp"     android:paddingBottom="4dp" />   </android.support.v4.view.ViewPager> 

EDIT: Turns out I can close the NavigationDrawer, but not how it should be. To close it, I have to swipe from left to right, and then swipe from right to left without taking my finger off the screen. So I have to make the same gesture as opening the drawer and then instantly make the closing gesture, but thats not how it should be.

like image 588
Kevin Avatar asked Jan 26 '14 17:01

Kevin


People also ask

How do I change my navigation drawer to open from right to left?

set DrawerLayout tools:openDrawer="end" set NavigationView android:layout_gravity="end" change tag view from androidx.


1 Answers

I think the XML causes your problem. The ListView (left_drawer) should be the last element in your XML so it can overlay your content and catch your swipe gesture.

If you put your ViewPager within the FrameLayout (that's why it's called content_frame), it should work as expected.

like image 113
peitek Avatar answered Oct 12 '22 13:10

peitek