Changing between Navigation Drawer fragments is slow

  • Replies:28
  • OpenNot stickiedUnanswered
  • Forum posts: 26

Jun 1, 2016 2:10:58 PM via Website

I have an app with a Navigation Drawer that uses fragments for each menu item.
Each time an item is clicked, I replace the current fragment.

The problem is that it takes a long time to show the new fragment after the user clicked.
The fragment that takes the longest to load is a fragment that has also tabs inside it with child fragments.
Is there any way I can speed up the loading of the fragments? (Perhaps initializing them beforehand, if this is possible?)

Here is my code:

protected override void OnCreate(Bundle bundle)
{
    drawerLayout = FindViewById<DrawerLayout>(Resource.Id.drawer_layout);
    navigationView = FindViewById<NavigationView>(Resource.Id.nav_view);
    drawerLayout.DrawerClosed += DrawerLayout_DrawerClosed;
    var mainFab = FindViewById<FloatingActionButton>(Resource.Id.mainFab);
    mainFab.Click += MainFab_Click;

    var callFab = FindViewById<FloatingActionButton>(Resource.Id.callFab);
    callFab.Click += CallFab_Click;
    var messageFab = FindViewById<FloatingActionButton>(Resource.Id.messageFab);
    messageFab.Click += MessageFab_Click;
    // Initialize the ViewPager and set an adapter
    //var pager = FindViewById<ViewPager>(Resource.Id.pager);
    //pager.Adapter = new TabsFragmentPagerAdapter(SupportFragmentManager, fragments, titles);

    // Bind the tabs to the ViewPager
    //var tabs = FindViewById<PagerSlidingTabStrip>(Resource.Id.tabs);
    //tabs.SetViewPager(pager);

    navigationView.NavigationItemSelected += (sender, e) =>
    {
        e.MenuItem.SetChecked(true);
        //react to click here and swap fragments or navigate

        switch (e.MenuItem.ItemId)
        {
            case (Resource.Id.nav_home):
                ListItemClicked(0);
                break;

            case (Resource.Id.nav_halachot):
                ListItemClicked(1);
                break;

            case (Resource.Id.nav_times):
                ListItemClicked(2);
                break;

            case (Resource.Id.nav_siddur):
                ListItemClicked(3);
                break;
            case (Resource.Id.nav_compass):
                ListItemClicked(4);
                break;

            case (Resource.Id.nav_settings):
                ListItemClicked(5);
                break;
        }


        drawerLayout.CloseDrawers();                
    };

    if (bundle == null)
    {
        ListItemClicked(0);
        navigationView.Menu.GetItem(0).SetChecked(true);
        fragment = new HomeFragment();
        SupportFragmentManager.BeginTransaction()
        .Replace(Resource.Id.content_frame, fragment)
        .Commit();
    }
}

public override void OnBackPressed()
{

    if (drawerLayout.IsDrawerOpen((int)GravityFlags.Start))
    {
        drawerLayout.CloseDrawer((int)GravityFlags.Start);
    }
    else
    {
        base.OnBackPressed();
    }
}

private void ListItemClicked(int position)
{

    switch (position)
    {
        case 0:
            fragment = new HomeFragment();
            Title = "Home";
            SupportActionBar.Elevation = 8;
            break;
        case 1:
            fragment = new HalachaFragment();
            Title = "aaa";
            SupportActionBar.Elevation = 0;
            break;
        case 2:
            fragment = new TimesFragment();
            Title = "bbb";
            SupportActionBar.Elevation = 8;

            break;
        case 3:
            fragment = new SiddurFragment();
            Title = "ccc";
            SupportActionBar.Elevation = 8;
            break;
        case 4:
            fragment = new CompassFragment();
            Title = "ddd";
            SupportActionBar.Elevation = 8;
            break;
        case 5:
            fragment = new SettingsFragment();
            Title = "eee";
            break;
    }



}

private void DrawerLayout_DrawerClosed(object sender, DrawerLayout.DrawerClosedEventArgs e)
{
    SupportFragmentManager.BeginTransaction()
        .Replace(Resource.Id.content_frame, fragment).AddToBackStack("BACK")
        .Commit();

}

HalachaFragment.cs (The fragment that contains the tabs):

public class HalachaFragment : Fragment
{
    private ViewPager halachotPager;
    private PagerSlidingTabStrip tabs;

public HalachaFragment()
{
    this.RetainInstance = true;
}
public override void OnCreate(Bundle savedInstanceState)
{
    base.OnCreate(savedInstanceState);

    // Create your fragment here
}

public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
    // Use this to return your custom view for this Fragment

    var view = inflater.Inflate(Resource.Layout.HalachaSection, container, false);

    var fragments = new Android.Support.V4.App.Fragment[]
   {
       new HalachotFragment(),
       new BooksFragment(),
   };

    var titles = CharSequence.ArrayFromStringArray(new[]
    {
            "הלכות",
            "ספרים",
    });

    halachotPager = view.FindViewById<ViewPager>(Resource.Id.halachotPager);

    halachotPager.Adapter = new TabsFragmentPagerAdapter(this.ChildFragmentManager, fragments, titles);
    halachotPager.OffscreenPageLimit = 2;
    halachotPager.SetCurrentItem(1, true);
    // Bind the tabs to the ViewPager
    tabs = view.FindViewById<PagerSlidingTabStrip>(Resource.Id.halachotTabs);

    tabs.SetViewPager(halachotPager);

    return view;

}

}

Hope someone can help me.

Thanks.

  • Forum posts: 258

Jun 1, 2016 2:31:30 PM via Website

Hello,

Does this problem present both on real device and on the emulator?

  • Forum posts: 26

Jun 2, 2016 8:05:32 PM via Website

Thanks, but I already did that, and replaced the fragments onDrawerClosed, but it still has a lag.

  • Forum posts: 258

Jun 2, 2016 8:39:20 PM via Website

Do you use hardware acceleration? If not, add android:hardwareAccelerated="true" to the manifest.

— modified on Jun 2, 2016 8:39:52 PM

  • Forum posts: 258

Jun 2, 2016 9:00:38 PM via Website

Sometimes a lot of data transfering between your test device and PC may slow it down. Did you try to disconnect usb cable after app installation?

  • Forum posts: 26

Jun 2, 2016 9:02:48 PM via Website

Yes, it happens even when the device isn't connected.

  • Forum posts: 9

Jun 2, 2016 9:06:21 PM via Website

Well, good to read that here nice and good topic under discussion. I really like this.

  • Forum posts: 258

Jun 2, 2016 9:37:19 PM via Website

@Amitai can you post some screenshots or video of your app?

  • Forum posts: 26

Jun 2, 2016 10:43:47 PM via Website

Here's a link to a video of my app demonstrating this:

Notice that the second fragment takes the longest to load and that it shows the animation only on the second time I open it.

Thanks for your investigation and trying to help. I really appreciate it!

  • Forum posts: 258

Jun 2, 2016 10:53:25 PM via Website

  1. Why do you use two TabsFragmentPagerAdapter. There are not tabs in top level of menu, try to use simple FragmentPagerAdapter, which can load all fragments in memory and theoretically would be better.
  2. Redusing images size to minimal suitable dimensions and using of the indexed colors can help

— modified on Jun 3, 2016 7:32:17 AM

  • Forum posts: 26

Jun 4, 2016 8:29:12 PM via Website

Sorry, but I didn't quite understand you. Where am I using 'two' TabsFragmentPagerAdapter?

— modified on Jun 4, 2016 8:43:40 PM

  • Forum posts: 258

Jun 4, 2016 8:39:20 PM via Website

Oh, i haven't noticed what there are comments...

  • Forum posts: 26

Jun 4, 2016 9:15:50 PM via Website

Is there a way to initialize the fragment before opening it, so that once it is opened it will be loaded and won't lag?

  • Forum posts: 258

Jun 4, 2016 9:22:24 PM via Website

Indexed color saves a lot of memory and storage space - your layout will be inflated more quickly. Most of grafics editor can convert pics to the indexed color format.

  • Forum posts: 26

Jun 4, 2016 9:43:08 PM via Website

Thanks. I managed to minimize the lag by hardware acceleration, removing animation and unnecessary code. Although even when I don't put any image in the second fragment (the one with the tabs), there is a small lag that doesn't happen when I click on the others or when I open the same fragment a second time.

Is there a way to initialize the fragment before opening it, so that once it is opened it will be loaded and won't lag?
Or any other suggestions?

Thanks!

— modified on Jun 4, 2016 9:43:26 PM