leanback DatePicker: fix range updates
Missing a notifyDataSetChange in scroll pass caused the mess, do the
updateSpinner in a post Runnable
Bug 27431465
Change-Id: I489b19645ee0934e15beb7dcb131f150b5cfa0d1
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/picker/DatePicker.java b/v17/leanback/src/android/support/v17/leanback/widget/picker/DatePicker.java
index b9cfc97..77b7665 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/picker/DatePicker.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/picker/DatePicker.java
@@ -345,7 +345,18 @@
return false;
}
- private void updateSpinners(boolean animation) {
+ private void updateSpinners(final boolean animation) {
+ // update range in a post call. The reason is that RV does not allow notifyDataSetChange()
+ // in scroll pass. UpdateSpinner can be called in a scroll pass, UpdateSpinner() may
+ // notifyDataSetChange to update the range.
+ post(new Runnable() {
+ public void run() {
+ updateSpinnersImpl(animation);
+ }
+ });
+ }
+
+ private void updateSpinnersImpl(boolean animation) {
// set the spinner ranges respecting the min and max dates
boolean dayRangeChanged = false;
boolean monthRangeChanged = false;
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/picker/Picker.java b/v17/leanback/src/android/support/v17/leanback/widget/picker/Picker.java
index 297d46c..1f35aae 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/picker/Picker.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/picker/Picker.java
@@ -217,7 +217,7 @@
/**
* When column labels change or column range changes, call this function to re-populate the
- * selection list.
+ * selection list. Note this function cannot be called from RecyclerView layout/scroll pass.
* @param columnIndex Index of column to update.
* @param column New column to update.
*/
@@ -225,7 +225,7 @@
mColumns.set(columnIndex, column);
VerticalGridView columnView = mColumnViews.get(columnIndex);
PickerScrollArrayAdapter adapter = (PickerScrollArrayAdapter) columnView.getAdapter();
- if (adapter != null && !columnView.isComputingLayout()) {
+ if (adapter != null) {
adapter.notifyDataSetChanged();
}
columnView.setSelectedPosition(column.getCurrentValue() - column.getMinValue());
diff --git a/v17/tests/src/android/support/v17/leanback/widget/GridWidgetTest.java b/v17/tests/src/android/support/v17/leanback/widget/GridWidgetTest.java
index 0f55e66..513a74a 100644
--- a/v17/tests/src/android/support/v17/leanback/widget/GridWidgetTest.java
+++ b/v17/tests/src/android/support/v17/leanback/widget/GridWidgetTest.java
@@ -556,6 +556,63 @@
verifyBeginAligned();
}
+ public void testSetSelectedPositionDetached() throws Throwable {
+
+ mInstrumentation = getInstrumentation();
+ Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
+ intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
+ R.layout.horizontal_linear);
+ intent.putExtra(GridActivity.EXTRA_NUM_ITEMS, 50);
+ initActivity(intent);
+ mOrientation = BaseGridView.HORIZONTAL;
+ mNumRows = 1;
+
+ final int focusToIndex = 49;
+ final ViewGroup parent = (ViewGroup) mGridView.getParent();
+ runTestOnUiThread(new Runnable() {
+ public void run() {
+ parent.removeView(mGridView);
+ }
+ });
+ runTestOnUiThread(new Runnable() {
+ public void run() {
+ mGridView.setSelectedPositionSmooth(focusToIndex);
+ }
+ });
+ runTestOnUiThread(new Runnable() {
+ public void run() {
+ parent.addView(mGridView);
+ mGridView.requestFocus();
+ }
+ });
+ waitForTransientStateGone(null);
+ waitForScrollIdle();
+ assertEquals(mGridView.getSelectedPosition(), focusToIndex);
+ assertTrue(mGridView.getLayoutManager().findViewByPosition(focusToIndex).hasFocus());
+
+ final int focusToIndex2 = 0;
+ runTestOnUiThread(new Runnable() {
+ public void run() {
+ parent.removeView(mGridView);
+ }
+ });
+ runTestOnUiThread(new Runnable() {
+ public void run() {
+ mGridView.setSelectedPosition(focusToIndex2);
+ }
+ });
+ runTestOnUiThread(new Runnable() {
+ public void run() {
+ parent.addView(mGridView);
+ mGridView.requestFocus();
+ }
+ });
+ assertEquals(mGridView.getSelectedPosition(), focusToIndex2);
+ waitForTransientStateGone(null);
+ waitForScrollIdle();
+ assertTrue(mGridView.getLayoutManager().findViewByPosition(focusToIndex2).hasFocus());
+ }
+
public void testBug22209986() throws Throwable {
mInstrumentation = getInstrumentation();