blob: c5bc191d2db4c24210dfd16bdedabd57f01b6ba7 [file] [log] [blame]
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.widget.cts;
import com.android.cts.widget.R;
import org.xmlpull.v1.XmlPullParser;
import android.app.Activity;
import android.app.Instrumentation;
import android.content.Context;
import android.cts.util.PollingCheck;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.test.ActivityInstrumentationTestCase2;
import android.test.UiThreadTest;
import android.test.suitebuilder.annotation.MediumTest;
import android.util.AttributeSet;
import android.util.Pair;
import android.util.SparseBooleanArray;
import android.util.Xml;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.LayoutAnimationController;
import android.widget.AbsListView;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import junit.framework.Assert;
public class ListViewTest extends ActivityInstrumentationTestCase2<ListViewCtsActivity> {
private final String[] mCountryList = new String[] {
"Argentina", "Australia", "China", "France", "Germany", "Italy", "Japan", "United States"
};
private final String[] mNameList = new String[] {
"Jacky", "David", "Kevin", "Michael", "Andy"
};
private final String[] mEmptyList = new String[0];
private ListView mListView;
private Activity mActivity;
private Instrumentation mInstrumentation;
private AttributeSet mAttributeSet;
private ArrayAdapter<String> mAdapter_countries;
private ArrayAdapter<String> mAdapter_names;
private ArrayAdapter<String> mAdapter_empty;
public ListViewTest() {
super("com.android.cts.widget", ListViewCtsActivity.class);
}
protected void setUp() throws Exception {
super.setUp();
mActivity = getActivity();
mInstrumentation = getInstrumentation();
XmlPullParser parser = mActivity.getResources().getXml(R.layout.listview_layout);
mAttributeSet = Xml.asAttributeSet(parser);
mAdapter_countries = new ArrayAdapter<String>(mActivity,
android.R.layout.simple_list_item_1, mCountryList);
mAdapter_names = new ArrayAdapter<String>(mActivity, android.R.layout.simple_list_item_1,
mNameList);
mAdapter_empty = new ArrayAdapter<String>(mActivity, android.R.layout.simple_list_item_1,
mEmptyList);
mListView = (ListView) mActivity.findViewById(R.id.listview_default);
}
public void testConstructor() {
new ListView(mActivity);
new ListView(mActivity, mAttributeSet);
new ListView(mActivity, mAttributeSet, 0);
try {
new ListView(null);
fail("There should be a NullPointerException thrown out. ");
} catch (NullPointerException e) {
// expected, test success.
}
try {
new ListView(null, null);
fail("There should be a NullPointerException thrown out. ");
} catch (NullPointerException e) {
// expected, test success.
}
try {
new ListView(null, null, -1);
fail("There should be a NullPointerException thrown out. ");
} catch (NullPointerException e) {
// expected, test success.
}
}
public void testGetMaxScrollAmount() {
setAdapter(mAdapter_empty);
int scrollAmount = mListView.getMaxScrollAmount();
assertEquals(0, scrollAmount);
setAdapter(mAdapter_names);
scrollAmount = mListView.getMaxScrollAmount();
assertTrue(scrollAmount > 0);
}
private void setAdapter(final ArrayAdapter<String> adapter) {
mInstrumentation.runOnMainSync(new Runnable() {
public void run() {
mListView.setAdapter(adapter);
}
});
mInstrumentation.waitForIdleSync();
}
public void testAccessDividerHeight() {
mInstrumentation.runOnMainSync(new Runnable() {
public void run() {
mListView.setAdapter(mAdapter_countries);
}
});
mInstrumentation.waitForIdleSync();
Drawable d = mListView.getDivider();
final Rect r = d.getBounds();
new PollingCheck() {
@Override
protected boolean check() {
return r.bottom - r.top > 0;
}
}.run();
mInstrumentation.runOnMainSync(new Runnable() {
public void run() {
mListView.setDividerHeight(20);
}
});
mInstrumentation.waitForIdleSync();
assertEquals(20, mListView.getDividerHeight());
assertEquals(20, r.bottom - r.top);
mInstrumentation.runOnMainSync(new Runnable() {
public void run() {
mListView.setDividerHeight(10);
}
});
mInstrumentation.waitForIdleSync();
assertEquals(10, mListView.getDividerHeight());
assertEquals(10, r.bottom - r.top);
}
public void testAccessItemsCanFocus() {
mListView.setItemsCanFocus(true);
assertTrue(mListView.getItemsCanFocus());
mListView.setItemsCanFocus(false);
assertFalse(mListView.getItemsCanFocus());
// TODO: how to check?
}
public void testAccessAdapter() {
mInstrumentation.runOnMainSync(new Runnable() {
public void run() {
mListView.setAdapter(mAdapter_countries);
}
});
mInstrumentation.waitForIdleSync();
assertSame(mAdapter_countries, mListView.getAdapter());
assertEquals(mCountryList.length, mListView.getCount());
mInstrumentation.runOnMainSync(new Runnable() {
public void run() {
mListView.setAdapter(mAdapter_names);
}
});
mInstrumentation.waitForIdleSync();
assertSame(mAdapter_names, mListView.getAdapter());
assertEquals(mNameList.length, mListView.getCount());
}
@UiThreadTest
public void testAccessItemChecked() {
// NONE mode
mListView.setChoiceMode(ListView.CHOICE_MODE_NONE);
assertEquals(ListView.CHOICE_MODE_NONE, mListView.getChoiceMode());
mListView.setItemChecked(1, true);
assertEquals(ListView.INVALID_POSITION, mListView.getCheckedItemPosition());
assertFalse(mListView.isItemChecked(1));
// SINGLE mode
mListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
assertEquals(ListView.CHOICE_MODE_SINGLE, mListView.getChoiceMode());
mListView.setItemChecked(2, true);
assertEquals(2, mListView.getCheckedItemPosition());
assertTrue(mListView.isItemChecked(2));
mListView.setItemChecked(3, true);
assertEquals(3, mListView.getCheckedItemPosition());
assertTrue(mListView.isItemChecked(3));
assertFalse(mListView.isItemChecked(2));
// test attempt to uncheck a item that wasn't checked to begin with
mListView.setItemChecked(4, false);
// item three should still be checked
assertEquals(3, mListView.getCheckedItemPosition());
assertFalse(mListView.isItemChecked(4));
assertTrue(mListView.isItemChecked(3));
assertFalse(mListView.isItemChecked(2));
mListView.setItemChecked(4, true);
assertTrue(mListView.isItemChecked(4));
mListView.clearChoices();
assertEquals(ListView.INVALID_POSITION, mListView.getCheckedItemPosition());
assertFalse(mListView.isItemChecked(4));
// MULTIPLE mode
mListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
assertEquals(ListView.CHOICE_MODE_MULTIPLE, mListView.getChoiceMode());
mListView.setItemChecked(1, true);
assertEquals(ListView.INVALID_POSITION, mListView.getCheckedItemPosition());
SparseBooleanArray array = mListView.getCheckedItemPositions();
assertTrue(array.get(1));
assertFalse(array.get(2));
assertTrue(mListView.isItemChecked(1));
assertFalse(mListView.isItemChecked(2));
mListView.setItemChecked(2, true);
mListView.setItemChecked(3, false);
mListView.setItemChecked(4, true);
assertTrue(array.get(1));
assertTrue(array.get(2));
assertFalse(array.get(3));
assertTrue(array.get(4));
assertTrue(mListView.isItemChecked(1));
assertTrue(mListView.isItemChecked(2));
assertFalse(mListView.isItemChecked(3));
assertTrue(mListView.isItemChecked(4));
mListView.clearChoices();
assertFalse(array.get(1));
assertFalse(array.get(2));
assertFalse(array.get(3));
assertFalse(array.get(4));
assertFalse(mListView.isItemChecked(1));
assertFalse(mListView.isItemChecked(2));
assertFalse(mListView.isItemChecked(3));
assertFalse(mListView.isItemChecked(4));
}
public void testAccessFooterView() {
final TextView footerView1 = new TextView(mActivity);
footerView1.setText("footerview1");
final TextView footerView2 = new TextView(mActivity);
footerView2.setText("footerview2");
mInstrumentation.runOnMainSync(new Runnable() {
public void run() {
mListView.setFooterDividersEnabled(true);
}
});
mInstrumentation.waitForIdleSync();
assertEquals(0, mListView.getFooterViewsCount());
mInstrumentation.runOnMainSync(new Runnable() {
public void run() {
mListView.addFooterView(footerView1, null, true);
}
});
mInstrumentation.waitForIdleSync();
assertEquals(1, mListView.getFooterViewsCount());
mInstrumentation.runOnMainSync(new Runnable() {
public void run() {
mListView.addFooterView(footerView2);
}
});
mInstrumentation.waitForIdleSync();
assertEquals(2, mListView.getFooterViewsCount());
mInstrumentation.runOnMainSync(new Runnable() {
public void run() {
mListView.setAdapter(mAdapter_countries);
}
});
mInstrumentation.waitForIdleSync();
mInstrumentation.runOnMainSync(new Runnable() {
public void run() {
mListView.removeFooterView(footerView1);
}
});
mInstrumentation.waitForIdleSync();
assertEquals(1, mListView.getFooterViewsCount());
mInstrumentation.runOnMainSync(new Runnable() {
public void run() {
mListView.removeFooterView(footerView2);
}
});
mInstrumentation.waitForIdleSync();
assertEquals(0, mListView.getFooterViewsCount());
}
public void testAccessHeaderView() {
final TextView headerView1 = (TextView) mActivity.findViewById(R.id.headerview1);
final TextView headerView2 = (TextView) mActivity.findViewById(R.id.headerview2);
mInstrumentation.runOnMainSync(new Runnable() {
public void run() {
mListView.setHeaderDividersEnabled(true);
}
});
mInstrumentation.waitForIdleSync();
assertEquals(0, mListView.getHeaderViewsCount());
mInstrumentation.runOnMainSync(new Runnable() {
public void run() {
mListView.addHeaderView(headerView2, null, true);
}
});
mInstrumentation.waitForIdleSync();
assertEquals(1, mListView.getHeaderViewsCount());
mInstrumentation.runOnMainSync(new Runnable() {
public void run() {
mListView.addHeaderView(headerView1);
}
});
mInstrumentation.waitForIdleSync();
assertEquals(2, mListView.getHeaderViewsCount());
}
public void testHeaderFooterType() throws Throwable {
final TextView headerView = new TextView(getActivity());
final List<Pair<View, View>> mismatch = new ArrayList<Pair<View, View>>();
final ArrayAdapter adapter = new ArrayAdapter<String>(mActivity,
android.R.layout.simple_list_item_1, mNameList) {
@Override
public int getItemViewType(int position) {
return position == 0 ? AdapterView.ITEM_VIEW_TYPE_HEADER_OR_FOOTER :
super.getItemViewType(position - 1);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (position == 0) {
if (convertView != null && convertView != headerView) {
mismatch.add(new Pair<View, View>(headerView, convertView));
}
return headerView;
} else {
return super.getView(position - 1, convertView, parent);
}
}
@Override
public int getCount() {
return super.getCount() + 1;
}
};
runTestOnUiThread(new Runnable() {
@Override
public void run() {
mListView.setAdapter(adapter);
}
});
getInstrumentation().waitForIdleSync();
runTestOnUiThread(new Runnable() {
@Override
public void run() {
adapter.notifyDataSetChanged();
}
});
getInstrumentation().waitForIdleSync();
assertEquals(0, mismatch.size());
}
public void testAccessDivider() {
mInstrumentation.runOnMainSync(new Runnable() {
public void run() {
mListView.setAdapter(mAdapter_countries);
}
});
mInstrumentation.waitForIdleSync();
Drawable defaultDrawable = mListView.getDivider();
final Rect r = defaultDrawable.getBounds();
new PollingCheck() {
@Override
protected boolean check() {
return r.bottom - r.top > 0;
}
}.run();
final Drawable d = mActivity.getResources().getDrawable(R.drawable.scenery);
mInstrumentation.runOnMainSync(new Runnable() {
public void run() {
mListView.setDivider(d);
}
});
mInstrumentation.waitForIdleSync();
assertSame(d, mListView.getDivider());
assertEquals(d.getBounds().height(), mListView.getDividerHeight());
mInstrumentation.runOnMainSync(new Runnable() {
public void run() {
mListView.setDividerHeight(10);
}
});
mInstrumentation.waitForIdleSync();
assertEquals(10, mListView.getDividerHeight());
assertEquals(10, r2.bottom - r2.top);
}
public void testSetSelection() {
mInstrumentation.runOnMainSync(new Runnable() {
public void run() {
mListView.setAdapter(mAdapter_countries);
}
});
mInstrumentation.waitForIdleSync();
mInstrumentation.runOnMainSync(new Runnable() {
public void run() {
mListView.setSelection(1);
}
});
mInstrumentation.waitForIdleSync();
String item = (String) mListView.getSelectedItem();
assertEquals(mCountryList[1], item);
mInstrumentation.runOnMainSync(new Runnable() {
public void run() {
mListView.setSelectionFromTop(5, 0);
}
});
mInstrumentation.waitForIdleSync();
item = (String) mListView.getSelectedItem();
assertEquals(mCountryList[5], item);
mInstrumentation.runOnMainSync(new Runnable() {
public void run() {
mListView.setSelectionAfterHeaderView();
}
});
mInstrumentation.waitForIdleSync();
item = (String) mListView.getSelectedItem();
assertEquals(mCountryList[0], item);
}
public void testOnKeyUpDown() {
// implementation details, do NOT test
}
public void testPerformItemClick() {
mInstrumentation.runOnMainSync(new Runnable() {
public void run() {
mListView.setAdapter(mAdapter_countries);
}
});
mInstrumentation.waitForIdleSync();
mListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
mInstrumentation.runOnMainSync(new Runnable() {
public void run() {
mListView.setSelection(2);
}
});
mInstrumentation.waitForIdleSync();
final TextView child = (TextView) mAdapter_countries.getView(2, null, mListView);
assertNotNull(child);
assertEquals(mCountryList[2], child.getText().toString());
final long itemID = mAdapter_countries.getItemId(2);
assertEquals(2, itemID);
mInstrumentation.runOnMainSync(new Runnable() {
public void run() {
mListView.performItemClick(child, 2, itemID);
}
});
mInstrumentation.waitForIdleSync();
MockOnItemClickListener onClickListener = new MockOnItemClickListener();
mListView.setOnItemClickListener(onClickListener);
assertNull(onClickListener.getView());
assertEquals(0, onClickListener.getPosition());
assertEquals(0, onClickListener.getID());
mInstrumentation.runOnMainSync(new Runnable() {
public void run() {
mListView.performItemClick(child, 2, itemID);
}
});
mInstrumentation.waitForIdleSync();
assertSame(child, onClickListener.getView());
assertEquals(2, onClickListener.getPosition());
assertEquals(2, onClickListener.getID());
}
public void testSaveAndRestoreInstanceState() {
// implementation details, do NOT test
}
public void testDispatchKeyEvent() {
mInstrumentation.runOnMainSync(new Runnable() {
public void run() {
mListView.setAdapter(mAdapter_countries);
mListView.requestFocus();
}
});
mInstrumentation.waitForIdleSync();
assertTrue(mListView.hasFocus());
mInstrumentation.runOnMainSync(new Runnable() {
public void run() {
mListView.setSelection(1);
}
});
mInstrumentation.waitForIdleSync();
String item = (String) mListView.getSelectedItem();
assertEquals(mCountryList[1], item);
mInstrumentation.runOnMainSync(new Runnable() {
public void run() {
KeyEvent keyEvent = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_A);
mListView.dispatchKeyEvent(keyEvent);
}
});
mInstrumentation.waitForIdleSync();
mInstrumentation.runOnMainSync(new Runnable() {
public void run() {
KeyEvent keyEvent = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_DOWN);
mListView.dispatchKeyEvent(keyEvent);
mListView.dispatchKeyEvent(keyEvent);
mListView.dispatchKeyEvent(keyEvent);
}
});
mInstrumentation.waitForIdleSync();
item = (String)mListView.getSelectedItem();
assertEquals(mCountryList[4], item);
}
public void testRequestChildRectangleOnScreen() {
mInstrumentation.runOnMainSync(new Runnable() {
public void run() {
mListView.setAdapter(mAdapter_countries);
}
});
mInstrumentation.waitForIdleSync();
TextView child = (TextView) mAdapter_countries.getView(0, null, mListView);
assertNotNull(child);
assertEquals(mCountryList[0], child.getText().toString());
Rect rect = new Rect(0, 0, 10, 10);
assertFalse(mListView.requestChildRectangleOnScreen(child, rect, false));
// TODO: how to check?
}
public void testOnTouchEvent() {
// implementation details, do NOT test
}
@UiThreadTest
public void testCanAnimate() {
MyListView listView = new MyListView(mActivity, mAttributeSet);
assertFalse(listView.canAnimate());
listView.setAdapter(mAdapter_countries);
assertFalse(listView.canAnimate());
LayoutAnimationController controller = new LayoutAnimationController(
mActivity, mAttributeSet);
listView.setLayoutAnimation(controller);
assertTrue(listView.canAnimate());
}
@UiThreadTest
public void testDispatchDraw() {
// implementation details, do NOT test
}
@UiThreadTest
public void testFindViewTraversal() {
MyListView listView = new MyListView(mActivity, mAttributeSet);
TextView headerView = (TextView) mActivity.findViewById(R.id.headerview1);
assertNull(listView.findViewTraversal(R.id.headerview1));
listView.addHeaderView(headerView);
assertNotNull(listView.findViewTraversal(R.id.headerview1));
assertSame(headerView, listView.findViewTraversal(R.id.headerview1));
}
@UiThreadTest
public void testFindViewWithTagTraversal() {
MyListView listView = new MyListView(mActivity, mAttributeSet);
TextView headerView = (TextView) mActivity.findViewById(R.id.headerview1);
assertNull(listView.findViewWithTagTraversal("header"));
headerView.setTag("header");
listView.addHeaderView(headerView);
assertNotNull(listView.findViewWithTagTraversal("header"));
assertSame(headerView, listView.findViewWithTagTraversal("header"));
}
public void testLayoutChildren() {
// TODO: how to test?
}
public void testOnFinishInflate() {
// implementation details, do NOT test
}
public void testOnFocusChanged() {
// implementation details, do NOT test
}
public void testOnMeasure() {
// implementation details, do NOT test
}
/**
* MyListView for test
*/
private static class MyListView extends ListView {
public MyListView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected boolean canAnimate() {
return super.canAnimate();
}
@Override
protected void dispatchDraw(Canvas canvas) {
super.dispatchDraw(canvas);
}
@Override
protected View findViewTraversal(int id) {
return super.findViewTraversal(id);
}
@Override
protected View findViewWithTagTraversal(Object tag) {
return super.findViewWithTagTraversal(tag);
}
@Override
protected void layoutChildren() {
super.layoutChildren();
}
}
private static class MockOnItemClickListener implements OnItemClickListener {
private View mView;
private int mPosition;
private long mID;
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
mView = view;
mPosition = position;
mID = id;
}
public View getView() {
return mView;
}
public int getPosition() {
return mPosition;
}
public long getID() {
return mID;
}
}
/**
* The following functions are merged from frameworktest.
*/
@MediumTest
public void testRequestLayout() throws Exception {
ListView listView = new ListView(mActivity);
List<String> items = new ArrayList<>();
items.add("hello");
Adapter<String> adapter = new Adapter<String>(mActivity, 0, items);
listView.setAdapter(adapter);
int measureSpec = View.MeasureSpec.makeMeasureSpec(100, View.MeasureSpec.EXACTLY);
adapter.notifyDataSetChanged();
listView.measure(measureSpec, measureSpec);
listView.layout(0, 0, 100, 100);
MockView childView = (MockView) listView.getChildAt(0);
childView.requestLayout();
childView.onMeasureCalled = false;
listView.measure(measureSpec, measureSpec);
listView.layout(0, 0, 100, 100);
Assert.assertTrue(childView.onMeasureCalled);
}
@MediumTest
public void testNoSelectableItems() throws Exception {
ListView listView = new ListView(mActivity);
// We use a header as the unselectable item to remain after the selectable one is removed.
listView.addHeaderView(new View(mActivity), null, false);
List<String> items = new ArrayList<>();
items.add("hello");
Adapter<String> adapter = new Adapter<String>(mActivity, 0, items);
listView.setAdapter(adapter);
listView.setSelection(1);
int measureSpec = View.MeasureSpec.makeMeasureSpec(100, View.MeasureSpec.EXACTLY);
adapter.notifyDataSetChanged();
listView.measure(measureSpec, measureSpec);
listView.layout(0, 0, 100, 100);
items.remove(0);
adapter.notifyDataSetChanged();
listView.measure(measureSpec, measureSpec);
listView.layout(0, 0, 100, 100);
}
private class MockView extends View {
public boolean onMeasureCalled = false;
public MockView(Context context) {
super(context);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
onMeasureCalled = true;
}
}
private class Adapter<T> extends ArrayAdapter<T> {
public Adapter(Context context, int resource, List<T> objects) {
super(context, resource, objects);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
return new MockView(getContext());
}
}
public void testTransientStateUnstableIds() throws Exception {
final ListView listView = mListView;
final ArrayList<String> items = new ArrayList<String>(Arrays.asList(mCountryList));
final ArrayAdapter<String> adapter = new ArrayAdapter<String>(mActivity,
android.R.layout.simple_list_item_1, items);
mInstrumentation.runOnMainSync(new Runnable() {
@Override
public void run() {
listView.setAdapter(adapter);
}
});
mInstrumentation.waitForIdleSync();
final View oldItem = listView.getChildAt(2);
final CharSequence oldText = ((TextView) oldItem.findViewById(android.R.id.text1))
.getText();
oldItem.setHasTransientState(true);
mInstrumentation.runOnMainSync(new Runnable() {
@Override
public void run() {
adapter.remove(adapter.getItem(0));
adapter.notifyDataSetChanged();
}
});
mInstrumentation.waitForIdleSync();
final View newItem = listView.getChildAt(2);
final CharSequence newText = ((TextView) newItem.findViewById(android.R.id.text1))
.getText();
Assert.assertFalse(oldText.equals(newText));
}
public void testTransientStateStableIds() throws Exception {
final ListView listView = mListView;
final ArrayList<String> items = new ArrayList<String>(Arrays.asList(mCountryList));
final StableArrayAdapter<String> adapter = new StableArrayAdapter<String>(mActivity,
android.R.layout.simple_list_item_1, items);
mInstrumentation.runOnMainSync(new Runnable() {
@Override
public void run() {
listView.setAdapter(adapter);
}
});
mInstrumentation.waitForIdleSync();
final Object tag = new Object();
final View oldItem = listView.getChildAt(2);
final CharSequence oldText = ((TextView) oldItem.findViewById(android.R.id.text1))
.getText();
oldItem.setHasTransientState(true);
oldItem.setTag(tag);
mInstrumentation.runOnMainSync(new Runnable() {
@Override
public void run() {
adapter.remove(adapter.getItem(0));
adapter.notifyDataSetChanged();
}
});
mInstrumentation.waitForIdleSync();
final View newItem = listView.getChildAt(1);
final CharSequence newText = ((TextView) newItem.findViewById(android.R.id.text1))
.getText();
Assert.assertTrue(newItem.hasTransientState());
Assert.assertEquals(oldText, newText);
Assert.assertEquals(tag, newItem.getTag());
}
private static class StableArrayAdapter<T> extends ArrayAdapter<T> {
public StableArrayAdapter(Context context, int resource, List<T> objects) {
super(context, resource, objects);
}
@Override
public long getItemId(int position) {
return getItem(position).hashCode();
}
@Override
public boolean hasStableIds() {
return true;
}
}
}