我有两个片段,片段A和片段B.片段A使用摇动手势切换到片段B,片段B使用不同的手势切换回片段A.所以当我在片段A中时,我使用SensorManager注册手势A,当检测到抖动时,我取消注册手势A,切换到片段B,并使用SensorManager注册手势B.
片段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手机上情况并非如此。
这只是我用来检查行为是否可以复制的小型测试应用程序,但我的实际应用程序要大得多,并且有更多手势,所以只需使用SensorManager注册所有手势一次并检查不同的片段/手势不是一个理想的解决方案,因为它变得非常混乱和复杂。有没有人知道如何清洁" SensorManager是否会丢失对以前注册/未注册的任何侦听器的所有引用?或者这只是Android Wear中的一个错误。我使用的设备是Moto360。感谢。
答案 0 :(得分:0)
在最近几天的问题中,包含类似代码并且我认为是相关的,我还没有看到您的事件监听器/手势检测器的代码发布。似乎至少有一个使用陀螺仪传感器。在您的代码的一个发布版本中,您使用的是快速更新率(SENSOR_DELAY_GAME)。
您的聆听/检测处理中是否存在逻辑以确保给定的手腕动作仅导致手势被报告一次?我正在思考您设计中的控制流程:传感器事件,手势检测,片段事务,侦听器取消注册。因为所有这一切都发生在主线程上,并且片段事件是异步的,我怀疑你的监听器会在触发手势检测的事件之后再获得一些事件。这更有可能是更快的更新速率。根据我的经验,片段事务中涉及的步骤的执行以及片段回调(onCreateView()
,onResume()
等)可能需要20毫秒或更长时间。在调用要删除的片段的onPause()
之前,仍会注册该片段的侦听器,并且正在为侦听器排队事件。如果触发了多个手势检测,则您的片段管理可能会混乱,可能会导致多次添加相同的片段。向您的Log
添加gestureXDetected()
语句将确认您的设计需要检测一次手势。
关于SensorManager
中有关错误的问题,嗯,一切皆有可能,但我认为这不太可能。您可以通过在MainActivity的onCreate()
方法中调试调试代码以在开始正常操作之前注册/取消注册侦听器100次来轻松确认您的怀疑,然后观察您的应用是否立即缓慢或切换片段后延迟发展反复。