Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Navigation Drawer twitches on close

I try implement Navigation Drawer (Material Design) in my app. My activity contains FrameLayout with fragments. When user select item in Navigation Drawer FrameLayout reload new fragment:

    listViewDrawer.setOnItemClickListener( new AdapterView.OnItemClickListener() {

        @Override
        public void onItemClick( AdapterView<?> parent, View view, int position, long id) {

            drawerLayout.closeDrawer( listViewDrawer); // <<<-------

            toolbar.setTitle( getResources().getString( R.string.title));

            fragmentMain = new FragmentMain();

            android.app.FragmentManager fragmentManager = getFragmentManager();
            fragmentManager.beginTransaction()
                       .replace( R.id.frameLayoutMain, ApplicationTapaKiosk.getInstance().fragmentMain)
                       .commit();

        }
     }

When I click on item all work fine. Navigation Drawer closed not smoothly but with frozen (twitches, jerks) because fragment reload in background.

How close Navigation Drawer smoothly?

like image 296
Tapa Save Avatar asked Dec 20 '22 04:12

Tapa Save


2 Answers

You have to decide whether you like more:

replacing Fragment in your FrameLayout and then closing DrawerLayout

or

closing DrawerLayout and then replacing your Fragment.

To implement the first approach:

just make those changes in your code:

listViewDrawer.setOnItemClickListener(new AdapterView.OnItemClickListener() {

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        toolbar.setTitle(getResources().getString(R.string.title));

        fragmentMain = new FragmentMain();

        android.app.FragmentManager fragmentManager = getFragmentManager();
        fragmentManager.beginTransaction()
                   .replace(R.id.frameLayoutMain, ApplicationTapaKiosk.getInstance().fragmentMain)
                   .commit();

        fragmentManager.executePendingTransactions(); // wait for the transaction to finish
        drawerLayout.closeDrawer(listViewDrawer); // call closeDrawer(...) as a last thing
    }
 }

To implement the second approach:

set some sort of flag when user clicked:

listViewDrawer.setOnItemClickListener(new AdapterView.OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        mDrawerItemClicked = true;
        drawerLayout.closeDrawer(listViewDrawer); 
    }
 }

and set DrawerLayout.DrawerListener on your DrawerLayout, like this:

drawerLayout.setDrawerListener(new DrawerLayout.DrawerListener() {
    @Override
    public void onDrawerSlide(View drawerView, float slideOffset) {
    }

    @Override
    public void onDrawerOpened(View drawerView) {
    }

    @Override
    public void onDrawerClosed(View drawerView) {
        if (mDrawerItemClicked){
            mDrawerItemClicked = false;

            toolbar.setTitle(getResources().getString(R.string.title));
            fragmentMain = new FragmentMain();
            android.app.FragmentManager fragmentManager = getFragmentManager();
            fragmentManager.beginTransaction()
                   .replace(R.id.frameLayoutMain, ApplicationTapaKiosk.getInstance().fragmentMain)
                   .commit();
        }
    }

    @Override
    public void onDrawerStateChanged(int newState) {
    }
});
like image 183
Bartek Lipinski Avatar answered Dec 27 '22 09:12

Bartek Lipinski


it takes about 200 milliseconds for the drawer to close. so you can do something like:

Handler mHandler = new Handler();

drawerLayout.closeDrawer( listViewDrawer);
mHandler.postDelayed(
                new Runnable() {
                    @Override
                    public void run () {
                        loadFragment();
                    }
                }
                , NAVDRAWER_CLOSE_DELAY // 250...for delay
        );
like image 43
royB Avatar answered Dec 27 '22 09:12

royB