Splitting bindItems method to also accept already inflated views
which will eventually allow us to inflate icons on the background thread
Bug: 318539160
Test: Presubmit
Flag: None
Change-Id: I61e4981c1c3201e92102153d9558a0885637da3a
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 44a1bf0..aa37344 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -99,7 +99,6 @@
import static com.android.launcher3.util.SettingsCache.TOUCHPAD_NATURAL_SCROLLING;
import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ValueAnimator;
import android.annotation.TargetApi;
@@ -132,6 +131,7 @@
import android.util.AttributeSet;
import android.util.FloatProperty;
import android.util.Log;
+import android.util.Pair;
import android.util.SparseArray;
import android.view.KeyEvent;
import android.view.KeyboardShortcutGroup;
@@ -264,7 +264,6 @@
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
-import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
@@ -2125,30 +2124,23 @@
*/
@Override
public void bindItems(final List<ItemInfo> items, final boolean forceAnimateIcons) {
- bindItems(items, forceAnimateIcons, /* focusFirstItemForAccessibility= */ false);
+ bindItems(items.stream().map(i -> Pair.create(
+ i, getItemInflater().inflateItem(i, getModelWriter()))).toList(),
+ forceAnimateIcons ? new AnimatorSet() : null);
}
-
/**
- * Bind the items start-end from the list.
+ * Bind all the items in the map, ignoring any null views
*
- * Implementation of the method from LauncherModel.Callbacks.
- *
- * @param focusFirstItemForAccessibility true iff the first item to be added to the workspace
- * should be focused for accessibility.
+ * @param boundAnim if non-null, uses it to create and play the bounce animation for added views
*/
- public void bindItems(
- final List<ItemInfo> items,
- final boolean forceAnimateIcons,
- final boolean focusFirstItemForAccessibility) {
+ public void bindItems(List<Pair<ItemInfo, View>> shortcuts, @Nullable AnimatorSet boundAnim) {
// Get the list of added items and intersect them with the set of items here
- final Collection<Animator> bounceAnims = new ArrayList<>();
Workspace<?> workspace = mWorkspace;
int newItemsScreenId = -1;
- int end = items.size();
- View newView = null;
- for (int i = 0; i < end; i++) {
- final ItemInfo item = items.get(i);
+ int index = 0;
+ for (Pair<ItemInfo, View> e : shortcuts) {
+ final ItemInfo item = e.first;
// Remove colliding items.
CellPos presenterPos = getCellPosMapper().mapModelToPresenter(item);
@@ -2167,42 +2159,26 @@
}
}
- final View view = mItemInflater.inflateItem(item, getModelWriter());
+ final View view = e.second;
if (view == null) {
continue;
}
workspace.addInScreenFromBind(view, item);
- if (forceAnimateIcons) {
+ if (boundAnim != null) {
// Animate all the applications up now
view.setAlpha(0f);
view.setScaleX(0f);
view.setScaleY(0f);
- bounceAnims.add(createNewAppBounceAnimation(view, i));
+ boundAnim.play(createNewAppBounceAnimation(view, index++));
newItemsScreenId = presenterPos.screenId;
}
-
- if (newView == null) {
- newView = view;
- }
}
- View viewToFocus = newView;
// Animate to the correct page
- if (forceAnimateIcons && newItemsScreenId > -1) {
- AnimatorSet anim = new AnimatorSet();
- anim.playTogether(bounceAnims);
- if (focusFirstItemForAccessibility && viewToFocus != null) {
- anim.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- viewToFocus.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED);
- }
- });
- }
-
+ if (boundAnim != null && newItemsScreenId > -1) {
int currentScreenId = mWorkspace.getScreenIdForPageIndex(mWorkspace.getNextPage());
final int newScreenIndex = mWorkspace.getPageIndexForScreenId(newItemsScreenId);
- final Runnable startBounceAnimRunnable = anim::start;
+ final Runnable startBounceAnimRunnable = boundAnim::start;
if (canAnimatePageChange() && newItemsScreenId != currentScreenId) {
// We post the animation slightly delayed to prevent slowdowns
@@ -2215,8 +2191,6 @@
} else {
mWorkspace.postDelayed(startBounceAnimRunnable, NEW_APPS_ANIMATION_DELAY);
}
- } else if (focusFirstItemForAccessibility && viewToFocus != null) {
- viewToFocus.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED);
}
workspace.requestLayout();
}
diff --git a/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java b/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java
index 0844275..e65e614 100644
--- a/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java
+++ b/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java
@@ -5,18 +5,22 @@
import static android.view.accessibility.AccessibilityNodeInfo.ACTION_LONG_CLICK;
import static com.android.launcher3.LauncherState.NORMAL;
+import static com.android.launcher3.anim.AnimatorListeners.forEndCallback;
import static com.android.launcher3.anim.AnimatorListeners.forSuccessCallback;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.IGNORE;
import static com.android.launcher3.model.data.ItemInfoWithIcon.FLAG_NOT_PINNABLE;
+import android.animation.AnimatorSet;
import android.appwidget.AppWidgetProviderInfo;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.RectF;
import android.os.Handler;
import android.util.Log;
+import android.util.Pair;
import android.view.KeyEvent;
import android.view.View;
+import android.view.accessibility.AccessibilityEvent;
import com.android.launcher3.BubbleTextView;
import com.android.launcher3.ButtonDropTarget;
@@ -396,10 +400,7 @@
LauncherSettings.Favorites.CONTAINER_DESKTOP,
screenId, coordinates[0], coordinates[1]);
- mContext.bindItems(
- Collections.singletonList(info),
- /* forceAnimateIcons= */ true,
- /* focusFirstItemForAccessibility= */ accessibility);
+ bindItem(item, accessibility);
announceConfirmation(R.string.item_added_to_workspace);
} else if (item instanceof PendingAddItemInfo) {
PendingAddItemInfo info = (PendingAddItemInfo) item;
@@ -412,7 +413,7 @@
mContext.getModelWriter().addItemToDatabase(info,
LauncherSettings.Favorites.CONTAINER_DESKTOP,
screenId, coordinates[0], coordinates[1]);
- mContext.bindItems(Collections.singletonList(info), true, accessibility);
+ bindItem(info, accessibility);
} else if (item instanceof FolderInfo fi) {
mContext.getModelWriter().addItemToDatabase(fi,
LauncherSettings.Favorites.CONTAINER_DESKTOP, screenId, coordinates[0],
@@ -420,11 +421,26 @@
fi.contents.forEach(member -> {
mContext.getModelWriter().addItemToDatabase(member, fi.id, -1, -1, -1);
});
- mContext.bindItems(Collections.singletonList(fi), true, accessibility);
+ bindItem(fi, accessibility);
}
}));
return true;
}
+
+ private void bindItem(ItemInfo item, boolean focusForAccessibility) {
+ View view = mContext.getItemInflater().inflateItem(item, mContext.getModelWriter());
+ if (view == null) {
+ return;
+ }
+ AnimatorSet anim = null;
+ if (focusForAccessibility) {
+ anim = new AnimatorSet();
+ anim.addListener(forEndCallback(
+ () -> view.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED)));
+ }
+ mContext.bindItems(Collections.singletonList(Pair.create(item, view)), anim);
+ }
+
/**
* Functionality to move the item {@link ItemInfo} to the workspace
* @param item item to be moved