Skip to content
88 changes: 78 additions & 10 deletions JetNews/app/src/main/java/com/example/jetnews/ui/SwipeToRefresh.kt
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,23 @@ import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.offset
import androidx.compose.material.ExperimentalMaterialApi
import androidx.compose.material.FractionalThreshold
import androidx.compose.material.SwipeableState
import androidx.compose.material.rememberSwipeableState
import androidx.compose.material.swipeable
import androidx.compose.runtime.Composable
import androidx.compose.runtime.onCommit
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.gesture.nestedscroll.NestedScrollConnection
import androidx.compose.ui.gesture.nestedscroll.NestedScrollSource
import androidx.compose.ui.gesture.nestedscroll.nestedScroll
import androidx.compose.ui.gesture.scrollorientationlocking.Orientation
import androidx.compose.ui.platform.AmbientDensity
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.Velocity
import androidx.compose.ui.unit.dp
import kotlin.math.roundToInt

private val RefreshDistance = 80.dp

Expand All @@ -48,18 +56,24 @@ fun SwipeToRefreshLayout(
}

Box(
modifier = Modifier.swipeable(
state = state,
anchors = mapOf(
-refreshDistance to false,
refreshDistance to true
),
thresholds = { _, _ -> FractionalThreshold(0.5f) },
orientation = Orientation.Vertical
)
modifier = Modifier
.nestedScroll(state.PreUpPostDownNestedScrollConnection)
.swipeable(
state = state,
anchors = mapOf(
-refreshDistance to false,
refreshDistance to true
),
thresholds = { _, _ -> FractionalThreshold(0.5f) },
orientation = Orientation.Vertical
)
) {
content()
Box(Modifier.align(Alignment.TopCenter).offset(y = { state.offset.value })) {
Box(
Modifier
.align(Alignment.TopCenter)
.offset { IntOffset(0, state.offset.value.roundToInt()) }
) {
if (state.offset.value != -refreshDistance) {
refreshIndicator()
}
Expand All @@ -73,3 +87,57 @@ fun SwipeToRefreshLayout(
}
}
}

/**
* Temporary workaround for nested scrolling behavior. See b/174756744
*/
@ExperimentalMaterialApi
private val <T> SwipeableState<T>.PreUpPostDownNestedScrollConnection: NestedScrollConnection
get() = object : NestedScrollConnection {
override fun onPreScroll(available: Offset, source: NestedScrollSource): Offset {
val delta = available.toFloat()
return if (delta < 0 && source == NestedScrollSource.Drag) {
performDrag(delta).toOffset()
} else {
Offset.Zero
}
}

override fun onPostScroll(
consumed: Offset,
available: Offset,
source: NestedScrollSource
): Offset {
return if (source == NestedScrollSource.Drag) {
performDrag(available.toFloat()).toOffset()
} else {
Offset.Zero
}
}

override fun onPreFling(available: Velocity): Velocity {
val toFling = available.pixelsPerSecond.toFloat()
return if (toFling < 0) {
performFling(velocity = toFling) {}
// since we go to the anchor with tween settling, consume all for the best UX
available
} else {
Velocity.Zero
}
}

override fun onPostFling(
consumed: Velocity,
available: Velocity,
onFinished: (Velocity) -> Unit
) {
performFling(velocity = available.pixelsPerSecond.toFloat()) {
// since we go to the anchor with tween settling, consume all for the best UX
onFinished.invoke(available)
}
}

private fun Float.toOffset(): Offset = Offset(0f, this)

private fun Offset.toFloat(): Float = this.y
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
package com.example.jetnews.ui.theme

import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.material.Colors
import androidx.compose.material.MaterialTheme
import androidx.compose.material.darkColors
import androidx.compose.material.lightColors
Expand All @@ -43,10 +42,6 @@ private val DarkThemeColors = darkColors(
error = Red200
)

@Composable
val Colors.snackbarAction: Color
get() = if (isLight) Red300 else Red700

@Composable
fun JetnewsTheme(
darkTheme: Boolean = isSystemInDarkTheme(),
Expand Down
10 changes: 7 additions & 3 deletions JetNews/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@
*/

buildscript {
ext.kotlin_version = '1.4.20'
ext.compose_version = '1.0.0-alpha08'
ext.coroutines_version = '1.4.1'
ext.kotlin_version = '1.4.21'
ext.compose_version = '1.0.0-SNAPSHOT'
ext.coroutines_version = '1.4.2'

repositories {
google()
Expand All @@ -36,6 +36,10 @@ plugins {

subprojects {
repositories {
maven {
def snapshot = "7033025"
url "https://androidx.dev/snapshots/builds/$snapshot/artifacts/repository/"
}
google()
jcenter()
}
Expand Down