1 /* 2 * Copyright (C) 2024 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.systemui.screenshot.ui 18 19 import android.view.MotionEvent 20 import android.view.VelocityTracker 21 import android.view.View 22 import com.android.systemui.screenshot.FloatingWindowUtil 23 import kotlin.math.abs 24 25 class SwipeGestureListener( 26 private val view: View, 27 private val onDismiss: (Float?) -> Unit, 28 private val onCancel: () -> Unit 29 ) { 30 private val velocityTracker = VelocityTracker.obtain() 31 private val displayMetrics = view.resources.displayMetrics 32 33 private var startX = 0f 34 onMotionEventnull35 fun onMotionEvent(ev: MotionEvent): Boolean { 36 ev.offsetLocation(view.translationX, 0f) 37 when (ev.actionMasked) { 38 MotionEvent.ACTION_DOWN -> { 39 velocityTracker.addMovement(ev) 40 startX = ev.rawX 41 } 42 MotionEvent.ACTION_UP -> { 43 velocityTracker.computeCurrentVelocity(1) 44 val xVelocity = velocityTracker.xVelocity 45 if ( 46 abs(xVelocity) > FloatingWindowUtil.dpToPx(displayMetrics, FLING_THRESHOLD_DP) 47 ) { 48 onDismiss.invoke(xVelocity) 49 return true 50 } else if ( 51 abs(view.translationX) > 52 FloatingWindowUtil.dpToPx(displayMetrics, DISMISS_THRESHOLD_DP) 53 ) { 54 onDismiss.invoke(xVelocity) 55 return true 56 } else { 57 velocityTracker.clear() 58 onCancel.invoke() 59 } 60 } 61 MotionEvent.ACTION_MOVE -> { 62 velocityTracker.addMovement(ev) 63 view.translationX = ev.rawX - startX 64 } 65 } 66 return false 67 } 68 69 companion object { 70 private const val DISMISS_THRESHOLD_DP = 80f 71 private const val FLING_THRESHOLD_DP = .8f // dp per ms 72 } 73 } 74