在本篇文章中我们将要探讨的是一种称作晃动刷新的应用UI刷新方式。我们都知道在多个应用中已经实现的下拉刷新模式,在这个模式中我们用手指沿着屏幕滑动界面就刷新了:
尽管这种模式很有用,我们还可以使用其他的模式来刷新UI,通过智能手机的传感器,我们称之为晃动刷新。与手指下拉不同,我们晃动手机来刷新UI。
为使我们的应用支持晃动刷新功能,我们要使用智能手机的传感器和专门的运动传感器:加速度传感器。如果你想了解更多关于如何使用传感器的信息,你可以到这里看一看。
正如上面所说的,我们希望用户晃动手机来刷新,同时我们不希望用户在不小心或只是移动手机时启动刷新进程。所以我们要实施一些控制措施以确保用户是在刻意晃动手机。另一方面,我们也不希望在处理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的刷新事件, 需要验证一些条件, 这些条件要保证用户是有意晃动他们的智能机的.这些条件是:
加速度值要大于一个阈值
要发生特定数量的加速度事件
这些事件之间的间隔必须在一个固定的时间段内
我们在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(); }其它翻译版本 (1) 加载中
现在,我们已经实现了晃动事件的管理器,我们开始准备创建一个简单的应用程序。我们可以用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(); }其它翻译版本 (1) 加载中 本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接。 2KB翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。
2KB项目(www.2kb.com,源码交易平台),提供担保交易、源码交易、虚拟商品、在家创业、在线创业、任务交易、网站设计、软件设计、网络兼职、站长交易、域名交易、链接买卖、网站交易、广告买卖、站长培训、建站美工等服务