commonMain.com.lt.compose_views.refresh_layout.RefreshLayoutNestedScrollConnection.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of ComposeViews-desktop Show documentation
Show all versions of ComposeViews-desktop Show documentation
Jatpack(JetBrains) Compose views
The newest version!
/*
* Copyright lt 2023
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.lt.compose_views.refresh_layout
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
import androidx.compose.ui.input.nestedscroll.NestedScrollSource
import androidx.compose.ui.unit.Velocity
import com.lt.compose_views.util.ComposePosition
/**
* creator: lt 2022/9/18 [email protected]
* effect : [RefreshLayout]的[NestedScrollConnection]
* [NestedScrollConnection] of the [RefreshLayout]
* warning:
*/
internal class RefreshLayoutNestedScrollConnection(
private val composePosition: ComposePosition,
private val refreshLayoutState: RefreshLayoutState,
private val dragEfficiency: Float,
private val orientationIsHorizontal: Boolean,
private val refreshingCanScroll: Boolean = false,
) : NestedScrollConnection {
//处理子组件用不完的手势,返回消费的手势
override fun onPostScroll(
consumed: Offset,
available: Offset,
source: NestedScrollSource
): Offset {
if (source == NestedScrollSource.UserInput) {
when (composePosition) {
ComposePosition.Start -> {
val value = available.x
if (value > 0) {
//过滤误差值(系统bug?)
if (value > 0.01f)
refreshLayoutState.offset(value * dragEfficiency)
return Offset(value, 0f)
}
}
ComposePosition.End -> {
val value = available.x
if (value < 0) {
if (value < -0.01f)
refreshLayoutState.offset(value * dragEfficiency)
return Offset(value, 0f)
}
}
ComposePosition.Top -> {
val value = available.y
if (value > 0) {
if (value > 0.01f)
refreshLayoutState.offset(value * dragEfficiency)
return Offset(0f, value)
}
}
ComposePosition.Bottom -> {
val value = available.y
if (value < 0) {
if (value < -0.01f)
refreshLayoutState.offset(value * dragEfficiency)
return Offset(0f, value)
}
}
}
}
return Offset.Zero
}
//预先处理手势,返回消费的手势
override fun onPreScroll(available: Offset, source: NestedScrollSource): Offset {
//如果是刷新中状态,并且刷新中不允许滚动,就拒绝对刷新区域和上下区域滚动
if (!refreshingCanScroll && refreshLayoutState.refreshContentState.value == RefreshContentStateEnum.Refreshing) {
return if (orientationIsHorizontal)
Offset(available.x, 0f)
else
Offset(0f, available.y)
}
val refreshOffset = refreshLayoutState.refreshContentOffsetState.value
if (source == NestedScrollSource.UserInput) {
when (composePosition) {
ComposePosition.Start -> {
if (available.x < 0 && refreshOffset > 0) {
//消费的手势
var consumptive = available.x
if (-available.x > refreshOffset) {
consumptive = available.x - refreshOffset
}
refreshLayoutState.offset(consumptive * dragEfficiency)
return Offset(consumptive, 0f)
}
}
ComposePosition.End -> {
if (available.x > 0 && refreshOffset < 0) {
//消费的手势
var consumptive = available.x
if (-available.x > refreshOffset) {
consumptive = available.x - refreshOffset
}
refreshLayoutState.offset(consumptive * dragEfficiency)
return Offset(consumptive, 0f)
}
}
ComposePosition.Top -> {
if (available.y < 0 && refreshOffset > 0) {
//消费的手势
var consumptive = available.y
if (-available.y > refreshOffset) {
consumptive = available.y - refreshOffset
}
refreshLayoutState.offset(consumptive * dragEfficiency)
return Offset(0f, consumptive)
}
}
ComposePosition.Bottom -> {
if (available.y > 0 && refreshOffset < 0) {
//消费的手势
var consumptive = available.y
if (-available.y < refreshOffset) {
consumptive = available.y - refreshOffset
}
refreshLayoutState.offset(consumptive * dragEfficiency)
return Offset(0f, consumptive)
}
}
}
}
return Offset.Zero
}
//手势惯性滑动前回调,返回消费的速度,可以当做action_up
override suspend fun onPreFling(available: Velocity): Velocity {
//如果是刷新中状态,并且刷新中不允许滚动,就拒绝对刷新区域和上下区域滚动
if (!refreshingCanScroll && refreshLayoutState.refreshContentState.value == RefreshContentStateEnum.Refreshing) {
return available
}
if (refreshLayoutState.refreshContentOffsetState.value != 0f) {
refreshLayoutState.offsetHoming()
return available
}
return Velocity.Zero
}
}
@Composable
internal fun rememberRefreshLayoutNestedScrollConnection(
composePosition: ComposePosition,
refreshLayoutState: RefreshLayoutState,
dragEfficiency: Float,
orientationIsHorizontal: Boolean,
refreshingCanScroll: Boolean = false,
) = remember(composePosition) {
RefreshLayoutNestedScrollConnection(
composePosition, refreshLayoutState, dragEfficiency, orientationIsHorizontal, refreshingCanScroll
)
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy