Bug 1410221: Pass in parent snackbarAnchor for WebpageItemRow. r=liuche
MozReview-Commit-ID: 76VLKcEPQWF
--- a/mobile/android/base/java/org/mozilla/gecko/activitystream/homepanel/StreamHighlightItemRowContextMenuListener.java
+++ b/mobile/android/base/java/org/mozilla/gecko/activitystream/homepanel/StreamHighlightItemRowContextMenuListener.java
@@ -1,18 +1,19 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.gecko.activitystream.homepanel;
import android.support.annotation.NonNull;
+import android.view.View;
import org.mozilla.gecko.activitystream.homepanel.stream.WebpageItemRow;
/**
* Provides a method to open the context menu for a highlight item.
*
* I tried declaring this inside StreamRecyclerAdapter but I got cyclical inheritance warnings
* (I don't understand why) so it's here instead.
*/
public interface StreamHighlightItemRowContextMenuListener {
- void openContextMenu(WebpageItemRow highlightItem, int position, @NonNull final String interactionExtra);
+ void openContextMenu(WebpageItemRow highlightItem, int position, View snackbarAnchor, @NonNull final String interactionExtra);
}
--- a/mobile/android/base/java/org/mozilla/gecko/activitystream/homepanel/StreamRecyclerAdapter.java
+++ b/mobile/android/base/java/org/mozilla/gecko/activitystream/homepanel/StreamRecyclerAdapter.java
@@ -17,16 +17,17 @@ import android.view.ViewGroup;
import org.mozilla.gecko.GeckoSharedPrefs;
import org.mozilla.gecko.R;
import org.mozilla.gecko.Telemetry;
import org.mozilla.gecko.TelemetryContract;
import org.mozilla.gecko.activitystream.ActivityStreamTelemetry;
import org.mozilla.gecko.activitystream.homepanel.menu.ActivityStreamContextMenu;
import org.mozilla.gecko.activitystream.homepanel.model.RowModel;
+import org.mozilla.gecko.activitystream.homepanel.model.WebpageModel;
import org.mozilla.gecko.activitystream.homepanel.model.WebpageRowModel;
import org.mozilla.gecko.activitystream.homepanel.stream.HighlightsEmptyStateRow;
import org.mozilla.gecko.activitystream.homepanel.stream.LearnMoreRow;
import org.mozilla.gecko.activitystream.homepanel.stream.TopPanelRow;
import org.mozilla.gecko.activitystream.homepanel.model.TopStory;
import org.mozilla.gecko.activitystream.homepanel.topstories.PocketStoriesLoader;
import org.mozilla.gecko.home.HomePager;
import org.mozilla.gecko.activitystream.homepanel.model.Highlight;
@@ -125,27 +126,31 @@ public class StreamRecyclerAdapter exten
if (position >= recyclerViewModel.size()) {
throw new IllegalArgumentException("Requested position, " + position + ", does not exist. Size is :" +
recyclerViewModel.size());
}
return recyclerViewModel.get(position).getRowItemType().getViewType();
}
@Override
- public StreamViewHolder onCreateViewHolder(ViewGroup parent, final int type) {
+ public StreamViewHolder onCreateViewHolder(final ViewGroup parent, final int type) {
final LayoutInflater inflater = LayoutInflater.from(parent.getContext());
if (type == RowItemType.TOP_PANEL.getViewType()) {
return new TopPanelRow(inflater.inflate(TopPanelRow.LAYOUT_ID, parent, false), onUrlOpenListener, onUrlOpenInBackgroundListener);
} else if (type == RowItemType.TOP_STORIES_TITLE.getViewType()) {
return new StreamTitleRow(inflater.inflate(StreamTitleRow.LAYOUT_ID, parent, false), R.string.activity_stream_topstories, R.string.activity_stream_link_more, LINK_MORE_POCKET, onUrlOpenListener);
- } else if (type == RowItemType.TOP_STORIES_ITEM.getViewType()) {
- return new WebpageItemRow(inflater.inflate(WebpageItemRow.LAYOUT_ID, parent, false), this);
- } else if (type == RowItemType.HIGHLIGHT_ITEM.getViewType()) {
- return new WebpageItemRow(inflater.inflate(WebpageItemRow.LAYOUT_ID, parent, false), this);
+ } else if (type == RowItemType.TOP_STORIES_ITEM.getViewType() ||
+ type == RowItemType.HIGHLIGHT_ITEM.getViewType()) {
+ return new WebpageItemRow(inflater.inflate(WebpageItemRow.LAYOUT_ID, parent, false), new WebpageItemRow.OnMenuButtonClickListener() {
+ @Override
+ public void onMenuButtonClicked(final WebpageItemRow row, final int position) {
+ openContextMenu(row, position, parent, ActivityStreamTelemetry.Contract.INTERACTION_MENU_BUTTON);
+ }
+ });
} else if (type == RowItemType.HIGHLIGHTS_TITLE.getViewType()) {
return new StreamTitleRow(inflater.inflate(StreamTitleRow.LAYOUT_ID, parent, false), R.string.activity_stream_highlights);
} else if (type == RowItemType.HIGHLIGHTS_EMPTY_STATE.getViewType()) {
return new HighlightsEmptyStateRow(inflater.inflate(HighlightsEmptyStateRow.LAYOUT_ID, parent, false));
} else if (type == RowItemType.LEARN_MORE_LINK.getViewType()) {
return new LearnMoreRow(inflater.inflate(LearnMoreRow.LAYOUT_ID, parent, false));
} else {
throw new IllegalStateException("Missing inflation for ViewType " + type);
@@ -281,17 +286,17 @@ public class StreamRecyclerAdapter exten
@Override
public boolean onItemLongClicked(final RecyclerView recyclerView, final int position, final View v) {
if (!onItemClickIsValidRowItem(position)) {
return false;
}
final WebpageItemRow highlightItem = (WebpageItemRow) recyclerView.getChildViewHolder(v);
- openContextMenu(highlightItem, position, ActivityStreamTelemetry.Contract.INTERACTION_LONG_CLICK);
+ openContextMenu(highlightItem, position, recyclerView, ActivityStreamTelemetry.Contract.INTERACTION_LONG_CLICK);
return true;
}
private boolean onItemClickIsValidRowItem(final int position) {
// The position this method receives is from RecyclerView.ViewHolder.getAdapterPosition, whose docs state:
// "Note that if you've called notifyDataSetChanged(), until the next layout pass, the return value of this
// method will be NO_POSITION."
//
@@ -311,18 +316,23 @@ public class StreamRecyclerAdapter exten
&& viewType != RowItemType.TOP_STORIES_ITEM.getViewType()) {
// Headers (containing topsites and/or the highlights title) do their own click handling as needed
return false;
}
return true;
}
+ /**
+ * @param snackbarAnchor See {@link ActivityStreamContextMenu#show(Context, View, ActivityStreamTelemetry.Extras.Builder, ActivityStreamContextMenu.MenuMode, WebpageModel, boolean, HomePager.OnUrlOpenListener, HomePager.OnUrlOpenInBackgroundListener, int, int)}
+ * for additional details.
+ */
@Override
- public void openContextMenu(final WebpageItemRow webpageItemRow, final int position, @NonNull final String interactionExtra) {
+ public void openContextMenu(final WebpageItemRow webpageItemRow, final int position, final View snackbarAnchor,
+ @NonNull final String interactionExtra) {
final WebpageRowModel model = (WebpageRowModel) recyclerViewModel.get(position);
final String sourceType;
final int actionPosition;
final ActivityStreamContextMenu.MenuMode menuMode;
ActivityStreamTelemetry.Extras.Builder extras = ActivityStreamTelemetry.Extras.builder();
if (model.getRowItemType() == RowItemType.HIGHLIGHT_ITEM) {
@@ -336,17 +346,17 @@ public class StreamRecyclerAdapter exten
menuMode = ActivityStreamContextMenu.MenuMode.TOPSTORY;
}
extras.set(ActivityStreamTelemetry.Contract.SOURCE_TYPE, sourceType)
.set(ActivityStreamTelemetry.Contract.ACTION_POSITION, actionPosition)
.set(ActivityStreamTelemetry.Contract.INTERACTION, interactionExtra);
ActivityStreamContextMenu.show(webpageItemRow.itemView.getContext(),
- webpageItemRow.getContextMenuAnchor(),
+ snackbarAnchor,
extras,
menuMode,
model,
/* shouldOverrideWithImageProvider */ true, // we use image providers in HighlightItem.pageIconLayout.
onUrlOpenListener, onUrlOpenInBackgroundListener,
webpageItemRow.getTileWidth(), webpageItemRow.getTileHeight());
Telemetry.sendUIEvent(
--- a/mobile/android/base/java/org/mozilla/gecko/activitystream/homepanel/menu/ActivityStreamContextMenu.java
+++ b/mobile/android/base/java/org/mozilla/gecko/activitystream/homepanel/menu/ActivityStreamContextMenu.java
@@ -336,16 +336,18 @@ public abstract class ActivityStreamCont
telemetryExtraBuilder.build()
);
dismiss();
return true;
}
/**
+ * @param anchor A view to anchor the Snackbar on. Don't use items in the recyclerView because these views can be
+ * removed from the view hierarchy when the recyclerView scrolls.
* @param shouldOverrideIconWithImageProvider true if the favicon should be replaced with an image provider,
* if applicable, false otherwise.
*/
@RobocopTarget
public static ActivityStreamContextMenu show(Context context,
View anchor, ActivityStreamTelemetry.Extras.Builder telemetryExtraBuilder,
final MenuMode menuMode, final WebpageModel item,
final boolean shouldOverrideIconWithImageProvider,
--- a/mobile/android/base/java/org/mozilla/gecko/activitystream/homepanel/stream/WebpageItemRow.java
+++ b/mobile/android/base/java/org/mozilla/gecko/activitystream/homepanel/stream/WebpageItemRow.java
@@ -9,19 +9,17 @@ import android.content.Context;
import android.graphics.Color;
import android.support.annotation.UiThread;
import android.text.TextUtils;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import org.mozilla.gecko.R;
-import org.mozilla.gecko.activitystream.ActivityStreamTelemetry;
import org.mozilla.gecko.activitystream.Utils;
-import org.mozilla.gecko.activitystream.homepanel.StreamHighlightItemRowContextMenuListener;
import org.mozilla.gecko.activitystream.homepanel.model.WebpageRowModel;
import org.mozilla.gecko.util.DrawableUtil;
import org.mozilla.gecko.util.StringUtils;
import org.mozilla.gecko.util.TouchTargetUtil;
import org.mozilla.gecko.util.URIUtils;
import org.mozilla.gecko.util.ViewUtil;
import java.lang.ref.WeakReference;
@@ -38,37 +36,37 @@ public class WebpageItemRow extends Stre
private WebpageRowModel webpageModel;
private int position;
private final StreamOverridablePageIconLayout pageIconLayout;
private final TextView pageDomainView;
private final TextView pageTitleView;
private final ImageView pageSourceIconView;
private final TextView pageSourceView;
- private final ImageView menuButton;
- public WebpageItemRow(final View itemView, final StreamHighlightItemRowContextMenuListener contextMenuListener) {
+ public WebpageItemRow(final View itemView, final OnMenuButtonClickListener onMenuButtonClickListener) {
super(itemView);
pageTitleView = (TextView) itemView.findViewById(R.id.page_title);
pageIconLayout = (StreamOverridablePageIconLayout) itemView.findViewById(R.id.page_icon);
pageSourceView = (TextView) itemView.findViewById(R.id.page_source);
pageDomainView = (TextView) itemView.findViewById(R.id.page_domain);
pageSourceIconView = (ImageView) itemView.findViewById(R.id.page_source_icon);
- menuButton = (ImageView) itemView.findViewById(R.id.menu);
+ final ImageView menuButton = (ImageView) itemView.findViewById(R.id.menu);
menuButton.setImageDrawable(
DrawableUtil.tintDrawable(menuButton.getContext(), R.drawable.menu, Color.LTGRAY));
TouchTargetUtil.ensureTargetHitArea(menuButton, itemView);
ViewUtil.enableTouchRipple(menuButton);
menuButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
- contextMenuListener.openContextMenu(WebpageItemRow.this, position,
- ActivityStreamTelemetry.Contract.INTERACTION_MENU_BUTTON);
+ if (onMenuButtonClickListener != null) {
+ onMenuButtonClickListener.onMenuButtonClicked(WebpageItemRow.this, position);
+ }
}
});
}
public void bind(WebpageRowModel model, int position, int tilesWidth) {
this.webpageModel = model;
this.position = position;
@@ -120,20 +118,16 @@ public class WebpageItemRow extends Stre
return;
}
final UpdatePageDomainAsyncTask updatePageDomainTask = new UpdatePageDomainAsyncTask(itemView.getContext(),
highlightURI, pageDomainView);
updatePageDomainTask.execute();
}
- public View getContextMenuAnchor() {
- return menuButton;
- }
-
public int getTileWidth() {
return pageIconLayout.getWidth();
}
public int getTileHeight() {
return pageIconLayout.getHeight();
}
@@ -171,9 +165,13 @@ public class WebpageItemRow extends Stre
* Returns true if the tag on the given view matches the tag from the constructor. We do this to ensure
* the View we're making this request for hasn't been re-used by the time this request completes.
*/
@UiThread
private boolean isTagSameAsStartTag(final View viewToCheck) {
return viewTagAtStart.equals(viewToCheck.getTag(VIEW_TAG_ID));
}
}
+
+ public interface OnMenuButtonClickListener {
+ void onMenuButtonClicked(WebpageItemRow row, int position);
+ }
}