1 /* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.widget.cts; 18 19 import android.test.suitebuilder.annotation.MediumTest; 20 import android.widget.cts.R; 21 22 import org.xmlpull.v1.XmlPullParser; 23 import org.xmlpull.v1.XmlPullParserException; 24 25 import android.app.Activity; 26 import android.app.Instrumentation; 27 import android.content.Context; 28 import android.cts.util.PollingCheck; 29 import android.cts.util.WidgetTestUtils; 30 import android.graphics.Canvas; 31 import android.graphics.Color; 32 import android.graphics.Rect; 33 import android.graphics.drawable.Drawable; 34 import android.test.ActivityInstrumentationTestCase2; 35 import android.test.TouchUtils; 36 import android.text.Editable; 37 import android.text.SpannableStringBuilder; 38 import android.util.AttributeSet; 39 import android.util.Xml; 40 import android.view.ContextMenu.ContextMenuInfo; 41 import android.view.View; 42 import android.view.ViewGroup; 43 import android.widget.AbsListView; 44 import android.widget.AbsListView.OnScrollListener; 45 import android.widget.AbsListView.RecyclerListener; 46 import android.widget.AdapterView; 47 import android.widget.AdapterView.OnItemLongClickListener; 48 import android.widget.ArrayAdapter; 49 import android.widget.ListAdapter; 50 import android.widget.ListView; 51 import android.widget.TextView; 52 53 import java.io.IOException; 54 import java.util.ArrayList; 55 import java.util.List; 56 57 public class AbsListViewTest extends ActivityInstrumentationTestCase2<ListViewCtsActivity> { 58 private final String[] mShortList = new String[] { 59 "This", "is", "short", "!", 60 }; 61 private final String[] mCountryList = new String[] { 62 "Argentina", "Australia", "China", "France", "Germany", "Italy", "Japan", "United States", 63 "Argentina", "Australia", "China", "France", "Germany", "Italy", "Japan", "United States", 64 "Argentina", "Australia", "China", "France", "Germany", "Italy", "Japan", "United States" 65 }; 66 67 private ListView mListView; 68 private Activity mActivity; 69 private Instrumentation mInstrumentation; 70 private AttributeSet mAttributeSet; 71 private ArrayAdapter<String> mAdapter_short; 72 private ArrayAdapter<String> mAdapter_countries; 73 74 private static final float DELTA = 0.001f; 75 AbsListViewTest()76 public AbsListViewTest() { 77 super("android.widget.cts", ListViewCtsActivity.class); 78 } 79 80 81 @Override setUp()82 protected void setUp() throws Exception { 83 super.setUp(); 84 85 mActivity = getActivity(); 86 new PollingCheck() { 87 @Override 88 protected boolean check() { 89 return mActivity.hasWindowFocus(); 90 } 91 }.run(); 92 mInstrumentation = getInstrumentation(); 93 94 XmlPullParser parser = mActivity.getResources().getXml(R.layout.listview_layout); 95 WidgetTestUtils.beginDocument(parser, "LinearLayout"); 96 mAttributeSet = Xml.asAttributeSet(parser); 97 98 mAdapter_short = new ArrayAdapter<String>(mActivity, 99 android.R.layout.simple_list_item_1, mShortList); 100 mAdapter_countries = new ArrayAdapter<String>(mActivity, 101 android.R.layout.simple_list_item_1, mCountryList); 102 103 mListView = (ListView)mActivity.findViewById(R.id.listview_default); 104 } 105 testConstructor()106 public void testConstructor() { 107 /** 108 * We can not test the constructors. 109 */ 110 } 111 testAccessFastScrollEnabled()112 public void testAccessFastScrollEnabled() { 113 mListView.setFastScrollEnabled(false); 114 assertFalse(mListView.isFastScrollEnabled()); 115 116 mListView.setFastScrollEnabled(true); 117 assertTrue(mListView.isFastScrollEnabled()); 118 } 119 testAccessSmoothScrollbarEnabled()120 public void testAccessSmoothScrollbarEnabled() { 121 mListView.setSmoothScrollbarEnabled(false); 122 assertFalse(mListView.isSmoothScrollbarEnabled()); 123 124 mListView.setSmoothScrollbarEnabled(true); 125 assertTrue(mListView.isSmoothScrollbarEnabled()); 126 } 127 testAccessScrollingCacheEnabled()128 public void testAccessScrollingCacheEnabled() { 129 mListView.setScrollingCacheEnabled(false); 130 assertFalse(mListView.isScrollingCacheEnabled()); 131 132 mListView.setScrollingCacheEnabled(true); 133 assertTrue(mListView.isScrollingCacheEnabled()); 134 } 135 setAdapter()136 private void setAdapter() throws Throwable { 137 setAdapter(mAdapter_countries); 138 } 139 setAdapter(final ListAdapter adapter)140 private void setAdapter(final ListAdapter adapter) throws Throwable { 141 runTestOnUiThread(new Runnable() { 142 public void run() { 143 mListView.setAdapter(adapter); 144 } 145 }); 146 mInstrumentation.waitForIdleSync(); 147 } 148 setListSelection(int index)149 private void setListSelection(int index) throws Throwable { 150 final int i = index; 151 152 runTestOnUiThread(new Runnable() { 153 public void run() { 154 mListView.setSelection(i); 155 } 156 }); 157 mInstrumentation.waitForIdleSync(); 158 } testSetOnScrollListener()159 public void testSetOnScrollListener() throws Throwable { 160 MockOnScrollListener onScrollListener = new MockOnScrollListener(); 161 162 assertNull(onScrollListener.getView()); 163 assertEquals(0, onScrollListener.getFirstVisibleItem()); 164 assertEquals(0, onScrollListener.getVisibleItemCount()); 165 assertEquals(0, onScrollListener.getTotalItemCount()); 166 assertEquals(-1, onScrollListener.getScrollState()); 167 168 assertFalse(onScrollListener.isOnScrollCalled()); 169 assertFalse(onScrollListener.isOnScrollStateChangedCalled()); 170 171 mListView.setOnScrollListener(onScrollListener); 172 assertSame(mListView, onScrollListener.getView()); 173 assertEquals(0, onScrollListener.getFirstVisibleItem()); 174 assertEquals(0, onScrollListener.getVisibleItemCount()); 175 assertEquals(0, onScrollListener.getTotalItemCount()); 176 assertEquals(-1, onScrollListener.getScrollState()); 177 178 assertTrue(onScrollListener.isOnScrollCalled()); 179 assertFalse(onScrollListener.isOnScrollStateChangedCalled()); 180 onScrollListener.reset(); 181 182 setAdapter(); 183 184 assertSame(mListView, onScrollListener.getView()); 185 assertEquals(0, onScrollListener.getFirstVisibleItem()); 186 assertEquals(mListView.getChildCount(), onScrollListener.getVisibleItemCount()); 187 assertEquals(mCountryList.length, onScrollListener.getTotalItemCount()); 188 assertEquals(-1, onScrollListener.getScrollState()); 189 190 assertTrue(onScrollListener.isOnScrollCalled()); 191 assertFalse(onScrollListener.isOnScrollStateChangedCalled()); 192 onScrollListener.reset(); 193 194 TouchUtils.scrollToBottom(this, mActivity, mListView); 195 assertSame(mListView, onScrollListener.getView()); 196 assertEquals(mListView.getChildCount(), onScrollListener.getVisibleItemCount()); 197 assertEquals(mCountryList.length, onScrollListener.getTotalItemCount()); 198 199 assertTrue(onScrollListener.isOnScrollCalled()); 200 assertTrue(onScrollListener.isOnScrollStateChangedCalled()); 201 } 202 testFling()203 public void testFling() throws Throwable { 204 MockOnScrollListener onScrollListener = new MockOnScrollListener(); 205 mListView.setOnScrollListener(onScrollListener); 206 207 setAdapter(); 208 209 // Fling down from top, expect a scroll. 210 fling(10000, onScrollListener); 211 assertTrue(onScrollListener.isOnScrollCalled()); 212 assertTrue(0 < onScrollListener.getFirstVisibleItem()); 213 214 // Fling up the same amount, expect a scroll to the original position. 215 fling(-10000, onScrollListener); 216 assertTrue(onScrollListener.isOnScrollCalled()); 217 assertEquals(0, onScrollListener.getFirstVisibleItem()); 218 219 // Fling up again, expect no scroll, as the viewport is already at top. 220 fling(-10000, onScrollListener); 221 assertFalse(onScrollListener.isOnScrollCalled()); 222 assertEquals(0, onScrollListener.getFirstVisibleItem()); 223 224 // Fling up again with a huge velocity, expect no scroll. 225 fling(-50000, onScrollListener); 226 assertFalse(onScrollListener.isOnScrollCalled()); 227 assertEquals(0, onScrollListener.getFirstVisibleItem()); 228 } 229 fling(int velocityY, MockOnScrollListener onScrollListener)230 private void fling(int velocityY, MockOnScrollListener onScrollListener) throws Throwable { 231 onScrollListener.reset(); 232 233 final int v = velocityY; 234 runTestOnUiThread(new Runnable() { 235 public void run() { 236 mListView.fling(v); 237 } 238 }); 239 240 do { 241 mInstrumentation.waitForIdleSync(); 242 } while (onScrollListener.getScrollState() != OnScrollListener.SCROLL_STATE_IDLE); 243 } 244 testGetFocusedRect()245 public void testGetFocusedRect() throws Throwable { 246 setAdapter(mAdapter_short); 247 setListSelection(0); 248 249 Rect r1 = new Rect(); 250 mListView.getFocusedRect(r1); 251 252 assertEquals(0, r1.top); 253 assertTrue(r1.bottom > 0); 254 assertEquals(0, r1.left); 255 assertTrue(r1.right > 0); 256 257 setListSelection(3); 258 Rect r2 = new Rect(); 259 mListView.getFocusedRect(r2); 260 assertTrue(r2.top > 0); 261 assertTrue(r2.bottom > 0); 262 assertEquals(0, r2.left); 263 assertTrue(r2.right > 0); 264 265 assertTrue(r2.top > r1.top); 266 assertEquals(r1.bottom - r1.top, r2.bottom - r2.top); 267 assertEquals(r1.right, r2.right); 268 } 269 testAccessStackFromBottom()270 public void testAccessStackFromBottom() throws Throwable { 271 setAdapter(); 272 273 runTestOnUiThread(new Runnable() { 274 public void run() { 275 mListView.setStackFromBottom(false); 276 } 277 }); 278 assertFalse(mListView.isStackFromBottom()); 279 assertEquals(0, mListView.getSelectedItemPosition()); 280 281 runTestOnUiThread(new Runnable() { 282 public void run() { 283 mListView.setStackFromBottom(true); 284 } 285 }); 286 287 mInstrumentation.waitForIdleSync(); 288 assertTrue(mListView.isStackFromBottom()); 289 // ensure last item in list is selected 290 assertEquals(mCountryList.length-1, mListView.getSelectedItemPosition()); 291 } 292 testAccessSelectedItem()293 public void testAccessSelectedItem() throws Throwable { 294 assertNull(mListView.getSelectedView()); 295 296 setAdapter(); 297 TextView tv = (TextView) mListView.getSelectedView(); 298 assertEquals(mCountryList[0], tv.getText().toString()); 299 300 setListSelection(5); 301 tv = (TextView) mListView.getSelectedView(); 302 assertEquals(mCountryList[5], tv.getText().toString()); 303 304 setListSelection(2); 305 tv = (TextView) mListView.getSelectedView(); 306 assertEquals(mCountryList[2], tv.getText().toString()); 307 } 308 testAccessListPadding()309 public void testAccessListPadding() throws Throwable { 310 setAdapter(); 311 312 assertEquals(0, mListView.getListPaddingLeft()); 313 assertEquals(0, mListView.getListPaddingTop()); 314 assertEquals(0, mListView.getListPaddingRight()); 315 assertEquals(0, mListView.getListPaddingBottom()); 316 317 final Rect r = new Rect(0, 0, 40, 60); 318 runTestOnUiThread(new Runnable() { 319 public void run() { 320 mListView.setPadding(r.left, r.top, r.right, r.bottom); 321 } 322 }); 323 mInstrumentation.waitForIdleSync(); 324 325 assertEquals(r.left, mListView.getListPaddingLeft()); 326 assertEquals(r.top, mListView.getListPaddingTop()); 327 assertEquals(r.right, mListView.getListPaddingRight()); 328 assertEquals(r.bottom, mListView.getListPaddingBottom()); 329 } 330 testAccessSelector()331 public void testAccessSelector() throws Throwable { 332 setAdapter(); 333 334 final Drawable d = mActivity.getResources().getDrawable(R.drawable.pass); 335 mListView.setSelector(d); 336 337 runTestOnUiThread(new Runnable() { 338 public void run() { 339 mListView.requestLayout(); 340 } 341 }); 342 mInstrumentation.waitForIdleSync(); 343 assertSame(d, mListView.getSelector()); 344 assertTrue(mListView.verifyDrawable(d)); 345 346 mListView.setSelector(R.drawable.failed); 347 mListView.setDrawSelectorOnTop(true); 348 349 runTestOnUiThread(new Runnable() { 350 public void run() { 351 mListView.requestLayout(); 352 } 353 }); 354 mInstrumentation.waitForIdleSync(); 355 356 Drawable drawable = mListView.getSelector(); 357 assertNotNull(drawable); 358 final Rect r = drawable.getBounds(); 359 360 final TextView v = (TextView) mListView.getSelectedView(); 361 new PollingCheck() { 362 @Override 363 protected boolean check() { 364 return v.getRight() == r.right; 365 } 366 }.run(); 367 assertEquals(v.getLeft(), r.left); 368 assertEquals(v.getTop(), r.top); 369 assertEquals(v.getBottom(), r.bottom); 370 } 371 testSetScrollIndicators()372 public void testSetScrollIndicators() throws Throwable { 373 TextView tv1 = (TextView) mActivity.findViewById(R.id.headerview1); 374 TextView tv2 = (TextView) mActivity.findViewById(R.id.footerview1); 375 376 setAdapter(); 377 378 mListView.setScrollIndicators(tv1, tv2); 379 380 runTestOnUiThread(new Runnable() { 381 public void run() { 382 mListView.requestLayout(); 383 } 384 }); 385 mInstrumentation.waitForIdleSync(); 386 } 387 testShowContextMenuForChild()388 public void testShowContextMenuForChild() throws Throwable { 389 setAdapter(); 390 setListSelection(1); 391 392 TextView tv = (TextView) mListView.getSelectedView(); 393 assertFalse(mListView.showContextMenuForChild(tv)); 394 395 // TODO: how to show the contextMenu success 396 } 397 testPointToPosition()398 public void testPointToPosition() throws Throwable { 399 assertEquals(AbsListView.INVALID_POSITION, mListView.pointToPosition(-1, -1)); 400 assertEquals(AbsListView.INVALID_ROW_ID, mListView.pointToRowId(-1, -1)); 401 402 setAdapter(); 403 404 View row = mListView.getChildAt(0); 405 int rowHeight = row.getHeight(); 406 int middleOfSecondRow = rowHeight + rowHeight/2; 407 408 int position1 = mListView.pointToPosition(0, 0); 409 int position2 = mListView.pointToPosition(50, middleOfSecondRow); 410 411 assertEquals(mAdapter_countries.getItemId(position1), mListView.pointToRowId(0, 0)); 412 assertEquals(mAdapter_countries.getItemId(position2), 413 mListView.pointToRowId(50, middleOfSecondRow)); 414 415 assertTrue(position2 > position1); 416 } 417 testDraw()418 public void testDraw() { 419 Canvas canvas = new Canvas(); 420 mListView.draw(canvas); 421 422 MyListView listView = new MyListView(mActivity); 423 listView.dispatchDraw(canvas); 424 425 // TODO: how to check 426 } 427 testSetRecyclerListener()428 public void testSetRecyclerListener() throws Throwable { 429 setAdapter(); 430 431 MockRecyclerListener recyclerListener = new MockRecyclerListener(); 432 List<View> views = new ArrayList<View>(); 433 434 assertNull(recyclerListener.getView()); 435 mListView.setRecyclerListener(recyclerListener); 436 mListView.reclaimViews(views); 437 438 assertTrue(views.size() > 0); 439 assertNotNull(recyclerListener.getView()); 440 441 assertSame(recyclerListener.getView(), views.get(views.size() - 1)); 442 } 443 testAccessCacheColorHint()444 public void testAccessCacheColorHint() { 445 mListView.setCacheColorHint(Color.RED); 446 assertEquals(Color.RED, mListView.getCacheColorHint()); 447 assertEquals(Color.RED, mListView.getSolidColor()); 448 449 mListView.setCacheColorHint(Color.LTGRAY); 450 assertEquals(Color.LTGRAY, mListView.getCacheColorHint()); 451 assertEquals(Color.LTGRAY, mListView.getSolidColor()); 452 453 mListView.setCacheColorHint(Color.GRAY); 454 assertEquals(Color.GRAY, mListView.getCacheColorHint()); 455 assertEquals(Color.GRAY, mListView.getSolidColor()); 456 } 457 testAccessTranscriptMode()458 public void testAccessTranscriptMode() { 459 mListView.setTranscriptMode(AbsListView.TRANSCRIPT_MODE_ALWAYS_SCROLL); 460 assertEquals(AbsListView.TRANSCRIPT_MODE_ALWAYS_SCROLL, mListView.getTranscriptMode()); 461 462 mListView.setTranscriptMode(AbsListView.TRANSCRIPT_MODE_DISABLED); 463 assertEquals(AbsListView.TRANSCRIPT_MODE_DISABLED, mListView.getTranscriptMode()); 464 465 mListView.setTranscriptMode(AbsListView.TRANSCRIPT_MODE_NORMAL); 466 assertEquals(AbsListView.TRANSCRIPT_MODE_NORMAL, mListView.getTranscriptMode()); 467 } 468 testCheckLayoutParams()469 public void testCheckLayoutParams() { 470 MyListView listView = new MyListView(mActivity); 471 472 AbsListView.LayoutParams param1 = new AbsListView.LayoutParams(10, 10); 473 assertTrue(listView.checkLayoutParams(param1)); 474 475 ViewGroup.LayoutParams param2 = new ViewGroup.LayoutParams(10, 10); 476 assertFalse(listView.checkLayoutParams(param2)); 477 } 478 testComputeVerticalScrollValues()479 public void testComputeVerticalScrollValues() { 480 MyListView listView = new MyListView(mActivity); 481 assertEquals(0, listView.computeVerticalScrollRange()); 482 assertEquals(0, listView.computeVerticalScrollOffset()); 483 assertEquals(0, listView.computeVerticalScrollExtent()); 484 485 listView.setAdapter(mAdapter_countries); 486 listView.setSmoothScrollbarEnabled(false); 487 assertEquals(mAdapter_countries.getCount(), listView.computeVerticalScrollRange()); 488 assertEquals(0, listView.computeVerticalScrollOffset()); 489 assertEquals(0, listView.computeVerticalScrollExtent()); 490 491 listView.setSmoothScrollbarEnabled(true); 492 assertEquals(0, listView.computeVerticalScrollOffset()); 493 assertEquals(0, listView.computeVerticalScrollExtent()); 494 } 495 testGenerateLayoutParams()496 public void testGenerateLayoutParams() throws XmlPullParserException, IOException { 497 ViewGroup.LayoutParams res = mListView.generateLayoutParams(mAttributeSet); 498 assertNotNull(res); 499 assertTrue(res instanceof AbsListView.LayoutParams); 500 501 MyListView listView = new MyListView(mActivity); 502 ViewGroup.LayoutParams p = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 503 ViewGroup.LayoutParams.WRAP_CONTENT); 504 505 res = listView.generateLayoutParams(p); 506 assertNotNull(res); 507 assertTrue(res instanceof AbsListView.LayoutParams); 508 assertEquals(ViewGroup.LayoutParams.MATCH_PARENT, res.width); 509 assertEquals(ViewGroup.LayoutParams.WRAP_CONTENT, res.height); 510 } 511 testBeforeAndAfterTextChanged()512 public void testBeforeAndAfterTextChanged() { 513 // The java doc says these two methods do nothing 514 CharSequence str = "test"; 515 SpannableStringBuilder sb = new SpannableStringBuilder(); 516 517 mListView.beforeTextChanged(str, 0, str.length(), str.length()); 518 mListView.afterTextChanged(sb); 519 520 // test callback 521 MyListView listView = new MyListView(mActivity); 522 TextView tv = new TextView(mActivity); 523 524 assertFalse(listView.isBeforeTextChangedCalled()); 525 assertFalse(listView.isOnTextChangedCalled()); 526 assertFalse(listView.isAfterTextChangedCalled()); 527 528 tv.addTextChangedListener(listView); 529 assertFalse(listView.isBeforeTextChangedCalled()); 530 assertFalse(listView.isOnTextChangedCalled()); 531 assertFalse(listView.isAfterTextChangedCalled()); 532 533 tv.setText("abc"); 534 assertTrue(listView.isBeforeTextChangedCalled()); 535 assertTrue(listView.isOnTextChangedCalled()); 536 assertTrue(listView.isAfterTextChangedCalled()); 537 } 538 testAddTouchables()539 public void testAddTouchables() throws Throwable { 540 ArrayList<View> views = new ArrayList<View>(); 541 assertEquals(0, views.size()); 542 543 setAdapter(); 544 545 mListView.addTouchables(views); 546 assertEquals(mListView.getChildCount(), views.size()); 547 } 548 testInvalidateViews()549 public void testInvalidateViews() throws Throwable { 550 TextView tv1 = (TextView) mActivity.findViewById(R.id.headerview1); 551 TextView tv2 = (TextView) mActivity.findViewById(R.id.footerview1); 552 553 setAdapter(); 554 555 mListView.setScrollIndicators(tv1, tv2); 556 557 runTestOnUiThread(new Runnable() { 558 public void run() { 559 mListView.invalidateViews(); 560 } 561 }); 562 mInstrumentation.waitForIdleSync(); 563 } 564 testGetContextMenuInfo()565 public void testGetContextMenuInfo() throws Throwable { 566 final MyListView listView = new MyListView(mActivity, mAttributeSet); 567 568 runTestOnUiThread(new Runnable() { 569 public void run() { 570 mActivity.setContentView(listView); 571 listView.setAdapter(mAdapter_countries); 572 listView.setSelection(2); 573 } 574 }); 575 mInstrumentation.waitForIdleSync(); 576 577 final TextView v = (TextView) listView.getSelectedView(); 578 assertNull(listView.getContextMenuInfo()); 579 580 final MockOnItemLongClickListener listener = new MockOnItemLongClickListener(); 581 listView.setOnItemLongClickListener(listener); 582 583 assertNull(listener.getParent()); 584 assertNull(listener.getView()); 585 assertEquals(0, listener.getPosition()); 586 assertEquals(0, listener.getID()); 587 588 mInstrumentation.waitForIdleSync(); 589 TouchUtils.longClickView(this, v); 590 591 new PollingCheck() { 592 @Override 593 protected boolean check() { 594 return v == listener.getView(); 595 } 596 }.run(); 597 598 assertSame(listView, listener.getParent()); 599 assertEquals(2, listener.getPosition()); 600 assertEquals(listView.getItemIdAtPosition(2), listener.getID()); 601 602 ContextMenuInfo cmi = listView.getContextMenuInfo(); 603 assertNotNull(cmi); 604 } 605 testGetTopBottomFadingEdgeStrength()606 public void testGetTopBottomFadingEdgeStrength() { 607 MyListView listView = new MyListView(mActivity); 608 609 assertEquals(0.0f, listView.getTopFadingEdgeStrength(), DELTA); 610 assertEquals(0.0f, listView.getBottomFadingEdgeStrength(), DELTA); 611 } 612 testHandleDataChanged()613 public void testHandleDataChanged() { 614 MyListView listView = new MyListView(mActivity, mAttributeSet, 0); 615 listView.handleDataChanged(); 616 // TODO: how to check? 617 } 618 testSetFilterText()619 public void testSetFilterText() { 620 MyListView listView = new MyListView(mActivity, mAttributeSet, 0); 621 String filterText = "xyz"; 622 623 assertFalse(listView.isTextFilterEnabled()); 624 assertFalse(listView.hasTextFilter()); 625 assertFalse(listView.isInFilterMode()); 626 assertTrue(mListView.checkInputConnectionProxy(null)); 627 628 listView.setTextFilterEnabled(false); 629 listView.setFilterText(filterText); 630 assertFalse(listView.isTextFilterEnabled()); 631 assertFalse(listView.hasTextFilter()); 632 assertFalse(listView.isInFilterMode()); 633 634 listView.setTextFilterEnabled(true); 635 listView.setFilterText(null); 636 assertTrue(listView.isTextFilterEnabled()); 637 assertFalse(listView.hasTextFilter()); 638 assertFalse(listView.isInFilterMode()); 639 640 listView.setTextFilterEnabled(true); 641 listView.setFilterText(filterText); 642 assertTrue(listView.isTextFilterEnabled()); 643 assertTrue(listView.hasTextFilter()); 644 assertTrue(listView.isInFilterMode()); 645 646 listView.clearTextFilter(); 647 assertTrue(listView.isTextFilterEnabled()); 648 assertFalse(listView.hasTextFilter()); 649 assertFalse(listView.isInFilterMode()); 650 } 651 652 @MediumTest testSetItemChecked_multipleModeSameValue()653 public void testSetItemChecked_multipleModeSameValue() 654 throws Throwable { 655 // Calling setItemChecked with the same value in multiple choice mode should not cause 656 // requestLayout 657 mListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); 658 runTestOnUiThread(new Runnable() { 659 @Override 660 public void run() { 661 mListView.setItemChecked(0, false); 662 } 663 }); 664 mInstrumentation.waitForIdleSync(); 665 assertFalse(mListView.isLayoutRequested()); 666 runTestOnUiThread(new Runnable() { 667 @Override 668 public void run() { 669 mListView.setItemChecked(0, false); 670 } 671 }); 672 assertFalse(mListView.isLayoutRequested()); 673 } 674 675 @MediumTest testSetItemChecked_singleModeSameValue()676 public void testSetItemChecked_singleModeSameValue() 677 throws Throwable { 678 // Calling setItemChecked with the same value in single choice mode should not cause 679 // requestLayout 680 mListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE); 681 runTestOnUiThread(new Runnable() { 682 @Override 683 public void run() { 684 mListView.setItemChecked(0, false); 685 } 686 }); 687 mInstrumentation.waitForIdleSync(); 688 assertFalse(mListView.isLayoutRequested()); 689 runTestOnUiThread(new Runnable() { 690 @Override 691 public void run() { 692 mListView.setItemChecked(0, false); 693 } 694 }); 695 assertFalse(mListView.isLayoutRequested()); 696 } 697 698 @MediumTest testSetItemChecked_multipleModeDifferentValue()699 public void testSetItemChecked_multipleModeDifferentValue() 700 throws Throwable { 701 // Calling setItemChecked with a different value in multiple choice mode should cause 702 // requestLayout 703 mListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); 704 runTestOnUiThread(new Runnable() { 705 @Override 706 public void run() { 707 mListView.setItemChecked(0, false); 708 } 709 }); 710 mInstrumentation.waitForIdleSync(); 711 assertFalse(mListView.isLayoutRequested()); 712 runTestOnUiThread(new Runnable() { 713 @Override 714 public void run() { 715 mListView.setItemChecked(0, true); 716 } 717 }); 718 assertTrue(mListView.isLayoutRequested()); 719 } 720 721 @MediumTest testSetItemChecked_singleModeDifferentValue()722 public void testSetItemChecked_singleModeDifferentValue() 723 throws Throwable { 724 // Calling setItemChecked with a different value in single choice mode should cause 725 // requestLayout 726 mListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE); 727 runTestOnUiThread(new Runnable() { 728 @Override 729 public void run() { 730 mListView.setItemChecked(0, false); 731 } 732 }); 733 mInstrumentation.waitForIdleSync(); 734 assertFalse(mListView.isLayoutRequested()); 735 runTestOnUiThread(new Runnable() { 736 @Override 737 public void run() { 738 mListView.setItemChecked(0, true); 739 } 740 }); 741 assertTrue(mListView.isLayoutRequested()); 742 } 743 testLayoutChildren()744 public void testLayoutChildren() { 745 /** 746 * the subclass ListView and GridView override this method, so we can not test 747 * this method. 748 */ 749 } 750 testFoo()751 public void testFoo() { 752 /** 753 * Do not test these APIs. They are callbacks which: 754 * 755 * 1. The callback machanism has been tested in super class 756 * 2. The functionality is implmentation details, no need to test 757 */ 758 } 759 760 private static class MockOnScrollListener implements OnScrollListener { 761 private AbsListView mView; 762 private int mFirstVisibleItem; 763 private int mVisibleItemCount; 764 private int mTotalItemCount; 765 private int mScrollState; 766 767 private boolean mIsOnScrollCalled; 768 private boolean mIsOnScrollStateChangedCalled; 769 MockOnScrollListener()770 private MockOnScrollListener() { 771 mView = null; 772 mFirstVisibleItem = 0; 773 mVisibleItemCount = 0; 774 mTotalItemCount = 0; 775 mScrollState = -1; 776 777 mIsOnScrollCalled = false; 778 mIsOnScrollStateChangedCalled = false; 779 } 780 onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount)781 public void onScroll(AbsListView view, int firstVisibleItem, 782 int visibleItemCount, int totalItemCount) { 783 mView = view; 784 mFirstVisibleItem = firstVisibleItem; 785 mVisibleItemCount = visibleItemCount; 786 mTotalItemCount = totalItemCount; 787 mIsOnScrollCalled = true; 788 } 789 onScrollStateChanged(AbsListView view, int scrollState)790 public void onScrollStateChanged(AbsListView view, int scrollState) { 791 mScrollState = scrollState; 792 mIsOnScrollStateChangedCalled = true; 793 } 794 getView()795 public AbsListView getView() { 796 return mView; 797 } 798 getFirstVisibleItem()799 public int getFirstVisibleItem() { 800 return mFirstVisibleItem; 801 } 802 getVisibleItemCount()803 public int getVisibleItemCount() { 804 return mVisibleItemCount; 805 } 806 getTotalItemCount()807 public int getTotalItemCount() { 808 return mTotalItemCount; 809 } 810 getScrollState()811 public int getScrollState() { 812 return mScrollState; 813 } 814 isOnScrollCalled()815 public boolean isOnScrollCalled() { 816 return mIsOnScrollCalled; 817 } 818 isOnScrollStateChangedCalled()819 public boolean isOnScrollStateChangedCalled() { 820 return mIsOnScrollStateChangedCalled; 821 } 822 reset()823 public void reset() { 824 mIsOnScrollCalled = false; 825 mIsOnScrollStateChangedCalled = false; 826 } 827 } 828 829 private static class MockRecyclerListener implements RecyclerListener { 830 private View mView; 831 MockRecyclerListener()832 private MockRecyclerListener() { 833 mView = null; 834 } 835 onMovedToScrapHeap(View view)836 public void onMovedToScrapHeap(View view) { 837 mView = view; 838 } 839 getView()840 public View getView() { 841 return mView; 842 } 843 } 844 845 private static class MockOnItemLongClickListener implements OnItemLongClickListener { 846 private AdapterView<?> parent; 847 private View view; 848 private int position; 849 private long id; 850 onItemLongClick(AdapterView<?> parent, View view, int position, long id)851 public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) { 852 this.parent = parent; 853 this.view = view; 854 this.position = position; 855 this.id = id; 856 return false; 857 } 858 getParent()859 public AdapterView<?> getParent() { 860 return parent; 861 } 862 getView()863 public View getView() { 864 return view; 865 } 866 getPosition()867 public int getPosition() { 868 return position; 869 } 870 getID()871 public long getID() { 872 return id; 873 } 874 } 875 876 /** 877 * MyListView for test 878 */ 879 private static class MyListView extends ListView { MyListView(Context context)880 public MyListView(Context context) { 881 super(context); 882 } 883 MyListView(Context context, AttributeSet attrs)884 public MyListView(Context context, AttributeSet attrs) { 885 super(context, attrs); 886 } 887 MyListView(Context context, AttributeSet attrs, int defStyle)888 public MyListView(Context context, AttributeSet attrs, int defStyle) { 889 super(context, attrs, defStyle); 890 } 891 892 @Override checkLayoutParams(ViewGroup.LayoutParams p)893 protected boolean checkLayoutParams(ViewGroup.LayoutParams p) { 894 return super.checkLayoutParams(p); 895 } 896 897 @Override computeVerticalScrollExtent()898 protected int computeVerticalScrollExtent() { 899 return super.computeVerticalScrollExtent(); 900 } 901 902 @Override computeVerticalScrollOffset()903 protected int computeVerticalScrollOffset() { 904 return super.computeVerticalScrollOffset(); 905 } 906 907 @Override computeVerticalScrollRange()908 protected int computeVerticalScrollRange() { 909 return super.computeVerticalScrollRange(); 910 } 911 912 @Override dispatchDraw(Canvas canvas)913 protected void dispatchDraw(Canvas canvas) { 914 super.dispatchDraw(canvas); 915 } 916 917 @Override dispatchSetPressed(boolean pressed)918 protected void dispatchSetPressed(boolean pressed) { 919 super.dispatchSetPressed(pressed); 920 } 921 922 @Override generateLayoutParams(ViewGroup.LayoutParams p)923 protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) { 924 return super.generateLayoutParams(p); 925 } 926 927 @Override getBottomFadingEdgeStrength()928 protected float getBottomFadingEdgeStrength() { 929 return super.getBottomFadingEdgeStrength(); 930 } 931 932 @Override getContextMenuInfo()933 protected ContextMenuInfo getContextMenuInfo() { 934 return super.getContextMenuInfo(); 935 } 936 937 @Override getTopFadingEdgeStrength()938 protected float getTopFadingEdgeStrength() { 939 return super.getTopFadingEdgeStrength(); 940 } 941 942 @Override handleDataChanged()943 protected void handleDataChanged() { 944 super.handleDataChanged(); 945 } 946 947 @Override isInFilterMode()948 protected boolean isInFilterMode() { 949 return super.isInFilterMode(); 950 } 951 952 private boolean mIsBeforeTextChangedCalled; 953 private boolean mIsOnTextChangedCalled; 954 private boolean mIsAfterTextChangedCalled; 955 956 @Override beforeTextChanged(CharSequence s, int start, int count, int after)957 public void beforeTextChanged(CharSequence s, int start, int count, int after) { 958 mIsBeforeTextChangedCalled = true; 959 super.beforeTextChanged(s, start, count, after); 960 } 961 962 @Override onTextChanged(CharSequence s, int start, int before, int count)963 public void onTextChanged(CharSequence s, int start, int before, int count) { 964 mIsOnTextChangedCalled = true; 965 super.onTextChanged(s, start, before, count); 966 } 967 968 @Override afterTextChanged(Editable s)969 public void afterTextChanged(Editable s) { 970 mIsAfterTextChangedCalled = true; 971 super.afterTextChanged(s); 972 } 973 isBeforeTextChangedCalled()974 public boolean isBeforeTextChangedCalled() { 975 return mIsBeforeTextChangedCalled; 976 } 977 isOnTextChangedCalled()978 public boolean isOnTextChangedCalled() { 979 return mIsOnTextChangedCalled; 980 } 981 isAfterTextChangedCalled()982 public boolean isAfterTextChangedCalled() { 983 return mIsAfterTextChangedCalled; 984 } 985 } 986 } 987