Android Shake to Refresh教程

在本文中,我们想探索另一种刷新应用程序UI的方法,称为Shake to Refresh 。 我们都知道在几个应用程序中实现的“从上到下”模式。 在这种模式下,我们沿着屏幕下拉手指,并刷新了UI:

android_pull_to_refresh4

即使此模式非常有用,我们也可以基于智能手机传感器使用另一种模式来刷新我们的UI,我们可以称其为Shake刷新 。 我们不用动动手指,而是摇动智能手机来刷新UI:

adroid_shake_to_refresh4

实作

为了使我们的应用程序支持摇动刷新功能,我们必须使用智能手机传感器,特别是运动传感器 :加速度计。 如果您想了解更多有关如何使用传感器的信息,可以在这里看看。

如前所述,我们希望用户摇动智能手机进行刷新,同时我们不希望刷新过程意外启动或用户只是移动智能手机而启动。 因此,我们必须实施一些控件以确保用户故意晃动智能手机。 另一方面,我们不想在处理UI的类中实现此逻辑,因为不建议将UI逻辑与其他事物混合使用,而使用另一个类,我们可以在其他上下文中重用此“模式” 。

然后,我们将创建另一个名为ShakeEventManager类。 此类必须侦听传感器事件:

public class ShakeEventManager implements SensorEventListener {
..
}

这样它将实现SensorEventListener 。 然后,我们必须寻找加速度传感器,并将我们的课程注册为事件监听器:

public void init(Context ctx) {
    sManager = (SensorManager)  ctx.getSystemService(Context.SENSOR_SERVICE);
    s = sManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
    register();
}

然后:

public void register() {
    sManager.registerListener(this, s, SensorManager.SENSOR_DELAY_NORMAL);
}

要在UI上触发刷新事件,必须验证一些条件,这些条件可确保用户故意晃动他的智能手机。 条件是:

  1. 加速度必须大于阈值水平
  2. 必须发生固定数量的加速事件
  3. 这些事件之间的时间必须在固定的时间窗口内

我们将在每次有新值可用时调用onSensorChanged方法中实现此逻辑。 第一步是计算加速度,我们想知道三个轴上的最大加速度值,并希望从重力中清除传感器值。 因此,如Android官方文档中所述,我们首先应用低通滤波器来隔离重力,然后再应用高通滤波器:

private float calcMaxAcceleration(SensorEvent event) {
    gravity[0] = calcGravityForce(event.values[0], 0);
    gravity[1] = calcGravityForce(event.values[1], 1);
    gravity[2] = calcGravityForce(event.values[2], 2);

    float accX = event.values[0] - gravity[0];
    float accY = event.values[1] - gravity[1];
    float accZ = event.values[2] - gravity[2];

    float max1 = Math.max(accX, accY);
    return Math.max(max1, accZ);
}

哪里

// Low pass filter
private float calcGravityForce(float currentVal, int index) {
    return  ALPHA * gravity[index] + (1 - ALPHA) * currentVal;
}

一旦知道最大加速度,便实现我们的逻辑:

@Override
public void onSensorChanged(SensorEvent sensorEvent) {
    float maxAcc = calcMaxAcceleration(sensorEvent);
    Log.d("SwA", "Max Acc ["+maxAcc+"]");
    if (maxAcc >= MOV_THRESHOLD) {
        if (counter == 0) {
            counter++;
            firstMovTime = System.currentTimeMillis();
            Log.d("SwA", "First mov..");
        } else {
            long now = System.currentTimeMillis();
            if ((now - firstMovTime) < SHAKE_WINDOW_TIME_INTERVAL)
                counter++;
            else {
                resetAllData();
                counter++;
                return;
            }
            Log.d("SwA", "Mov counter ["+counter+"]");

            if (counter >= MOV_COUNTS)
                if (listener != null)
                    listener.onShake();
        }
    }

}

分析第3行的代码,我们简单地计算出加速度,然后检查加速度是否大于阈值(条件1)(第5行)。 如果是第一个动作(第7-8行),我们将保存时间戳以检查是否在指定的时间范围内发生了其他事件。 如果满足所有条件,则在回调接口中调用一个回调方法定义:

public static interface ShakeListener {
    public void onShake();
}

测试应用

现在,我们已经实现了震动事件管理器,我们准备创建一个使用它的简单应用程序。 我们可以使用ListView创建一个简单的活动,当震动事件发生时会刷新该活动:

public class MainActivity extends ActionBarActivity implements ShakeEventManager.ShakeListener {
....

  @Override
    public void onShake() {
       // We update the ListView
    }
}

在第5行的位置,我们更新了UI,因为仅当用户摇动智能手机时才调用此方法。

最后一些注意事项:暂停应用程序时,我们必须注销传感器侦听器,以使其不再侦听事件,并以此节省电池。 另一方面,当应用恢复时,我们将再次注册侦听器:

Override
protected void onResume() {
    super.onResume();
    sd.register();
}

@Override
protected void onPause() {
    super.onPause();
    sd.deregister();
}

翻译自: https://www.javacodegeeks.com/2014/04/android-shake-to-refresh-tutorial.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值