Bug 1116415 - 3. Add an ItemTouchHelper to the tabs panel list for swipe to close. r?sebastian
MozReview-Commit-ID: 8QlbSg7qsZK
--- a/mobile/android/base/java/org/mozilla/gecko/tabs/TabsLayout.java
+++ b/mobile/android/base/java/org/mozilla/gecko/tabs/TabsLayout.java
@@ -18,17 +18,18 @@ import android.util.AttributeSet;
import android.view.View;
import android.widget.Button;
import java.util.ArrayList;
public abstract class TabsLayout extends RecyclerView
implements TabsPanel.TabsLayout,
Tabs.OnTabsChangedListener,
- RecyclerViewClickSupport.OnItemClickListener {
+ RecyclerViewClickSupport.OnItemClickListener,
+ TabsTouchHelperCallback.DismissListener {
private static final String LOGTAG = "Gecko" + TabsLayout.class.getSimpleName();
private final boolean isPrivate;
private TabsPanel tabsPanel;
private final TabsLayoutRecyclerAdapter tabsAdapter;
public TabsLayout(Context context, AttributeSet attrs, int itemViewLayoutResId) {
@@ -169,16 +170,21 @@ public abstract class TabsLayout extends
// In the normal panel we want to close all tabs (both private and normal),
// but in the private panel we only want to close private tabs.
if (!isPrivate || tab.isPrivate()) {
Tabs.getInstance().closeTab(tab, false);
}
}
}
+ @Override
+ public void onItemDismiss(View view) {
+ closeTab(view);
+ }
+
private Tab getTabForView(View view) {
if (view == null) {
return null;
}
return Tabs.getInstance().getTab(((TabsLayoutItemView) view).getTabId());
}
@Override
--- a/mobile/android/base/java/org/mozilla/gecko/tabs/TabsListLayout.java
+++ b/mobile/android/base/java/org/mozilla/gecko/tabs/TabsListLayout.java
@@ -6,16 +6,17 @@
package org.mozilla.gecko.tabs;
import org.mozilla.gecko.R;
import org.mozilla.gecko.animation.PropertyAnimator;
import org.mozilla.gecko.util.ThreadUtils;
import android.content.Context;
import android.support.v7.widget.LinearLayoutManager;
+import android.support.v7.widget.helper.ItemTouchHelper;
import android.util.AttributeSet;
import android.view.View;
public class TabsListLayout extends TabsLayout {
// Time to animate non-flinged tabs of screen, in milliseconds
private static final int ANIMATION_DURATION = 250;
// Time between starting successive tab animations in closeAllTabs.
@@ -24,16 +25,21 @@ public class TabsListLayout extends Tabs
private int closeAllAnimationCount;
public TabsListLayout(Context context, AttributeSet attrs) {
super(context, attrs, R.layout.tabs_list_item_view);
setHasFixedSize(true);
setLayoutManager(new LinearLayoutManager(context));
+
+ // A TouchHelper handler for swipe to close.
+ final TabsTouchHelperCallback callback = new TabsTouchHelperCallback(this);
+ final ItemTouchHelper touchHelper = new ItemTouchHelper(callback);
+ touchHelper.attachToRecyclerView(this);
}
@Override
public void closeAll() {
final int childCount = getChildCount();
// Just close the panel if there are no tabs to close.
if (childCount == 0) {
new file mode 100644
--- /dev/null
+++ b/mobile/android/base/java/org/mozilla/gecko/tabs/TabsTouchHelperCallback.java
@@ -0,0 +1,69 @@
+/* -*- 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.tabs;
+
+import android.graphics.Canvas;
+import android.support.v7.widget.RecyclerView;
+import android.support.v7.widget.helper.ItemTouchHelper;
+import android.view.View;
+
+class TabsTouchHelperCallback extends ItemTouchHelper.Callback {
+ private final DismissListener dismissListener;
+
+ interface DismissListener {
+ void onItemDismiss(View view);
+ }
+
+ public TabsTouchHelperCallback(DismissListener dismissListener) {
+ this.dismissListener = dismissListener;
+ }
+
+ @Override
+ public boolean isItemViewSwipeEnabled() {
+ return true;
+ }
+
+ @Override
+ public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
+ return makeFlag(ItemTouchHelper.ACTION_STATE_SWIPE, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT);
+ }
+
+ @Override
+ public void onSwiped(RecyclerView.ViewHolder viewHolder, int i) {
+ dismissListener.onItemDismiss(viewHolder.itemView);
+ }
+
+ @Override
+ public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder,
+ RecyclerView.ViewHolder target) {
+ return false;
+ }
+
+ // Alpha on an itemView being swiped should decrease to a min over a distance equal to the
+ // width of the item being swiped.
+ @Override
+ public void onChildDraw(Canvas c,
+ RecyclerView recyclerView,
+ RecyclerView.ViewHolder viewHolder,
+ float dX,
+ float dY,
+ int actionState,
+ boolean isCurrentlyActive) {
+ if (actionState != ItemTouchHelper.ACTION_STATE_SWIPE) {
+ return;
+ }
+
+ super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
+
+ viewHolder.itemView.setAlpha(Math.max(0.1f,
+ Math.min(1f, 1f - 2f * Math.abs(dX) / viewHolder.itemView.getWidth())));
+ }
+
+ public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
+ super.clearView(recyclerView, viewHolder);
+ viewHolder.itemView.setAlpha(1);
+ }
+}
--- a/mobile/android/base/moz.build
+++ b/mobile/android/base/moz.build
@@ -669,16 +669,17 @@ gbjar.sources += ['java/org/mozilla/geck
'tabs/TabsGridLayout.java',
'tabs/TabsLayout.java',
'tabs/TabsLayoutAdapter.java',
'tabs/TabsLayoutItemView.java',
'tabs/TabsLayoutRecyclerAdapter.java',
'tabs/TabsListLayout.java',
'tabs/TabsPanel.java',
'tabs/TabsPanelThumbnailView.java',
+ 'tabs/TabsTouchHelperCallback.java',
'Telemetry.java',
'telemetry/measurements/CampaignIdMeasurements.java',
'telemetry/measurements/SearchCountMeasurements.java',
'telemetry/measurements/SessionMeasurements.java',
'telemetry/pingbuilders/TelemetryCorePingBuilder.java',
'telemetry/pingbuilders/TelemetryPingBuilder.java',
'telemetry/schedulers/TelemetryUploadAllPingsImmediatelyScheduler.java',
'telemetry/schedulers/TelemetryUploadScheduler.java',