项目中用到侧滑导航,点击导航切换Fragment时,菜单回弹会有很明显的卡顿。
首先想到的是Fragment的优化,是不是Fragment在OnCreateView的时候做了太多的工作。
方案1:将Fragment中的布局移出去,使用ViewStub预加载布局,在onCreateView时不对布局进行加载。在Fragment的onResume时使用viewStub.inflate()加载布局
运行发现,菜单回弹时的卡顿改善不是很明显,但有所改善。继续寻找解决方案。
后来想到,是不是fragment的事务管理有问题。
方案2:之前采用的是
transaction.hide(lastFragment).replace(R.id.home_content, insuranceFragment).commit();
replace这种替换方法是之前加载的被替换后就被移除,下次再加载时会重新生成。这样也会造成一定的资源浪费。
修改:
if (aboutFragment == null) {
aboutFragment = new AboutFragment();
}
transaction = fragmentManager.beginTransaction();
if (lastMenuItemId != menuItemId) {
//点击的不是当前选中菜单做如下处理,如点击的是当前选中菜单不做处理
if (aboutFragment.isAdded()) {
//当前Fragment已经被加载过
transaction.hide(lastFragment).show(aboutFragment).commit();
} else {
transaction.hide(lastFragment).add(R.id.home_content, aboutFragment).commit();
}
lastFragment = aboutFragment;
lastMenuItemId = menuItemId;
}
修改后运行发现,菜单回弹流畅度有了很大的提升,但是还是有轻微的卡顿。虽然这种卡顿是不注意不会发现的,高标准,严要求(小公司是不会给你十天半个月去优化一个卡顿的)。现在fragment已经找不到可以优化的点了,看DrawLayout吧。
方案3:对DrawLayout下手
@Override
public boolean onNavigationItemSelected(MenuItem item) {
menuItemId = item.getItemId();
isSelectMenuItem = true;
/**
*之前的菜单点击判断,以及点击后的Fragment切换写在了这里*/
if (drawer != null) {
drawer.closeDrawer(GravityCompat.START);
}
return true;
}
看这里,fragment的切换和drawer的close是同时进行的,close是有动画效果的,在刷新过程中同时执行了fragment的事务和初始化相关操作,这样UI线程处理的事情是不是太多?
先看一下close的动画时间是多长。左侧X轴滑动,找源码,在ViewDragHelper中发现: