Android 震动相关实现
[TOC]
Android中的震动可以通过多种方法实现,其中包括使用Vibrate类和HapticFeedback类,本文主要介绍通过这两个类来实现震动的方式。
Vibrator
震动属于系统服务,获取Vibrator示例的方式如下:
1 | mVibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE); |
震动效果VibrateEffects(API>=26才可使用)
VibrateEffects类用来描述一次震动效果,常见的效果有一下两种:
- one shot vibration,只震动一次,通过VibrationEffect的
createOneShot
方法创建,在API<26时,对应Vibrator下的vibrate(long milliseconds)
方法; - wave form vibration,周期性震动,通过VibrationEffect的
createWaveform
方法创建,在API<26时,对应Vibrator下的vibrate(long[] pattern, int repeat)
方法;
NOTE具体参数参见源码
取消震动
调用Vibrator下的
cancel()
即可取消震动,如果震动不取消的话,只要进程没有关闭,会一直震动
HapticFeedback
系统控件震动反馈效果
Android 好多系统应用在长按某个空间(如Button)时会有一个震动反馈,看如下的代码:
1 | btnSystemFeedback.setOnLongClickListener(new View.OnLongClickListener() { |
上面的代码在onLongClick返回true的时候,有震动反馈;返回false的时候,没有震动反馈。那么查看调用onLongClick的地方,最终定位到View的performLongClickInternal(float x, float y)
方法:
1 | private boolean performLongClickInternal(float x, float y) { |
上面的代码中performHapticFeedback(HapticFeedbackConstants.LONG_PRESS)
就是触发震动反馈的,它的执行条件是handled为true,所以冬onLongClick返回为true时就会触发震动反馈,那么可不可以手动触发震动反馈呢?往下看。
手动触发震动反馈效果
从上面的分析可以看出,我们可以手动调用performHapticFeedback(HapticFeedbackConstants.LONG_PRESS)
方法来触发震动反馈效果,看下面代码:
1 | btnUserFeedback.setOnClickListener(new View.OnClickListener() { |
添加完上面代码后,也可触发震动效果。看看performHapticFeedback(int feedbackConstants)
的源码,最终调用同名重载函数performHapticFeedback(int feedbackConstants, int flags)
,其实现如下:
1 | /** |
从上面可以看到,在不考虑flags参数的情况下,如果要想有震动反馈效果,isHapticFeedbackEnabled()
必须返回true,但考虑flags时,在其返回为false的情况下,如果flags的值设置为HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING
,同样可以出发震动效果。还可以通过设置flags为`HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING
,即使用户关闭了系统的震动反馈,同样会有效果,不过不建议这样使用。
看代码,这样设置,即使关闭了Button的震动反馈效果(设置android:hapticFeedbackEnabled="false"
),同样会有震动:
1 | Button btnUserFeedback = findViewById(R.id.btn_user_feedback); |
这样设置,即使用户关闭了系统的震动反馈效果,同样会有震动:
1 | Button btnUserFeedback = findViewById(R.id.btn_user_feedback); |
震动反馈常量
震动反馈常量在HapticFeedbackConstants
类中定义,比较重要的是如下几个:
LONG_PRESS
,长按FLAG_IGNORE_VIEW_SETTING
,忽略View的限制FLAG_IGNORE_GLOBAL_SETTING
,忽略系统的限制
本文完,本文源码请点这