From 25c2e3ef07bda7df1e591cf9cdf9f6512ee2dbf7 Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Wed, 28 Oct 2015 23:28:21 -0700 Subject: Allowing widgets to be focusable > Pressing 'enter' enters the focus inside the widget. > If the widget has only one focusable, it directly performs click > Pressing 'esc' brings the focus back to the parent host. Bug: 25199581 Change-Id: Ia7fd5d929f5945d61173abd349660a5efbe74afc --- src/com/android/launcher3/Launcher.java | 32 +++++----- .../launcher3/LauncherAppWidgetHostView.java | 69 +++++++++++++++++++++- .../android/launcher3/LauncherAppWidgetInfo.java | 10 +--- 3 files changed, 87 insertions(+), 24 deletions(-) (limited to 'src/com/android/launcher3') diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index d2581414d..8ba8f3e3a 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -1622,16 +1622,26 @@ public class Launcher extends Activity // The AppWidgetHostView has already been inflated and instantiated launcherInfo.hostView = hostView; } - launcherInfo.hostView.setTag(launcherInfo); launcherInfo.hostView.setVisibility(View.VISIBLE); - launcherInfo.notifyWidgetSizeChanged(this); + addAppWidgetToWorkspace(launcherInfo, appWidgetInfo, isWorkspaceLocked()); + } + resetAddInfo(); + } - mWorkspace.addInScreen(launcherInfo.hostView, container, screenId, info.cellX, - info.cellY, launcherInfo.spanX, launcherInfo.spanY, isWorkspaceLocked()); + private void addAppWidgetToWorkspace(LauncherAppWidgetInfo item, + LauncherAppWidgetProviderInfo appWidgetInfo, boolean insert) { + item.hostView.setTag(item); + item.onBindAppWidget(this); - addWidgetToAutoAdvanceIfNeeded(launcherInfo.hostView, appWidgetInfo); + item.hostView.setFocusable(true); + item.hostView.setOnFocusChangeListener(mFocusHandler); + + mWorkspace.addInScreen(item.hostView, item.container, item.screenId, + item.cellX, item.cellY, item.spanX, item.spanY, insert); + + if (!item.isCustomWidget()) { + addWidgetToAutoAdvanceIfNeeded(item.hostView, appWidgetInfo); } - resetAddInfo(); } private final BroadcastReceiver mReceiver = new BroadcastReceiver() { @@ -4123,15 +4133,7 @@ public class Launcher extends Activity item.hostView.setOnClickListener(this); } - item.hostView.setTag(item); - item.onBindAppWidget(this); - - workspace.addInScreen(item.hostView, item.container, item.screenId, item.cellX, - item.cellY, item.spanX, item.spanY, false); - if (!item.isCustomWidget()) { - addWidgetToAutoAdvanceIfNeeded(item.hostView, appWidgetInfo); - } - + addAppWidgetToWorkspace(item, appWidgetInfo, false); workspace.requestLayout(); if (DEBUG_WIDGETS) { diff --git a/src/com/android/launcher3/LauncherAppWidgetHostView.java b/src/com/android/launcher3/LauncherAppWidgetHostView.java index cf461a5b8..34c2943cb 100644 --- a/src/com/android/launcher3/LauncherAppWidgetHostView.java +++ b/src/com/android/launcher3/LauncherAppWidgetHostView.java @@ -19,6 +19,8 @@ package com.android.launcher3; import android.appwidget.AppWidgetHostView; import android.appwidget.AppWidgetProviderInfo; import android.content.Context; +import android.graphics.Rect; +import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; @@ -28,6 +30,8 @@ import android.widget.RemoteViews; import com.android.launcher3.DragLayer.TouchCompleteListener; +import java.util.ArrayList; + /** * {@inheritDoc} */ @@ -43,6 +47,8 @@ public class LauncherAppWidgetHostView extends AppWidgetHostView implements Touc private float mSlop; + private boolean mChildrenFocused; + public LauncherAppWidgetHostView(Context context) { super(context); mContext = context; @@ -175,6 +181,67 @@ public class LauncherAppWidgetHostView extends AppWidgetHostView implements Touc @Override public int getDescendantFocusability() { - return ViewGroup.FOCUS_BLOCK_DESCENDANTS; + return mChildrenFocused ? ViewGroup.FOCUS_BEFORE_DESCENDANTS + : ViewGroup.FOCUS_BLOCK_DESCENDANTS; + } + + @Override + public boolean dispatchKeyEvent(KeyEvent event) { + if (mChildrenFocused && event.getKeyCode() == KeyEvent.KEYCODE_ESCAPE + && event.getAction() == KeyEvent.ACTION_UP) { + mChildrenFocused = false; + requestFocus(); + return true; + } + return super.dispatchKeyEvent(event); + } + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (!mChildrenFocused && keyCode == KeyEvent.KEYCODE_ENTER) { + event.startTracking(); + return true; + } + return super.onKeyDown(keyCode, event); + } + + @Override + public boolean onKeyUp(int keyCode, KeyEvent event) { + if (event.isTracking()) { + if (!mChildrenFocused && keyCode == KeyEvent.KEYCODE_ENTER) { + mChildrenFocused = true; + ArrayList focusableChildren = getFocusables(FOCUS_FORWARD); + focusableChildren.remove(this); + int childrenCount = focusableChildren.size(); + switch (childrenCount) { + case 0: + mChildrenFocused = false; + break; + case 1: { + if (getTag() instanceof ItemInfo) { + ItemInfo item = (ItemInfo) getTag(); + if (item.spanX == 1 && item.spanY == 1) { + focusableChildren.get(0).performClick(); + mChildrenFocused = false; + return true; + } + } + // continue; + } + default: + focusableChildren.get(0).requestFocus(); + return true; + } + } + } + return super.onKeyUp(keyCode, event); + } + + @Override + protected void onFocusChanged(boolean gainFocus, int direction, Rect previouslyFocusedRect) { + if (gainFocus) { + mChildrenFocused = false; + } + super.onFocusChanged(gainFocus, direction, previouslyFocusedRect); } } diff --git a/src/com/android/launcher3/LauncherAppWidgetInfo.java b/src/com/android/launcher3/LauncherAppWidgetInfo.java index 882f7e202..55edf45d2 100644 --- a/src/com/android/launcher3/LauncherAppWidgetInfo.java +++ b/src/com/android/launcher3/LauncherAppWidgetInfo.java @@ -123,17 +123,11 @@ public class LauncherAppWidgetInfo extends ItemInfo { */ void onBindAppWidget(Launcher launcher) { if (!mHasNotifiedInitialWidgetSizeChanged) { - notifyWidgetSizeChanged(launcher); + AppWidgetResizeFrame.updateWidgetSizeRanges(hostView, launcher, spanX, spanY); + mHasNotifiedInitialWidgetSizeChanged = true; } } - /** - * Trigger an update callback to the widget to notify it that its size has changed. - */ - void notifyWidgetSizeChanged(Launcher launcher) { - AppWidgetResizeFrame.updateWidgetSizeRanges(hostView, launcher, spanX, spanY); - mHasNotifiedInitialWidgetSizeChanged = true; - } @Override public String toString() { -- cgit v1.2.3