Download Home : Enable multi-selection
Added ListItemView, GenericListItemView, PrefetchListItemView,
ImageListItemView classes to handle selection. Each of these
views will implement its own UI to handle selection.
Bug: 850600
Change-Id: I9707adb050b38c405ef153b2d4de9b93049ddd61
Reviewed-on: https://chromium-review.googlesource.com/1141159
Commit-Queue: Shakti Sahu <shaktisahu@chromium.org>
Reviewed-by: Theresa <twellington@chromium.org>
Cr-Commit-Position: refs/heads/master@{#576208}
diff --git a/chrome/android/java/res/layout/download_manager_generic_item.xml b/chrome/android/java/res/layout/download_manager_generic_item.xml
index 1cde489..d159ece 100644
--- a/chrome/android/java/res/layout/download_manager_generic_item.xml
+++ b/chrome/android/java/res/layout/download_manager_generic_item.xml
@@ -4,52 +4,59 @@
found in the LICENSE file.
-->
-<android.support.v7.widget.GridLayout
+<org.chromium.chrome.browser.download.home.view.GenericListItemView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:minHeight="64dp"
+ android:layout_height="match_parent"
android:clickable="true"
- android:background="@android:color/white"
- app:columnCount="3"
- app:rowCount="2">
- <org.chromium.chrome.browser.widget.TintedImageView
- android:id="@+id/thumbnail"
- android:layout_width="@dimen/download_manager_generic_thumbnail_size"
- android:layout_height="@dimen/download_manager_generic_thumbnail_size"
- android:layout_marginStart="16dp"
- android:layout_marginEnd="16dp"
- android:scaleType="center"
- app:layout_column="0"
- app:layout_row="0"
- app:layout_rowSpan="2"
- app:layout_gravity="center_vertical"
- app:chrometint="@color/dark_mode_tint" />
+ android:background="@color/modern_primary_color" >
- <TextView
- android:id="@+id/title"
- style="@style/DownloadItemText"
- android:layout_marginTop="11dp"
- android:textAppearance="@style/BlackTitle1"
- app:layout_column="1"
- app:layout_row="0"
- app:layout_gravity="fill_horizontal" />
- <TextView
- android:id="@+id/caption"
- style="@style/DownloadItemText"
- android:textAppearance="@style/BlackHint2"
- app:layout_column="1"
- app:layout_row="1"
- app:layout_gravity="fill_horizontal" />
+ <android.support.v7.widget.GridLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:minHeight="64dp"
+ android:background="@android:color/white"
+ app:columnCount="3"
+ app:rowCount="2">
- <include layout="@layout/list_menu_button"
- android:layout_width="48dp"
- android:layout_height="48dp"
- app:layout_column="2"
- app:layout_row="0"
- app:layout_rowSpan="2"
- app:layout_gravity="center_vertical" />
+ <org.chromium.chrome.browser.widget.TintedImageView
+ android:id="@+id/thumbnail"
+ android:layout_width="@dimen/download_manager_generic_thumbnail_size"
+ android:layout_height="@dimen/download_manager_generic_thumbnail_size"
+ android:layout_marginStart="16dp"
+ android:layout_marginEnd="16dp"
+ android:scaleType="center"
+ app:layout_column="0"
+ app:layout_row="0"
+ app:layout_rowSpan="2"
+ app:layout_gravity="center_vertical"
+ app:chrometint="@color/dark_mode_tint" />
-</android.support.v7.widget.GridLayout>
\ No newline at end of file
+ <TextView
+ android:id="@+id/title"
+ style="@style/DownloadItemText"
+ android:layout_marginTop="11dp"
+ android:textAppearance="@style/BlackTitle1"
+ app:layout_column="1"
+ app:layout_row="0"
+ app:layout_gravity="fill_horizontal" />
+
+ <TextView
+ android:id="@+id/caption"
+ style="@style/DownloadItemText"
+ android:textAppearance="@style/BlackHint2"
+ app:layout_column="1"
+ app:layout_row="1"
+ app:layout_gravity="fill_horizontal" />
+
+ <include layout="@layout/list_menu_button"
+ android:layout_width="48dp"
+ android:layout_height="48dp"
+ app:layout_column="2"
+ app:layout_row="0"
+ app:layout_rowSpan="2"
+ app:layout_gravity="center_vertical" />
+ </android.support.v7.widget.GridLayout>
+</org.chromium.chrome.browser.download.home.view.GenericListItemView>
\ No newline at end of file
diff --git a/chrome/android/java/res/layout/download_manager_image_item.xml b/chrome/android/java/res/layout/download_manager_image_item.xml
index 6fb4abb5..20cc082 100644
--- a/chrome/android/java/res/layout/download_manager_image_item.xml
+++ b/chrome/android/java/res/layout/download_manager_image_item.xml
@@ -4,12 +4,21 @@
found in the LICENSE file.
-->
-<ImageView
+<org.chromium.chrome.browser.download.home.view.ImageListItemView
xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
- android:id="@+id/thumbnail"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:scaleType="centerCrop"
- android:layout_gravity="center_vertical"
- tools:ignore="ContentDescription" />
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:clickable="true"
+ android:background="@color/modern_primary_color" >
+
+ <ImageView
+ android:id="@+id/thumbnail"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:scaleType="centerCrop"
+ android:layout_gravity="center_vertical"
+ tools:ignore="ContentDescription" />
+
+</org.chromium.chrome.browser.download.home.view.ImageListItemView>
diff --git a/chrome/android/java/res/layout/download_manager_prefetch_item.xml b/chrome/android/java/res/layout/download_manager_prefetch_item.xml
index 27ee4a40..ef371e2 100644
--- a/chrome/android/java/res/layout/download_manager_prefetch_item.xml
+++ b/chrome/android/java/res/layout/download_manager_prefetch_item.xml
@@ -4,95 +4,101 @@
found in the LICENSE file.
-->
-<android.support.v7.widget.GridLayout
+<org.chromium.chrome.browser.download.home.view.PrefetchListItemView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
- android:layout_height="114dp"
- android:clickable="true"
- android:background="@android:color/white"
- app:columnCount="4"
- app:rowCount="4">
- <ImageView
- android:id="@+id/thumbnail"
- android:layout_width="114dp"
+ android:layout_height="match_parent"
+ android:clickable="true" >
+
+ <android.support.v7.widget.GridLayout
+ android:layout_width="match_parent"
android:layout_height="114dp"
- android:layout_marginEnd="9dp"
- android:scaleType="fitCenter"
- android:background="@color/google_grey_100"
- app:layout_column="0"
- app:layout_row="0"
- app:layout_rowSpan="4"
- tools:ignore="ContentDescription" />
+ android:background="@android:color/white"
+ app:columnCount="4"
+ app:rowCount="4">
- <Space
- android:layout_width="wrap_content"
- android:layout_height="0dp"
- app:layout_gravity="fill"
- app:layout_column="0"
- app:layout_row="3"
- app:layout_columnSpan="4" />
+ <ImageView
+ android:id="@+id/thumbnail"
+ android:layout_width="114dp"
+ android:layout_height="114dp"
+ android:layout_marginEnd="9dp"
+ android:scaleType="fitCenter"
+ android:background="@color/google_grey_100"
+ app:layout_column="0"
+ app:layout_row="0"
+ app:layout_rowSpan="4"
+ tools:ignore="ContentDescription" />
- <TextView
- android:id="@+id/title"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_marginTop="12dp"
- android:minHeight="40dp"
- android:maxLines="2"
- android:ellipsize="end"
- android:textAppearance="@style/BlackBodyDefault"
- android:textAlignment="viewStart"
- app:layout_column="1"
- app:layout_row="0"
- app:layout_columnSpan="2"
- app:layout_gravity="fill_horizontal" />
+ <Space
+ android:layout_width="wrap_content"
+ android:layout_height="0dp"
+ app:layout_gravity="fill"
+ app:layout_column="0"
+ app:layout_row="3"
+ app:layout_columnSpan="4" />
- <TextView
- android:id="@+id/caption"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginTop="8dp"
- android:layout_marginBottom="8dp"
- android:maxLines="1"
- android:ellipsize="end"
- android:textAppearance="@style/BlackCaption"
- android:textAlignment="viewStart"
- app:layout_column="1"
- app:layout_row="1"
- app:layout_columnSpan="3"
- app:layout_gravity="fill_horizontal" />
+ <TextView
+ android:id="@+id/title"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="12dp"
+ android:minHeight="40dp"
+ android:maxLines="2"
+ android:ellipsize="end"
+ android:textAppearance="@style/BlackBodyDefault"
+ android:textAlignment="viewStart"
+ app:layout_column="1"
+ app:layout_row="0"
+ app:layout_columnSpan="2"
+ app:layout_gravity="fill_horizontal" />
- <TextView
- android:id="@+id/timestamp"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:maxLines="1"
- android:ellipsize="end"
- android:textAppearance="@style/BlackCaption"
- android:textAlignment="viewStart"
- app:layout_column="1"
- app:layout_row="2"
- app:layout_gravity="center_vertical" />
+ <TextView
+ android:id="@+id/caption"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="8dp"
+ android:layout_marginBottom="8dp"
+ android:maxLines="1"
+ android:ellipsize="end"
+ android:textAppearance="@style/BlackCaption"
+ android:textAlignment="viewStart"
+ app:layout_column="1"
+ app:layout_row="1"
+ app:layout_columnSpan="3"
+ app:layout_gravity="fill_horizontal" />
- <ImageView
- android:layout_width="12dp"
- android:layout_height="12dp"
- android:layout_marginStart="4dp"
- android:src="@drawable/offline_pin_round"
- android:scaleType="centerInside"
- android:tint="@color/default_icon_color"
- app:layout_column="2"
- app:layout_row="2"
- app:layout_columnSpan="2"
- app:layout_gravity="start|center_vertical"
- tools:ignore="ContentDescription" />
+ <TextView
+ android:id="@+id/timestamp"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:maxLines="1"
+ android:ellipsize="end"
+ android:textAppearance="@style/BlackCaption"
+ android:textAlignment="viewStart"
+ app:layout_column="1"
+ app:layout_row="2"
+ app:layout_gravity="center_vertical" />
- <include layout="@layout/list_menu_button"
- android:layout_width="48dp"
- android:layout_height="48dp"
- android:paddingTop="12dp"
- app:layout_column="3"
- app:layout_row="0" />
-</android.support.v7.widget.GridLayout>
\ No newline at end of file
+ <ImageView
+ android:layout_width="12dp"
+ android:layout_height="12dp"
+ android:layout_marginStart="4dp"
+ android:src="@drawable/offline_pin_round"
+ android:scaleType="centerInside"
+ android:tint="@color/default_icon_color"
+ app:layout_column="2"
+ app:layout_row="2"
+ app:layout_columnSpan="2"
+ app:layout_gravity="start|center_vertical"
+ tools:ignore="ContentDescription" />
+
+ <include layout="@layout/list_menu_button"
+ android:layout_width="48dp"
+ android:layout_height="48dp"
+ android:paddingTop="12dp"
+ app:layout_column="3"
+ app:layout_row="0" />
+ </android.support.v7.widget.GridLayout>
+</org.chromium.chrome.browser.download.home.view.PrefetchListItemView>
\ No newline at end of file
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/home/DownloadManagerCoordinatorImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/download/home/DownloadManagerCoordinatorImpl.java
index e858aa5..bf72126 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/download/home/DownloadManagerCoordinatorImpl.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/download/home/DownloadManagerCoordinatorImpl.java
@@ -63,7 +63,7 @@
mSelectionDelegate = new SelectionDelegate<ListItem>();
mListCoordinator = new DateOrderedListCoordinator(mActivity, offTheRecord,
OfflineContentAggregatorFactory.forProfile(profile),
- mDeleteCoordinator::showSnackbar, this ::notifyFilterChanged);
+ mDeleteCoordinator::showSnackbar, mSelectionDelegate, this ::notifyFilterChanged);
mMainView =
(ViewGroup) LayoutInflater.from(mActivity).inflate(R.layout.download_main, null);
@@ -138,6 +138,7 @@
}
private void notifyFilterChanged(@FilterType int filter) {
+ mSelectionDelegate.clearSelection();
if (mMuteFilterChanges) return;
String url = Filters.toUrl(filter);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/DateOrderedListCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/DateOrderedListCoordinator.java
index 0b006c8a..6f2f7fd4 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/DateOrderedListCoordinator.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/DateOrderedListCoordinator.java
@@ -11,6 +11,7 @@
import org.chromium.chrome.browser.download.home.filter.FilterCoordinator;
import org.chromium.chrome.browser.download.home.filter.Filters.FilterType;
import org.chromium.chrome.browser.download.home.list.ListItem.ViewListItem;
+import org.chromium.chrome.browser.widget.selection.SelectionDelegate;
import org.chromium.components.offline_items_collection.OfflineContentProvider;
import org.chromium.components.offline_items_collection.OfflineItem;
@@ -58,11 +59,13 @@
*/
public DateOrderedListCoordinator(Context context, Boolean offTheRecord,
OfflineContentProvider provider, DeleteController deleteController,
+ SelectionDelegate<ListItem> selectionDelegate,
FilterCoordinator.Observer filterObserver) {
ListItemModel model = new ListItemModel();
DecoratedListItemModel decoratedModel = new DecoratedListItemModel(model);
mView = new DateOrderedListView(context, decoratedModel);
- mMediator = new DateOrderedListMediator(offTheRecord, provider, deleteController, model);
+ mMediator = new DateOrderedListMediator(
+ offTheRecord, provider, deleteController, selectionDelegate, model);
// Hook up the FilterCoordinator with our mediator.
mFilterCoordinator = new FilterCoordinator(context, mMediator.getFilterSource());
@@ -90,4 +93,4 @@
public void setSelectedFilter(@FilterType int filter) {
mFilterCoordinator.setSelectedFilter(filter);
}
-}
\ No newline at end of file
+}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/DateOrderedListMediator.java b/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/DateOrderedListMediator.java
index 8abf9a2..95bef20 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/DateOrderedListMediator.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/DateOrderedListMediator.java
@@ -22,6 +22,7 @@
import org.chromium.chrome.browser.widget.ThumbnailProvider;
import org.chromium.chrome.browser.widget.ThumbnailProvider.ThumbnailRequest;
import org.chromium.chrome.browser.widget.ThumbnailProviderImpl;
+import org.chromium.chrome.browser.widget.selection.SelectionDelegate;
import org.chromium.components.offline_items_collection.OfflineContentProvider;
import org.chromium.components.offline_items_collection.OfflineItem;
import org.chromium.components.offline_items_collection.VisualsCallback;
@@ -59,7 +60,8 @@
* @param model The {@link ListItemModel} to push {@code provider} into.
*/
public DateOrderedListMediator(boolean offTheRecord, OfflineContentProvider provider,
- DeleteController deleteController, ListItemModel model) {
+ DeleteController deleteController, SelectionDelegate<ListItem> selectionDelegate,
+ ListItemModel model) {
// Build a chain from the data source to the model. The chain will look like:
// [OfflineContentProvider] ->
// [OfflineItemSource] ->
@@ -92,6 +94,7 @@
mModel.getProperties().setShareCallback(item -> {});
mModel.getProperties().setRemoveCallback(this::onDeleteItem);
mModel.getProperties().setVisualsProvider(this::getVisuals);
+ mModel.getProperties().setSelectionDelegate(selectionDelegate);
}
/** Tears down this mediator. */
@@ -179,4 +182,4 @@
mHandler.post(() -> mModel.getProperties().setEnableItemAnimations(true));
}
}
-}
\ No newline at end of file
+}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/ListItemViewHolder.java b/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/ListItemViewHolder.java
index 07899c2d..c24216f 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/ListItemViewHolder.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/ListItemViewHolder.java
@@ -7,9 +7,6 @@
import android.support.annotation.CallSuper;
import android.support.annotation.DrawableRes;
import android.support.annotation.Nullable;
-import android.support.v4.graphics.drawable.RoundedBitmapDrawable;
-import android.support.v4.graphics.drawable.RoundedBitmapDrawableFactory;
-import android.support.v7.content.res.AppCompatResources;
import android.support.v7.widget.AppCompatTextView;
import android.support.v7.widget.RecyclerView.ViewHolder;
import android.view.LayoutInflater;
@@ -26,10 +23,11 @@
import org.chromium.chrome.browser.download.home.list.ListItem.DateListItem;
import org.chromium.chrome.browser.download.home.list.ListItem.OfflineItemListItem;
import org.chromium.chrome.browser.download.home.list.ListItem.ViewListItem;
+import org.chromium.chrome.browser.download.home.view.GenericListItemView;
+import org.chromium.chrome.browser.download.home.view.ListItemView;
import org.chromium.chrome.browser.widget.ListMenuButton;
import org.chromium.chrome.browser.widget.ListMenuButton.Item;
import org.chromium.chrome.browser.widget.TintedImageButton;
-import org.chromium.chrome.browser.widget.TintedImageView;
import org.chromium.components.offline_items_collection.ContentId;
import org.chromium.components.offline_items_collection.OfflineItem;
import org.chromium.components.offline_items_collection.OfflineItemState;
@@ -208,7 +206,6 @@
public static class GenericViewHolder extends ThumbnailAwareViewHolder {
private final TextView mTitle;
private final TextView mCaption;
- private final TintedImageView mThumbnail;
/**
* Whether or not we are currently showing an icon. This determines whether or not we
@@ -233,7 +230,6 @@
mTitle = (TextView) itemView.findViewById(R.id.title);
mCaption = (TextView) itemView.findViewById(R.id.caption);
- mThumbnail = (TintedImageView) itemView.findViewById(R.id.thumbnail);
}
// ListItemViewHolder implementation.
@@ -245,41 +241,22 @@
mTitle.setText(offlineItem.item.title);
mCaption.setText(UiUtils.generateGenericCaption(offlineItem.item));
- itemView.setOnClickListener(
- v -> properties.getOpenCallback().onResult(offlineItem.item));
-
mIconId = UiUtils.getIconForItem(offlineItem.item);
-
- if (mDrawingIcon) setThumbnailToIcon();
}
@Override
void onVisualsChanged(ImageView view, OfflineItemVisuals visuals) {
mDrawingIcon = visuals == null || visuals.icon == null;
+ GenericListItemView selectableView = (GenericListItemView) itemView;
if (mDrawingIcon) {
- setThumbnailToIcon();
+ if (mIconId != INVALID_ID) {
+ selectableView.setThumbnailResource(mIconId);
+ }
} else {
- mThumbnail.setBackground(null);
- mThumbnail.setTint(null);
-
- RoundedBitmapDrawable drawable =
- RoundedBitmapDrawableFactory.create(view.getResources(), visuals.icon);
- drawable.setCircular(true);
- mThumbnail.setImageDrawable(drawable);
+ selectableView.setThumbnail(visuals.icon);
}
}
-
- private void setThumbnailToIcon() {
- if (mIconId == INVALID_ID) return;
-
- mThumbnail.setBackgroundResource(R.drawable.list_item_icon_modern_bg);
- mThumbnail.getBackground().setLevel(
- itemView.getResources().getInteger(R.integer.list_item_level_default));
- mThumbnail.setImageResource(mIconId);
- mThumbnail.setTint(AppCompatResources.getColorStateList(
- itemView.getContext(), R.color.default_icon_color_blue));
- }
}
/**
@@ -319,9 +296,6 @@
OfflineItemListItem offlineItem = (OfflineItemListItem) item;
View imageView = itemView.findViewById(R.id.thumbnail);
imageView.setContentDescription(offlineItem.item.title);
-
- itemView.setOnClickListener(
- v -> properties.getOpenCallback().onResult(offlineItem.item));
}
@Override
@@ -365,9 +339,6 @@
mTitle.setText(offlineItem.item.title);
mCaption.setText(UiUtils.generatePrefetchCaption(offlineItem.item));
mTimestamp.setText(UiUtils.generatePrefetchTimestamp(offlineItem.date));
-
- itemView.setOnClickListener(
- v -> properties.getOpenCallback().onResult(offlineItem.item));
}
@Override
@@ -480,6 +451,12 @@
// If we're rebinding the same item, ignore the bind.
if (offlineItem.id.equals(mId)) return;
+ ListItemView selectableView = (ListItemView) itemView;
+ selectableView.setSelectionDelegate(properties.getSelectionDelegate());
+ selectableView.setItem(item);
+ selectableView.setClickCallback(
+ () -> properties.getOpenCallback().onResult(offlineItem));
+
// Clear any associated bitmap from the thumbnail.
if (mId != null) onVisualsChanged(mThumbnail, null);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/ListPropertyModel.java b/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/ListPropertyModel.java
index 98aa197..1ddd249 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/ListPropertyModel.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/ListPropertyModel.java
@@ -6,6 +6,7 @@
import org.chromium.base.Callback;
import org.chromium.chrome.browser.modelutil.PropertyObservable;
+import org.chromium.chrome.browser.widget.selection.SelectionDelegate;
import org.chromium.components.offline_items_collection.OfflineItem;
import org.chromium.components.offline_items_collection.OfflineItemVisuals;
import org.chromium.components.offline_items_collection.VisualsCallback;
@@ -55,6 +56,7 @@
private Callback<OfflineItem> mShareCallback;
private Callback<OfflineItem> mRemoveCallback;
private VisualsProvider mVisualsProvider;
+ private SelectionDelegate<ListItem> mSelectionDelegate;
/** Sets whether or not item animations should be enabled. */
public void setEnableItemAnimations(boolean enableItemAnimations) {
@@ -151,4 +153,14 @@
public VisualsProvider getVisualsProvider() {
return mVisualsProvider;
}
-}
\ No newline at end of file
+
+ /** Sets the selection delegate to handle selection of list items. */
+ public void setSelectionDelegate(SelectionDelegate<ListItem> selectionDelegate) {
+ mSelectionDelegate = selectionDelegate;
+ }
+
+ /** @return The selection delegate to handle multiple item selections. */
+ public SelectionDelegate<ListItem> getSelectionDelegate() {
+ return mSelectionDelegate;
+ }
+}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/home/view/GenericListItemView.java b/chrome/android/java/src/org/chromium/chrome/browser/download/home/view/GenericListItemView.java
new file mode 100644
index 0000000..66ee464
--- /dev/null
+++ b/chrome/android/java/src/org/chromium/chrome/browser/download/home/view/GenericListItemView.java
@@ -0,0 +1,69 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.chrome.browser.download.home.view;
+
+import android.content.Context;
+import android.content.res.ColorStateList;
+import android.support.graphics.drawable.AnimatedVectorDrawableCompat;
+import android.support.v4.graphics.drawable.RoundedBitmapDrawable;
+import android.support.v4.graphics.drawable.RoundedBitmapDrawableFactory;
+import android.support.v7.content.res.AppCompatResources;
+import android.util.AttributeSet;
+
+import org.chromium.chrome.R;
+import org.chromium.chrome.browser.download.DownloadUtils;
+import org.chromium.chrome.browser.widget.TintedImageView;
+
+/**
+ * Represents a completed download in the download home.
+ */
+public class GenericListItemView extends ListItemView {
+ private TintedImageView mThumbnail;
+ private final ColorStateList mCheckedIconForegroundColorList;
+ private final AnimatedVectorDrawableCompat mCheckDrawable;
+
+ public GenericListItemView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ mCheckDrawable = AnimatedVectorDrawableCompat.create(
+ getContext(), R.drawable.ic_check_googblue_24dp_animated);
+ mCheckedIconForegroundColorList = DownloadUtils.getIconForegroundColorList(context);
+ }
+
+ @Override
+ protected void onFinishInflate() {
+ super.onFinishInflate();
+ mThumbnail = (TintedImageView) findViewById(R.id.thumbnail);
+ }
+
+ @Override
+ protected void updateView() {
+ if (isChecked()) {
+ mThumbnail.setBackgroundResource(R.drawable.list_item_icon_modern_bg);
+ mThumbnail.getBackground().setLevel(
+ getResources().getInteger(R.integer.list_item_level_selected));
+
+ mThumbnail.setImageDrawable(mCheckDrawable);
+ mThumbnail.setTint(mCheckedIconForegroundColorList);
+ mCheckDrawable.start();
+ } else if (mThumbnailBitmap != null) {
+ assert !mThumbnailBitmap.isRecycled();
+
+ mThumbnail.setBackground(null);
+ mThumbnail.setTint(null);
+
+ RoundedBitmapDrawable drawable = RoundedBitmapDrawableFactory.create(
+ mThumbnail.getResources(), mThumbnailBitmap);
+ drawable.setCircular(true);
+ mThumbnail.setImageDrawable(drawable);
+ } else {
+ mThumbnail.setBackgroundResource(R.drawable.list_item_icon_modern_bg);
+ mThumbnail.getBackground().setLevel(
+ mThumbnail.getResources().getInteger(R.integer.list_item_level_default));
+ mThumbnail.setImageResource(mIconResId);
+ mThumbnail.setTint(AppCompatResources.getColorStateList(
+ mThumbnail.getContext(), R.color.dark_mode_tint));
+ }
+ }
+}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/home/view/ImageListItemView.java b/chrome/android/java/src/org/chromium/chrome/browser/download/home/view/ImageListItemView.java
new file mode 100644
index 0000000..926e454
--- /dev/null
+++ b/chrome/android/java/src/org/chromium/chrome/browser/download/home/view/ImageListItemView.java
@@ -0,0 +1,17 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.chrome.browser.download.home.view;
+
+import android.content.Context;
+import android.util.AttributeSet;
+
+/**
+ * Represents an image in the download home.
+ */
+public class ImageListItemView extends ListItemView {
+ public ImageListItemView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/home/view/ListItemView.java b/chrome/android/java/src/org/chromium/chrome/browser/download/home/view/ListItemView.java
new file mode 100644
index 0000000..29ce1c8
--- /dev/null
+++ b/chrome/android/java/src/org/chromium/chrome/browser/download/home/view/ListItemView.java
@@ -0,0 +1,42 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.chrome.browser.download.home.view;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.util.AttributeSet;
+
+import org.chromium.chrome.browser.download.home.list.ListItem;
+import org.chromium.chrome.browser.widget.selection.SelectableItemViewBase;
+
+/** A class that represents a variety of possible list items to show in downloads home. */
+public abstract class ListItemView extends SelectableItemViewBase<ListItem> {
+ private Runnable mClickCallback;
+ protected Bitmap mThumbnailBitmap;
+ protected int mIconResId;
+
+ public ListItemView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public void setClickCallback(Runnable listener) {
+ mClickCallback = listener;
+ }
+
+ @Override
+ protected void onClick() {
+ mClickCallback.run();
+ }
+
+ public void setThumbnail(Bitmap thumbnail) {
+ mThumbnailBitmap = thumbnail;
+ updateView();
+ }
+
+ public void setThumbnailResource(int iconResId) {
+ mIconResId = iconResId;
+ updateView();
+ }
+}
\ No newline at end of file
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/home/view/PrefetchListItemView.java b/chrome/android/java/src/org/chromium/chrome/browser/download/home/view/PrefetchListItemView.java
new file mode 100644
index 0000000..3da25ed
--- /dev/null
+++ b/chrome/android/java/src/org/chromium/chrome/browser/download/home/view/PrefetchListItemView.java
@@ -0,0 +1,17 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.chrome.browser.download.home.view;
+
+import android.content.Context;
+import android.util.AttributeSet;
+
+/**
+ * Represents a prefetched page in the download home.
+ */
+public class PrefetchListItemView extends ListItemView {
+ public PrefetchListItemView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+}
diff --git a/chrome/android/java_sources.gni b/chrome/android/java_sources.gni
index 6d613493..e172677 100644
--- a/chrome/android/java_sources.gni
+++ b/chrome/android/java_sources.gni
@@ -479,6 +479,10 @@
"java/src/org/chromium/chrome/browser/download/home/list/ItemUtils.java",
"java/src/org/chromium/chrome/browser/download/home/list/ListItem.java",
"java/src/org/chromium/chrome/browser/download/home/list/ListItemModel.java",
+ "java/src/org/chromium/chrome/browser/download/home/view/GenericListItemView.java",
+ "java/src/org/chromium/chrome/browser/download/home/view/ImageListItemView.java",
+ "java/src/org/chromium/chrome/browser/download/home/view/ListItemView.java",
+ "java/src/org/chromium/chrome/browser/download/home/view/PrefetchListItemView.java",
"java/src/org/chromium/chrome/browser/download/home/list/ListItemViewHolder.java",
"java/src/org/chromium/chrome/browser/download/home/list/ListPropertyModel.java",
"java/src/org/chromium/chrome/browser/download/home/list/ListPropertyViewBinder.java",