我有两个片段,片段A和片段B。片段A使用抖动手势切换到片段B,片段B使用不同的手势切换回片段A。因此,当我在片段A中时,我将手势A注册到SensorManager,当检测到抖动时,我取消注册手势A,切换到片段B,并将手势B注册到SensorManager。
片段A:
public class FragmentA extends Fragment {
private MainWearActivity mMainWearActivity;
private SensorManager mSensorMgr;
private GestureA gestureA;
private OnShakeListener gestureAListener;
private View view;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mMainWearActivity = (MainWearActivity) getActivity();
mSensorMgr = (SensorManager) mMainWearActivity.getSystemService(Activity.SENSOR_SERVICE);
gestureA = new GestureA();
gestureAListener = new OnShakeListener() {
@Override
public void onShake() {
gestureADetected();
}
};
gestureA.setOnShakeListener(gestureAListener);
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_a, container, false);
return view;
}
@Override
public void onResume() {
super.onResume();
startListening();
}
@Override
public void onPause() {
stopListening();
super.onPause();
}
private void gestureADetected(){
mMainWearActivity.replaceFragment(mMainWearActivity.getFrag("B"));
}
private void startListening(){
mMainWearActivity.registerListener(gestureA);
}
private void stopListening(){
mMainWearActivity.unregisterListener(gestureA);
}
}片段B:
public class FragmentB extends Fragment {
private MainWearActivity mMainWearActivity;
private FragmentManager fm;
private SensorManager mSensorMgr;
private GestureB gestureB;
private OnShakeListener gestureBListener;
private View view;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mMainWearActivity = (MainWearActivity) getActivity();
fm = mMainWearActivity.getFragmentManager();
mSensorMgr = (SensorManager) mMainWearActivity.getSystemService(Activity.SENSOR_SERVICE);
gestureB = new GestureB();
gestureBListener = new OnShakeListener() {
@Override
public void onShake() {
gestureBDetected();
}
};
gestureB.setOnShakeListener(gestureBListener);
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_b, container, false);
return view;
}
@Override
public void onResume() {
super.onResume();
startListening();
}
@Override
public void onPause() {
stopListening();
super.onPause();
}
private void gestureBDetected(){
fm.popBackStackImmediate();
}
private void startListening(){
mMainWearActivity.registerListener(gestureB);
}
private void stopListening(){
mMainWearActivity.unregisterListener(gestureB);
}
}如果我运行这个应用程序,并连续在片段A和片段B之间切换,几次之后,SensorManager停止检测手势。这在Android手机上不是这样的,因为在Android手机上这种设置工作得很好。
这只是我做的一个小测试应用程序,用来检查行为是否可以被复制,但我的实际应用程序要大得多,有更多的手势,所以简单地用SensorManager注册所有的手势并检查不同的片段/手势不是一个理想的解决方案,因为它变得非常混乱和复杂。有没有人知道一种“清理”SensorManager的方法,这样它就会丢失对任何以前注册/未注册的侦听器的所有引用?或者这只是Android Wear中的一个bug。我使用的设备是Moto360。谢谢。
发布于 2016-02-11 14:04:39
在你最近几天的问题中,包含类似的代码,我认为是相关的,我没有看到你的事件侦听器/手势检测器的代码的帖子。看起来其中至少有一个使用了陀螺传感器。在代码的一个发布版本中,您使用的是快速更新速率(SENSOR_DELAY_GAME)。
在您的监听/检测过程中是否有逻辑来确保给定的手腕动作只会导致该手势被报告一次?我正在考虑你的设计中的控制流程:传感器事件,手势检测,片段事务,侦听器注销。因为所有这些都发生在主线程上,并且片段事件是异步的,所以我怀疑您的侦听器将在触发手势检测的事件之后获得更多的事件。更快的更新速度更有可能出现这种情况。根据我的经验,片段事务中涉及的步骤以及片段回调(onCreateView()、onResume()等)的执行可能需要20毫秒或更长时间。在调用要删除的片段的onPause()之前,该片段的侦听器仍会被注册,并且事件将排队等待该侦听器。如果触发多个手势检测,您的片段管理可能会变得混乱,可能会导致多次添加相同的片段。将Log语句添加到您的gestureXDetected()将确认手势被检测到一次,正如您的设计所期望的那样。
对于你关于SensorManager中的bug的问题,嗯,一切都是可能的,但我认为这是非常不可能的。你可以通过在MainActivity的onCreate()方法中添加调试代码,在开始正常操作之前对侦听器进行100次注册/取消注册,然后观察您的应用程序是否立即变慢或在您重复切换片段后出现延迟,从而轻松确认您的怀疑。
https://stackoverflow.com/questions/35294144
复制相似问题