Skip to content

Commit c71d816

Browse files
committed
feat: allow closing photos and videos with a swipe gesture (#5609)
Signed-off-by: Enrique López Mañas <eenriquelopez@gmail.com>
1 parent 946c018 commit c71d816

File tree

5 files changed

+106
-5
lines changed

5 files changed

+106
-5
lines changed

app/src/main/java/com/nextcloud/talk/fullscreenfile/FullScreenImageActivity.kt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ package com.nextcloud.talk.fullscreenfile
1212
import android.content.Intent
1313
import android.os.Bundle
1414
import android.util.Log
15+
import com.nextcloud.talk.ui.SwipeToCloseLayout
1516
import android.view.Menu
1617
import android.view.MenuItem
1718
import android.view.View
@@ -133,6 +134,12 @@ class FullScreenImageActivity : AppCompatActivity() {
133134
binding.photoView.visibility = View.VISIBLE
134135
displayImage(path)
135136
}
137+
138+
binding.swipeToCloseLayout.setOnSwipeToCloseListener(object : SwipeToCloseLayout.OnSwipeToCloseListener {
139+
override fun onSwipeToClose() {
140+
finish()
141+
}
142+
})
136143
}
137144

138145
private fun displayImage(path: String) {

app/src/main/java/com/nextcloud/talk/fullscreenfile/FullScreenMediaActivity.kt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ import com.nextcloud.talk.BuildConfig
3939
import com.nextcloud.talk.R
4040
import com.nextcloud.talk.application.NextcloudTalkApplication
4141
import com.nextcloud.talk.databinding.ActivityFullScreenMediaBinding
42+
import com.nextcloud.talk.ui.SwipeToCloseLayout
4243
import com.nextcloud.talk.ui.dialog.SaveToStorageDialogFragment
4344
import com.nextcloud.talk.utils.Mimetype.VIDEO_PREFIX_GENERIC
4445
import java.io.File
@@ -135,6 +136,12 @@ class FullScreenMediaActivity : AppCompatActivity() {
135136
}
136137
}
137138
)
139+
140+
binding.swipeToCloseLayout.setOnSwipeToCloseListener(object : SwipeToCloseLayout.OnSwipeToCloseListener {
141+
override fun onSwipeToClose() {
142+
finish()
143+
}
144+
})
138145
}
139146

140147
override fun onStart() {
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
package com.nextcloud.talk.ui
2+
3+
import android.content.Context
4+
import android.util.AttributeSet
5+
import android.view.MotionEvent
6+
import android.view.View
7+
import android.widget.FrameLayout
8+
import androidx.customview.widget.ViewDragHelper
9+
import kotlin.math.abs
10+
11+
class SwipeToCloseLayout @JvmOverloads constructor(
12+
context: Context,
13+
attrs: AttributeSet? = null,
14+
defStyleAttr: Int = 0
15+
) : FrameLayout(context, attrs, defStyleAttr) {
16+
17+
private var dragHelper: ViewDragHelper
18+
private var swipeListener: OnSwipeToCloseListener? = null
19+
20+
interface OnSwipeToCloseListener {
21+
fun onSwipeToClose()
22+
}
23+
24+
init {
25+
dragHelper = ViewDragHelper.create(this, 1.0f, DragCallback())
26+
}
27+
28+
fun setOnSwipeToCloseListener(listener: OnSwipeToCloseListener) {
29+
this.swipeListener = listener
30+
}
31+
32+
override fun onInterceptTouchEvent(ev: MotionEvent): Boolean {
33+
val action = ev.actionMasked
34+
if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) {
35+
dragHelper.cancel()
36+
return false
37+
}
38+
return dragHelper.shouldInterceptTouchEvent(ev)
39+
}
40+
41+
override fun onTouchEvent(ev: MotionEvent): Boolean {
42+
dragHelper.processTouchEvent(ev)
43+
return true
44+
}
45+
46+
private inner class DragCallback : ViewDragHelper.Callback() {
47+
override fun tryCaptureView(child: View, pointerId: Int): Boolean {
48+
return true // Capture any child view
49+
}
50+
51+
override fun getViewVerticalDragRange(child: View): Int {
52+
return height
53+
}
54+
55+
override fun clampViewPositionVertical(child: View, therapeutic: Int, dy: Int): Int {
56+
return therapeutic
57+
}
58+
59+
override fun onViewReleased(releasedChild: View, xvel: Float, yvel: Float) {
60+
val totalDragDistance = abs(releasedChild.top)
61+
if (totalDragDistance > height * DRAG_THRESHOLD || abs(yvel) > dragHelper.minVelocity) {
62+
swipeListener?.onSwipeToClose()
63+
} else {
64+
dragHelper.settleCapturedViewAt(0, 0)
65+
invalidate()
66+
}
67+
}
68+
69+
override fun onViewPositionChanged(changedView: View, left: Int, top: Int, dx: Int, dy: Int) {
70+
val progress = 1f - (abs(top).toFloat() / height)
71+
alpha = progress.coerceIn(MIN_ALPHA, MAX_ALPHA)
72+
}
73+
}
74+
75+
override fun computeScroll() {
76+
if (dragHelper.continueSettling(true)) {
77+
postInvalidateOnAnimation()
78+
}
79+
}
80+
81+
companion object {
82+
private const val DRAG_THRESHOLD = 0.3f
83+
private const val MIN_ALPHA = 0.5f
84+
private const val MAX_ALPHA = 1.0f
85+
}
86+
}

app/src/main/res/layout/activity_full_screen_image.xml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@
77
~ SPDX-FileCopyrightText: 2021 Dariusz Olszewski <starypatyk@gmail.com>
88
~ SPDX-License-Identifier: GPL-3.0-or-later
99
-->
10-
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
10+
<com.nextcloud.talk.ui.SwipeToCloseLayout xmlns:android="http://schemas.android.com/apk/res/android"
1111
xmlns:tools="http://schemas.android.com/tools"
1212
xmlns:app="http://schemas.android.com/apk/res-auto"
13-
android:id="@+id/image_wrapper_view"
13+
android:id="@+id/swipe_to_close_layout"
1414
android:layout_width="match_parent"
1515
android:layout_height="match_parent"
1616
tools:context=".fullscreenfile.FullScreenImageActivity">
@@ -35,4 +35,4 @@
3535
android:layout_height="match_parent"
3636
android:visibility="invisible" />
3737

38-
</FrameLayout>
38+
</com.nextcloud.talk.ui.SwipeToCloseLayout>

app/src/main/res/layout/activity_full_screen_media.xml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,10 @@
66
~ SPDX-FileCopyrightText: 2021 Marcel Hibbe <dev@mhibbe.de>
77
~ SPDX-License-Identifier: GPL-3.0-or-later
88
-->
9-
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
9+
<com.nextcloud.talk.ui.SwipeToCloseLayout xmlns:android="http://schemas.android.com/apk/res/android"
1010
xmlns:app="http://schemas.android.com/apk/res-auto"
1111
xmlns:tools="http://schemas.android.com/tools"
12+
android:id="@+id/swipe_to_close_layout"
1213
android:layout_width="match_parent"
1314
android:layout_height="match_parent"
1415
tools:context=".fullscreenfile.FullScreenMediaActivity">
@@ -28,4 +29,4 @@
2829
app:show_buffering="when_playing"
2930
app:show_shuffle_button="true" />
3031

31-
</FrameLayout>
32+
</com.nextcloud.talk.ui.SwipeToCloseLayout>

0 commit comments

Comments
 (0)