DrawerLayout's item click - When is the right time to replace fragment?

后端 未结 7 756
轻奢々
轻奢々 2020-12-07 11:16

I\'m developing an application which uses the navigation drawer pattern (With DrawerLayout).

Each click on a drawer\'s item, replaces the fragment in the main contai

相关标签:
7条回答
  • 2020-12-07 11:45

    Another solution is to create a Handler and post a delayed Runnable after you close the drawer, as shown here: https://stackoverflow.com/a/18483633/769501. The benefit with this approach is that your fragments will be replaced much sooner than they would be if you waited for DrawerListener#onDrawerClosed(), but of course the arbitrary delay doesn't 100% guarantee the drawer animation will be finished in time.

    That said, I use a 200ms delay and it works wonderfully.

    private class DrawerItemClickListener implements OnItemClickListener {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, final int position, long id) {
            drawerLayout.closeDrawer(drawerList);
            new Handler().postDelayed(new Runnable() {
                @Override
                public void run() {
                    switchFragments(position); // your fragment transactions go here
                }
            }, 200);
        }
    }
    
    0 讨论(0)
  • 2020-12-07 11:54

    If you want it smooth and without any delay, leave the drawer open and close it afterwards when returning (in the onRestart() method).

    @Override
    protected void onRestart() {
        // TODO Auto-generated method stub
        super.onRestart();
        mDrawerLayout.closeDrawer(mDrawerList);     
    }
    

    The side effect is an (speedy) animation when returning, but this might be acceptable.

    0 讨论(0)
  • 2020-12-07 11:57

    I know this question is old but I ran into the same problem and figured I would post my solution as I think it is a better implementation than adding a hardcoded delay time. What I did was use the onDrawerClosed function to verify that the drawer IS closed before doing my task.

    //on button click...
    private void displayView(int position) {
        switch (position) {
        //if item 1 is selected, update a global variable `"int itemPosition"` to be 1
        case 1:
            itemPosition = 1;
            //();
            break;
        default:
            break;
        }
    
        // update selected item and title, then close the drawer
        mDrawerList.setItemChecked(position, true);
        mDrawerList.setSelection(position);
        mDrawerLayout.closeDrawer(mDrawerList); //close drawer
    }
    

    and then in onDrawerClosed, open the corresponding activity.

    public void onDrawerClosed(View view) {
        getSupportActionBar().setTitle(mTitle);
        // calling onPrepareOptionsMenu() to show action bar icons
        supportInvalidateOptionsMenu();
        if (itemPosition == 1) {
            Intent intent = new Intent(BaseActivity.this, SecondActivity.class);
            startActivity(intent);
        }
    }
    
    0 讨论(0)
  • 2020-12-07 11:57

    Instead of delaying your item clicks which may make your app feel slow. I would just delay the closing of the mDrawerLayout. I would not use the DrawerLayout.OnDrawerListener onClose(...) either because those callbacks are so slow to be called.

    new Handler().postDelayed(new Runnable() {
        @Override
        public void run() {
            mDrawerLayout.closeDrawer(GravityCompat.START);
        }
    }, 200);
    
    0 讨论(0)
  • 2020-12-07 12:01

    Yup, couldn't agree more, performing a fragment (with view) transaction results in a layout pass which causes janky animations on views being animated, citing DrawerLayout docs:

    DrawerLayout.DrawerListener can be used to monitor the state and motion of drawer views. Avoid performing expensive operations such as layout during animation as it can cause stuttering; try to perform expensive operations during the STATE_IDLE state.

    So please perform your fragment transactions after the drawer is closed or somebody patches the support library to somehow fix that :)

    0 讨论(0)
  • 2020-12-07 12:04

    Just write your code in a handler and put 200 ms delay.

     new Handler().postDelayed(new Runnable() {
      @Override
       public void run() {
           openSelectionDrawerItem(position);          
       }
     }, 200);
    
    0 讨论(0)
提交回复
热议问题