Focus behavior for scroll containers in watch mode

Change default scrolling containers not to request a reveal (parent
scroll) on focus, and to be focusable in touch mode. This helps watch
devices with other input mechanisms that rely on view focus.

Since there's no attribute for the reveal on focus hint, set that in
code. Set focusable in touch mode on the default styles for
ScrollView/HorizontalScrollView. AbsListView already sets this
historically anyway.

Change-Id: I74760f6d523874127da6f6134f0461cc59ce189a
This commit is contained in:
Adam Powell
2016-08-15 16:34:37 -07:00
committed by Ned Burns
parent b8e74df82d
commit 2fe301db75
6 changed files with 41 additions and 10 deletions

View File

@@ -21,6 +21,7 @@ import android.annotation.DrawableRes;
import android.annotation.NonNull;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Rect;
@@ -857,6 +858,10 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
R.styleable.AbsListView_fastScrollAlwaysVisible, false));
a.recycle();
if (context.getResources().getConfiguration().uiMode == Configuration.UI_MODE_TYPE_WATCH) {
setRevealOnFocusHint(false);
}
}
private void initAbsListView() {

View File

@@ -18,6 +18,7 @@ package android.widget;
import android.annotation.NonNull;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Rect;
@@ -165,6 +166,10 @@ public class HorizontalScrollView extends FrameLayout {
setFillViewport(a.getBoolean(android.R.styleable.HorizontalScrollView_fillViewport, false));
a.recycle();
if (context.getResources().getConfiguration().uiMode == Configuration.UI_MODE_TYPE_WATCH) {
setRevealOnFocusHint(false);
}
}
@Override
@@ -1430,11 +1435,13 @@ public class HorizontalScrollView extends FrameLayout {
@Override
public void requestChildFocus(View child, View focused) {
if (!mIsLayoutDirty) {
scrollToChild(focused);
} else {
// The child may not be laid out yet, we can't compute the scroll yet
mChildToScrollTo = focused;
if (focused.getRevealOnFocusHint()) {
if (!mIsLayoutDirty) {
scrollToChild(focused);
} else {
// The child may not be laid out yet, we can't compute the scroll yet
mChildToScrollTo = focused;
}
}
super.requestChildFocus(child, focused);
}

View File

@@ -17,6 +17,7 @@
package android.widget;
import android.annotation.NonNull;
import android.content.res.Configuration;
import android.os.Build;
import android.os.Build.VERSION_CODES;
import android.os.Parcel;
@@ -186,6 +187,10 @@ public class ScrollView extends FrameLayout {
setFillViewport(a.getBoolean(R.styleable.ScrollView_fillViewport, false));
a.recycle();
if (context.getResources().getConfiguration().uiMode == Configuration.UI_MODE_TYPE_WATCH) {
setRevealOnFocusHint(false);
}
}
@Override
@@ -1455,11 +1460,13 @@ public class ScrollView extends FrameLayout {
@Override
public void requestChildFocus(View child, View focused) {
if (!mIsLayoutDirty) {
scrollToChild(focused);
} else {
// The child may not be laid out yet, we can't compute the scroll yet
mChildToScrollTo = focused;
if (focused.getRevealOnFocusHint()) {
if (!mIsLayoutDirty) {
scrollToChild(focused);
} else {
// The child may not be laid out yet, we can't compute the scroll yet
mChildToScrollTo = focused;
}
}
super.requestChildFocus(child, focused);
}

View File

@@ -57,4 +57,9 @@
<!-- Use a custom transition for RemoteViews. -->
<bool name="config_overrideRemoteViewsActivityTransition">true</bool>
<!-- Default value for android:focusableInTouchMode for some framework scrolling containers.
ListView/GridView are notably absent since this is their default anyway.
Set to true for watch devices. -->
<bool name="config_focusScrollContainersInTouchMode">true</bool>
</resources>

View File

@@ -2567,6 +2567,11 @@
<string-array translatable="false" name="config_defaultFirstUserRestrictions">
</string-array>
<!-- Default value for android:focusableInTouchMode for some framework scrolling containers.
ListView/GridView are notably absent since this is their default anyway.
Set to true for watch devices. -->
<bool name="config_focusScrollContainersInTouchMode">false</bool>
<string name="config_networkOverLimitComponent" translatable="false">com.android.systemui/com.android.systemui.net.NetworkOverLimitActivity</string>
<string name="config_dataUsageSummaryComponent" translatable="false">com.android.settings/com.android.settings.Settings$DataUsageSummaryActivity</string>

View File

@@ -649,11 +649,13 @@ please see styles_device_defaults.xml.
<style name="Widget.ScrollView">
<item name="scrollbars">vertical</item>
<item name="fadingEdge">vertical</item>
<item name="focusableInTouchMode">@bool/config_focusScrollContainersInTouchMode</item>
</style>
<style name="Widget.HorizontalScrollView">
<item name="scrollbars">horizontal</item>
<item name="fadingEdge">horizontal</item>
<item name="focusableInTouchMode">@bool/config_focusScrollContainersInTouchMode</item>
</style>
<style name="Widget.ListView" parent="Widget.AbsListView">