how to create smooth navigation drawer

前端 未结 5 477
醉话见心
醉话见心 2021-01-30 09:45

I am using this example for navigation drawer. When clicking on of item of left drawer listview it shows some images but drawerLayout closes not smoothly.

What should I

相关标签:
5条回答
  • 2021-01-30 09:56

    I don't use threads, because i need to update UI after close the navigation menu.

    Following code works for me.

    i am using fragment as member variable of class to update ui

    setFragment() function use to assign fragment to fragment variable

    In onDrawerClosed() event, i update ui.

    mDrawerList.setOnItemClickListener(new ListView.OnItemClickListener()
    {
       @Override
       public void onItemClick(AdapterView<?> parent, View view, int position, long id)
       {
           setFragment(position);
       }
    });
    
    
    // for getting fragment
    protected void setFragment(int p)
    {
        fragment = null;
    
        switch (position)
        {
            case 1:
                fragment = new DashboardFragment();                
                break;
        }
    
        if (fragment != null)
        {
            mDrawerList.setItemChecked(position, true);
            mDrawerList.setSelection(p);
            mDrawerLayout.closeDrawer(mDrawerList);
        }
    }
    
    
    // on close draw , fragment is loaded on screen
    public void onDrawerClosed(View view)
    {
       getSupportActionBar().setTitle(mTitle);
       invalidateOptionsMenu();
    
       FragmentManager fragmentManager = getSupportFragmentManager();
    
       fragmentManager.beginTransaction().replace(R.id.frame_container, fragment).commit();
    }
    
    0 讨论(0)
  • 2021-01-30 10:00

    Please review my MainActivity to make smooth DrawerLayout (open/close) with a custom topBar layout.

    public class MainActivity extends BaseActivity
        implements NavigationView.OnNavigationItemSelectedListener {
    
    Fragment fragment = null;
    Class fragmentClass = null;
    FrameLayout frameLayout;
    TextView topTilte;
    DrawerLayout drawer;
    NavigationView navigationView;
    private boolean isDrawerOpen = false;
    
    @Override
    protected void onCreateFinished() {
        setContentView(R.layout.activity_main);
    
        drawer = findViewById(R.id.drawer_layout);
        navigationView = findViewById(R.id.nav_view);
    
        topTilte = findViewById(R.id.toolbar_title);
        fragmentClass = HomeFragment.class;
        topTilte.setText(R.string.menu_home);
        setFragment();
    
        drawer.addDrawerListener(new DrawerLayout.DrawerListener() {
            @Override
            public void onDrawerSlide(@NonNull View view, float slideOffset) {
                if(slideOffset > .55 && !isDrawerOpen){
                    onDrawerOpened(view);
                    isDrawerOpen = true;
                } else if(slideOffset < .45 && isDrawerOpen) {
                    onDrawerClosed(view);
                    isDrawerOpen = false;
                }
            }
    
            @Override
            public void onDrawerOpened(@NonNull View view) {
    
            }
    
            @Override
            public void onDrawerClosed(@NonNull View view) {
    
            }
    
            @Override
            public void onDrawerStateChanged(int i) {
    
            }
        });
    
        navigationView.setNavigationItemSelectedListener(this);
    }
    
    @Override
    protected void afterInjection() {
    
    }
    
    public void openMenu(View v) {
        drawer.openDrawer(Gravity.LEFT);
    }
    
    @Override
    public void onBackPressed() {
        DrawerLayout drawer = findViewById(R.id.drawer_layout);
        if (drawer.isDrawerOpen(GravityCompat.START)) {
            drawer.closeDrawer(GravityCompat.START);
        } else {
            super.onBackPressed();
        }
    }
    
    @SuppressWarnings("StatementWithEmptyBody")
    @Override
    public boolean onNavigationItemSelected(MenuItem item) {
        // Handle navigation view item clicks here.
        int id = item.getItemId();
        if (id == R.id.nav_home) {
            topTilte.setText(R.string.menu_home);
            fragmentClass = HomeFragment.class;
            setFragment();
    
        } else if (id == R.id.nav_profile) {
    
        } 
    
        return true;
    }
    
    private void setFragment() {
    
    
        final Handler handler = new Handler();
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                try {
                    fragment = (Fragment) fragmentClass.newInstance();
                } catch (Exception e) {
                    e.printStackTrace();
                }
    
                FragmentManager fragmentManager = getSupportFragmentManager();
                fragmentManager.beginTransaction().replace(R.id.container, fragment).commit();
    
                drawer.closeDrawer(GravityCompat.START);
            }
        }, 200);
    }
    }
    
    0 讨论(0)
  • 2021-01-30 10:03

    Not sure this is the best route, but the way I solved this was to create a pending Runnable that runs in onDrawerClosed. Eg:

    private void selectItem(final int position) {
        mPendingRunnable = new Runnable() {
            @Override
            public void run() {
                // update the main content by replacing fragments
                Fragment fragment = new PlanetFragment();
                Bundle args = new Bundle();
                args.putInt(PlanetFragment.ARG_PLANET_NUMBER, position);
                fragment.setArguments(args); 
    
                FragmentManager fragmentManager = getFragmentManager();
                fragmentManager.beginTransaction().replace(R.id.content_frame, fragment).commit();
            }
        });
    
        // update selected item and title, then close the drawer
        mDrawerList.setItemChecked(position, true);
        setTitle(mPlanetTitles[position]);
        mDrawerLayout.closeDrawer(mDrawerList);
    }
    
    @Override
    public void onDrawerClosed(View view) {
        getActionBar().setTitle(mTitle);
        invalidateOptionsMenu();
    
        // If mPendingRunnable is not null, then add to the message queue 
        if (mPendingRunnable != null) {
            mHandler.post(mPendingRunnable);
            mPendingRunnable = null;
        }
    }
    
    0 讨论(0)
  • 2021-01-30 10:03

    Just posting the drawerLayout.closeDrawer() on the message queue using the handler, with a minimal delay solved my problem. Handler.postDelayed() is the key here.

     public void selectItem(int position)
        {
            switch (position)
            {
                case 0:
    
                    DashboardFragment dashboardFragment = new DashboardFragment();
                    Bundle args = new Bundle();
                    args.putInt(dashboardFragment.ARG_SCREEN_NUMBER, position);
                    dashboardFragment.setArguments(args);
    
                    FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
    
                    // Replace whatever is in the fragment_container view with this fragment,
                    // and add the transaction to the back stack so the user can navigate back
                    transaction.replace(R.id.fragmentLayout, dashboardFragment, TAG_DASHBOARD);
                    transaction.addToBackStack(null);
    
                    // Commit the transaction
                    transaction.commit();
                    getSupportFragmentManager().executePendingTransactions();
                    break;            
    
                default:
                    break;
    
            }
    
            // Highlight the selected item, update the title, and close the drawer
            drawerList.setItemChecked(position, true);
            setTitle(mScreenTitles[position]);
    
            mPendingRunnable = new Runnable()
            {
                @Override
                public void run()
                {
                    drawerLayout.closeDrawer(GravityCompat.START);
                }
            };
            mHandler.postDelayed(mPendingRunnable,50);
    
        }
    
    0 讨论(0)
  • 2021-01-30 10:13

    Works perfect

    private class DrawerItemClickListener implements ListView.OnItemClickListener {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, final int position, long id) {
                mDrawerLayout.closeDrawer(mDrawerList);
                mDrawerLayout.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        selectItem(position);
                    }
                }, 300);
            }
        }
    
    0 讨论(0)
提交回复
热议问题