Подтвердить что ты не робот

Как создать плавный навигационный ящик

Я использую этот пример для навигационного ящика. При нажатии на элемент списка списка левого ящика отображаются некоторые изображения, но drawerLayout закрывается не плавно.

Что мне следует сделать для плавного закрытия макета левого ящика после щелчка элемента списка.

4b9b3361

Ответ 1

Не уверен, что это лучший маршрут, но так, как я решил, это создать ожидающий Runnable, который работает в onDrawerClosed. Например:

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;
    }
}

Ответ 2

Отлично работает

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);
        }
    }

Ответ 3

Просто разместив drawerLayout.closeDrawer() в очереди сообщений с помощью обработчика, с минимальной задержкой решила мою проблему. Здесь используется ключ Handler.postDelayed().

 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);

    }

Ответ 4

Я не использую потоки, потому что мне нужно обновить интерфейс после закрытия меню навигации.

Следующий код работает для меня.

Я использую фрагмент в качестве переменной-члена класса для обновления ui

Функция setFragment() используется для назначения фрагмента переменной фрагмента

В событии onDrawerClosed() я обновляю 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();
}

Ответ 5

Пожалуйста, просмотрите мой MainActivity, чтобы сделать плавный DrawerLayout (открыть/закрыть) с пользовательским макетом topBar.

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);
}
}