diff --git a/go/quickstep/src/com/android/quickstep/TaskActionController.java b/go/quickstep/src/com/android/quickstep/TaskActionController.java index 77b287ba5d..71bee9181d 100644 --- a/go/quickstep/src/com/android/quickstep/TaskActionController.java +++ b/go/quickstep/src/com/android/quickstep/TaskActionController.java @@ -42,6 +42,9 @@ public final class TaskActionController { * @param viewHolder the task view holder to launch */ public void launchTask(TaskHolder viewHolder) { + if (viewHolder.getTask() == null) { + return; + } TaskItemView itemView = (TaskItemView) (viewHolder.itemView); View v = itemView.getThumbnailView(); int left = 0; @@ -60,6 +63,9 @@ public final class TaskActionController { * @param viewHolder the task view holder to remove */ public void removeTask(TaskHolder viewHolder) { + if (viewHolder.getTask() == null) { + return; + } int position = viewHolder.getAdapterPosition(); Task task = viewHolder.getTask(); ActivityManagerWrapper.getInstance().removeTask(task.key.id); diff --git a/go/quickstep/src/com/android/quickstep/TaskAdapter.java b/go/quickstep/src/com/android/quickstep/TaskAdapter.java index c98eca6221..674fcae914 100644 --- a/go/quickstep/src/com/android/quickstep/TaskAdapter.java +++ b/go/quickstep/src/com/android/quickstep/TaskAdapter.java @@ -28,6 +28,7 @@ import com.android.quickstep.views.TaskItemView; import com.android.systemui.shared.recents.model.Task; import java.util.List; +import java.util.Objects; /** * Recycler view adapter that dynamically inflates and binds {@link TaskHolder} instances with the @@ -40,6 +41,7 @@ public final class TaskAdapter extends Adapter { private final TaskListLoader mLoader; private final ArrayMap mTaskIdToViewMap = new ArrayMap<>(); private TaskActionController mTaskActionController; + private boolean mIsShowingLoadingUi; public TaskAdapter(@NonNull TaskListLoader loader) { mLoader = loader; @@ -49,6 +51,18 @@ public final class TaskAdapter extends Adapter { mTaskActionController = taskActionController; } + /** + * Sets all positions in the task adapter to loading views, binding new views if necessary. + * This changes the task adapter's view of the data, so the appropriate notify events should be + * called in addition to this method to reflect the changes. + * + * @param isShowingLoadingUi true to bind loading task views to all positions, false to return + * to the real data + */ + public void setIsShowingLoadingUi(boolean isShowingLoadingUi) { + mIsShowingLoadingUi = isShowingLoadingUi; + } + /** * Get task item view for a given task id if it's attached to the view. * @@ -70,6 +84,10 @@ public final class TaskAdapter extends Adapter { @Override public void onBindViewHolder(TaskHolder holder, int position) { + if (mIsShowingLoadingUi) { + holder.bindEmptyUi(); + return; + } List tasks = mLoader.getCurrentTaskList(); if (position >= tasks.size()) { // Task list has updated. @@ -79,13 +97,13 @@ public final class TaskAdapter extends Adapter { holder.bindTask(task); mLoader.loadTaskIconAndLabel(task, () -> { // Ensure holder still has the same task. - if (task.equals(holder.getTask())) { + if (Objects.equals(task, holder.getTask())) { holder.getTaskItemView().setIcon(task.icon); holder.getTaskItemView().setLabel(task.titleDescription); } }); mLoader.loadTaskThumbnail(task, () -> { - if (task.equals(holder.getTask())) { + if (Objects.equals(task, holder.getTask())) { holder.getTaskItemView().setThumbnail(task.thumbnail.thumbnail); } }); @@ -93,16 +111,27 @@ public final class TaskAdapter extends Adapter { @Override public void onViewAttachedToWindow(@NonNull TaskHolder holder) { + if (holder.getTask() == null) { + return; + } mTaskIdToViewMap.put(holder.getTask().key.id, (TaskItemView) holder.itemView); } @Override public void onViewDetachedFromWindow(@NonNull TaskHolder holder) { + if (holder.getTask() == null) { + return; + } mTaskIdToViewMap.remove(holder.getTask().key.id); } @Override public int getItemCount() { - return Math.min(mLoader.getCurrentTaskList().size(), MAX_TASKS_TO_DISPLAY); + if (mIsShowingLoadingUi) { + // Show loading version of all items. + return MAX_TASKS_TO_DISPLAY; + } else { + return Math.min(mLoader.getCurrentTaskList().size(), MAX_TASKS_TO_DISPLAY); + } } } diff --git a/go/quickstep/src/com/android/quickstep/TaskHolder.java b/go/quickstep/src/com/android/quickstep/TaskHolder.java index 744afd766e..98dc989317 100644 --- a/go/quickstep/src/com/android/quickstep/TaskHolder.java +++ b/go/quickstep/src/com/android/quickstep/TaskHolder.java @@ -15,7 +15,7 @@ */ package com.android.quickstep; -import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.recyclerview.widget.RecyclerView.ViewHolder; import com.android.quickstep.views.TaskItemView; @@ -50,11 +50,23 @@ public final class TaskHolder extends ViewHolder { } /** - * Gets the task currently bound to this view + * Bind a generic empty UI to the holder to make it clear that the item is loading/unbound and + * should not be expected to react to user input. + */ + public void bindEmptyUi() { + mTask = null; + // TODO: Set the task view to a loading, empty UI. + // Temporarily using the one below for visual confirmation but should be swapped out to new + // UI later. + mTaskItemView.resetTaskItemView(); + } + + /** + * Gets the task currently bound to this view. May be null if task holder is in a loading state. * * @return the current task */ - public @NonNull Task getTask() { + public @Nullable Task getTask() { return mTask; } } diff --git a/go/quickstep/src/com/android/quickstep/views/IconRecentsView.java b/go/quickstep/src/com/android/quickstep/views/IconRecentsView.java index 5bb4c5aaaa..f525c9d9d5 100644 --- a/go/quickstep/src/com/android/quickstep/views/IconRecentsView.java +++ b/go/quickstep/src/com/android/quickstep/views/IconRecentsView.java @@ -157,10 +157,12 @@ public final class IconRecentsView extends FrameLayout { * becomes visible. */ public void onBeginTransitionToOverview() { + mTaskAdapter.setIsShowingLoadingUi(true); + mTaskAdapter.notifyDataSetChanged(); // Load any task changes mTaskLoader.loadTaskList(tasks -> { - // TODO: Put up some loading UI while task content is loading. May have to do something - // smarter when animating from app to overview. + mTaskAdapter.setIsShowingLoadingUi(false); + // TODO: Animate the loading UI out and the loaded data in. mTaskAdapter.notifyDataSetChanged(); }); }