• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.dialer.speeddial.draghelper;
18 
19 import android.support.v7.widget.RecyclerView.ViewHolder;
20 import android.support.v7.widget.helper.ItemTouchHelper;
21 import android.view.HapticFeedbackConstants;
22 import android.view.MotionEvent;
23 import android.view.View;
24 import android.view.View.OnTouchListener;
25 import android.view.ViewConfiguration;
26 import com.android.dialer.common.Assert;
27 
28 /** OnTouchListener for the {@link com.android.dialer.speeddial.FavoritesViewHolder}. */
29 public class SpeedDialFavoritesViewHolderOnTouchListener implements OnTouchListener {
30 
31   private final ViewConfiguration configuration;
32   private final ItemTouchHelper itemTouchHelper;
33   private final ViewHolder viewHolder;
34   private final OnTouchFinishCallback onTouchFinishCallback;
35 
36   private boolean hasPerformedLongClick;
37   private float startX;
38   private float startY;
39 
SpeedDialFavoritesViewHolderOnTouchListener( ViewConfiguration configuration, ItemTouchHelper itemTouchHelper, ViewHolder viewHolder, OnTouchFinishCallback onTouchFinishCallback)40   public SpeedDialFavoritesViewHolderOnTouchListener(
41       ViewConfiguration configuration,
42       ItemTouchHelper itemTouchHelper,
43       ViewHolder viewHolder,
44       OnTouchFinishCallback onTouchFinishCallback) {
45     this.configuration = configuration;
46     this.itemTouchHelper = itemTouchHelper;
47     this.viewHolder = viewHolder;
48     this.onTouchFinishCallback = onTouchFinishCallback;
49   }
50 
51   @Override
onTouch(View v, MotionEvent event)52   public boolean onTouch(View v, MotionEvent event) {
53     switch (event.getAction()) {
54       case MotionEvent.ACTION_DOWN:
55         startX = event.getX();
56         startY = event.getY();
57         return true;
58       case MotionEvent.ACTION_MOVE:
59         // If the user has long clicked the view
60         if (event.getEventTime() - event.getDownTime() > ViewConfiguration.getLongPressTimeout()) {
61           // Perform long click if we haven't already
62           if (!hasPerformedLongClick) {
63             v.performLongClick();
64             v.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
65             hasPerformedLongClick = true;
66           } else if (moveEventExceedsTouchSlop(event)) {
67             itemTouchHelper.startDrag(viewHolder);
68             onTouchFinishCallback.onTouchFinished(true);
69           }
70         }
71         return true;
72       case MotionEvent.ACTION_UP:
73         if (event.getEventTime() - event.getDownTime() < ViewConfiguration.getLongPressTimeout()) {
74           v.performClick();
75         }
76         // fallthrough
77       case MotionEvent.ACTION_CANCEL:
78         hasPerformedLongClick = false;
79         onTouchFinishCallback.onTouchFinished(false);
80         return true;
81       default:
82         return false;
83     }
84   }
85 
moveEventExceedsTouchSlop(MotionEvent event)86   private boolean moveEventExceedsTouchSlop(MotionEvent event) {
87     Assert.checkArgument(event.getAction() == MotionEvent.ACTION_MOVE);
88     if (event.getHistorySize() <= 0) {
89       return false;
90     }
91 
92     return Math.abs(startX - event.getX()) > configuration.getScaledTouchSlop()
93         || Math.abs(startY - event.getY()) > configuration.getScaledTouchSlop();
94   }
95 
96   /** Callback to listen for on touch events ending. */
97   public interface OnTouchFinishCallback {
98 
99     /**
100      * Called when the user stops touching the view.
101      *
102      * @see MotionEvent#ACTION_UP
103      * @see MotionEvent#ACTION_CANCEL
104      */
onTouchFinished(boolean closeContextMenu)105     void onTouchFinished(boolean closeContextMenu);
106   }
107 }
108