Bug 1315717 - Add ripple feedback to AS context menu buttons on Android >= 5 r=sebastian
authorAndrzej Hunt <ahunt@mozilla.com>
Tue, 08 Nov 2016 10:11:02 -0500
changeset 322005 86d2e155758ce5eb42f29f3cfae120a647189e95
parent 322004 f1c1918210f7e34b0ce3cf7f89f202f25c60c33d
child 322006 bc22ca7ff05bbe74b770f9c41ca7bcadfe188d98
push id34133
push userahunt@mozilla.com
push dateFri, 11 Nov 2016 01:25:40 +0000
treeherderautoland@86d2e155758c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssebastian
bugs1315717
milestone52.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1315717 - Add ripple feedback to AS context menu buttons on Android >= 5 r=sebastian The circular ripple is only available on API >= 21. We can fallback to a different solution for older devices, see following patch. MozReview-Commit-ID: C0aBqsKsuZ5
mobile/android/base/java/org/mozilla/gecko/home/activitystream/StreamItem.java
mobile/android/base/java/org/mozilla/gecko/home/activitystream/topsites/TopSitesCard.java
mobile/android/base/java/org/mozilla/gecko/util/ViewUtil.java
mobile/android/base/moz.build
--- a/mobile/android/base/java/org/mozilla/gecko/home/activitystream/StreamItem.java
+++ b/mobile/android/base/java/org/mozilla/gecko/home/activitystream/StreamItem.java
@@ -22,16 +22,17 @@ import org.mozilla.gecko.db.BrowserContr
 import org.mozilla.gecko.home.HomePager;
 import org.mozilla.gecko.home.activitystream.menu.ActivityStreamContextMenu;
 import org.mozilla.gecko.home.activitystream.topsites.CirclePageIndicator;
 import org.mozilla.gecko.home.activitystream.topsites.TopSitesPagerAdapter;
 import org.mozilla.gecko.icons.IconCallback;
 import org.mozilla.gecko.icons.IconResponse;
 import org.mozilla.gecko.icons.Icons;
 import org.mozilla.gecko.util.DrawableUtil;
+import org.mozilla.gecko.util.ViewUtil;
 import org.mozilla.gecko.util.TouchTargetUtil;
 import org.mozilla.gecko.widget.FaviconView;
 
 import java.util.concurrent.Future;
 
 import static org.mozilla.gecko.activitystream.ActivityStream.extractLabel;
 
 public abstract class StreamItem extends RecyclerView.ViewHolder {
@@ -119,16 +120,18 @@ public abstract class StreamItem extends
                 public void onClick(View v) {
                     ActivityStreamContextMenu.show(v.getContext(),
                             menuButton,
                             ActivityStreamContextMenu.MenuMode.HIGHLIGHT,
                             title, url, onUrlOpenListener, onUrlOpenInBackgroundListener,
                             vIconView.getWidth(), vIconView.getHeight());
                 }
             });
+
+            ViewUtil.enableTouchRipple(menuButton);
         }
 
         public void bind(Cursor cursor, int tilesWidth, int tilesHeight) {
 
             final long time = cursor.getLong(cursor.getColumnIndexOrThrow(BrowserContract.Highlights.DATE));
             final String ago = DateUtils.getRelativeTimeSpanString(time, System.currentTimeMillis(), DateUtils.MINUTE_IN_MILLIS, 0).toString();
 
             title = cursor.getString(cursor.getColumnIndexOrThrow(BrowserContract.History.TITLE));
--- a/mobile/android/base/java/org/mozilla/gecko/home/activitystream/topsites/TopSitesCard.java
+++ b/mobile/android/base/java/org/mozilla/gecko/home/activitystream/topsites/TopSitesCard.java
@@ -14,16 +14,17 @@ import android.widget.TextView;
 import org.mozilla.gecko.R;
 import org.mozilla.gecko.activitystream.ActivityStream;
 import org.mozilla.gecko.home.HomePager;
 import org.mozilla.gecko.home.activitystream.menu.ActivityStreamContextMenu;
 import org.mozilla.gecko.icons.IconCallback;
 import org.mozilla.gecko.icons.IconResponse;
 import org.mozilla.gecko.icons.Icons;
 import org.mozilla.gecko.util.DrawableUtil;
+import org.mozilla.gecko.util.ViewUtil;
 import org.mozilla.gecko.util.TouchTargetUtil;
 import org.mozilla.gecko.widget.FaviconView;
 
 import java.util.EnumSet;
 import java.util.concurrent.Future;
 
 class TopSitesCard extends RecyclerView.ViewHolder
         implements IconCallback, View.OnClickListener {
@@ -48,16 +49,18 @@ class TopSitesCard extends RecyclerView.
 
         this.onUrlOpenListener = onUrlOpenListener;
         this.onUrlOpenInBackgroundListener = onUrlOpenInBackgroundListener;
 
         card.setOnClickListener(this);
 
         TouchTargetUtil.ensureTargetHitArea(menuButton, card);
         menuButton.setOnClickListener(this);
+
+        ViewUtil.enableTouchRipple(menuButton);
     }
 
     void bind(final TopSitesPageAdapter.TopSite topSite) {
         ActivityStream.extractLabel(itemView.getContext(), topSite.url, true, new ActivityStream.LabelCallback() {
             @Override
             public void onLabelExtracted(String label) {
                 title.setText(label);
             }
new file mode 100644
--- /dev/null
+++ b/mobile/android/base/java/org/mozilla/gecko/util/ViewUtil.java
@@ -0,0 +1,33 @@
+/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
+ * 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.util;
+
+import android.content.res.TypedArray;
+import android.view.View;
+
+import org.mozilla.gecko.AppConstants;
+import org.mozilla.gecko.R;
+
+public class ViewUtil {
+
+    /**
+     * Enable a circular touch ripple for a given view. This is intended for borderless views,
+     * such as (3-dot) menu buttons.
+     *
+     * Because of platform limitations a square ripple is used on Android 4.
+     */
+    public static void enableTouchRipple(View view) {
+        final TypedArray backgroundDrawableArray;
+        if (AppConstants.Versions.feature21Plus) {
+            backgroundDrawableArray = view.getContext().obtainStyledAttributes(new int[] { R.attr.selectableItemBackgroundBorderless });
+        } else {
+            backgroundDrawableArray = view.getContext().obtainStyledAttributes(new int[] { R.attr.selectableItemBackground });
+        }
+
+        // This call is deprecated, but the replacement setBackground(Drawable) isn't available
+        // until API 16.
+        view.setBackgroundDrawable(backgroundDrawableArray.getDrawable(0));
+    }
+}
--- a/mobile/android/base/moz.build
+++ b/mobile/android/base/moz.build
@@ -737,16 +737,17 @@ gbjar.sources += ['java/org/mozilla/geck
     'trackingprotection/TrackingProtectionPrompt.java',
     'updater/PostUpdateHandler.java',
     'updater/UpdateService.java',
     'updater/UpdateServiceHelper.java',
     'util/ColorUtil.java',
     'util/DrawableUtil.java',
     'util/ResourceDrawableUtils.java',
     'util/TouchTargetUtil.java',
+    'util/ViewUtil.java',
     'widget/ActivityChooserModel.java',
     'widget/AllCapsTextView.java',
     'widget/AnchoredPopup.java',
     'widget/AnimatedHeightLayout.java',
     'widget/BasicColorPicker.java',
     'widget/CheckableLinearLayout.java',
     'widget/ClickableWhenDisabledEditText.java',
     'widget/ContentSecurityDoorHanger.java',