Android BottomSheetBehavior 只允许向上拖动
Android BottomSheetBehavior allow only drag up
我正在尝试构建一个 bottomSheetBehavior 以允许用户仅使用向下拖动手势关闭 bottomSheet。要打开它,他将单击一个按钮。
所以我弄清楚了他是如何通过这个 禁用拖动 up/down 的。
现在我只需要停用向上拖动手势?
这是我创建的行为:
class LockedBottomSheetBehavior<V : View>(context: Context, attrs: AttributeSet) :
BottomSheetBehavior<V>(context, attrs) {
companion object {
fun <V : View> from(view: V): LockedBottomSheetBehavior<*> {
val params = view.layoutParams as? CoordinatorLayout.LayoutParams
?: throw IllegalArgumentException("The view is not a child of CoordinatorLayout")
return params.behavior as? LockedBottomSheetBehavior<*>
?: throw IllegalArgumentException(
"The view is not associated with BottomSheetBehavior")
}
}
override fun onInterceptTouchEvent(
parent: CoordinatorLayout,
child: V, event: MotionEvent
) = false
override fun onTouchEvent(
parent: CoordinatorLayout,
child: V,
event: MotionEvent
) = false
override fun onStartNestedScroll(
coordinatorLayout: CoordinatorLayout,
child: V,
directTargetChild: View,
target: View,
axes: Int,
type: Int) = false
override fun onNestedPreScroll(
coordinatorLayout: CoordinatorLayout,
child: V,
target: View,
dx: Int,
dy: Int,
consumed: IntArray,
type: Int) {
}
override fun onStopNestedScroll(
coordinatorLayout: CoordinatorLayout,
child: V,
target: View,
type: Int) {
}
override fun onNestedPreFling(
coordinatorLayout: CoordinatorLayout,
child: V,
target: View,
velocityX: Float,
velocityY: Float
) = false
}
所以我在 Behavior 中添加了一个 if 语句,以防止手势状态折叠。
override fun onInterceptTouchEvent(
parent: CoordinatorLayout,
child: V, event: MotionEvent
): Boolean {
if (this.state == STATE_EXPANDED) {
super.onInterceptTouchEvent(parent, child, event)
return true
} else {
return false
}
}
override fun onTouchEvent(
parent: CoordinatorLayout,
child: V,
event: MotionEvent
): Boolean {
if (this.state == STATE_EXPANDED) {
super.onTouchEvent(parent, child, event)
return true
} else {
return false
}
}
override fun onStartNestedScroll(
coordinatorLayout: CoordinatorLayout,
child: V,
directTargetChild: View,
target: View,
axes: Int,
type: Int): Boolean {
if (this.state == STATE_DRAGGING) {
super.onStartNestedScroll(coordinatorLayout, child, directTargetChild, target, axes, type)
return true
} else {
return false
}
}
override fun onNestedPreScroll(
coordinatorLayout: CoordinatorLayout,
child: V,
target: View,
dx: Int,
dy: Int,
consumed: IntArray,
type: Int) {
if (this.state == STATE_DRAGGING) {
super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed, type)
}
}
override fun onStopNestedScroll(
coordinatorLayout: CoordinatorLayout,
child: V,
target: View,
type: Int) {
if (this.state == STATE_DRAGGING || this.state == STATE_EXPANDED) {
super.onStopNestedScroll(coordinatorLayout, child, target, type)
}
}
override fun onNestedPreFling(
coordinatorLayout: CoordinatorLayout,
child: V,
target: View,
velocityX: Float,
velocityY: Float
) = false
但它永远不会达到拖动手势。
按照
的回答
他添加了一个锁定的变量来知道我们是否应该激活拖动手势(在自定义行为中)。
class LockedBottomSheetBehavior<V : View>(context: Context, attrs: AttributeSet) :
BottomSheetBehavior<V>(context, attrs) {
private var mLocked = true
fun setLocked(locked: Boolean) {
mLocked = locked
}
override fun onInterceptTouchEvent(parent: CoordinatorLayout, child: V, event: MotionEvent): Boolean {
var handled = false
if (!mLocked) {
handled = super.onInterceptTouchEvent(parent, child, event)
}
return handled
}
override fun onTouchEvent(parent: CoordinatorLayout, child: V, event: MotionEvent): Boolean {
var handled = false
if (!mLocked) {
handled = super.onTouchEvent(parent, child, event)
}
return handled
}
override fun onStartNestedScroll(
coordinatorLayout: CoordinatorLayout,
child: V,
directTargetChild: View,
target: View,
axes: Int,
type: Int) : Boolean {
var handled = false
if (!mLocked) {
handled = super.onStartNestedScroll(coordinatorLayout, child, directTargetChild, target, axes, type)
}
return handled
}
override fun onNestedPreScroll(
coordinatorLayout: CoordinatorLayout,
child: V,
target: View,
dx: Int,
dy: Int,
consumed: IntArray,
type: Int) {
if (!mLocked) {
super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed, type)
}
}
override fun onStopNestedScroll(
coordinatorLayout: CoordinatorLayout,
child: V,
target: View,
type: Int) {
if (!mLocked) {
super.onStopNestedScroll(coordinatorLayout, child, target, type)
}
}
override fun onNestedPreFling(
coordinatorLayout: CoordinatorLayout,
child: V,
target: View,
velocityX: Float,
velocityY: Float
): Boolean {
var handled = false
if (!mLocked) {
handled = super.onNestedPreFling(coordinatorLayout, child, target, velocityX, velocityY)
}
return handled
}
}
然后如果bottomSheet的状态改变了,我们激活或者不激活行为手势。
所以在我的例子中,我只想在 bottomSheet 为 STATE_EXPANDED
时激活手势,并在 STATE_COLLAPSED
.
时停用它
所以这是我在 Kotlin 中的 bottomSheet 行为版本,允许用户仅将其向下拖动,并禁用向上拖动手势。
bottomSheetBehavior.setBottomSheetCallback(object: BottomSheetBehavior.BottomSheetCallback() {
override fun onSlide(bottomSheet: View, slideOffset: Float) {
Log.d("CAMERA ACTIVITY", "SLIDE, ${this@apply.state}")
}
override fun onStateChanged(bottomSheet: View, newState: Int) {
if (newState == BottomSheetBehavior.STATE_EXPANDED) {
Log.d("CAMERA ACTIVITY", "STATE CHANGED, ${this@apply.state}")
(bottomSheetBehavior as LockedBottomSheetBehavior).setLocked(false)
} else if (newState == BottomSheetBehavior.STATE_COLLAPSED){
(bottomSheetBehavior as LockedBottomSheetBehavior).setLocked(true)
}
}
})
我正在尝试构建一个 bottomSheetBehavior 以允许用户仅使用向下拖动手势关闭 bottomSheet。要打开它,他将单击一个按钮。
所以我弄清楚了他是如何通过这个
现在我只需要停用向上拖动手势?
这是我创建的行为:
class LockedBottomSheetBehavior<V : View>(context: Context, attrs: AttributeSet) :
BottomSheetBehavior<V>(context, attrs) {
companion object {
fun <V : View> from(view: V): LockedBottomSheetBehavior<*> {
val params = view.layoutParams as? CoordinatorLayout.LayoutParams
?: throw IllegalArgumentException("The view is not a child of CoordinatorLayout")
return params.behavior as? LockedBottomSheetBehavior<*>
?: throw IllegalArgumentException(
"The view is not associated with BottomSheetBehavior")
}
}
override fun onInterceptTouchEvent(
parent: CoordinatorLayout,
child: V, event: MotionEvent
) = false
override fun onTouchEvent(
parent: CoordinatorLayout,
child: V,
event: MotionEvent
) = false
override fun onStartNestedScroll(
coordinatorLayout: CoordinatorLayout,
child: V,
directTargetChild: View,
target: View,
axes: Int,
type: Int) = false
override fun onNestedPreScroll(
coordinatorLayout: CoordinatorLayout,
child: V,
target: View,
dx: Int,
dy: Int,
consumed: IntArray,
type: Int) {
}
override fun onStopNestedScroll(
coordinatorLayout: CoordinatorLayout,
child: V,
target: View,
type: Int) {
}
override fun onNestedPreFling(
coordinatorLayout: CoordinatorLayout,
child: V,
target: View,
velocityX: Float,
velocityY: Float
) = false
}
所以我在 Behavior 中添加了一个 if 语句,以防止手势状态折叠。
override fun onInterceptTouchEvent(
parent: CoordinatorLayout,
child: V, event: MotionEvent
): Boolean {
if (this.state == STATE_EXPANDED) {
super.onInterceptTouchEvent(parent, child, event)
return true
} else {
return false
}
}
override fun onTouchEvent(
parent: CoordinatorLayout,
child: V,
event: MotionEvent
): Boolean {
if (this.state == STATE_EXPANDED) {
super.onTouchEvent(parent, child, event)
return true
} else {
return false
}
}
override fun onStartNestedScroll(
coordinatorLayout: CoordinatorLayout,
child: V,
directTargetChild: View,
target: View,
axes: Int,
type: Int): Boolean {
if (this.state == STATE_DRAGGING) {
super.onStartNestedScroll(coordinatorLayout, child, directTargetChild, target, axes, type)
return true
} else {
return false
}
}
override fun onNestedPreScroll(
coordinatorLayout: CoordinatorLayout,
child: V,
target: View,
dx: Int,
dy: Int,
consumed: IntArray,
type: Int) {
if (this.state == STATE_DRAGGING) {
super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed, type)
}
}
override fun onStopNestedScroll(
coordinatorLayout: CoordinatorLayout,
child: V,
target: View,
type: Int) {
if (this.state == STATE_DRAGGING || this.state == STATE_EXPANDED) {
super.onStopNestedScroll(coordinatorLayout, child, target, type)
}
}
override fun onNestedPreFling(
coordinatorLayout: CoordinatorLayout,
child: V,
target: View,
velocityX: Float,
velocityY: Float
) = false
但它永远不会达到拖动手势。
按照
他添加了一个锁定的变量来知道我们是否应该激活拖动手势(在自定义行为中)。
class LockedBottomSheetBehavior<V : View>(context: Context, attrs: AttributeSet) :
BottomSheetBehavior<V>(context, attrs) {
private var mLocked = true
fun setLocked(locked: Boolean) {
mLocked = locked
}
override fun onInterceptTouchEvent(parent: CoordinatorLayout, child: V, event: MotionEvent): Boolean {
var handled = false
if (!mLocked) {
handled = super.onInterceptTouchEvent(parent, child, event)
}
return handled
}
override fun onTouchEvent(parent: CoordinatorLayout, child: V, event: MotionEvent): Boolean {
var handled = false
if (!mLocked) {
handled = super.onTouchEvent(parent, child, event)
}
return handled
}
override fun onStartNestedScroll(
coordinatorLayout: CoordinatorLayout,
child: V,
directTargetChild: View,
target: View,
axes: Int,
type: Int) : Boolean {
var handled = false
if (!mLocked) {
handled = super.onStartNestedScroll(coordinatorLayout, child, directTargetChild, target, axes, type)
}
return handled
}
override fun onNestedPreScroll(
coordinatorLayout: CoordinatorLayout,
child: V,
target: View,
dx: Int,
dy: Int,
consumed: IntArray,
type: Int) {
if (!mLocked) {
super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed, type)
}
}
override fun onStopNestedScroll(
coordinatorLayout: CoordinatorLayout,
child: V,
target: View,
type: Int) {
if (!mLocked) {
super.onStopNestedScroll(coordinatorLayout, child, target, type)
}
}
override fun onNestedPreFling(
coordinatorLayout: CoordinatorLayout,
child: V,
target: View,
velocityX: Float,
velocityY: Float
): Boolean {
var handled = false
if (!mLocked) {
handled = super.onNestedPreFling(coordinatorLayout, child, target, velocityX, velocityY)
}
return handled
}
}
然后如果bottomSheet的状态改变了,我们激活或者不激活行为手势。
所以在我的例子中,我只想在 bottomSheet 为 STATE_EXPANDED
时激活手势,并在 STATE_COLLAPSED
.
所以这是我在 Kotlin 中的 bottomSheet 行为版本,允许用户仅将其向下拖动,并禁用向上拖动手势。
bottomSheetBehavior.setBottomSheetCallback(object: BottomSheetBehavior.BottomSheetCallback() {
override fun onSlide(bottomSheet: View, slideOffset: Float) {
Log.d("CAMERA ACTIVITY", "SLIDE, ${this@apply.state}")
}
override fun onStateChanged(bottomSheet: View, newState: Int) {
if (newState == BottomSheetBehavior.STATE_EXPANDED) {
Log.d("CAMERA ACTIVITY", "STATE CHANGED, ${this@apply.state}")
(bottomSheetBehavior as LockedBottomSheetBehavior).setLocked(false)
} else if (newState == BottomSheetBehavior.STATE_COLLAPSED){
(bottomSheetBehavior as LockedBottomSheetBehavior).setLocked(true)
}
}
})