if语句使用runnable处理程序

问题描述 投票:2回答:2

我正在创建一个Android应用程序,我正在使用图书馆地震https://github.com/square/seismic添加摇动功能

有了这个摇动功能,我试图让它根据每次摇动的次数打开一个相应的页面,即为第1页摇一次,为第2页摇两次,依此类推。

我在启动if语句之前使用处理程序等待1700ms,因此它知道正确的计数而不是直接转到第一个if语句(当count为1时)但它仍然从第1页到第2页再到第3页而不是等待并第一次进入正确的页面。

家庭班

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);



            }
        });

ShakeDetector类

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);
            }
        }
    }
}

所以抖动检测器类基本上在重置之前将抖动计数记录3秒,这很好但是现在在我的Home类中,我希望它注册我的抖动等待X秒然后正确打开类但我不确定是什么问题我的做法?

我添加了一个不计算的系统,它的检测抖动很好

I/System.out: 1 I/System.out: 2 I/System.out: 3

但它从第1页到第2页到第3页(你可以看到过渡);这是什么原因?

java android if-statement runnable
2个回答
3
投票

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类只是为了区分本地变量和全局变量。


0
投票

我相信你把超时放在了错误的位置。每次计数增加时,您都会触发3次事件。

你的OnShakeListener应该保持计数。 onShake应该负责更新侦听器中的计数并在一些超时后重置触发器并重置抖动计数。

© www.soinside.com 2019 - 2024. All rights reserved.