summaryrefslogtreecommitdiffstats
path: root/go/quickstep
diff options
context:
space:
mode:
authorKevin <kevhan@google.com>2019-04-17 09:28:36 -0700
committerKevin Han <kevhan@google.com>2019-04-23 19:25:05 +0000
commiteda02641a2ebe3729ea2259fea044be699456d43 (patch)
tree559b4f4e8f732c579b7f78aaed5cae90b22d01c3 /go/quickstep
parent56abdd7ade200a3c5dc8bca5f147ee593a313323 (diff)
downloadandroid_packages_apps_Trebuchet-eda02641a2ebe3729ea2259fea044be699456d43.tar.gz
android_packages_apps_Trebuchet-eda02641a2ebe3729ea2259fea044be699456d43.tar.bz2
android_packages_apps_Trebuchet-eda02641a2ebe3729ea2259fea044be699456d43.zip
Move clear all to recycler view (1/2)
First part of moving clear all button to recycler view. This CL adds support in the recycler view adapter for a clear all holder type and hooks it up to the previous clear all animation. Adding this breaks several assumptions made externally on the type of the item and index which will be addressed in the second part. Bug: 114136250 Test: Builds, testing pending 2nd part Change-Id: Ib16790028d4e9f520945a987b3dace40d19f2468 (cherry pick from 8573ff04b4148c47222abd1a89d99eda734290c3)
Diffstat (limited to 'go/quickstep')
-rw-r--r--go/quickstep/res/layout/clear_all_button.xml28
-rw-r--r--go/quickstep/res/layout/icon_recents_root_view.xml24
-rw-r--r--go/quickstep/src/com/android/quickstep/ClearAllHolder.java30
-rw-r--r--go/quickstep/src/com/android/quickstep/TaskAdapter.java110
-rw-r--r--go/quickstep/src/com/android/quickstep/views/IconRecentsView.java19
5 files changed, 140 insertions, 71 deletions
diff --git a/go/quickstep/res/layout/clear_all_button.xml b/go/quickstep/res/layout/clear_all_button.xml
new file mode 100644
index 000000000..eceffec42
--- /dev/null
+++ b/go/quickstep/res/layout/clear_all_button.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2019 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.
+-->
+<Button xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/clear_all_button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal"
+ android:background="@drawable/clear_all_button"
+ android:gravity="center"
+ android:text="@string/recents_clear_all"
+ android:textAllCaps="false"
+ android:textColor="@color/clear_all_button_text"
+ android:textSize="14sp">
+</Button>
diff --git a/go/quickstep/res/layout/icon_recents_root_view.xml b/go/quickstep/res/layout/icon_recents_root_view.xml
index 6dc293f74..6fb7e19d1 100644
--- a/go/quickstep/res/layout/icon_recents_root_view.xml
+++ b/go/quickstep/res/layout/icon_recents_root_view.xml
@@ -19,29 +19,11 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
- <LinearLayout
- android:id="@+id/recent_task_content_view"
+ <androidx.recyclerview.widget.RecyclerView
+ android:id="@+id/recent_task_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:orientation="vertical"
- android:visibility="gone">
- <androidx.recyclerview.widget.RecyclerView
- android:id="@+id/recent_task_recycler_view"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:scrollbars="none"/>
- <Button
- android:id="@+id/clear_all_button"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center_horizontal"
- android:background="@drawable/clear_all_button"
- android:gravity="center"
- android:text="@string/recents_clear_all"
- android:textAllCaps="false"
- android:textColor="@color/clear_all_button_text"
- android:textSize="14sp"/>
- </LinearLayout>
+ android:scrollbars="none"/>
<TextView
android:id="@+id/recent_task_empty_view"
android:layout_width="match_parent"
diff --git a/go/quickstep/src/com/android/quickstep/ClearAllHolder.java b/go/quickstep/src/com/android/quickstep/ClearAllHolder.java
new file mode 100644
index 000000000..ce87171f4
--- /dev/null
+++ b/go/quickstep/src/com/android/quickstep/ClearAllHolder.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2019 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.quickstep;
+
+import android.view.View;
+
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.RecyclerView.ViewHolder;
+
+/**
+ * Holder for clear all button view in task recycler view.
+ */
+final class ClearAllHolder extends ViewHolder {
+ public ClearAllHolder(@NonNull View itemView) {
+ super(itemView);
+ }
+}
diff --git a/go/quickstep/src/com/android/quickstep/TaskAdapter.java b/go/quickstep/src/com/android/quickstep/TaskAdapter.java
index 18d5877aa..4eec78be2 100644
--- a/go/quickstep/src/com/android/quickstep/TaskAdapter.java
+++ b/go/quickstep/src/com/android/quickstep/TaskAdapter.java
@@ -16,12 +16,14 @@
package com.android.quickstep;
import android.view.LayoutInflater;
+import android.view.View.OnClickListener;
import android.view.ViewGroup;
+import android.widget.Button;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView.Adapter;
+import androidx.recyclerview.widget.RecyclerView.ViewHolder;
-import com.android.launcher3.DeviceProfile;
import com.android.launcher3.R;
import com.android.quickstep.views.TaskItemView;
import com.android.systemui.shared.recents.model.Task;
@@ -34,14 +36,17 @@ import java.util.Optional;
* Recycler view adapter that dynamically inflates and binds {@link TaskHolder} instances with the
* appropriate {@link Task} from the recents task list.
*/
-public final class TaskAdapter extends Adapter<TaskHolder> {
+public final class TaskAdapter extends Adapter<ViewHolder> {
public static final int CHANGE_EVENT_TYPE_EMPTY_TO_CONTENT = 0;
public static final int MAX_TASKS_TO_DISPLAY = 6;
private static final String TAG = "TaskAdapter";
+ private static final int ITEM_TYPE_TASK = 0;
+ private static final int ITEM_TYPE_CLEAR_ALL = 1;
private final TaskListLoader mLoader;
private TaskActionController mTaskActionController;
+ private OnClickListener mClearAllListener;
private boolean mIsShowingLoadingUi;
public TaskAdapter(@NonNull TaskListLoader loader) {
@@ -52,6 +57,10 @@ public final class TaskAdapter extends Adapter<TaskHolder> {
mTaskActionController = taskActionController;
}
+ public void setOnClearAllClickListener(OnClickListener listener) {
+ mClearAllListener = listener;
+ }
+
/**
* 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
@@ -65,21 +74,32 @@ public final class TaskAdapter extends Adapter<TaskHolder> {
}
@Override
- public TaskHolder onCreateViewHolder(ViewGroup parent, int viewType) {
- TaskItemView itemView = (TaskItemView) LayoutInflater.from(parent.getContext())
- .inflate(R.layout.task_item_view, parent, false);
- TaskHolder holder = new TaskHolder(itemView);
- itemView.setOnClickListener(view -> mTaskActionController.launchTask(holder));
- return holder;
+ public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+ switch (viewType) {
+ case ITEM_TYPE_TASK:
+ TaskItemView itemView = (TaskItemView) LayoutInflater.from(parent.getContext())
+ .inflate(R.layout.task_item_view, parent, false);
+ TaskHolder taskHolder = new TaskHolder(itemView);
+ itemView.setOnClickListener(view -> mTaskActionController.launchTask(taskHolder));
+ return taskHolder;
+ case ITEM_TYPE_CLEAR_ALL:
+ Button clearView = (Button) LayoutInflater.from(parent.getContext())
+ .inflate(R.layout.clear_all_button, parent, false);
+ ClearAllHolder clearAllHolder = new ClearAllHolder(clearView);
+ clearView.setOnClickListener(mClearAllListener);
+ return clearAllHolder;
+ default:
+ throw new IllegalArgumentException("No known holder for item type: " + viewType);
+ }
}
@Override
- public void onBindViewHolder(TaskHolder holder, int position) {
+ public void onBindViewHolder(ViewHolder holder, int position) {
onBindViewHolderInternal(holder, position, false /* willAnimate */);
}
@Override
- public void onBindViewHolder(@NonNull TaskHolder holder, int position,
+ public void onBindViewHolder(@NonNull ViewHolder holder, int position,
@NonNull List<Object> payloads) {
if (payloads.isEmpty()) {
super.onBindViewHolder(holder, position, payloads);
@@ -95,40 +115,60 @@ public final class TaskAdapter extends Adapter<TaskHolder> {
}
}
- private void onBindViewHolderInternal(@NonNull TaskHolder holder, int position,
+ private void onBindViewHolderInternal(@NonNull ViewHolder holder, int position,
boolean willAnimate) {
- if (mIsShowingLoadingUi) {
- holder.bindEmptyUi();
- return;
+ int itemType = getItemViewType(position);
+ switch (itemType) {
+ case ITEM_TYPE_TASK:
+ TaskHolder taskHolder = (TaskHolder) holder;
+ if (mIsShowingLoadingUi) {
+ taskHolder.bindEmptyUi();
+ return;
+ }
+ List<Task> tasks = mLoader.getCurrentTaskList();
+ if (position >= tasks.size()) {
+ // Task list has updated.
+ return;
+ }
+ Task task = tasks.get(position);
+ taskHolder.bindTask(task, willAnimate /* willAnimate */);
+ mLoader.loadTaskIconAndLabel(task, () -> {
+ // Ensure holder still has the same task.
+ if (Objects.equals(Optional.of(task), taskHolder.getTask())) {
+ taskHolder.getTaskItemView().setIcon(task.icon);
+ taskHolder.getTaskItemView().setLabel(task.titleDescription);
+ }
+ });
+ mLoader.loadTaskThumbnail(task, () -> {
+ if (Objects.equals(Optional.of(task), taskHolder.getTask())) {
+ taskHolder.getTaskItemView().setThumbnail(task.thumbnail.thumbnail);
+ }
+ });
+ break;
+ case ITEM_TYPE_CLEAR_ALL:
+ // Nothing to bind.
+ break;
+ default:
+ throw new IllegalArgumentException("No known holder for item type: " + itemType);
}
- List<Task> tasks = mLoader.getCurrentTaskList();
- if (position >= tasks.size()) {
- // Task list has updated.
- return;
- }
- Task task = tasks.get(position);
- holder.bindTask(task, willAnimate /* willAnimate */);
- mLoader.loadTaskIconAndLabel(task, () -> {
- // Ensure holder still has the same task.
- if (Objects.equals(Optional.of(task), holder.getTask())) {
- holder.getTaskItemView().setIcon(task.icon);
- holder.getTaskItemView().setLabel(task.titleDescription);
- }
- });
- mLoader.loadTaskThumbnail(task, () -> {
- if (Objects.equals(Optional.of(task), holder.getTask())) {
- holder.getTaskItemView().setThumbnail(task.thumbnail.thumbnail);
- }
- });
+ }
+
+ @Override
+ public int getItemViewType(int position) {
+ // Bottom is always clear all button.
+ return (position == 0) ? ITEM_TYPE_CLEAR_ALL : ITEM_TYPE_TASK;
}
@Override
public int getItemCount() {
+ // Always at least one for clear all button.
+ int itemCount = 1;
if (mIsShowingLoadingUi) {
// Show loading version of all items.
- return MAX_TASKS_TO_DISPLAY;
+ itemCount += MAX_TASKS_TO_DISPLAY;
} else {
- return Math.min(mLoader.getCurrentTaskList().size(), MAX_TASKS_TO_DISPLAY);
+ itemCount += Math.min(mLoader.getCurrentTaskList().size(), MAX_TASKS_TO_DISPLAY);
}
+ return itemCount;
}
}
diff --git a/go/quickstep/src/com/android/quickstep/views/IconRecentsView.java b/go/quickstep/src/com/android/quickstep/views/IconRecentsView.java
index 3c08b7ec7..e2dad58b9 100644
--- a/go/quickstep/src/com/android/quickstep/views/IconRecentsView.java
+++ b/go/quickstep/src/com/android/quickstep/views/IconRecentsView.java
@@ -18,9 +18,6 @@ package com.android.quickstep.views;
import static androidx.recyclerview.widget.LinearLayoutManager.VERTICAL;
import static com.android.quickstep.TaskAdapter.CHANGE_EVENT_TYPE_EMPTY_TO_CONTENT;
-import static com.android.quickstep.views.TaskLayoutUtils.getClearAllButtonHeight;
-import static com.android.quickstep.views.TaskLayoutUtils.getClearAllButtonTopBottomMargin;
-import static com.android.quickstep.views.TaskLayoutUtils.getClearAllButtonWidth;
import static com.android.quickstep.views.TaskLayoutUtils.getTaskListHeight;
import android.animation.Animator;
@@ -114,7 +111,6 @@ public final class IconRecentsView extends FrameLayout {
private View mShowingContentView;
private View mEmptyView;
private View mContentView;
- private View mClearAllView;
private boolean mTransitionedFromApp;
private AnimatorSet mLayoutAnimation;
private final ArraySet<View> mLayingOutViews = new ArraySet<>();
@@ -141,6 +137,7 @@ public final class IconRecentsView extends FrameLayout {
mDeviceProfile = activity.getDeviceProfile();
mTaskLoader = new TaskListLoader(mContext);
mTaskAdapter = new TaskAdapter(mTaskLoader);
+ mTaskAdapter.setOnClearAllClickListener(view -> animateClearAllTasks());
mTaskActionController = new TaskActionController(mTaskLoader, mTaskAdapter);
mTaskAdapter.setActionController(mTaskActionController);
RecentsModel.INSTANCE.get(context).addThumbnailChangeListener(listener);
@@ -178,7 +175,7 @@ public final class IconRecentsView extends FrameLayout {
() -> mTaskRecyclerView.setItemAnimator(new DefaultItemAnimator()));
mEmptyView = findViewById(R.id.recent_task_empty_view);
- mContentView = findViewById(R.id.recent_task_content_view);
+ mContentView = mTaskRecyclerView;
mTaskAdapter.registerAdapterDataObserver(new AdapterDataObserver() {
@Override
public void onChanged() {
@@ -190,16 +187,7 @@ public final class IconRecentsView extends FrameLayout {
updateContentViewVisibility();
}
});
- // TODO: Move clear all button to recycler view so that it can scroll off screen.
// TODO: Move layout param logic into onMeasure
- mClearAllView = findViewById(R.id.clear_all_button);
- MarginLayoutParams clearAllParams =
- (MarginLayoutParams) mClearAllView.getLayoutParams();
- clearAllParams.height = getClearAllButtonHeight(mDeviceProfile);
- clearAllParams.width = getClearAllButtonWidth(mDeviceProfile);
- clearAllParams.topMargin = getClearAllButtonTopBottomMargin(mDeviceProfile);
- clearAllParams.bottomMargin = getClearAllButtonTopBottomMargin(mDeviceProfile);
- mClearAllView.setOnClickListener(v -> animateClearAllTasks());
}
}
@@ -210,7 +198,7 @@ public final class IconRecentsView extends FrameLayout {
for (TaskItemView itemView : itemViews) {
itemView.setEnabled(enabled);
}
- mClearAllView.setEnabled(enabled);
+ // TODO: Disable clear all button.
}
/**
@@ -365,6 +353,7 @@ public final class IconRecentsView extends FrameLayout {
* @return array of attached task item views
*/
private TaskItemView[] getTaskViews() {
+ // TODO: Check that clear all button isn't here..
int taskCount = mTaskRecyclerView.getChildCount();
TaskItemView[] itemViews = new TaskItemView[taskCount];
for (int i = 0; i < taskCount; i ++) {