我在导航抽屉中使用this示例。点击左侧抽屉列表视图的项目时,它会显示一些图像,但抽屉布局关闭不顺畅。
点击列表视图项后,我应该怎样做才能平滑地关闭左侧抽屉布局。
答案 0 :(得分:62)
不确定这是最好的路线,但我解决这个问题的方法是创建一个在onDrawerClosed
中运行的待处理Runnable。例如:
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;
}
}
答案 1 :(得分:11)
完美无缺
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);
}
}
答案 2 :(得分:1)
只需使用处理程序在消息队列上发布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);
}
答案 3 :(得分:0)
我不使用线程,因为我需要在关闭导航菜单后更新UI。
以下代码适用于我。
我使用fragment作为类的成员变量来更新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();
}
答案 4 :(得分:0)
请查看我的MainActivity,以使用自定义的topBar布局使DrawerLayout平滑(打开/关闭)。
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);
}
}