我正在使用 Google DrawerLayout
。
当一个项目被点击时,抽屉会平滑关闭,一个Activity
会被启动。将这些 Activity 变成Fragment
是不是的一种选择。因此,启动 Activity 然后关闭抽屉也不是一种选择。关闭抽屉并同时启动 Activity 会导致关闭动画卡顿。
鉴于我想先顺利关闭它,然后启动 Activity,我遇到了用户单击抽屉项目和他们看到他们想要去的 Activity 之间的延迟问题。
这就是每个项目的点击监听器的样子。
final View.OnClickListener mainItemClickListener = new View.OnClickListener() {
@Override
public void onClick(final View v) {
mViewToLaunch = v;
mDrawerLayout.closeDrawers();
}
};
我的activity也是DrawerListener,它的onDrawerClosed
方法如下:
@Override
public synchronized void onDrawerClosed(final View view) {
if (mViewToLaunch != null) {
onDrawerItemSelection(mViewToLaunch);
mViewToLaunch = null;
}
}
onDrawerItemSelection
只是启动五个 Activity 之一。
我对 DrawerActivity
的 onPause
什么都不做。
我正在对此进行检测,从调用 onClick 到 onDrawerClosed 结束的那一刻平均需要 500-650 毫秒。
有一个明显的延迟,一旦抽屉关闭,在相应的 Activity 启动之前。
我意识到有几件事正在发生:
结束动画发生,这是几毫秒的时间(假设是 300)。
那么在抽屉视觉关闭和它的监听器被触发之间可能会有一些延迟。我试图弄清楚到底发生了多少 by looking at
DrawerLayout
source但还没弄明白。然后是启动的 Activity 执行其启动生命周期方法所需的时间,直到(包括)
onResume
。我还没有对此进行检测,但我估计大约需要 200-300 毫秒。
这似乎是一个问题,走错路会付出相当高的代价,所以我想确保我完全理解它。
一种解决方案是跳过结束动画,但我希望保留它。
如何尽可能缩短过渡时间?
最佳答案
根据docs ,
Avoid performing expensive operations such as layout during animation as it can cause stuttering; try to perform expensive operations during the STATE_IDLE state.
您可以覆盖 ActionBarDrawerToggle
的 onDrawerStateChanged
方法(实现 >DrawerLayout.DrawerListener
),以便在抽屉完全关闭时执行昂贵的操作。
在 MainActivity 内部,
private class SmoothActionBarDrawerToggle extends ActionBarDrawerToggle {
private Runnable runnable;
public SmoothActionBarDrawerToggle(Activity activity, DrawerLayout drawerLayout, Toolbar toolbar, int openDrawerContentDescRes, int closeDrawerContentDescRes) {
super(activity, drawerLayout, toolbar, openDrawerContentDescRes, closeDrawerContentDescRes);
}
@Override
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
invalidateOptionsMenu();
}
@Override
public void onDrawerClosed(View view) {
super.onDrawerClosed(view);
invalidateOptionsMenu();
}
@Override
public void onDrawerStateChanged(int newState) {
super.onDrawerStateChanged(newState);
if (runnable != null && newState == DrawerLayout.STATE_IDLE) {
runnable.run();
runnable = null;
}
}
public void runWhenIdle(Runnable runnable) {
this.runnable = runnable;
}
}
在onCreate
中设置DrawerListener
:
mDrawerToggle = new SmoothActionBarDrawerToggle(this, mDrawerLayout, mToolbar, R.string.open, R.string.close);
mDrawerLayout.setDrawerListener(mDrawerToggle);
最后,
private void selectItem(int position) {
switch (position) {
case DRAWER_ITEM_SETTINGS: {
mDrawerToggle.runWhenIdle(new Runnable() {
@Override
public void run() {
Intent intent = new Intent(MainActivity.this, SettingsActivity.class);
startActivity(intent);
}
});
mDrawerLayout.closeDrawers();
break;
}
case DRAWER_ITEM_HELP: {
mDrawerToggle.runWhenIdle(new Runnable() {
@Override
public void run() {
Intent intent = new Intent(MainActivity.this, HelpActivity.class);
startActivity(intent);
}
});
mDrawerLayout.closeDrawers();
break;
}
}
}
关于android - 优化抽屉和 Activity 启动速度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18343018/