Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fragments overlapping with DrawerLayout/NavigationView

Using a DrawerLayout with a NavigationView and a FrameLayout I want to switch Fragments. That works great. However, if I switch too quickly, then the Fragments overlaps...

It is like executePendingTransactions() does not work.

<android.support.v4.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/drawerLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <include layout="@layout/toolbar" />

        <FrameLayout
            android:id="@+id/frameLayout"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

    </LinearLayout>

    <android.support.design.widget.NavigationView
        android:id="@+id/navigationView"
        android:layout_width="@240dp"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:choiceMode="singleChoice"
        android:divider="@color/transparent"
        android:dividerHeight="0dp"
        app:menu="@menu/navigationdrawer" />

</android.support.v4.widget.DrawerLayout>

If I switch Fragments (too) rapidly (manually or by code with a 750ms delay on my Nexus 5), I get both Fragments to overlap, with the second Fragment having the touch enabled BUT the first Fragment being on top...

The first Fragment contains an ImageView and TextViews. The second Fragment contains a TabLayout and a ViewPager (if that could have anything to day with my issue). Yes I'm using AppCompat 22.2.0 and Design 22.2.0 libraries.

If I set a background color to both, then I can only see the first Fragment, and it never changes.

I tried popBackStackImmediate(), executePendingTransactions(), remove(fragment), android:fitsSystemWindows="true", Android: fragments overlapping issue, delaying, and other things, without success.

@Override
protected void onCreate(final Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // ...

    mNavigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
        @Override
        public boolean onNavigationItemSelected(final MenuItem menuItem) {
            navigationDrawer(menuItem.getItemId());
            return true;
        }
    });

    if (savedInstanceState == null) {
        final MenuItem menuItem = mNavigationView.getMenu().getItem(0);
        if (menuItem != null) {
            navigationDrawer(menuItem.getItemId());
        }
    }
}

private void navigationDrawer(final int itemId) {
    final Fragment fragment = getFragment(itemId);
    getSupportFragmentManager().beginTrasaction()
        .replace(R.id.frameLayout, fragment)
        .addToBackStack(null)
        .commit();
    mNavigationView.getMenu().findItem(itemId).setChecked(true);
    mDrawerLayout.closeDrawer(mNavigationView);
    supportInvalidateOptionsMenu();
}

@Override
public boolean onOptionsItemSelected(final MenuItem item) {
    switch (item.getItemId()) {
        case R.id.menu_first:
        case R.id.menu_second:
        case R.id.menu_third:
            navigationDrawer(item.getItemId());
            return true;
    }
    return super.onOptionsItemSelected(item);
}

EDIT

In my onCreate() I was doing this:

if (savedInstanceState == null) {
    final MenuItem menuItem = mNavigationView.getMenu().getItem(0);
    if (menuItem != null) {
        navigationDrawer(menuItem.getItemId());
    }
}

Which turns out to make a call too rapidly. Removing this code solved my issue (temporally, see below).

I still don't know why executePendingTransactions() did not prevent such weird issue...

EDIT 2

I thought about keeping a boolean (init to false) to keep track of when a Fragment transaction takes place. I set it to true in my navigationDrawer() and to false in Fragment.onResume(). Still no go...

So: still having problem on my MainFragment that loads an image using Picasso and switching too rapidly (800ms) to another Fragment: they still overlap...

like image 473
shkschneider Avatar asked Jun 10 '15 09:06

shkschneider


1 Answers

You may try this ... It will delay your frequent click ...

private final Handler mDrawerActionHandler = new Handler();
private static final long DRAWER_CLOSE_DELAY_MS = 250;

mDrawerActionHandler.postDelayed(new Runnable() {
      @Override
      public void run() {
        // your navigation code goes here
      }
}, DRAWER_CLOSE_DELAY_MS);
like image 181
Moinkhan Avatar answered Sep 21 '22 00:09

Moinkhan