Как создать плавный навигационный ящик
Я использую этот пример для навигационного ящика. При нажатии на элемент списка списка левого ящика отображаются некоторые изображения, но drawerLayout закрывается не плавно.
Что мне следует сделать для плавного закрытия макета левого ящика после щелчка элемента списка.
Ответы
Ответ 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);
}
}