Commit 43de5037 authored by Mei Liang's avatar Mei Liang Committed by Commit Bot

Refactor TabGridViewHolder to support various item view types

This is the first CL for upstreaming TabSelectionEditor. This CL
refactors TabGridViewHolder to support creating different ViewHolders
for a RecyclerView based on the provided item view type.

Change-Id: I94aa3c92875b31b0f9f79d4ce0e0c56b43ef9392
Bug: 970087
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1642140Reviewed-by: default avatarYusuf Ozuysal <yusufo@chromium.org>
Reviewed-by: default avatarWei-Yin Chen (陳威尹) <wychen@chromium.org>
Commit-Queue: Mei Liang <meiliang@chromium.org>
Cr-Commit-Position: refs/heads/master@{#666120}
parent 40d392e3
......@@ -21,6 +21,7 @@ android_library("java") {
java_files = [
"java/src/org/chromium/chrome/browser/tasks/tab_groups/TabGroupUtils.java",
"java/src/org/chromium/chrome/browser/tasks/tab_management/ClosableTabGridViewHolder.java",
"java/src/org/chromium/chrome/browser/tasks/tab_management/GridTabSwitcherCoordinator.java",
"java/src/org/chromium/chrome/browser/tasks/tab_management/GridTabSwitcherMediator.java",
"java/src/org/chromium/chrome/browser/tasks/tab_management/MultiThumbnailCardProvider.java",
......@@ -34,6 +35,7 @@ android_library("java") {
"java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridSheetProperties.java",
"java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridSheetToolbarCoordinator.java",
"java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridSheetViewBinder.java",
"java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridView.java",
"java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridViewBinder.java",
"java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridViewHolder.java",
"java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiCoordinator.java",
......
......@@ -3,7 +3,8 @@
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file. -->
<!-- TODO(crbug/928388): Handle elevation for KitKat.-->
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
<org.chromium.chrome.browser.tasks.tab_management.TabGridView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content">
......@@ -68,11 +69,11 @@
style="@style/FilledButton"/>
</RelativeLayout>
<org.chromium.ui.widget.ChromeImageView
android:id="@+id/close_button"
android:id="@+id/action_button"
android:layout_width="48dp"
android:layout_height="48dp"
android:scaleType="center"
android:layout_gravity="end"
android:tint="@color/modern_grey_800"
android:contentDescription="@string/accessibility_tabstrip_btn_close_tab"/>
</FrameLayout>
android:tint="@color/modern_grey_800"/>
</org.chromium.chrome.browser.tasks.tab_management.TabGridView>
// Copyright 2019 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.tasks.tab_management;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import java.lang.ref.WeakReference;
/**
* A {@link TabGridViewHolder} with a close button. This is used in the Grid Tab Switcher.
*/
class ClosableTabGridViewHolder extends TabGridViewHolder {
private static WeakReference<Bitmap> sCloseButtonBitmapWeakRef;
ClosableTabGridViewHolder(TabGridView itemView) {
super(itemView);
if (sCloseButtonBitmapWeakRef == null || sCloseButtonBitmapWeakRef.get() == null) {
int closeButtonSize = (int) itemView.getResources().getDimension(
org.chromium.chrome.tab_ui.R.dimen.tab_grid_close_button_size);
Bitmap bitmap = BitmapFactory.decodeResource(
itemView.getResources(), org.chromium.chrome.tab_ui.R.drawable.btn_close);
sCloseButtonBitmapWeakRef = new WeakReference<>(
Bitmap.createScaledBitmap(bitmap, closeButtonSize, closeButtonSize, true));
bitmap.recycle();
}
actionButton.setImageBitmap(sCloseButtonBitmapWeakRef.get());
}
}
// Copyright 2019 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.tasks.tab_management;
import android.content.Context;
import android.util.AttributeSet;
import android.widget.FrameLayout;
/**
* Holds the view for tab grid.
*/
public class TabGridView extends FrameLayout {
public TabGridView(Context context, AttributeSet attrs) {
super(context, attrs);
}
}
......@@ -40,8 +40,6 @@ class TabGridViewBinder {
if (TabProperties.TITLE == propertyKey) {
String title = item.get(TabProperties.TITLE);
holder.title.setText(title);
holder.closeButton.setContentDescription(holder.itemView.getResources().getString(
org.chromium.chrome.R.string.accessibility_tabstrip_btn_close_tab, title));
} else if (TabProperties.IS_SELECTED == propertyKey) {
Resources res = holder.itemView.getResources();
Resources.Theme theme = holder.itemView.getContext().getTheme();
......@@ -60,14 +58,6 @@ class TabGridViewBinder {
holder.itemView.setForeground(
item.get(TabProperties.IS_SELECTED) ? drawable : null);
}
} else if (TabProperties.TAB_SELECTED_LISTENER == propertyKey) {
holder.itemView.setOnClickListener(view -> {
item.get(TabProperties.TAB_SELECTED_LISTENER).run(holder.getTabId());
});
} else if (TabProperties.TAB_CLOSED_LISTENER == propertyKey) {
holder.closeButton.setOnClickListener(view -> {
item.get(TabProperties.TAB_CLOSED_LISTENER).run(holder.getTabId());
});
} else if (TabProperties.FAVICON == propertyKey) {
holder.favicon.setImageDrawable(item.get(TabProperties.FAVICON));
} else if (TabProperties.THUMBNAIL_FETCHER == propertyKey) {
......@@ -81,11 +71,35 @@ class TabGridViewBinder {
}
};
fetcher.fetch(callback);
} else if (TabProperties.IPH_PROVIDER == propertyKey) {
TabListMediator.IphProvider provider = item.get(TabProperties.IPH_PROVIDER);
if (provider != null) provider.showIPH(holder.thumbnail);
} else if (TabProperties.TAB_ID == propertyKey) {
holder.setTabId(item.get(TabProperties.TAB_ID));
}
if (holder instanceof ClosableTabGridViewHolder) {
onBindClosableTab(holder, item, propertyKey);
} else {
onBindSelectableTab(holder, item, propertyKey);
}
}
private static void onBindViewHolder(TabGridViewHolder holder, PropertyModel item) {
for (PropertyKey propertyKey : TabProperties.ALL_KEYS_TAB_GRID) {
onBindViewHolder(holder, item, propertyKey);
}
}
private static void onBindClosableTab(
TabGridViewHolder holder, PropertyModel item, PropertyKey propertyKey) {
assert holder instanceof ClosableTabGridViewHolder;
if (TabProperties.TAB_CLOSED_LISTENER == propertyKey) {
holder.actionButton.setOnClickListener(view -> {
item.get(TabProperties.TAB_CLOSED_LISTENER).run(holder.getTabId());
});
} else if (TabProperties.TAB_SELECTED_LISTENER == propertyKey) {
holder.itemView.setOnClickListener(view -> {
item.get(TabProperties.TAB_SELECTED_LISTENER).run(holder.getTabId());
});
} else if (TabProperties.CREATE_GROUP_LISTENER == propertyKey) {
TabListMediator.TabActionListener listener =
item.get(TabProperties.CREATE_GROUP_LISTENER);
......@@ -97,12 +111,18 @@ class TabGridViewBinder {
holder.createGroupButton.setOnClickListener(view -> listener.run(holder.getTabId()));
} else if (TabProperties.ALPHA == propertyKey) {
holder.itemView.setAlpha(item.get(TabProperties.ALPHA));
} else if (TabProperties.TITLE == propertyKey) {
String title = item.get(TabProperties.TITLE);
holder.actionButton.setContentDescription(holder.itemView.getResources().getString(
org.chromium.chrome.R.string.accessibility_tabstrip_btn_close_tab, title));
} else if (TabProperties.IPH_PROVIDER == propertyKey) {
TabListMediator.IphProvider provider = item.get(TabProperties.IPH_PROVIDER);
if (provider != null) provider.showIPH(holder.thumbnail);
}
}
private static void onBindViewHolder(TabGridViewHolder holder, PropertyModel item) {
for (PropertyKey propertyKey : TabProperties.ALL_KEYS_TAB_GRID) {
onBindViewHolder(holder, item, propertyKey);
}
private static void onBindSelectableTab(
TabGridViewHolder holder, PropertyModel item, PropertyKey propertyKey) {
// TODO(meiliang): Bind SELECTABLE_TAB properties
}
}
......@@ -4,8 +4,7 @@
package org.chromium.chrome.browser.tasks.tab_management;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.support.annotation.IntDef;
import android.support.v4.content.ContextCompat;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
......@@ -17,24 +16,32 @@ import android.widget.TextView;
import org.chromium.chrome.tab_ui.R;
import org.chromium.ui.widget.ButtonCompat;
import java.lang.ref.WeakReference;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* {@link RecyclerView.ViewHolder} for tab grid. Owns the tab info card
* and the associated view hierarchy.
*/
class TabGridViewHolder extends RecyclerView.ViewHolder {
private static WeakReference<Bitmap> sCloseButtonBitmapWeakRef;
@IntDef({TabGridViewItemType.CLOSABLE_TAB, TabGridViewItemType.SELECTABLE_TAB})
@Retention(RetentionPolicy.SOURCE)
public @interface TabGridViewItemType {
int CLOSABLE_TAB = 0;
int SELECTABLE_TAB = 1;
int NUM_ENTRIES = 2;
}
public final ImageView favicon;
public final TextView title;
public final ImageView thumbnail;
public final ImageView closeButton;
public final ButtonCompat createGroupButton;
public final View backgroundView;
public final ImageView actionButton;
private int mTabId;
private TabGridViewHolder(View itemView) {
protected TabGridViewHolder(TabGridView itemView) {
super(itemView);
this.thumbnail = itemView.findViewById(R.id.tab_thumbnail);
this.title = itemView.findViewById(R.id.tab_title);
......@@ -42,26 +49,20 @@ class TabGridViewHolder extends RecyclerView.ViewHolder {
title.setTextColor(ContextCompat.getColor(
itemView.getContext(), org.chromium.chrome.R.color.default_text_color_dark));
this.favicon = itemView.findViewById(R.id.tab_favicon);
this.closeButton = itemView.findViewById(R.id.close_button);
this.actionButton = itemView.findViewById(R.id.action_button);
this.createGroupButton = itemView.findViewById(R.id.create_group_button);
this.backgroundView = itemView.findViewById(R.id.background_view);
if (sCloseButtonBitmapWeakRef == null || sCloseButtonBitmapWeakRef.get() == null) {
int closeButtonSize =
(int) itemView.getResources().getDimension(R.dimen.tab_grid_close_button_size);
Bitmap bitmap = BitmapFactory.decodeResource(
itemView.getResources(), org.chromium.chrome.R.drawable.btn_close);
sCloseButtonBitmapWeakRef = new WeakReference<>(
Bitmap.createScaledBitmap(bitmap, closeButtonSize, closeButtonSize, true));
bitmap.recycle();
}
this.closeButton.setImageBitmap(sCloseButtonBitmapWeakRef.get());
}
public static TabGridViewHolder create(ViewGroup parent, int itemViewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.tab_grid_card_item, parent, false);
return new TabGridViewHolder(view);
TabGridView view = (TabGridView) LayoutInflater.from(parent.getContext())
.inflate(R.layout.tab_grid_card_item, parent, false);
if (itemViewType == TabGridViewItemType.CLOSABLE_TAB) {
return new ClosableTabGridViewHolder(view);
} else {
// TODO(meiliang): Return SelectableTabGridViewHolder
return new TabGridViewHolder(view);
}
}
public void setTabId(int tabId) {
......
......@@ -187,7 +187,7 @@ public class TabListViewHolderTest extends DummyUiActivityTestCase {
@MediumTest
@UiThreadTest
public void testClickToClose() throws Exception {
mTabGridViewHolder.closeButton.performClick();
mTabGridViewHolder.actionButton.performClick();
Assert.assertTrue(mCloseClicked.get());
mCloseClicked.set(false);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment