Android listview垂直滑动指定距离

来源:互联网 发布:unity3d培训多久学完 编辑:程序博客网 时间:2024/05/22 01:32

Android listview垂直滑动指定距离

在写自动化代码的时候对于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,可以比较灵活的实现滚动操作(例如滚动一屏或者半屏)。 
若有错误,欢迎指正!

0 0
原创粉丝点击