Android listview垂直スライド距離の指定

3580 ワード

自動化コードを書くときにlistviewのドラッグに効果がない場合があります.例えば、robotiumが持っているスクロール操作scrollListToLineなど、最終的なコアは次のとおりです.
inst.runOnMainSync(new Runnable(){
      public void run(){
        view.setSelection(lineToMoveTo);
      }
    });

つまり、このようにスクロールするのは最終的にlistviewのitemの高さによってスクロールする距離を決めるので、毎回y距離だけをスクロールしたいと思います.android-19のAbsListViewによれば、次の方法があります.
/**
  * Scrolls the list items within the view by a specified number of pixels.
  *
  * @param y the amount of pixels to scroll by vertically
  * @see #canScrollList(int)
  */
    public void scrollListBy(int y) {
     trackMotionScroll(-y, -y);
    }

実際にこの方法を直接呼び出すと、ドラッグ指定listviewの垂直距離を解決できますが、android-19(18があるかどうかは不明ですが、17はありません)が前提ですので、汎用性が強くなく、ほとんどのプラットフォームに適していませんが、方法がわかります.
/**
  * Track a motion scroll
  *
  * @param deltaY Amount to offset mMotionView. This is the accumulated delta since the motion
  *	   began. Positive numbers mean the user's finger is moving down the screen.
  * @param incrementalDeltaY Change in deltaY from the previous event.
  * @return true if we're already at the beginning/end of the list and have nothing to do.
  */
    boolean trackMotionScroll(int deltaY, int incrementalDeltaY)

android-10(これ以上注目していない)から既に存在しており、パッケージ内に対してアクセスしているにすぎないので、次にjava反射を利用してこのメソッドを呼び出すことができるが、ListViewの親のデフォルト修飾子のメソッドであるため、親のメソッドを反射する必要がある点に注意が必要である.
/**
   * scroll Vertical
   * @param solo
   * @param y        
   */
public void scrollVertical(final ListView listView, Activity activity, final int y){
    if(listView == null)
      return;
    activity.runOnUiThread(new Runnable() { //                  UI    
      @Override
      public void run() {
        invokeMethod(listView, "trackMotionScroll", new Object[]{-y, -y}, new Class[]{int.class, int.class});
      }
    });
  }
  
  /**
   *               ,  ,      
   * @param object 
   * @param methodName
   * @param params
   * @param paramTypes
   * @return
   */
public Object invokeMethod(Object object, String methodName, Object[] params, Class[] paramTypes){
    Object returnObj = null;
  if (object == null) {
      return null;
  }
  Class cls = object.getClass();
  Method method = null;
  for (; cls != Object.class; cls = cls.getSuperclass()) { //                ,           
    try {
          method = cls.getDeclaredMethod(methodName, paramTypes);
          break;
        } catch (NoSuchMethodException e) {
//					e.printStackTrace();
        } catch (SecurityException e) {
//					e.printStackTrace();
        }
  }
  if(method != null){
    method.setAccessible(true);
    try {
      returnObj = method.invoke(object, params);
      } catch (IllegalAccessException e) {
        e.printStackTrace();
      } catch (IllegalArgumentException e) {
        e.printStackTrace();
      } catch (InvocationTargetException e) {
        e.printStackTrace();
      }
  }
    return returnObj;
  }

以上が重要なコード全体ですが、robotiumと組み合わせて使用するには、書くことができるパスはもっと少ないです.
public void scrollVertical(final ListView listView, Activity activity, final int y){
.....
}

  :
public void scrollVertical(Solo solo, final int y){
    listViews = solo.xxx()//      listview    
    solo.getCurrentActivity().runOnUiThread(new Runnable() {
      @Override
      public void run() {
        invokeMethod(listView, "trackMotionScroll", new Object[]{-y, -y}, new Class[]{int.class, int.class});
      }
    });
  }

使用例:
ここでyは、ダイナミック取得デバイス画面の高さ:height/nを指定し、スクロール操作(例えば、1画面または半画面をスクロールする)を比較的柔軟に実現することができる.