From dcbcc86353e9ed52daac87f292aece667cd0ac71 Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Tue, 12 Aug 2014 15:58:36 -0700 Subject: Updating the UI for focused state of an icon/folder. issue: 16352129 Change-Id: If2e154dba06a0648f933f9aea38898642db9fd85 --- .../android/launcher3/AppsCustomizeCellLayout.java | 8 ++ .../android/launcher3/AppsCustomizePagedView.java | 1 + src/com/android/launcher3/CellLayout.java | 5 +- src/com/android/launcher3/FocusIndicatorView.java | 146 +++++++++++++++++++++ src/com/android/launcher3/Folder.java | 8 ++ src/com/android/launcher3/FolderIcon.java | 1 + src/com/android/launcher3/Hotseat.java | 1 + src/com/android/launcher3/Launcher.java | 4 + 8 files changed, 170 insertions(+), 4 deletions(-) create mode 100644 src/com/android/launcher3/FocusIndicatorView.java (limited to 'src/com/android/launcher3') diff --git a/src/com/android/launcher3/AppsCustomizeCellLayout.java b/src/com/android/launcher3/AppsCustomizeCellLayout.java index 3c8bda9db..76b81d2d1 100644 --- a/src/com/android/launcher3/AppsCustomizeCellLayout.java +++ b/src/com/android/launcher3/AppsCustomizeCellLayout.java @@ -20,8 +20,16 @@ import android.content.Context; import android.view.View; public class AppsCustomizeCellLayout extends CellLayout implements Page { + + final FocusIndicatorView mFocusHandlerView; + public AppsCustomizeCellLayout(Context context) { super(context); + + mFocusHandlerView = new FocusIndicatorView(context); + addView(mFocusHandlerView, 0); + mFocusHandlerView.getLayoutParams().width = FocusIndicatorView.DEFAULT_LAYOUT_SIZE; + mFocusHandlerView.getLayoutParams().height = FocusIndicatorView.DEFAULT_LAYOUT_SIZE; } @Override diff --git a/src/com/android/launcher3/AppsCustomizePagedView.java b/src/com/android/launcher3/AppsCustomizePagedView.java index e0543ceb6..f78cff09d 100644 --- a/src/com/android/launcher3/AppsCustomizePagedView.java +++ b/src/com/android/launcher3/AppsCustomizePagedView.java @@ -1041,6 +1041,7 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen icon.setOnLongClickListener(this); icon.setOnTouchListener(this); icon.setOnKeyListener(this); + icon.setOnFocusChangeListener(layout.mFocusHandlerView); int index = i - startIndex; int x = index % mCellCountX; diff --git a/src/com/android/launcher3/CellLayout.java b/src/com/android/launcher3/CellLayout.java index 107376482..07120c5e4 100644 --- a/src/com/android/launcher3/CellLayout.java +++ b/src/com/android/launcher3/CellLayout.java @@ -989,10 +989,7 @@ public class CellLayout extends ViewGroup { } public ShortcutAndWidgetContainer getShortcutsAndWidgets() { - if (getChildCount() > 0) { - return (ShortcutAndWidgetContainer) getChildAt(0); - } - return null; + return mShortcutsAndWidgets; } public View getChildAt(int x, int y) { diff --git a/src/com/android/launcher3/FocusIndicatorView.java b/src/com/android/launcher3/FocusIndicatorView.java new file mode 100644 index 000000000..12b7a4076 --- /dev/null +++ b/src/com/android/launcher3/FocusIndicatorView.java @@ -0,0 +1,146 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.launcher3; + +import android.content.Context; +import android.graphics.Canvas; +import android.util.AttributeSet; +import android.util.Pair; +import android.view.View; +import android.view.ViewParent; + +public class FocusIndicatorView extends View implements View.OnFocusChangeListener { + + // It can be any number >0. The view is resized using scaleX and scaleY. + static final int DEFAULT_LAYOUT_SIZE = 100; + private static final float MIN_VISIBLE_ALPHA = 0.2f; + + private static final int[] sTempPos = new int[2]; + private static final int[] sTempShift = new int[2]; + + private final int[] mIndicatorPos = new int[2]; + private final int[] mTargetViewPos = new int[2]; + + private View mLastFocusedView; + private boolean mInitiated; + + private Pair mPendingCall; + + public FocusIndicatorView(Context context) { + this(context, null); + } + + public FocusIndicatorView(Context context, AttributeSet attrs) { + super(context, attrs); + setAlpha(0); + setBackgroundColor(getResources().getColor(R.color.focused_background)); + } + + @Override + protected void onSizeChanged(int w, int h, int oldw, int oldh) { + super.onSizeChanged(w, h, oldw, oldh); + + // Redraw if it is already showing. This avoids a bug where the height changes by a small + // amount on connecting/disconnecting a bluetooth keyboard. + if (mLastFocusedView != null) { + mPendingCall = Pair.create(mLastFocusedView, Boolean.TRUE); + invalidate(); + } + } + + @Override + public void onFocusChange(View v, boolean hasFocus) { + mPendingCall = null; + if (!mInitiated && (getWidth() == 0)) { + // View not yet laid out. Wait until the view is ready to be drawn, so that be can + // get the location on screen. + mPendingCall = Pair.create(v, hasFocus); + invalidate(); + return; + } + + if (!mInitiated) { + getLocationRelativeToParentPagedView(this, mIndicatorPos); + mInitiated = true; + } + + if (hasFocus) { + int indicatorWidth = getWidth(); + int indicatorHeight = getHeight(); + + float scaleX = v.getScaleX() * v.getWidth() / indicatorWidth; + float scaleY = v.getScaleY() * v.getHeight() / indicatorHeight; + + getLocationRelativeToParentPagedView(v, mTargetViewPos); + float x = mTargetViewPos[0] - mIndicatorPos[0] - (1 - scaleX) * indicatorWidth / 2; + float y = mTargetViewPos[1] - mIndicatorPos[1] - (1 - scaleY) * indicatorHeight / 2; + + if (getAlpha() > MIN_VISIBLE_ALPHA) { + animate() + .translationX(x) + .translationY(y) + .scaleX(scaleX) + .scaleY(scaleY) + .alpha(1); + } else { + setTranslationX(x); + setTranslationY(y); + setScaleX(scaleX); + setScaleY(scaleY); + animate().alpha(1); + } + mLastFocusedView = v; + } else { + if (mLastFocusedView == v) { + mLastFocusedView = null; + animate().alpha(0); + } + } + } + + @Override + protected void onDraw(Canvas canvas) { + if (mPendingCall != null) { + onFocusChange(mPendingCall.first, mPendingCall.second); + } + } + + /** + * Gets the location of a view relative in the window, off-setting any shift due to + * page view scroll + */ + private static void getLocationRelativeToParentPagedView(View v, int[] pos) { + getPagedViewScrollShift(v, sTempShift); + v.getLocationInWindow(sTempPos); + pos[0] = sTempPos[0] + sTempShift[0]; + pos[1] = sTempPos[1] + sTempShift[1]; + } + + private static void getPagedViewScrollShift(View child, int[] shift) { + ViewParent parent = child.getParent(); + if (parent instanceof PagedView) { + View parentView = (View) parent; + child.getLocationInWindow(sTempPos); + shift[0] = parentView.getPaddingLeft() - sTempPos[0]; + shift[1] = -(int) child.getTranslationY(); + } else if (parent instanceof View) { + getPagedViewScrollShift((View) parent, shift); + } else { + shift[0] = shift[1] = 0; + } + } +} diff --git a/src/com/android/launcher3/Folder.java b/src/com/android/launcher3/Folder.java index fcedaead3..4a707711d 100644 --- a/src/com/android/launcher3/Folder.java +++ b/src/com/android/launcher3/Folder.java @@ -112,6 +112,8 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList private static String sDefaultFolderName; private static String sHintText; + private FocusIndicatorView mFocusIndicatorHandler; + private int DRAG_MODE_NONE = 0; private int DRAG_MODE_REORDER = 1; private int mDragMode = DRAG_MODE_NONE; @@ -178,6 +180,11 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList mScrollView = (ScrollView) findViewById(R.id.scroll_view); mContent = (CellLayout) findViewById(R.id.folder_content); + mFocusIndicatorHandler = new FocusIndicatorView(getContext()); + mContent.addView(mFocusIndicatorHandler, 0); + mFocusIndicatorHandler.getLayoutParams().height = FocusIndicatorView.DEFAULT_LAYOUT_SIZE; + mFocusIndicatorHandler.getLayoutParams().width = FocusIndicatorView.DEFAULT_LAYOUT_SIZE; + LauncherAppState app = LauncherAppState.getInstance(); DeviceProfile grid = app.getDynamicGrid().getDeviceProfile(); @@ -572,6 +579,7 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList textView.setOnClickListener(this); textView.setOnLongClickListener(this); + textView.setOnFocusChangeListener(mFocusIndicatorHandler); // We need to check here to verify that the given item's location isn't already occupied // by another item. diff --git a/src/com/android/launcher3/FolderIcon.java b/src/com/android/launcher3/FolderIcon.java index c0b9da7d4..21efd7113 100644 --- a/src/com/android/launcher3/FolderIcon.java +++ b/src/com/android/launcher3/FolderIcon.java @@ -178,6 +178,7 @@ public class FolderIcon extends FrameLayout implements FolderListener { icon.mFolderRingAnimator = new FolderRingAnimator(launcher, icon); folderInfo.addListener(icon); + icon.setOnFocusChangeListener(launcher.mFocusHandler); return icon; } diff --git a/src/com/android/launcher3/Hotseat.java b/src/com/android/launcher3/Hotseat.java index 79cac8f64..3d6befae5 100644 --- a/src/com/android/launcher3/Hotseat.java +++ b/src/com/android/launcher3/Hotseat.java @@ -159,6 +159,7 @@ public class Hotseat extends FrameLayout { allAppsButton.setOnTouchListener(mLauncher.getHapticFeedbackTouchListener()); mLauncher.setAllAppsButton(allAppsButton); allAppsButton.setOnClickListener(mLauncher); + allAppsButton.setOnFocusChangeListener(mLauncher.mFocusHandler); } // Note: We do this to ensure that the hotseat is always laid out in the orientation of diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index 062e84838..c9d423c34 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -384,6 +384,8 @@ public class Launcher extends Activity private Stats mStats; + FocusIndicatorView mFocusHandler; + static boolean isPropertyEnabled(String propertyName) { return Log.isLoggable(propertyName, Log.VERBOSE); } @@ -1289,6 +1291,7 @@ public class Launcher extends Activity final DragController dragController = mDragController; mLauncherView = findViewById(R.id.launcher); + mFocusHandler = (FocusIndicatorView) findViewById(R.id.focus_indicator); mDragLayer = (DragLayer) findViewById(R.id.drag_layer); mWorkspace = (Workspace) mDragLayer.findViewById(R.id.workspace); mWorkspace.setPageSwitchListener(this); @@ -1428,6 +1431,7 @@ public class Launcher extends Activity BubbleTextView favorite = (BubbleTextView) mInflater.inflate(layoutResId, parent, false); favorite.applyFromShortcutInfo(info, mIconCache, true); favorite.setOnClickListener(this); + favorite.setOnFocusChangeListener(mFocusHandler); return favorite; } -- cgit v1.2.3