android fragment的用处非常大,常用于同一界面下点击下方或者左/右侧菜单栏切换不同的内容
普通操作下并没有问题,但是在专业人员的测试下就有问题了,如Fragment already active,或者no host。
这2个问题主要的原因有如下2点。
第一点:
每一次切换并没有写
FragmentTransaction fragmentTransaction = fManager.beginTransaction();
fragmentTransaction.replace(R.id.index_content, fragment);
fragmentTransaction.commit();或者少写,当然也可以直接这样
fragmentTransaction.replace(R.id.index_content, homefragment).commit();
是写了以上的代码,但是还报错
之所以出现的原因在于我们写切换fragment中,都有切换的动画,而频繁操作的话,点击操作或者遥控按键操作都小于fragment的动画切换时间,就会出现上述问题了。
而切换fragment中,大部分都需要设置bundle进去传递数据。
通过查看我们的源码,可以看到
public void setArguments(Bundle args) { if (mIndex >= 0) { throw new IllegalStateException("Fragment already active"); } mArguments = args; }简单的理解,是因为这个上一个fragment还没挂我们就 setArguments了。
因此,解决的兼容方案并不是其他博客说的那样,在fragment中用getter and setter的方法设置数据进去,而是用延迟操作的方法
通常我们为了不让用户重复点击都会在onclick的时间中加上点击时间的判断,重复点击500毫秒内只算一次,因此,我们这里也是
在replace方法调用前,我们可以通过设置一个标志位,如
private boolean isReplacing=false;然后在replace方法调用前加上
isRepacing = true;
再后者就是在commit提交事物后,加上
mHandler.postDelayed(new Runnable() {@Overridepublic void run() {// TODO Auto-generated method stub
isRepacing = false;
}
}, 500);
当然我们如果是机顶盒应用的话可以在dispatchKeyEvent方法中加上
if (isRepacing) { if (event.getKeyCode() == KeyEvent.KEYCODE_DPAD_LEFT//拦截按键事件自己看着写 || event.getKeyCode() == KeyEvent.KEYCODE_DPAD_RIGHT) { return true; } }如果是手机应用可以在onclick中加上
if (isRepacing) { return; }这样就解决了上述的2个报错问题了,当然为了用户效果更好,可以在上面代码return 前加上一切提示,如 请不要频繁点击之类增加用户体验的温馨提示。
谢~