如何在顶层视图上接收拖动事件,但通过点击传递?
How to receive drag events on a top-layer View, but pass through clicks?
该应用有一些 UI 可以接收点击,例如一个用于接收焦点的 EditText,以及一个触发操作的按钮(不在下面的屏幕截图中)。但是整个 UI 部分还需要滑到一边才能显示下面的视图。我将其实现为包含 UI 并在拖动时移动(可见)的视图,以及一个不可见但收集拖动输入的顶层视图。
下面的代码部分起作用,因为当拖动不可见视图时可见视图会拖动,并且它可以感知拖动和点击之间的区别,但是尽管 returning false in View.OnTouchListener.onTouch(),不可见的可拖动View下面的View没有收到点击
如何让点击传递到下面的视图,而不影响正在运行的拖动功能?
import android.view.MotionEvent
import android.view.View
class ViewHorizontalSlider(dragView: View,
private val moveView: View,
private val distancePx: Int = 100) {
private var xPos = 0f
private var downX = 0f
private var isOnClick = false
private val scrollThreshold = 6
init {
dragView.setOnTouchListener { _, event ->
when (event.actionMasked) {
MotionEvent.ACTION_DOWN -> {
downX = event.x
xPos = moveView.x - event.rawX
isOnClick = true
return@setOnTouchListener true
}
MotionEvent.ACTION_MOVE -> {
var newX = event.rawX + xPos
if (newX > distancePx) newX = distancePx.toFloat()
if (newX < 0) newX = 0f
moveView.x = newX
val movement = Math.abs(downX - event.x)
if (isOnClick && (movement > scrollThreshold)) {
isOnClick = false;
}
return@setOnTouchListener true
}
MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
if (isOnClick) {
return@setOnTouchListener false
} else {
return@setOnTouchListener true
}
} else -> {
return@setOnTouchListener false
}
}
}
}
在屏幕截图中,"P1" 等是 EditText 视图。整个彩色面板应该可以向右拖动(如 P1,以显示删除 UI),但也应该可以单击(在不可见的叠加可拖动视图上)但将焦点放在下面的 EditText 上。我希望在上面的代码中只是 return false,但这似乎不足以让点击通过。
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="72dp"
>
<ImageView
android:id="@+id/delete"
android:layout_width="@dimen/perspective_delete_slide"
android:layout_height="match_parent"
android:src="@drawable/ic_delete"
android:scaleType="center"
android:background="@color/black_light"
android:contentDescription="@string/delete_perspective"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
/>
<android.support.constraint.ConstraintLayout
android:id="@+id/container"
android:layout_width="0dp"
android:layout_height="0dp"
android:focusableInTouchMode="true"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
tools:layout_marginStart="72dp"
>
<EditText
android:id="@+id/name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="@null"
android:inputType="text|textCapSentences"
android:layout_marginStart="12dp"
android:layout_marginEnd="12dp"
android:visibility="visible"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/marker"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
/>
<View
android:id="@+id/marker"
android:layout_width="8dp"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/name"
app:layout_constraintTop_toTopOf="parent"
/>
<View
android:id="@+id/draggable"
android:layout_width="0dp"
android:layout_height="0dp"
android:clickable="false"
android:focusable="false"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
/>
</android.support.constraint.ConstraintLayout>
</android.support.constraint.ConstraintLayout>
如果你想要滑动菜单那么你需要这个Swipe on menu or like that Swipe on Menu 2
该应用有一些 UI 可以接收点击,例如一个用于接收焦点的 EditText,以及一个触发操作的按钮(不在下面的屏幕截图中)。但是整个 UI 部分还需要滑到一边才能显示下面的视图。我将其实现为包含 UI 并在拖动时移动(可见)的视图,以及一个不可见但收集拖动输入的顶层视图。
下面的代码部分起作用,因为当拖动不可见视图时可见视图会拖动,并且它可以感知拖动和点击之间的区别,但是尽管 returning false in View.OnTouchListener.onTouch(),不可见的可拖动View下面的View没有收到点击
如何让点击传递到下面的视图,而不影响正在运行的拖动功能?
import android.view.MotionEvent
import android.view.View
class ViewHorizontalSlider(dragView: View,
private val moveView: View,
private val distancePx: Int = 100) {
private var xPos = 0f
private var downX = 0f
private var isOnClick = false
private val scrollThreshold = 6
init {
dragView.setOnTouchListener { _, event ->
when (event.actionMasked) {
MotionEvent.ACTION_DOWN -> {
downX = event.x
xPos = moveView.x - event.rawX
isOnClick = true
return@setOnTouchListener true
}
MotionEvent.ACTION_MOVE -> {
var newX = event.rawX + xPos
if (newX > distancePx) newX = distancePx.toFloat()
if (newX < 0) newX = 0f
moveView.x = newX
val movement = Math.abs(downX - event.x)
if (isOnClick && (movement > scrollThreshold)) {
isOnClick = false;
}
return@setOnTouchListener true
}
MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
if (isOnClick) {
return@setOnTouchListener false
} else {
return@setOnTouchListener true
}
} else -> {
return@setOnTouchListener false
}
}
}
}
在屏幕截图中,"P1" 等是 EditText 视图。整个彩色面板应该可以向右拖动(如 P1,以显示删除 UI),但也应该可以单击(在不可见的叠加可拖动视图上)但将焦点放在下面的 EditText 上。我希望在上面的代码中只是 return false,但这似乎不足以让点击通过。
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="72dp"
>
<ImageView
android:id="@+id/delete"
android:layout_width="@dimen/perspective_delete_slide"
android:layout_height="match_parent"
android:src="@drawable/ic_delete"
android:scaleType="center"
android:background="@color/black_light"
android:contentDescription="@string/delete_perspective"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
/>
<android.support.constraint.ConstraintLayout
android:id="@+id/container"
android:layout_width="0dp"
android:layout_height="0dp"
android:focusableInTouchMode="true"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
tools:layout_marginStart="72dp"
>
<EditText
android:id="@+id/name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="@null"
android:inputType="text|textCapSentences"
android:layout_marginStart="12dp"
android:layout_marginEnd="12dp"
android:visibility="visible"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/marker"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
/>
<View
android:id="@+id/marker"
android:layout_width="8dp"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/name"
app:layout_constraintTop_toTopOf="parent"
/>
<View
android:id="@+id/draggable"
android:layout_width="0dp"
android:layout_height="0dp"
android:clickable="false"
android:focusable="false"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
/>
</android.support.constraint.ConstraintLayout>
</android.support.constraint.ConstraintLayout>
如果你想要滑动菜单那么你需要这个Swipe on menu or like that Swipe on Menu 2