/* TMTS - Android automation testing Framework.
Copyright (C) 2010-2011 TaoBao UI AutoMan Team
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., HuaXing road, Hangzhou,China.
Email:taichan@taobao.com,shidun@taobao.com,bingyang@taobao.com
*/
package com.taobao.tmts.framework.utils;
import java.util.ArrayList;
import junit.framework.Assert;
import android.app.Instrumentation;
import android.view.View;
import android.widget.AbsListView;
import android.widget.GridView;
import android.widget.ListView;
import android.widget.ScrollView;
/**
* Some methods come from come from Solo Scroller.java.
* @author bingyang.djj, original authors is Renas Reda, renas.reda@jayway.com.
*
*/
public class ScrollUtils {
private static final String LOG_TAG = "ScrollUtils";
private Instrumentation inst;
private ActivityUtils activityUtils;
private ViewUtils viewUtils;
private Sleeper sleeper;
public static final int DOWN = 0;
public static final int UP = 1;
public ScrollUtils(Instrumentation inst, ActivityUtils activityUtils,
ViewUtils viewUtils, Sleeper sleeper) {
this.inst = inst;
this.activityUtils = activityUtils;
this.viewUtils = viewUtils;
this.sleeper = sleeper;
}
/**
* Scrolls up and down.
*
* @param direction the direction in which to scroll
* @return {@code true} if more scrolling can be done
*
*/
public boolean scroll(int direction) {
final ArrayList<View> viewList = viewUtils.getViews(null, true);
final ArrayList<ListView> listViews = ViewUtils.filterViews(ListView.class, viewList);
if (listViews.size() > 0) {
return scrollList(ListView.class, 0, direction, listViews);
}
final ArrayList<GridView> gridViews = ViewUtils.filterViews(GridView.class, viewList);
if (gridViews.size() > 0) {
return scrollList(GridView.class, 0, direction, gridViews);
}
final ArrayList<ScrollView> scrollViews = ViewUtils.filterViews(ScrollView.class, viewList);
if (scrollViews.size() > 0) {
return scrollScrollView(direction, scrollViews);
}
return false;
}
/**
* Scrolls a list.
*
* @param listIndex the list to be scrolled
* @param direction the direction to be scrolled
* @return {@code true} if more scrolling can be done
*
*/
public <T extends AbsListView> boolean scrollList(Class<T> classToFilterBy, int listIndex, int direction, ArrayList<T> listViews) {
final T listView = viewUtils.getView(classToFilterBy, listViews, listIndex);
if(listView == null)
Assert.assertTrue("No ListView with index " + listIndex + " is found!", false);
if (direction == DOWN) {
if (listView.getLastVisiblePosition() >= listView.getCount()-1) {
scrollListToLine(listView, listView.getLastVisiblePosition());
return false;
}
if(listView.getFirstVisiblePosition() != listView.getLastVisiblePosition())
scrollListToLine(listView, listView.getLastVisiblePosition());
else
scrollListToLine(listView, listView.getFirstVisiblePosition()+1);
} else if (direction == UP) {
if (listView.getFirstVisiblePosition() < 2) {
scrollListToLine(listView, 0);
return false;
}
final int lines = listView.getLastVisiblePosition() - listView.getFirstVisiblePosition();
int lineToScrollTo = listView.getFirstVisiblePosition() - lines;
if(lineToScrollTo == listView.getLastVisiblePosition())
lineToScrollTo--;
if(lineToScrollTo < 0)
lineToScrollTo = 0;
scrollListToLine(listView, lineToScrollTo);
}
sleeper.sleep();
return true;
}
/**
* Scroll the list to a given line
* @param listView the listView to scroll
* @param line the line to scroll to
*/
private <T extends AbsListView> void scrollListToLine(final T view, final int line){
final int lineToMoveTo;
if(view instanceof GridView)
lineToMoveTo = line+1;
else
lineToMoveTo = line;
inst.runOnMainSync(new Runnable(){
public void run(){
view.setSelection(lineToMoveTo);
}
});
}
/**
* Scrolls a ScrollView.
*
* @param direction the direction to be scrolled
* @return {@code true} if more scrolling can be done
*
*/
private boolean scrollScrollView(int direction, ArrayList<ScrollView> scrollViews){
final ScrollView scroll = viewUtils.getView(ScrollView.class, scrollViews, 0);
int scrollAmount = 0;
if(scroll != null){
int height = scroll.getHeight();
height--;
int scrollTo = 0;
if (direction == DOWN) {
scrollTo = (height);
}
else if (direction == UP) {
scrollTo = (-height);
}
scrollAmount = scroll.getScrollY();
scrollScrollViewTo(scroll,0, scrollTo);
if (scrollAmount == scroll.getScrollY()) {
return false;
}
else{
return true;
}
}
return false;
}
/**
* Scroll the list to a given line
* @param listView the listView to scroll
* @param line the line to scroll to
*/
private void scrollScrollViewTo(final ScrollView scrollView, final int x, final int y){
inst.runOnMainSync(new Runnable(){
public void run(){
scrollView.scrollBy(x, y);
}
});
}
}