近期项目中要求增加摇一摇功能,搜了相关帖子,自己整理一套代码,发个博客保留一份。

解析:Android中摇一摇主要通过[SensorManager]实现,想了解可以查一下。

上期的不够完善 更新了一下,添加了防暴力摇动控制

public class ShakeService implements SensorEventListener {  private Context mContext;  private final MyHandler mHandler;  private static final int START_SHAKE = 0x1;  private static final int END_SHAKE = 0x2;  //传感器管理器  private SensorManager mSensorManager;  //检测的时间间隔  private static final int UPDATE_INTERVAL = 130;  //上一次检测的时间  private long mLastUpdateTime;  //上一次检测时,加速度在x、y、z方向上的分量,用于和当前加速度比较求差。  private float mLastX, mLastY, mLastZ;  //摇晃检测阈值,决定了对摇晃的敏感程度,越小越敏感。  private static final int shakeThreshold = 3800;  //记录摇动状态  private boolean isShake = false;  //动画  private Animation rotateAnimation, alphaAnimation, translateAnimation;  private static final int DURATION = 1000;  private static final int DURATION_STAR = 800;  public ShakeService(Context mContext) {    this.mContext = mContext;    mHandler = new MyHandler();  }  @Override  public void onSensorChanged(SensorEvent event) {    long currentTime = System.currentTimeMillis();    long diffTime = currentTime - mLastUpdateTime;    if (diffTime < UPDATE_INTERVAL) {      return;    }    mLastUpdateTime = currentTime;    float x = event.values[0];    float y = event.values[1];    float z = event.values[2];    float deltaX = x - mLastX;    float deltaY = y - mLastY;    float deltaZ = z - mLastZ;    mLastX = x;    mLastY = y;    mLastZ = z;    float delta =        (float) (Math.sqrt(deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ) / diffTime * 10000);    // 当加速度的差值大于指定的阈值,认为这是一个摇晃    if (delta > shakeThreshold && !isShake) {      isShake = true;      Thread thread = new Thread() {        @Override        public void run() {          super.run();          try {            if (isValid()) {              mHandler.obtainMessage(START_SHAKE).sendToTarget();            }            //开始 展示动画效果            //Thread.sleep(100);            //再来一次提示          } catch (Exception e) {            e.printStackTrace();          }        }      };      thread.start();    } else {      mHandler.obtainMessage(END_SHAKE).sendToTarget();    }  }  @Override  public void onAccuracyChanged(Sensor sensor, int accuracy) {  }  public void start() {    mSensorManager = (SensorManager) mContext.getSystemService(Context.SENSOR_SERVICE);    if (mSensorManager != null) {      //传感器      Sensor mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);      if (mSensor != null) {        mSensorManager.registerListener(this, mSensor, SensorManager.SENSOR_DELAY_GAME);      }    }  }  public void Stop() {    if (mSensorManager != null) {      mSensorManager.unregisterListener(this);      //清空消息队列      mHandler.removeCallbacks(null);      //置位可摇一摇      isShake = false;      //关闭动画    }    if (rotateAnimation != null) {      rotateAnimation.cancel();    }    if (alphaAnimation != null) {      alphaAnimation.cancel();    }    if (translateAnimation != null) {      translateAnimation.cancel();    }  }  private static final long intervalAtMillis = 1000L;  private static long sLastTime;  public static boolean isValid() {    //防止暴力摇动    long currentTime = System.currentTimeMillis();    if (currentTime - sLastTime < intervalAtMillis) {      return false;    }    sLastTime = currentTime;    return true;  }  class MyHandler extends Handler {    @Override    public void handleMessage(Message msg) {      super.handleMessage(msg);      switch (msg.what) {        case START_SHAKE:          //发出动画触发,执行动画          break;        case END_SHAKE:          isShake = false;          break;      }    }  }  //接口回调,摇一摇开始通知外部  public interface onStartListener {    void onStart();  }  public onStartListener startListener;  public void setStartListener(onStartListener startListener) {    this.startListener = startListener;  }}

动画部分 根据需求编写哦 

private void devilDialog() {    final CustomDialog dialog = new CustomDialog(mContext);    View view = LayoutInflater.from(mContext).inflate(R.layout.view_jackpot_shake, null);    dialog.setCanceledOnTouchOutside(false);    dialog.setContentView(view);    dialog.show();    ImageView devilFish = view.findViewById(R.id.iv_devilFish);    ImageView background = view.findViewById(R.id.iv_background);    ImageView soccer = view.findViewById(R.id.iv_soccer);    ImageView star1 = view.findViewById(R.id.iv_star1);    ImageView star2 = view.findViewById(R.id.iv_star2);    ImageView star3 = view.findViewById(R.id.iv_star3);    rotateAnimation =        new RotateAnimation(0f, 360f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,            0.5f);    rotateAnimation.setDuration(3000);    //rotateAnimation.setRepeatCount(Animation.INFINITE);    background.startAnimation(rotateAnimation);    rotateAnimation.setAnimationListener(new Animation.AnimationListener() {      @Override      public void onAnimationStart(Animation animation) {      }      @Override      public void onAnimationEnd(Animation animation) {        //动画结束  关闭动画效果  通知外部摇一摇结束        if (startListener != null) {          startListener.onStart();        }        rotateAnimation.cancel();        alphaAnimation.cancel();        translateAnimation.cancel();        dialog.dismiss();      }      @Override      public void onAnimationRepeat(Animation animation) {      }    });    //star闪烁      alphaAnimation = new AlphaAnimation(0.1f, 1.0f);    alphaAnimation.setDuration(DURATION_STAR);    alphaAnimation.setRepeatCount(Animation.INFINITE);    alphaAnimation.setRepeatMode(Animation.REVERSE);    star1.setAnimation(alphaAnimation);    star2.setAnimation(alphaAnimation);    star3.setAnimation(alphaAnimation);    //soccer弹跳    translateAnimation = new TranslateAnimation(0, 0, 0, 25);    translateAnimation.setDuration(DURATION);    translateAnimation.setInterpolator(new CycleInterpolator(Animation.INFINITE));    translateAnimation.setRepeatCount(Animation.INFINITE);    soccer.setAnimation(translateAnimation);  }

 

更多相关文章

  1. android xml之动画篇 alpha、scale、translate、rotate、set的属
  2. Android三种动画的实现
  3. android Animation动画的xml使用
  4. Android 动画之Tween动画详细讲解及java源码实现
  5. Android属性动画—实现第三方登录的上拉展开,下拉隐藏
  6. android 动画系列 - 目录

随机推荐

  1. PHP:oop->细说命名空间/命名空间类的自动
  2. js的for和php的for
  3. 4-29数组系统函数的操作
  4. 210428 PHP 函数 返回值 参数 闭包/匿名
  5. 【PHP 面向对象】面向对象(OOP)编程之解
  6. 12345
  7. 美团App插件化实践
  8. 【直播】美团点评技术沙龙Online006: WWD
  9. 美团App 插件化实践
  10. 美团点评旅游搜索召回策略的演进