2

我有一个包含很多元素的listView,即我们必须向下滚动才能看到所有元素。现在我想做的是,单击所有 listView 元素。我怎样才能做到这一点。现在,我正在使用以下代码,但它不会自动滚动。请帮忙。

ListView l = solo.getCurrentListViews().get(0);
        assertNotNull("No list views!", l);
        assertTrue("No items in list view!", l.getChildCount() > 0);
        // Get the last list item
        View v = l.getChildAt(l.getChildCount());
        System.out.println("getChildCount: " + l.getChildCount());

        int i = 1;
        while (i <= l.getChildCount()) {
            solo.clickInList(i);

            solo.goBack();

            i++;

        }
4

3 回答 3

11

我之前曾在稍微不同的状态下使用这些辅助函数来处理列表视图所需的大部分内容:

public View getViewAtIndex(final ListView listElement, final int indexInList, Instrumentation instrumentation) {
    ListView parent = listElement;
    if (parent != null) {
        if (indexInList <= parent.getAdapter().getCount()) {
            scrollListTo(parent, indexInList, instrumentation);
            int indexToUse = indexInList - parent.getFirstVisiblePosition();
            return parent.getChildAt(indexToUse);
        }
    }
    return null;
}

public <T extends AbsListView> void scrollListTo(final T listView,
        final int index, Instrumentation instrumentation) {
    instrumentation.runOnMainSync(new Runnable() {
        @Override
        public void run() {
            listView.setSelection(index);
        }
    });
    instrumentation.waitForIdleSync();
}

有了这些,您的方法将是:

ListView list = solo.getCurrentListViews().get(0);
for(int i=0; i < list.getAdapter().getCount(); i++){
    solo.clickOnView(getViewAtIndex(list, i, getInstrumentation()))
}
于 2013-02-01T07:57:35.763 回答
1

看起来您的代码,正如当前实现的那样,在控制循环和处理点击时只考虑可见的列表项。重要的是要注意两件事的行为:

首先,Android 中有一个称为视图回收的概念,它有助于在处理 ListView 时节省内存。仅创建当前在屏幕上的视图,一旦它们滚出屏幕,它们将被重新填充新数据。因此,在 ListView 上调用getChildCount和之类的方法getChildAt只会对可见项执行这些操作。要查找有关填充列表的数据的信息,您可以调用ListView 适配器上的getCount()或等方法。getItem()

其次,该clickInList()方法是 1-indexed,相对于列表的当前位置,并且只能用于可见项。据我所知,它永远不会自动滚动您的列表。这意味着clickInList(2)在列表顶部时调用将单击第二个项目,但是clickInList(2)当第 30 项位于列表顶部时再次调用将单击第 32 个。

了解这两件事后,您的解决方案将需要考虑所有列表数据,并且在进行点击时可能会更加精确。以下是我将如何重写您的 while 循环以确保您能够处理列表中的每个项目,希望这会有所帮助:

ListAdapter adapter = l.getAdapter();
for(int i=0; i < adapter.getCount(); i++) 
{
    //Scroll down the list to make sure the current item is visible
    solo.scrollListToLine(l, i);

    //Here you need to figure out which view to click on.
    //Perhaps using adapter.getItem() to get the data for the current list item, so you know the text it is displaying.

    //Here you need to click the item!
    //Even though you're in a list view, you can use methods such as clickOnText(), which might be easier based on how your adapter is set up

    solo.goBack();
}
于 2013-01-31T16:34:44.783 回答
0

它应该可以帮助您(未经测试):

public void clickAllElementsOnListView(int index) {
    ListView listView = solo.getCurrentListViews().get(index);
    count = listView.getAdapter() != null ? listView.getAdapter().getCount() : 0;
    for (int i = 0; i < count; i++) {
        scrollListToLine(listView, i);
        solo.clickInList(1, index);
        solo.goBack();
    }
}

protected void scrollListToLine(final ListView listView, final int line) {
    getInstrumentation().runOnMainSync(new Runnable() {
        public void run() {
            listView.setSelection(line);
        }
    });
}
于 2013-01-31T17:35:01.877 回答