Пример #1
0
  // 惯性线程
  class FlingThread extends Thread {
    // 初始速度
    private int velocity;
    private static final float INFLEXION = 0.35f;
    // 取得系统摩擦系数
    private float mFlingFriction = ViewConfiguration.getScrollFriction();
    private float mPhysicalCoeff;
    private final float DECELERATION_RATE = (float) (Math.log(0.78) / Math.log(0.9));
    // 计算出惯性总时间
    private double mDuration;
    // 刷新频率
    private int timeInterval = 1000 / 60; // 单位MS
    // 当前惯性耗时
    private int spendTime;

    public FlingThread(float velocityX) {
      velocity = (int) velocityX;
      final float ppi = context.getResources().getDisplayMetrics().density * 160.0f;
      mPhysicalCoeff =
          SensorManager.GRAVITY_EARTH // g (m/s^2)
              * 39.37f // inch/meter
              * ppi
              * 0.84f; // look and feel tuning
    }

    @Override
    public void run() {
      isInertia = true;
      boolean isEnable = false;
      if (velocity != 0) {
        mDuration = getSplineFlingDuration(velocity);
        // 不断循环直到惯性时间到达或者用户点击屏幕中断滑动
        while (mDuration >= spendTime && isInertia) {
          // 每时间间隔内惯性滑动的距离
          int space =
              (int)
                      (velocity
                          + (2 * spendTime / timeInterval + 1)
                              * -velocity
                              / mDuration
                              * timeInterval
                              / 2)
                  * timeInterval
                  / 1000;
          try {
            if (axesData.size() > 1) {
              int max = axesData.get(axesData.size() - 1).X;
              int min = axesData.get(0).X;
              int maxLimit = width - rightPadding - 20;
              int minLimit = leftPadding + yTextWidth + 20;
              if (min + space > minLimit) { // 滑动以后左边界判断
                if (min < minLimit) {
                  isEnable = true;
                } else {
                  space = 0;
                  refreshChart(space);
                  return;
                }
              } else {
                isEnable = true;
              }
              if (max + space < maxLimit) { // 滑动后右边界判断
                if (max > maxLimit) {
                  isEnable = true;
                } else {
                  space = 0;
                  refreshChart(space);
                  return;
                }
              } else {
                isEnable = true;
              }
              if (isEnable) {
                refreshChart(space);
              }
            } else {
              return;
            }
            spendTime += timeInterval;
            sleep(timeInterval);
            isScrollEnd = true;
          } catch (InterruptedException e) {
            e.printStackTrace();
          }
        }
      }
    }

    // 根据速度计算加速度
    private double getSplineDeceleration(int velocity) {
      return Math.log(INFLEXION * Math.abs(velocity) / (mFlingFriction * 2 * mPhysicalCoeff));
    }

    /* Returns the duration, expressed in milliseconds */
    private int getSplineFlingDuration(int velocity) {
      final double l = getSplineDeceleration(velocity);
      final double decelMinusOne = DECELERATION_RATE - 1.0;
      return (int) (1000.0 * Math.exp(l / decelMinusOne));
    }
  }