Bug 1315717 - Add ripple feedback to AS context menu buttons on Android >= 5 r?sebastian draft
authorAndrzej Hunt <ahunt@mozilla.com>
Tue, 08 Nov 2016 10:11:02 -0500
changeset 437521 87bb1b5bfddaac03d884b17e8d99878a881c4568
parent 437520 6a8cb91d7cee112d0f5267ed54cce1e85fda42d1
child 536657 c2e0c0697351b0ca94b3e605bd9e8faa20d45cef
push id35432
push userahunt@mozilla.com
push dateFri, 11 Nov 2016 01:23:08 +0000
reviewerssebastian
bugs1315717
milestone52.0a1
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',