Focus content or button on AlertController

Requests focus for the content view, or if the content does not accept
focus, a button on an alert dialog if not in touch mode.

Before, the ScrollView containing the buttons received focus, and the
user had to navigate to a button before being able to click it.

Tries to focus the first available button in the order of positive
button, negative button, neutral button.

Test: Manual test on Android TV:
       - Suspend YouTube package using `adb shell pm suspend com.google.android.youtube.tv`
       - Try starting the YouTube app, observe focus on alert dialog
       - Also tested with AlertDialogs with custom views, list view
Bug: 129467676
Change-Id: I69f39d0ade5a8b275f865ef1a76984407413c282
This commit is contained in:
Robert Horvath
2019-04-02 19:05:26 +02:00
parent 2adc431b31
commit b96ca99b49

View File

@@ -559,6 +559,13 @@ public class AlertController {
final boolean hasButtonPanel = buttonPanel != null
&& buttonPanel.getVisibility() != View.GONE;
if (!parentPanel.isInTouchMode()) {
final View content = hasCustomPanel ? customPanel : contentPanel;
if (!requestFocusForContent(content)) {
requestFocusForDefaultButton();
}
}
// Only display the text spacer if we don't have buttons.
if (!hasButtonPanel) {
if (contentPanel != null) {
@@ -624,6 +631,29 @@ public class AlertController {
a.recycle();
}
private boolean requestFocusForContent(View content) {
if (content != null && content.requestFocus()) {
return true;
}
if (mListView != null) {
mListView.setSelection(0);
return true;
}
return false;
}
private void requestFocusForDefaultButton() {
if (mButtonPositive.getVisibility() == View.VISIBLE) {
mButtonPositive.requestFocus();
} else if (mButtonNegative.getVisibility() == View.VISIBLE) {
mButtonNegative.requestFocus();
} else if (mButtonNeutral.getVisibility() == View.VISIBLE) {
mButtonNeutral.requestFocus();
}
}
private void setupCustomContent(ViewGroup customPanel) {
final View customView;
if (mView != null) {