bootstrapのFlick

5223 ワード

Flick

package io.appium.android.bootstrap.handler;

import com.android.uiautomator.core.UiDevice;
import io.appium.android.bootstrap.*;
import io.appium.android.bootstrap.exceptions.InvalidCoordinatesException;
import io.appium.android.bootstrap.utils.Point;
import org.json.JSONException;

import java.util.Hashtable;

/**
 * This handler is used to flick elements in the Android UI.
 * 
 * Based on the element Id, flick that element.
 * 
 */
public class Flick extends CommandHandler {

  private Point calculateEndPoint(final Point start, final Integer xSpeed,
      final Integer ySpeed) {
    final UiDevice d = UiDevice.getInstance();
    final Point end = new Point();
    final double speedRatio = (double) xSpeed / ySpeed;
    double xOff;
    double yOff;

    final double value = Math.min(d.getDisplayHeight(), d.getDisplayWidth());

    if (speedRatio < 1) {
      yOff = value / 4;
      xOff = value / 4 * speedRatio;
    } else {
      xOff = value / 4;
      yOff = value / 4 / speedRatio;
    }

    xOff = Integer.signum(xSpeed) * xOff;
    yOff = Integer.signum(ySpeed) * yOff;

    end.x = start.x + xOff;
    end.y = start.y + yOff;
    return end;
  }

  /*
   * @param command The {@link AndroidCommand} used for this handler.
   * 
   * @return {@link AndroidCommandResult}
   * 
   * @throws JSONException
   * 
   * @see io.appium.android.bootstrap.CommandHandler#execute(io.appium.android.
   * bootstrap.AndroidCommand)
   */
  @Override
  public AndroidCommandResult execute(final AndroidCommand command)
      throws JSONException {
    Point start = new Point(0.5, 0.5);
    Point end = new Point();
    Double steps;

    final Hashtable<String, Object> params = command.params();
    final UiDevice d = UiDevice.getInstance();

    if (command.isElementCommand()) {
      AndroidElement el;
      try {
        el = command.getElement();
        start = el.getAbsolutePosition(start);
        final Integer xoffset = (Integer) params.get("xoffset");
        final Integer yoffset = (Integer) params.get("yoffset");
        final Integer speed = (Integer) params.get("speed");

        steps = 1250.0 / speed + 1;
        end.x = start.x + xoffset;
        end.y = start.y + yoffset;

      } catch (final Exception e) {
        return getErrorResult(e.getMessage());
      }
    } else {
      try {
        final Integer xSpeed = (Integer) params.get("xSpeed");
        final Integer ySpeed = (Integer) params.get("ySpeed");

        final Double speed = Math.min(1250.0,
            Math.sqrt(xSpeed * xSpeed + ySpeed * ySpeed));
        steps = 1250.0 / speed + 1;

        start = getDeviceAbsPos(start);
        end = calculateEndPoint(start, xSpeed, ySpeed);
      } catch (final InvalidCoordinatesException e) {
        return getErrorResult(e.getMessage());
      }
    }

    steps = Math.abs(steps);
    Logger.debug("Flicking from " + start.toString() + " to " + end.toString()
        + " with steps: " + steps.intValue());
    final boolean res = d.swipe(start.x.intValue(), start.y.intValue(),
        end.x.intValue(), end.y.intValue(), steps.intValue());

    if (res) {
      return getSuccessResult(res);
    } else {
      return getErrorResult("Flick did not complete successfully");
    }
  }
}

コードの手順はswipeと同様であり、最終的に呼び出されるのもUiDeviceである.swipeメソッドでは、いったいどこが違うのか見てみましょう.まず、コントロールと座標に分けて分析します.

ツールバーの


まず、コントロールの中心点を開始座標とし、指定したパラメータxoffsetとyoffsetに基づいてシフトデータを取得し、speedパラメータを使用してステップを計算します.
steps = 1250.0 / speed + 1;
end.x = start.x + xoffset;
end.y = start.y + yoffset;

開始座標に変位を加えると終了座標になりますが、このstepsの設定は少し頭がつかめません.私の1250は最大変位だと思います.speedは一歩一歩の道のりを表しています.1250/speedでどれだけのステップを使用して終了点まで、さらに初期値を加えた点でstepsの値が得られます.これで開始点座標、終了点座標、ステップの値が設定されます.

座標


厳密に言えば、座標とは言えず、座標変位を計算すべきである.なぜなら、入力されたパラメータは座標系の速度xSpeedとySpeedであるからである.x軸はxSpeed距離を移動し、y軸はySpeed座標を移動します.座標値とsteps値を取得します.
ここで1250と変位の二乗を比較し,最小値を取り出してstepsを計算した.[始点座標点](Start Coordinate Point)画面の中心点座標を配置します.次にend=calculateEndPoint(start,xSpeed,ySpeed)を呼び出します.メソッドは、終了点座標を取得します.
private Point calculateEndPoint(final Point start, final Integer xSpeed,
      final Integer ySpeed) {
    final UiDevice d = UiDevice.getInstance();
    final Point end = new Point();
    final double speedRatio = (double) xSpeed / ySpeed;
    double xOff;
    double yOff;

    final double value = Math.min(d.getDisplayHeight(), d.getDisplayWidth());

    if (speedRatio < 1) {
      yOff = value / 4;
      xOff = value / 4 * speedRatio;
    } else {
      xOff = value / 4;
      yOff = value / 4 / speedRatio;
    }

    xOff = Integer.signum(xSpeed) * xOff;
    yOff = Integer.signum(ySpeed) * yOff;

    end.x = start.x + xOff;
    end.y = start.y + yOff;
    return end;
  }

まず、シフト比speedRatio(xのシフト/yのシフト)を算出する、画面幅と高校の最小数を取得してvalueにコピーする.speedRatio<1の場合、xの移動距離はvalueの値の1/4となる.y座標はxが移動する距離と同じである.したがって、上記の計算で得られた終了点の座標と開始点からなるのは正方形の対角線であるべきである.
最後にUIDeviceを呼び出します.swipeとSwipeは同じです.特にない

まとめ


特に1250が何を表しているのか知りたいです.さもないといつもこの方法の意味を理解していないような気がします.おや