使用可运行处理程序的 If 语句
If statement using a runnable handler
我正在创建一个 android 应用程序,我正在使用地震库 https://github.com/square/seismic
添加摇动功能
我正在尝试使用此摇动功能,以便根据每次摇动的次数打开相应的页面,即第 1 页摇动一次,第 2 页摇动两次,依此类推。
我正在使用处理程序在启动 if
语句之前等待 1700 毫秒,因此它知道正确的计数而不是直接转到第一个 if 语句(当计数为 1 时)但它仍然从页面开始1 到第 2 页到第 3 页,而不是第一次等待并转到正确的页面。
首页Class
mShakeDetector.setOnShakeListener(new com.example.name.project.ShakeDetector.OnShakeListener() {
@Override
public void onShake(final int count) {
System.out.println(count);
final Intent tts = new Intent(context, ttsScreen.class);
final Intent stt = new Intent(context, sttScreen.class);
final Intent cbb = new Intent(context, cbbScreen.class);
final Intent ocr = new Intent(context, ocrScreen.class);
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
if( count == 1 ) {
startActivity(tts);
}
else if (count == 2) {
startActivity(stt);
}
else if (count == 3) {
startActivity(cbb);
}
else if (count == 4) {
startActivity(ocr);
}
}
}, 1800);
}
});
抖动检测器Class
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.util.FloatMath;
public class ShakeDetector implements SensorEventListener {
/*
* The gForce that is necessary to register as shake.
* Must be greater than 1G (one earth gravity unit).
* You can install "G-Force", by Blake La Pierre
* from the Google Play Store and run it to see how
* many G's it takes to register a shake
*/
private static final float SHAKE_THRESHOLD_GRAVITY = 2.7F;
private static final int SHAKE_SLOP_TIME_MS = 500;
private static final int SHAKE_COUNT_RESET_TIME_MS = 3000;
private OnShakeListener mListener;
private long mShakeTimestamp;
private int mShakeCount;
public void setOnShakeListener(OnShakeListener listener) {
this.mListener = listener;
}
public interface OnShakeListener {
public void onShake(int count);
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// ignore
}
@Override
public void onSensorChanged(SensorEvent event) {
if (mListener != null) {
float x = event.values[0];
float y = event.values[1];
float z = event.values[2];
float gX = x / SensorManager.GRAVITY_EARTH;
float gY = y / SensorManager.GRAVITY_EARTH;
float gZ = z / SensorManager.GRAVITY_EARTH;
// gForce will be close to 1 when there is no movement.
float gForce = (float)Math.sqrt( gX * gX + gY * gY + gZ * gZ );
if (gForce > SHAKE_THRESHOLD_GRAVITY) {
final long now = System.currentTimeMillis();
// ignore shake events too close to each other (500ms)
if (mShakeTimestamp + SHAKE_SLOP_TIME_MS > now) {
return;
}
// reset the shake count after 3 seconds of no shakes
if (mShakeTimestamp + SHAKE_COUNT_RESET_TIME_MS < now) {
mShakeCount = 0;
}
mShakeTimestamp = now;
mShakeCount++;
mListener.onShake(mShakeCount);
}
}
}
}
基本上震动检测器 class 会在重置前记录 3 秒的震动计数,这很好,但现在在我的 Home class 中,我希望它记录我的震动,等待 X 秒然后打开class 正确,但我不确定我的方法有什么问题?
我添加了一个系统,检测抖动正常
I/System.out: 1
I/System.out: 2
I/System.out: 3
但是它从第 1 页到第 2 页再到第 3 页(您可以看到转换);这是什么原因?
我认为您将超时设置在了错误的位置。您触发事件 3 次,每次计数增加。
您的 OnShakeListener 应该保持计数。 onShake 应该负责更新侦听器中的计数并在超时后触发处理程序并重置摇动计数。
onShake
为每次摇动调用多次。
这里的第一个问题是你每次都发布 Runnable
但 onShake()
被调用但你没有取消最后一个。因此,您需要先取消队列中的最后一个 Runnable
,然后再发布新的。
试试下面的代码:-
public class MainActivity extends AppCompatActivity {
private int shakeCount=0;
private Runnable runnable ;
private Handler handler = new Handler();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
runnable =new Runnable() {
public void run() {
if( shakeCount == 1 ) {
final Intent tts = new Intent(context, ttsScreen.class);
startActivity(tts);
}
else if (shakeCount == 2) {
final Intent stt = new Intent(context, sttScreen.class);
startActivity(stt);
}
else if (shakeCount == 3) {
final Intent cbb = new Intent(context, cbbScreen.class);
startActivity(cbb);
}
else if (shakeCount == 4) {
final Intent ocr = new Intent(context, ocrScreen.class);
startActivity(ocr);
}
shakeCount=0;
}
};
mShakeDetector.setOnShakeListener(new com.example.name.project.ShakeDetector.OnShakeListener() {
@Override
public void onShake(final int count) {
shakeCount=count;
handler.removeCallbacks(runnable);
handler.postDelayed(runnable, 1800);
});
}
我放了一个 Activity class 只是为了区分局部变量和全局变量。
我正在创建一个 android 应用程序,我正在使用地震库 https://github.com/square/seismic
添加摇动功能我正在尝试使用此摇动功能,以便根据每次摇动的次数打开相应的页面,即第 1 页摇动一次,第 2 页摇动两次,依此类推。
我正在使用处理程序在启动 if
语句之前等待 1700 毫秒,因此它知道正确的计数而不是直接转到第一个 if 语句(当计数为 1 时)但它仍然从页面开始1 到第 2 页到第 3 页,而不是第一次等待并转到正确的页面。
首页Class
mShakeDetector.setOnShakeListener(new com.example.name.project.ShakeDetector.OnShakeListener() {
@Override
public void onShake(final int count) {
System.out.println(count);
final Intent tts = new Intent(context, ttsScreen.class);
final Intent stt = new Intent(context, sttScreen.class);
final Intent cbb = new Intent(context, cbbScreen.class);
final Intent ocr = new Intent(context, ocrScreen.class);
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
if( count == 1 ) {
startActivity(tts);
}
else if (count == 2) {
startActivity(stt);
}
else if (count == 3) {
startActivity(cbb);
}
else if (count == 4) {
startActivity(ocr);
}
}
}, 1800);
}
});
抖动检测器Class
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.util.FloatMath;
public class ShakeDetector implements SensorEventListener {
/*
* The gForce that is necessary to register as shake.
* Must be greater than 1G (one earth gravity unit).
* You can install "G-Force", by Blake La Pierre
* from the Google Play Store and run it to see how
* many G's it takes to register a shake
*/
private static final float SHAKE_THRESHOLD_GRAVITY = 2.7F;
private static final int SHAKE_SLOP_TIME_MS = 500;
private static final int SHAKE_COUNT_RESET_TIME_MS = 3000;
private OnShakeListener mListener;
private long mShakeTimestamp;
private int mShakeCount;
public void setOnShakeListener(OnShakeListener listener) {
this.mListener = listener;
}
public interface OnShakeListener {
public void onShake(int count);
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// ignore
}
@Override
public void onSensorChanged(SensorEvent event) {
if (mListener != null) {
float x = event.values[0];
float y = event.values[1];
float z = event.values[2];
float gX = x / SensorManager.GRAVITY_EARTH;
float gY = y / SensorManager.GRAVITY_EARTH;
float gZ = z / SensorManager.GRAVITY_EARTH;
// gForce will be close to 1 when there is no movement.
float gForce = (float)Math.sqrt( gX * gX + gY * gY + gZ * gZ );
if (gForce > SHAKE_THRESHOLD_GRAVITY) {
final long now = System.currentTimeMillis();
// ignore shake events too close to each other (500ms)
if (mShakeTimestamp + SHAKE_SLOP_TIME_MS > now) {
return;
}
// reset the shake count after 3 seconds of no shakes
if (mShakeTimestamp + SHAKE_COUNT_RESET_TIME_MS < now) {
mShakeCount = 0;
}
mShakeTimestamp = now;
mShakeCount++;
mListener.onShake(mShakeCount);
}
}
}
}
基本上震动检测器 class 会在重置前记录 3 秒的震动计数,这很好,但现在在我的 Home class 中,我希望它记录我的震动,等待 X 秒然后打开class 正确,但我不确定我的方法有什么问题?
我添加了一个系统,检测抖动正常
I/System.out: 1
I/System.out: 2
I/System.out: 3
但是它从第 1 页到第 2 页再到第 3 页(您可以看到转换);这是什么原因?
我认为您将超时设置在了错误的位置。您触发事件 3 次,每次计数增加。
您的 OnShakeListener 应该保持计数。 onShake 应该负责更新侦听器中的计数并在超时后触发处理程序并重置摇动计数。
onShake
为每次摇动调用多次。
这里的第一个问题是你每次都发布 Runnable
但 onShake()
被调用但你没有取消最后一个。因此,您需要先取消队列中的最后一个 Runnable
,然后再发布新的。
试试下面的代码:-
public class MainActivity extends AppCompatActivity {
private int shakeCount=0;
private Runnable runnable ;
private Handler handler = new Handler();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
runnable =new Runnable() {
public void run() {
if( shakeCount == 1 ) {
final Intent tts = new Intent(context, ttsScreen.class);
startActivity(tts);
}
else if (shakeCount == 2) {
final Intent stt = new Intent(context, sttScreen.class);
startActivity(stt);
}
else if (shakeCount == 3) {
final Intent cbb = new Intent(context, cbbScreen.class);
startActivity(cbb);
}
else if (shakeCount == 4) {
final Intent ocr = new Intent(context, ocrScreen.class);
startActivity(ocr);
}
shakeCount=0;
}
};
mShakeDetector.setOnShakeListener(new com.example.name.project.ShakeDetector.OnShakeListener() {
@Override
public void onShake(final int count) {
shakeCount=count;
handler.removeCallbacks(runnable);
handler.postDelayed(runnable, 1800);
});
}
我放了一个 Activity class 只是为了区分局部变量和全局变量。