Merge "Fix FocusSearchNavigationTest on API 15."
diff --git a/v7/recyclerview/src/android/support/v7/widget/RecyclerView.java b/v7/recyclerview/src/android/support/v7/widget/RecyclerView.java
index 11e94e5..1463722 100644
--- a/v7/recyclerview/src/android/support/v7/widget/RecyclerView.java
+++ b/v7/recyclerview/src/android/support/v7/widget/RecyclerView.java
@@ -182,6 +182,12 @@
*/
private static final boolean ALLOW_THREAD_GAP_WORK = Build.VERSION.SDK_INT >= 21;
+ /**
+ * FocusFinder#findNextFocus is broken on ICS MR1 and older for View.FOCUS_BACKWARD direction.
+ * We convert it to an absolute direction such as FOCUS_DOWN or FOCUS_LEFT.
+ */
+ private static final boolean FORCE_ABS_FOCUS_SEARCH_DIRECTION = Build.VERSION.SDK_INT <= 15;
+
static final boolean DISPATCH_TEMP_DETACH = false;
public static final int HORIZONTAL = 0;
public static final int VERTICAL = 1;
@@ -2234,6 +2240,10 @@
direction == View.FOCUS_FORWARD ? View.FOCUS_DOWN : View.FOCUS_UP;
final View found = ff.findNextFocus(this, focused, absDir);
needsFocusFailureLayout = found == null;
+ if (FORCE_ABS_FOCUS_SEARCH_DIRECTION) {
+ // Workaround for broken FOCUS_BACKWARD in API 15 and older devices.
+ direction = absDir;
+ }
}
if (!needsFocusFailureLayout && mLayout.canScrollHorizontally()) {
boolean rtl = mLayout.getLayoutDirection() == ViewCompat.LAYOUT_DIRECTION_RTL;
@@ -2241,6 +2251,10 @@
? View.FOCUS_RIGHT : View.FOCUS_LEFT;
final View found = ff.findNextFocus(this, focused, absDir);
needsFocusFailureLayout = found == null;
+ if (FORCE_ABS_FOCUS_SEARCH_DIRECTION) {
+ // Workaround for broken FOCUS_BACKWARD in API 15 and older devices.
+ direction = absDir;
+ }
}
if (needsFocusFailureLayout) {
consumePendingUpdateOperations();
diff --git a/v7/recyclerview/tests/src/android/support/v7/widget/FocusSearchNavigationTest.java b/v7/recyclerview/tests/src/android/support/v7/widget/FocusSearchNavigationTest.java
index 7bed232..55bed7e 100644
--- a/v7/recyclerview/tests/src/android/support/v7/widget/FocusSearchNavigationTest.java
+++ b/v7/recyclerview/tests/src/android/support/v7/widget/FocusSearchNavigationTest.java
@@ -28,6 +28,7 @@
import android.app.Activity;
import android.content.Context;
+import android.os.Build;
import android.support.test.InstrumentationRegistry;
import android.support.test.filters.MediumTest;
import android.support.test.rule.ActivityTestRule;
@@ -60,8 +61,8 @@
@RunWith(Parameterized.class)
public class FocusSearchNavigationTest {
@Rule
- public ActivityTestRule<RecyclerViewTestActivity> mActivityRule
- = new ActivityTestRule<>(RecyclerViewTestActivity.class);
+ public ActivityTestRule<RecyclerViewTestActivity> mActivityRule =
+ new ActivityTestRule<>(RecyclerViewTestActivity.class);
private final int mOrientation;
private final int mLayoutDir;
@@ -73,11 +74,19 @@
@Parameterized.Parameters(name = "orientation:{0},layoutDir:{1}")
public static List<Object[]> params() {
- return Arrays.asList(
- new Object[]{VERTICAL, ViewCompat.LAYOUT_DIRECTION_LTR},
- new Object[]{HORIZONTAL, ViewCompat.LAYOUT_DIRECTION_LTR},
- new Object[]{HORIZONTAL, ViewCompat.LAYOUT_DIRECTION_RTL}
- );
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
+ return Arrays.asList(
+ new Object[]{VERTICAL, ViewCompat.LAYOUT_DIRECTION_LTR},
+ new Object[]{HORIZONTAL, ViewCompat.LAYOUT_DIRECTION_LTR},
+ new Object[]{HORIZONTAL, ViewCompat.LAYOUT_DIRECTION_RTL}
+ );
+ } else {
+ // Do not test RTL before API 17
+ return Arrays.asList(
+ new Object[]{VERTICAL, ViewCompat.LAYOUT_DIRECTION_LTR},
+ new Object[]{HORIZONTAL, ViewCompat.LAYOUT_DIRECTION_LTR}
+ );
+ }
}
private Activity mActivity;
@@ -91,11 +100,11 @@
@Override
public void run() {
mActivity.setContentView(R.layout.focus_search_activity);
- mActivity.getWindow().getDecorView().setLayoutDirection(mLayoutDir);
+ ViewCompat.setLayoutDirection(mActivity.getWindow().getDecorView(), mLayoutDir);
LinearLayout linearLayout = (LinearLayout) mActivity.findViewById(R.id.root);
linearLayout.setOrientation(mOrientation);
mRecyclerView = (RecyclerView) mActivity.findViewById(R.id.recycler_view);
- mRecyclerView.setLayoutDirection(mLayoutDir);
+ ViewCompat.setLayoutDirection(mRecyclerView, mLayoutDir);
LinearLayoutManager layout = new LinearLayoutManager(mActivity.getBaseContext());
layout.setOrientation(mOrientation);
mRecyclerView.setLayoutManager(layout);
@@ -115,7 +124,7 @@
waitForIdleSync();
assertThat("test sanity", mRecyclerView.getLayoutManager().getLayoutDirection(),
is(mLayoutDir));
- assertThat("test sanity", mRecyclerView.getLayoutDirection(), is(mLayoutDir));
+ assertThat("test sanity", ViewCompat.getLayoutDirection(mRecyclerView), is(mLayoutDir));
}
@Test