Merge "Import updates from Accompanist"

This commit is contained in:
Chaohui Wang
2022-12-05 11:40:07 +00:00
committed by Android (Google) Code Review
4 changed files with 45 additions and 47 deletions

View File

@@ -20,6 +20,7 @@ import android.graphics.drawable.Animatable
import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.ColorDrawable
import android.graphics.drawable.Drawable
import android.os.Build
import android.os.Handler
import android.os.Looper
import android.view.View
@@ -117,13 +118,17 @@ class DrawablePainter(
return true
}
override fun applyLayoutDirection(layoutDirection: LayoutDirection): Boolean =
drawable.setLayoutDirection(
when (layoutDirection) {
LayoutDirection.Ltr -> View.LAYOUT_DIRECTION_LTR
LayoutDirection.Rtl -> View.LAYOUT_DIRECTION_RTL
}
)
override fun applyLayoutDirection(layoutDirection: LayoutDirection): Boolean {
if (Build.VERSION.SDK_INT >= 23) {
return drawable.setLayoutDirection(
when (layoutDirection) {
LayoutDirection.Ltr -> View.LAYOUT_DIRECTION_LTR
LayoutDirection.Rtl -> View.LAYOUT_DIRECTION_RTL
}
)
}
return false
}
override val intrinsicSize: Size get() = drawableIntrinsicSize

View File

@@ -19,8 +19,6 @@ package com.android.settingslib.spa.framework.compose
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.calculateEndPadding
import androidx.compose.foundation.layout.calculateStartPadding
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyRow
@@ -36,7 +34,6 @@ import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
import androidx.compose.ui.input.nestedscroll.NestedScrollSource
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.Velocity
import androidx.compose.ui.unit.dp
@@ -123,7 +120,7 @@ fun VerticalPager(
contentPadding: PaddingValues = PaddingValues(0.dp),
horizontalAlignment: Alignment.Horizontal = Alignment.CenterHorizontally,
key: ((page: Int) -> Any)? = null,
content: @Composable() (PagerScope.(page: Int) -> Unit),
content: @Composable PagerScope.(page: Int) -> Unit,
) {
Pager(
count = count,
@@ -175,24 +172,8 @@ internal fun Pager(
.collect { state.updateCurrentPageBasedOnLazyListState() }
}
val density = LocalDensity.current
val layoutDirection = LocalLayoutDirection.current
LaunchedEffect(density, contentPadding, isVertical, layoutDirection, reverseLayout, state) {
with(density) {
// this should be exposed on LazyListLayoutInfo instead. b/200920410
state.afterContentPadding = if (isVertical) {
if (!reverseLayout) {
contentPadding.calculateBottomPadding()
} else {
contentPadding.calculateTopPadding()
}
} else {
if (!reverseLayout) {
contentPadding.calculateEndPadding(layoutDirection)
} else {
contentPadding.calculateStartPadding(layoutDirection)
}
}.roundToPx()
}
LaunchedEffect(density, state, itemSpacing) {
with(density) { state.itemSpacing = itemSpacing.roundToPx() }
}
val pagerScope = remember(state) { PagerScopeImpl(state) }
@@ -203,6 +184,7 @@ internal fun Pager(
ConsumeFlingNestedScrollConnection(
consumeHorizontal = !isVertical,
consumeVertical = isVertical,
pagerState = state,
)
}
@@ -268,6 +250,7 @@ internal fun Pager(
private class ConsumeFlingNestedScrollConnection(
private val consumeHorizontal: Boolean,
private val consumeVertical: Boolean,
private val pagerState: PagerState,
) : NestedScrollConnection {
override fun onPostScroll(
consumed: Offset,
@@ -281,9 +264,15 @@ private class ConsumeFlingNestedScrollConnection(
}
override suspend fun onPostFling(consumed: Velocity, available: Velocity): Velocity {
// We can consume all post fling velocity on the main-axis
// so that it doesn't propagate up to the Pager
return available.consume(consumeHorizontal, consumeVertical)
return if (pagerState.currentPageOffset != 0f) {
// The Pager is already scrolling. This means that a nested scroll child was
// scrolled to end, and the Pager can use this fling
Velocity.Zero
} else {
// A nested scroll child is still scrolling. We can consume all post fling
// velocity on the main-axis so that it doesn't propagate up to the Pager
available.consume(consumeHorizontal, consumeVertical)
}
}
}

View File

@@ -85,12 +85,14 @@ class PagerState(
return layoutInfo.visibleItemsInfo.maxByOrNull {
val start = maxOf(it.offset, 0)
val end = minOf(
it.offset + it.size, layoutInfo.viewportEndOffset - afterContentPadding)
it.offset + it.size,
layoutInfo.viewportEndOffset - layoutInfo.afterContentPadding
)
end - start
}
}
internal var afterContentPadding = 0
internal var itemSpacing by mutableStateOf(0)
private val currentPageLayoutInfo: LazyListItemInfo?
get() = lazyListState.layoutInfo.visibleItemsInfo.lastOrNull {
@@ -135,9 +137,7 @@ class PagerState(
*/
val currentPageOffset: Float by derivedStateOf {
currentPageLayoutInfo?.let {
// We coerce since itemSpacing can make the offset > 1f.
// We don't want to count spacing in the offset so cap it to 1f
(-it.offset / it.size.toFloat()).coerceIn(-1f, 1f)
(-it.offset / (it.size + itemSpacing).toFloat()).coerceIn(-0.5f, 0.5f)
} ?: 0f
}
@@ -187,28 +187,26 @@ class PagerState(
// offset from the size
lazyListState.animateScrollToItem(
index = page,
scrollOffset = (target.size * pageOffset).roundToInt()
scrollOffset = ((target.size + itemSpacing) * pageOffset).roundToInt()
)
} else if (layoutInfo.visibleItemsInfo.isNotEmpty()) {
// If we don't, we use the current page size as a guide
val currentSize = layoutInfo.visibleItemsInfo.first().size
val currentSize = layoutInfo.visibleItemsInfo.first().size + itemSpacing
lazyListState.animateScrollToItem(
index = page,
scrollOffset = (currentSize * pageOffset).roundToInt()
)
// The target should be visible now
target = lazyListState.layoutInfo.visibleItemsInfo.firstOrNull {
it.index == page
}
target = layoutInfo.visibleItemsInfo.firstOrNull { it.index == page }
if (target != null && target.size != currentSize) {
if (target != null && target.size + itemSpacing != currentSize) {
// If the size we used for calculating the offset differs from the actual
// target page size, we need to scroll again. This doesn't look great,
// but there's not much else we can do.
lazyListState.animateScrollToItem(
index = page,
scrollOffset = (target.size * pageOffset).roundToInt()
scrollOffset = ((target.size + itemSpacing) * pageOffset).roundToInt()
)
}
}
@@ -248,7 +246,7 @@ class PagerState(
if (pageOffset.absoluteValue > 0.0001f) {
currentPageLayoutInfo?.let {
scroll {
scrollBy(it.size * pageOffset)
scrollBy((it.size + itemSpacing) * pageOffset)
}
}
}
@@ -295,7 +293,7 @@ class PagerState(
}
private fun requireCurrentPageOffset(value: Float, name: String) {
require(value in -1f..1f) { "$name must be >= 0 and <= 1" }
require(value in -1f..1f) { "$name must be >= -1 and <= 1" }
}
companion object {

View File

@@ -76,7 +76,13 @@ task coverageReport(type: JacocoReport, dependsOn: "connectedDebugAndroidTest")
sourceDirectories.from = files("../spa/src")
classDirectories.from = fileTree(
dir: "../spa/build/tmp/kotlin-classes/debug",
excludes: ["com/android/settingslib/spa/debug/**"],
excludes: [
"com/android/settingslib/spa/debug/**",
// Excludes files forked from Accompanist.
"com/android/settingslib/spa/framework/compose/DrawablePainter*",
"com/android/settingslib/spa/framework/compose/Pager*",
],
)
executionData.from = fileTree(dir: "$buildDir/outputs/code_coverage/debugAndroidTest/connected")
}