Deprecate Scroller. Introduce ScrollableColumn / ScrollableRow
This CL reworks Scrolling-related API. Scrollers and ScrollerPosition have been deprecated. Instead, ScrollableColumn, ScrollableRow and ScrollState have been introduced. Additionaly, for more flexibility and performance, Modifier.verticalScroll and Modifier.horizontalScroll have been introduced, so users can add scrolling to everything while saving layout node.
While moving from ScrollerPosition to ScrollState, few API were renamed and simplified and @Composable ScrollerPosition was replaced with rememberScrollState.
Relnote: 'VerticalScroller and HoriziontalScroller have been deprecated. Use ScrollableColumn and ScrollableRow for build-in experience with Column/Row behaviour and parameters, or Modifier.verticalScroll and Modifier.horizontalScroll on your own element. Similarly, ScrollerPosition has been deprecated in favor of ScrollState'
Fixes: 158571223
Fixes: 157225838
Bug: 148542949
Bug: 150706555
Fixes: 150458415
Fixes: 149460415
Fixes: 154105299
Test: Tests were fixed for new APIs
Change-Id: I400ce0e6c0e33aa865e0e49defef1eb92ac40a93
diff --git a/ui/integration-tests/demos/src/main/java/androidx/ui/demos/DemoApp.kt b/ui/integration-tests/demos/src/main/java/androidx/ui/demos/DemoApp.kt
index 7bc3203..375a966 100644
--- a/ui/integration-tests/demos/src/main/java/androidx/ui/demos/DemoApp.kt
+++ b/ui/integration-tests/demos/src/main/java/androidx/ui/demos/DemoApp.kt
@@ -31,8 +31,8 @@
import androidx.ui.demos.common.DemoCategory
import androidx.ui.demos.common.allLaunchableDemos
import androidx.ui.foundation.Icon
+import androidx.ui.foundation.ScrollableColumn
import androidx.ui.foundation.Text
-import androidx.ui.foundation.VerticalScroller
import androidx.ui.input.TextFieldValue
import androidx.ui.layout.fillMaxSize
import androidx.ui.layout.padding
@@ -121,7 +121,7 @@
@Composable
private fun DisplayDemoCategory(category: DemoCategory, onNavigate: (Demo) -> Unit) {
- VerticalScroller {
+ ScrollableColumn {
category.demos.forEach { demo ->
ListItem(
text = {
diff --git a/ui/integration-tests/demos/src/main/java/androidx/ui/demos/DemoFilter.kt b/ui/integration-tests/demos/src/main/java/androidx/ui/demos/DemoFilter.kt
index 7950fe3..1b3817e 100644
--- a/ui/integration-tests/demos/src/main/java/androidx/ui/demos/DemoFilter.kt
+++ b/ui/integration-tests/demos/src/main/java/androidx/ui/demos/DemoFilter.kt
@@ -21,12 +21,12 @@
import androidx.compose.onCommit
import androidx.ui.core.Alignment
import androidx.ui.core.Modifier
-import androidx.ui.demos.common.Demo
import androidx.ui.core.focus.FocusModifier
+import androidx.ui.demos.common.Demo
import androidx.ui.foundation.Icon
+import androidx.ui.foundation.ScrollableColumn
import androidx.ui.foundation.Text
import androidx.ui.foundation.TextField
-import androidx.ui.foundation.VerticalScroller
import androidx.ui.graphics.compositeOver
import androidx.ui.input.TextFieldValue
import androidx.ui.layout.fillMaxWidth
@@ -51,7 +51,7 @@
val filteredDemos = launchableDemos
.filter { it.title.contains(filterText, ignoreCase = true) }
.sortedBy { it.title }
- VerticalScroller {
+ ScrollableColumn {
filteredDemos.forEach { demo ->
FilteredDemoListItem(demo,
filterText = filterText,
diff --git a/ui/integration-tests/src/main/java/androidx/ui/integration/test/foundation/NestedScrollerTestCase.kt b/ui/integration-tests/src/main/java/androidx/ui/integration/test/foundation/NestedScrollerTestCase.kt
index c32678d..fe6400c 100644
--- a/ui/integration-tests/src/main/java/androidx/ui/integration/test/foundation/NestedScrollerTestCase.kt
+++ b/ui/integration-tests/src/main/java/androidx/ui/integration/test/foundation/NestedScrollerTestCase.kt
@@ -23,11 +23,12 @@
import androidx.ui.core.DensityAmbient
import androidx.ui.core.Modifier
import androidx.ui.foundation.Box
-import androidx.ui.foundation.HorizontalScroller
-import androidx.ui.foundation.ScrollerPosition
+import androidx.ui.foundation.ScrollState
+import androidx.ui.foundation.ScrollableColumn
+import androidx.ui.foundation.ScrollableRow
import androidx.ui.foundation.Text
-import androidx.ui.foundation.VerticalScroller
import androidx.ui.foundation.drawBackground
+import androidx.ui.foundation.rememberScrollState
import androidx.ui.graphics.Color
import androidx.ui.integration.test.ToggleableTestCase
import androidx.ui.layout.Column
@@ -46,14 +47,14 @@
*/
class NestedScrollerTestCase : ComposeTestCase, ToggleableTestCase {
// ScrollerPosition must now be constructed during composition to obtain the Density
- private lateinit var scrollerPosition: ScrollerPosition
+ private lateinit var scrollState: ScrollState
@Composable
override fun emitContent() {
- scrollerPosition = ScrollerPosition()
+ scrollState = rememberScrollState()
MaterialTheme {
Surface {
- VerticalScroller {
+ ScrollableColumn {
repeat(5) { index ->
// key is needed because of b/154920561
key(index) {
@@ -66,7 +67,7 @@
}
override fun toggleState() {
- scrollerPosition.scrollTo(if (scrollerPosition.value == 0f) 10f else 0f)
+ scrollState.scrollTo(if (scrollState.value == 0f) 10f else 0f)
}
@Composable
@@ -106,9 +107,9 @@
}
}
if (useScrollerPosition) {
- HorizontalScroller(scrollerPosition = scrollerPosition, children = content)
+ ScrollableRow(scrollState = scrollState, children = content)
} else {
- HorizontalScroller(children = content)
+ ScrollableRow(children = content)
}
}
}
diff --git a/ui/integration-tests/src/main/java/androidx/ui/integration/test/foundation/ScrollerTestCase.kt b/ui/integration-tests/src/main/java/androidx/ui/integration/test/foundation/ScrollerTestCase.kt
index 3d138e6..d1fb300 100644
--- a/ui/integration-tests/src/main/java/androidx/ui/integration/test/foundation/ScrollerTestCase.kt
+++ b/ui/integration-tests/src/main/java/androidx/ui/integration/test/foundation/ScrollerTestCase.kt
@@ -19,8 +19,9 @@
import androidx.compose.Composable
import androidx.ui.core.Modifier
import androidx.ui.foundation.Canvas
-import androidx.ui.foundation.ScrollerPosition
-import androidx.ui.foundation.VerticalScroller
+import androidx.ui.foundation.ScrollState
+import androidx.ui.foundation.ScrollableColumn
+import androidx.ui.foundation.rememberScrollState
import androidx.ui.graphics.Color
import androidx.ui.integration.test.ToggleableTestCase
import androidx.ui.layout.Column
@@ -33,14 +34,12 @@
* Test case that puts a large number of boxes in a column in a vertical scroller to force scrolling.
*/
class ScrollerTestCase() : ComposeTestCase, ToggleableTestCase {
- private lateinit var scrollerPosition: ScrollerPosition
+ private lateinit var scrollState: ScrollState
@Composable
override fun emitContent() {
- scrollerPosition = ScrollerPosition()
- VerticalScroller(
- scrollerPosition = scrollerPosition
- ) {
+ scrollState = rememberScrollState()
+ ScrollableColumn(scrollState = scrollState) {
Column(Modifier.fillMaxHeight()) {
for (green in 0..0xFF) {
ColorStripe(0xFF, green, 0)
@@ -65,7 +64,7 @@
}
override fun toggleState() {
- scrollerPosition.scrollTo(if (scrollerPosition.value == 0f) 10f else 0f)
+ scrollState.scrollTo(if (scrollState.value == 0f) 10f else 0f)
}
@Composable
diff --git a/ui/ui-android-view/integration-tests/android-view-demos/src/main/java/androidx/ui/androidview/demos/PointerInputInteropAndroidInCompose.kt b/ui/ui-android-view/integration-tests/android-view-demos/src/main/java/androidx/ui/androidview/demos/PointerInputInteropAndroidInCompose.kt
index cdaae2a..398107f 100644
--- a/ui/ui-android-view/integration-tests/android-view-demos/src/main/java/androidx/ui/androidview/demos/PointerInputInteropAndroidInCompose.kt
+++ b/ui/ui-android-view/integration-tests/android-view-demos/src/main/java/androidx/ui/androidview/demos/PointerInputInteropAndroidInCompose.kt
@@ -27,17 +27,17 @@
import androidx.ui.demos.common.ComposableDemo
import androidx.ui.demos.common.DemoCategory
import androidx.ui.foundation.Box
-import androidx.ui.foundation.HorizontalScroller
+import androidx.ui.foundation.ScrollableColumn
+import androidx.ui.foundation.ScrollableRow
import androidx.ui.foundation.Text
-import androidx.ui.foundation.VerticalScroller
import androidx.ui.foundation.drawBackground
+import androidx.ui.geometry.Offset
import androidx.ui.layout.Column
import androidx.ui.layout.fillMaxSize
import androidx.ui.layout.padding
import androidx.ui.layout.preferredHeight
import androidx.ui.layout.preferredSize
import androidx.ui.layout.wrapContentSize
-import androidx.ui.geometry.Offset
import androidx.ui.unit.dp
import androidx.ui.viewinterop.AndroidView
@@ -138,7 +138,7 @@
". If a pointer starts on a button and then drags horizontally, the button " +
"will not be clicked when released."
)
- HorizontalScroller {
+ ScrollableRow {
AndroidView(R.layout.android_tap_in_compose_scroll) { view ->
view.setBackgroundColor(Color.YELLOW)
view.findViewById<View>(R.id.buttonRed).apply {
@@ -176,7 +176,7 @@
Text("Demonstrates correct \"scroll orientation\" locking when something scrollable in " +
"Android is nested inside something scrollable in Compose.")
Text("You should only be able to scroll in one orientation at a time.")
- HorizontalScroller(modifier = Modifier.drawBackground(androidx.ui.graphics.Color.Blue)) {
+ ScrollableRow(modifier = Modifier.drawBackground(androidx.ui.graphics.Color.Blue)) {
Box(modifier = Modifier.padding(96.dp).drawBackground(androidx.ui.graphics.Color.Red)) {
AndroidView(R.layout.android_scroll_in_compose_scroll_different_orientation)
}
@@ -197,7 +197,7 @@
"that for Compose, and thus the child scrolls and prevents the parent from " +
"intercepting. "
)
- VerticalScroller(modifier = Modifier.drawBackground(androidx.ui.graphics.Color.Blue)) {
+ ScrollableColumn(modifier = Modifier.drawBackground(androidx.ui.graphics.Color.Blue)) {
Box(
modifier = Modifier
.padding(96.dp)
diff --git a/ui/ui-android-view/integration-tests/android-view-demos/src/main/java/androidx/ui/androidview/demos/PointerInputInteropComposeInAndroid.kt b/ui/ui-android-view/integration-tests/android-view-demos/src/main/java/androidx/ui/androidview/demos/PointerInputInteropComposeInAndroid.kt
index 8532fcd..3962a9c 100644
--- a/ui/ui-android-view/integration-tests/android-view-demos/src/main/java/androidx/ui/androidview/demos/PointerInputInteropComposeInAndroid.kt
+++ b/ui/ui-android-view/integration-tests/android-view-demos/src/main/java/androidx/ui/androidview/demos/PointerInputInteropComposeInAndroid.kt
@@ -32,8 +32,8 @@
import androidx.ui.demos.common.ActivityDemo
import androidx.ui.demos.common.DemoCategory
import androidx.ui.foundation.Box
-import androidx.ui.foundation.HorizontalScroller
-import androidx.ui.foundation.VerticalScroller
+import androidx.ui.foundation.ScrollableColumn
+import androidx.ui.foundation.ScrollableRow
import androidx.ui.foundation.clickable
import androidx.ui.foundation.drawBackground
import androidx.ui.graphics.Color
@@ -243,7 +243,7 @@
val container = findViewById<ViewGroup>(R.id.container)
composition = container.setContent(Recomposer.current()) {
- VerticalScroller(
+ ScrollableColumn(
modifier = Modifier
.padding(48.dp)
.drawBackground(Color.Gray, RectangleShape)
@@ -288,7 +288,7 @@
val container = findViewById<ViewGroup>(R.id.container)
composition = container.setContent(Recomposer.current()) {
- HorizontalScroller(
+ ScrollableRow(
modifier = Modifier
.padding(48.dp)
.drawBackground(Color.Gray, RectangleShape)
diff --git a/ui/ui-core/integration-tests/ui-core-demos/src/main/java/androidx/ui/core/demos/PopupDemo.kt b/ui/ui-core/integration-tests/ui-core-demos/src/main/java/androidx/ui/core/demos/PopupDemo.kt
index 187b68e..e69e07b 100644
--- a/ui/ui-core/integration-tests/ui-core-demos/src/main/java/androidx/ui/core/demos/PopupDemo.kt
+++ b/ui/ui-core/integration-tests/ui-core-demos/src/main/java/androidx/ui/core/demos/PopupDemo.kt
@@ -23,12 +23,11 @@
import androidx.ui.core.DropdownPopup
import androidx.ui.core.Modifier
import androidx.ui.core.Popup
-import androidx.ui.foundation.TextField
import androidx.ui.foundation.Box
import androidx.ui.foundation.ContentGravity
+import androidx.ui.foundation.ScrollableColumn
import androidx.ui.foundation.Text
import androidx.ui.foundation.TextField
-import androidx.ui.foundation.VerticalScroller
import androidx.ui.foundation.clickable
import androidx.ui.foundation.drawBackground
import androidx.ui.foundation.shape.corner.CircleShape
@@ -406,7 +405,7 @@
@Composable
private fun ColumnScope.PopupInsideScroller() {
- VerticalScroller(
+ ScrollableColumn(
modifier = Modifier.preferredSize(200.dp, 400.dp).gravity(Alignment.CenterHorizontally)
) {
Column(Modifier.fillMaxHeight()) {
diff --git a/ui/ui-foundation/api/0.1.0-dev15.txt b/ui/ui-foundation/api/0.1.0-dev15.txt
index 2fa0f01..cd9464e 100644
--- a/ui/ui-foundation/api/0.1.0-dev15.txt
+++ b/ui/ui-foundation/api/0.1.0-dev15.txt
@@ -119,29 +119,54 @@
@kotlin.RequiresOptIn(message="This API is internal to library.") @kotlin.annotation.Target(allowedTargets={AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER}) public @interface InternalFoundationApi {
}
- public final class ScrollerKt {
- method @androidx.compose.Composable public static void HorizontalScroller(androidx.ui.foundation.ScrollerPosition scrollerPosition = ScrollerPosition(), androidx.ui.core.Modifier modifier = Modifier, boolean isScrollable = true, kotlin.jvm.functions.Function1<? super androidx.ui.layout.RowScope,kotlin.Unit> children);
- method @androidx.compose.Composable public static androidx.ui.foundation.ScrollerPosition ScrollerPosition(float initial = 0f, boolean isReversed = false);
- method @androidx.compose.Composable public static void VerticalScroller(androidx.ui.foundation.ScrollerPosition scrollerPosition = ScrollerPosition(), androidx.ui.core.Modifier modifier = Modifier, boolean isScrollable = true, kotlin.jvm.functions.Function1<? super androidx.ui.layout.ColumnScope,kotlin.Unit> children);
+ public final class ScrollKt {
+ method @Deprecated @androidx.compose.Composable public static void HorizontalScroller(androidx.ui.foundation.ScrollerPosition scrollerPosition = ScrollerPosition(), androidx.ui.core.Modifier modifier = Modifier, boolean isScrollable = true, kotlin.jvm.functions.Function1<? super androidx.ui.layout.RowScope,kotlin.Unit> children);
+ method @androidx.compose.Composable public static void ScrollableColumn(androidx.ui.core.Modifier modifier = Modifier, androidx.ui.foundation.ScrollState scrollState = rememberScrollState(0.0), androidx.ui.layout.Arrangement.Vertical verticalArrangement = Arrangement.Top, androidx.ui.core.Alignment.Horizontal horizontalGravity = Alignment.Start, boolean reverseScrollDirection = false, boolean isScrollEnabled = true, androidx.ui.layout.InnerPadding contentPadding = androidx.ui.layout.InnerPadding(0.dp), kotlin.jvm.functions.Function1<? super androidx.ui.layout.ColumnScope,kotlin.Unit> children);
+ method @androidx.compose.Composable public static void ScrollableRow(androidx.ui.core.Modifier modifier = Modifier, androidx.ui.foundation.ScrollState scrollState = rememberScrollState(0.0), androidx.ui.layout.Arrangement.Horizontal horizontalArrangement = Arrangement.Start, androidx.ui.core.Alignment.Vertical verticalGravity = Alignment.Top, boolean reverseScrollDirection = false, boolean isScrollEnabled = true, androidx.ui.layout.InnerPadding contentPadding = androidx.ui.layout.InnerPadding(0.dp), kotlin.jvm.functions.Function1<? super androidx.ui.layout.RowScope,kotlin.Unit> children);
+ method @Deprecated @androidx.compose.Composable public static androidx.ui.foundation.ScrollerPosition ScrollerPosition(float initial = 0f, boolean isReversed = false);
+ method @Deprecated @androidx.compose.Composable public static void VerticalScroller(androidx.ui.foundation.ScrollerPosition scrollerPosition = ScrollerPosition(), androidx.ui.core.Modifier modifier = Modifier, boolean isScrollable = true, kotlin.jvm.functions.Function1<? super androidx.ui.layout.ColumnScope,kotlin.Unit> children);
+ method public static androidx.ui.core.Modifier horizontalScroll(androidx.ui.core.Modifier, androidx.ui.foundation.ScrollState state, boolean enabled = true, boolean reverseScrolling = false);
+ method @androidx.compose.Composable public static androidx.ui.foundation.ScrollState rememberScrollState(float initial = 0f);
+ method public static androidx.ui.core.Modifier verticalScroll(androidx.ui.core.Modifier, androidx.ui.foundation.ScrollState state, boolean enabled = true, boolean reverseScrolling = false);
}
- @androidx.compose.Stable public final class ScrollerPosition {
- ctor public ScrollerPosition(androidx.ui.foundation.animation.FlingConfig flingConfig, float initial, internal boolean isReversed, androidx.animation.AnimationClockObservable animationClock);
- method public float getMaxPosition();
+ @androidx.compose.Stable public final class ScrollState {
+ ctor public ScrollState(float initial, internal androidx.ui.foundation.animation.FlingConfig flingConfig, androidx.animation.AnimationClockObservable animationClock);
+ method public float getMaxValue();
method public float getValue();
- method public boolean isAnimating();
+ method public boolean isAnimationRunning();
method public void scrollBy(float value);
method public void scrollTo(float value);
- method public void smoothScrollBy(float value, kotlin.jvm.functions.Function2<? super androidx.animation.AnimationEndReason,? super java.lang.Float,kotlin.Unit> _, _ -> });
- method public void smoothScrollTo(float value, kotlin.jvm.functions.Function2<? super androidx.animation.AnimationEndReason,? super java.lang.Float,kotlin.Unit> _, _ -> });
- property public final boolean isAnimating;
- property public final float maxPosition;
+ method public void smoothScrollBy(float value, androidx.animation.AnimationSpec<java.lang.Float> spec = androidx.animation.SpringSpec(), kotlin.jvm.functions.Function2<? super androidx.animation.AnimationEndReason,? super java.lang.Float,kotlin.Unit> _, _ -> });
+ method public void smoothScrollTo(float value, androidx.animation.AnimationSpec<java.lang.Float> spec = androidx.animation.SpringSpec(), kotlin.jvm.functions.Function2<? super androidx.animation.AnimationEndReason,? super java.lang.Float,kotlin.Unit> _, _ -> });
+ method public void stopAnimation();
+ property public final boolean isAnimationRunning;
+ property public final float maxValue;
property public final float value;
- field public static final androidx.ui.foundation.ScrollerPosition.Companion Companion;
+ field public static final androidx.ui.foundation.ScrollState.Companion Companion;
}
- public static final class ScrollerPosition.Companion {
- method @androidx.compose.Composable public androidx.ui.savedinstancestate.Saver<androidx.ui.foundation.ScrollerPosition,?> Saver(androidx.ui.foundation.animation.FlingConfig flingConfig, boolean isReversed, androidx.animation.AnimationClockObservable animationClock);
+ public static final class ScrollState.Companion {
+ method public androidx.ui.savedinstancestate.Saver<androidx.ui.foundation.ScrollState,?> Saver(androidx.ui.foundation.animation.FlingConfig flingConfig, androidx.animation.AnimationClockObservable animationClock);
+ }
+
+ @Deprecated @androidx.compose.Stable public final class ScrollerPosition {
+ ctor @Deprecated public ScrollerPosition(internal androidx.ui.foundation.animation.FlingConfig flingConfig, float initial, internal boolean isReversed, internal androidx.animation.AnimationClockObservable animationClock);
+ method @Deprecated public float getMaxPosition();
+ method @Deprecated public float getValue();
+ method @Deprecated public void scrollBy(float value);
+ method @Deprecated public void scrollTo(float value);
+ method @Deprecated public void setMaxPosition(float newMax);
+ method @Deprecated public void setValue(float value);
+ method @Deprecated public void smoothScrollBy(float value, kotlin.jvm.functions.Function2<? super androidx.animation.AnimationEndReason,? super java.lang.Float,kotlin.Unit> _, _ -> });
+ method @Deprecated public void smoothScrollTo(float value, kotlin.jvm.functions.Function2<? super androidx.animation.AnimationEndReason,? super java.lang.Float,kotlin.Unit> _, _ -> });
+ property public final float maxPosition;
+ property public final float value;
+ field @Deprecated public static final androidx.ui.foundation.ScrollerPosition.Companion Companion;
+ }
+
+ @Deprecated public static final class ScrollerPosition.Companion {
+ method @Deprecated @androidx.compose.Composable public androidx.ui.savedinstancestate.Saver<androidx.ui.foundation.ScrollerPosition,?> Saver(androidx.ui.foundation.animation.FlingConfig flingConfig, boolean isReversed, androidx.animation.AnimationClockObservable animationClock);
}
public final class Strings {
diff --git a/ui/ui-foundation/api/current.txt b/ui/ui-foundation/api/current.txt
index 2fa0f01..cd9464e 100644
--- a/ui/ui-foundation/api/current.txt
+++ b/ui/ui-foundation/api/current.txt
@@ -119,29 +119,54 @@
@kotlin.RequiresOptIn(message="This API is internal to library.") @kotlin.annotation.Target(allowedTargets={AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER}) public @interface InternalFoundationApi {
}
- public final class ScrollerKt {
- method @androidx.compose.Composable public static void HorizontalScroller(androidx.ui.foundation.ScrollerPosition scrollerPosition = ScrollerPosition(), androidx.ui.core.Modifier modifier = Modifier, boolean isScrollable = true, kotlin.jvm.functions.Function1<? super androidx.ui.layout.RowScope,kotlin.Unit> children);
- method @androidx.compose.Composable public static androidx.ui.foundation.ScrollerPosition ScrollerPosition(float initial = 0f, boolean isReversed = false);
- method @androidx.compose.Composable public static void VerticalScroller(androidx.ui.foundation.ScrollerPosition scrollerPosition = ScrollerPosition(), androidx.ui.core.Modifier modifier = Modifier, boolean isScrollable = true, kotlin.jvm.functions.Function1<? super androidx.ui.layout.ColumnScope,kotlin.Unit> children);
+ public final class ScrollKt {
+ method @Deprecated @androidx.compose.Composable public static void HorizontalScroller(androidx.ui.foundation.ScrollerPosition scrollerPosition = ScrollerPosition(), androidx.ui.core.Modifier modifier = Modifier, boolean isScrollable = true, kotlin.jvm.functions.Function1<? super androidx.ui.layout.RowScope,kotlin.Unit> children);
+ method @androidx.compose.Composable public static void ScrollableColumn(androidx.ui.core.Modifier modifier = Modifier, androidx.ui.foundation.ScrollState scrollState = rememberScrollState(0.0), androidx.ui.layout.Arrangement.Vertical verticalArrangement = Arrangement.Top, androidx.ui.core.Alignment.Horizontal horizontalGravity = Alignment.Start, boolean reverseScrollDirection = false, boolean isScrollEnabled = true, androidx.ui.layout.InnerPadding contentPadding = androidx.ui.layout.InnerPadding(0.dp), kotlin.jvm.functions.Function1<? super androidx.ui.layout.ColumnScope,kotlin.Unit> children);
+ method @androidx.compose.Composable public static void ScrollableRow(androidx.ui.core.Modifier modifier = Modifier, androidx.ui.foundation.ScrollState scrollState = rememberScrollState(0.0), androidx.ui.layout.Arrangement.Horizontal horizontalArrangement = Arrangement.Start, androidx.ui.core.Alignment.Vertical verticalGravity = Alignment.Top, boolean reverseScrollDirection = false, boolean isScrollEnabled = true, androidx.ui.layout.InnerPadding contentPadding = androidx.ui.layout.InnerPadding(0.dp), kotlin.jvm.functions.Function1<? super androidx.ui.layout.RowScope,kotlin.Unit> children);
+ method @Deprecated @androidx.compose.Composable public static androidx.ui.foundation.ScrollerPosition ScrollerPosition(float initial = 0f, boolean isReversed = false);
+ method @Deprecated @androidx.compose.Composable public static void VerticalScroller(androidx.ui.foundation.ScrollerPosition scrollerPosition = ScrollerPosition(), androidx.ui.core.Modifier modifier = Modifier, boolean isScrollable = true, kotlin.jvm.functions.Function1<? super androidx.ui.layout.ColumnScope,kotlin.Unit> children);
+ method public static androidx.ui.core.Modifier horizontalScroll(androidx.ui.core.Modifier, androidx.ui.foundation.ScrollState state, boolean enabled = true, boolean reverseScrolling = false);
+ method @androidx.compose.Composable public static androidx.ui.foundation.ScrollState rememberScrollState(float initial = 0f);
+ method public static androidx.ui.core.Modifier verticalScroll(androidx.ui.core.Modifier, androidx.ui.foundation.ScrollState state, boolean enabled = true, boolean reverseScrolling = false);
}
- @androidx.compose.Stable public final class ScrollerPosition {
- ctor public ScrollerPosition(androidx.ui.foundation.animation.FlingConfig flingConfig, float initial, internal boolean isReversed, androidx.animation.AnimationClockObservable animationClock);
- method public float getMaxPosition();
+ @androidx.compose.Stable public final class ScrollState {
+ ctor public ScrollState(float initial, internal androidx.ui.foundation.animation.FlingConfig flingConfig, androidx.animation.AnimationClockObservable animationClock);
+ method public float getMaxValue();
method public float getValue();
- method public boolean isAnimating();
+ method public boolean isAnimationRunning();
method public void scrollBy(float value);
method public void scrollTo(float value);
- method public void smoothScrollBy(float value, kotlin.jvm.functions.Function2<? super androidx.animation.AnimationEndReason,? super java.lang.Float,kotlin.Unit> _, _ -> });
- method public void smoothScrollTo(float value, kotlin.jvm.functions.Function2<? super androidx.animation.AnimationEndReason,? super java.lang.Float,kotlin.Unit> _, _ -> });
- property public final boolean isAnimating;
- property public final float maxPosition;
+ method public void smoothScrollBy(float value, androidx.animation.AnimationSpec<java.lang.Float> spec = androidx.animation.SpringSpec(), kotlin.jvm.functions.Function2<? super androidx.animation.AnimationEndReason,? super java.lang.Float,kotlin.Unit> _, _ -> });
+ method public void smoothScrollTo(float value, androidx.animation.AnimationSpec<java.lang.Float> spec = androidx.animation.SpringSpec(), kotlin.jvm.functions.Function2<? super androidx.animation.AnimationEndReason,? super java.lang.Float,kotlin.Unit> _, _ -> });
+ method public void stopAnimation();
+ property public final boolean isAnimationRunning;
+ property public final float maxValue;
property public final float value;
- field public static final androidx.ui.foundation.ScrollerPosition.Companion Companion;
+ field public static final androidx.ui.foundation.ScrollState.Companion Companion;
}
- public static final class ScrollerPosition.Companion {
- method @androidx.compose.Composable public androidx.ui.savedinstancestate.Saver<androidx.ui.foundation.ScrollerPosition,?> Saver(androidx.ui.foundation.animation.FlingConfig flingConfig, boolean isReversed, androidx.animation.AnimationClockObservable animationClock);
+ public static final class ScrollState.Companion {
+ method public androidx.ui.savedinstancestate.Saver<androidx.ui.foundation.ScrollState,?> Saver(androidx.ui.foundation.animation.FlingConfig flingConfig, androidx.animation.AnimationClockObservable animationClock);
+ }
+
+ @Deprecated @androidx.compose.Stable public final class ScrollerPosition {
+ ctor @Deprecated public ScrollerPosition(internal androidx.ui.foundation.animation.FlingConfig flingConfig, float initial, internal boolean isReversed, internal androidx.animation.AnimationClockObservable animationClock);
+ method @Deprecated public float getMaxPosition();
+ method @Deprecated public float getValue();
+ method @Deprecated public void scrollBy(float value);
+ method @Deprecated public void scrollTo(float value);
+ method @Deprecated public void setMaxPosition(float newMax);
+ method @Deprecated public void setValue(float value);
+ method @Deprecated public void smoothScrollBy(float value, kotlin.jvm.functions.Function2<? super androidx.animation.AnimationEndReason,? super java.lang.Float,kotlin.Unit> _, _ -> });
+ method @Deprecated public void smoothScrollTo(float value, kotlin.jvm.functions.Function2<? super androidx.animation.AnimationEndReason,? super java.lang.Float,kotlin.Unit> _, _ -> });
+ property public final float maxPosition;
+ property public final float value;
+ field @Deprecated public static final androidx.ui.foundation.ScrollerPosition.Companion Companion;
+ }
+
+ @Deprecated public static final class ScrollerPosition.Companion {
+ method @Deprecated @androidx.compose.Composable public androidx.ui.savedinstancestate.Saver<androidx.ui.foundation.ScrollerPosition,?> Saver(androidx.ui.foundation.animation.FlingConfig flingConfig, boolean isReversed, androidx.animation.AnimationClockObservable animationClock);
}
public final class Strings {
diff --git a/ui/ui-foundation/api/public_plus_experimental_0.1.0-dev15.txt b/ui/ui-foundation/api/public_plus_experimental_0.1.0-dev15.txt
index 2fa0f01..cd9464e 100644
--- a/ui/ui-foundation/api/public_plus_experimental_0.1.0-dev15.txt
+++ b/ui/ui-foundation/api/public_plus_experimental_0.1.0-dev15.txt
@@ -119,29 +119,54 @@
@kotlin.RequiresOptIn(message="This API is internal to library.") @kotlin.annotation.Target(allowedTargets={AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER}) public @interface InternalFoundationApi {
}
- public final class ScrollerKt {
- method @androidx.compose.Composable public static void HorizontalScroller(androidx.ui.foundation.ScrollerPosition scrollerPosition = ScrollerPosition(), androidx.ui.core.Modifier modifier = Modifier, boolean isScrollable = true, kotlin.jvm.functions.Function1<? super androidx.ui.layout.RowScope,kotlin.Unit> children);
- method @androidx.compose.Composable public static androidx.ui.foundation.ScrollerPosition ScrollerPosition(float initial = 0f, boolean isReversed = false);
- method @androidx.compose.Composable public static void VerticalScroller(androidx.ui.foundation.ScrollerPosition scrollerPosition = ScrollerPosition(), androidx.ui.core.Modifier modifier = Modifier, boolean isScrollable = true, kotlin.jvm.functions.Function1<? super androidx.ui.layout.ColumnScope,kotlin.Unit> children);
+ public final class ScrollKt {
+ method @Deprecated @androidx.compose.Composable public static void HorizontalScroller(androidx.ui.foundation.ScrollerPosition scrollerPosition = ScrollerPosition(), androidx.ui.core.Modifier modifier = Modifier, boolean isScrollable = true, kotlin.jvm.functions.Function1<? super androidx.ui.layout.RowScope,kotlin.Unit> children);
+ method @androidx.compose.Composable public static void ScrollableColumn(androidx.ui.core.Modifier modifier = Modifier, androidx.ui.foundation.ScrollState scrollState = rememberScrollState(0.0), androidx.ui.layout.Arrangement.Vertical verticalArrangement = Arrangement.Top, androidx.ui.core.Alignment.Horizontal horizontalGravity = Alignment.Start, boolean reverseScrollDirection = false, boolean isScrollEnabled = true, androidx.ui.layout.InnerPadding contentPadding = androidx.ui.layout.InnerPadding(0.dp), kotlin.jvm.functions.Function1<? super androidx.ui.layout.ColumnScope,kotlin.Unit> children);
+ method @androidx.compose.Composable public static void ScrollableRow(androidx.ui.core.Modifier modifier = Modifier, androidx.ui.foundation.ScrollState scrollState = rememberScrollState(0.0), androidx.ui.layout.Arrangement.Horizontal horizontalArrangement = Arrangement.Start, androidx.ui.core.Alignment.Vertical verticalGravity = Alignment.Top, boolean reverseScrollDirection = false, boolean isScrollEnabled = true, androidx.ui.layout.InnerPadding contentPadding = androidx.ui.layout.InnerPadding(0.dp), kotlin.jvm.functions.Function1<? super androidx.ui.layout.RowScope,kotlin.Unit> children);
+ method @Deprecated @androidx.compose.Composable public static androidx.ui.foundation.ScrollerPosition ScrollerPosition(float initial = 0f, boolean isReversed = false);
+ method @Deprecated @androidx.compose.Composable public static void VerticalScroller(androidx.ui.foundation.ScrollerPosition scrollerPosition = ScrollerPosition(), androidx.ui.core.Modifier modifier = Modifier, boolean isScrollable = true, kotlin.jvm.functions.Function1<? super androidx.ui.layout.ColumnScope,kotlin.Unit> children);
+ method public static androidx.ui.core.Modifier horizontalScroll(androidx.ui.core.Modifier, androidx.ui.foundation.ScrollState state, boolean enabled = true, boolean reverseScrolling = false);
+ method @androidx.compose.Composable public static androidx.ui.foundation.ScrollState rememberScrollState(float initial = 0f);
+ method public static androidx.ui.core.Modifier verticalScroll(androidx.ui.core.Modifier, androidx.ui.foundation.ScrollState state, boolean enabled = true, boolean reverseScrolling = false);
}
- @androidx.compose.Stable public final class ScrollerPosition {
- ctor public ScrollerPosition(androidx.ui.foundation.animation.FlingConfig flingConfig, float initial, internal boolean isReversed, androidx.animation.AnimationClockObservable animationClock);
- method public float getMaxPosition();
+ @androidx.compose.Stable public final class ScrollState {
+ ctor public ScrollState(float initial, internal androidx.ui.foundation.animation.FlingConfig flingConfig, androidx.animation.AnimationClockObservable animationClock);
+ method public float getMaxValue();
method public float getValue();
- method public boolean isAnimating();
+ method public boolean isAnimationRunning();
method public void scrollBy(float value);
method public void scrollTo(float value);
- method public void smoothScrollBy(float value, kotlin.jvm.functions.Function2<? super androidx.animation.AnimationEndReason,? super java.lang.Float,kotlin.Unit> _, _ -> });
- method public void smoothScrollTo(float value, kotlin.jvm.functions.Function2<? super androidx.animation.AnimationEndReason,? super java.lang.Float,kotlin.Unit> _, _ -> });
- property public final boolean isAnimating;
- property public final float maxPosition;
+ method public void smoothScrollBy(float value, androidx.animation.AnimationSpec<java.lang.Float> spec = androidx.animation.SpringSpec(), kotlin.jvm.functions.Function2<? super androidx.animation.AnimationEndReason,? super java.lang.Float,kotlin.Unit> _, _ -> });
+ method public void smoothScrollTo(float value, androidx.animation.AnimationSpec<java.lang.Float> spec = androidx.animation.SpringSpec(), kotlin.jvm.functions.Function2<? super androidx.animation.AnimationEndReason,? super java.lang.Float,kotlin.Unit> _, _ -> });
+ method public void stopAnimation();
+ property public final boolean isAnimationRunning;
+ property public final float maxValue;
property public final float value;
- field public static final androidx.ui.foundation.ScrollerPosition.Companion Companion;
+ field public static final androidx.ui.foundation.ScrollState.Companion Companion;
}
- public static final class ScrollerPosition.Companion {
- method @androidx.compose.Composable public androidx.ui.savedinstancestate.Saver<androidx.ui.foundation.ScrollerPosition,?> Saver(androidx.ui.foundation.animation.FlingConfig flingConfig, boolean isReversed, androidx.animation.AnimationClockObservable animationClock);
+ public static final class ScrollState.Companion {
+ method public androidx.ui.savedinstancestate.Saver<androidx.ui.foundation.ScrollState,?> Saver(androidx.ui.foundation.animation.FlingConfig flingConfig, androidx.animation.AnimationClockObservable animationClock);
+ }
+
+ @Deprecated @androidx.compose.Stable public final class ScrollerPosition {
+ ctor @Deprecated public ScrollerPosition(internal androidx.ui.foundation.animation.FlingConfig flingConfig, float initial, internal boolean isReversed, internal androidx.animation.AnimationClockObservable animationClock);
+ method @Deprecated public float getMaxPosition();
+ method @Deprecated public float getValue();
+ method @Deprecated public void scrollBy(float value);
+ method @Deprecated public void scrollTo(float value);
+ method @Deprecated public void setMaxPosition(float newMax);
+ method @Deprecated public void setValue(float value);
+ method @Deprecated public void smoothScrollBy(float value, kotlin.jvm.functions.Function2<? super androidx.animation.AnimationEndReason,? super java.lang.Float,kotlin.Unit> _, _ -> });
+ method @Deprecated public void smoothScrollTo(float value, kotlin.jvm.functions.Function2<? super androidx.animation.AnimationEndReason,? super java.lang.Float,kotlin.Unit> _, _ -> });
+ property public final float maxPosition;
+ property public final float value;
+ field @Deprecated public static final androidx.ui.foundation.ScrollerPosition.Companion Companion;
+ }
+
+ @Deprecated public static final class ScrollerPosition.Companion {
+ method @Deprecated @androidx.compose.Composable public androidx.ui.savedinstancestate.Saver<androidx.ui.foundation.ScrollerPosition,?> Saver(androidx.ui.foundation.animation.FlingConfig flingConfig, boolean isReversed, androidx.animation.AnimationClockObservable animationClock);
}
public final class Strings {
diff --git a/ui/ui-foundation/api/public_plus_experimental_current.txt b/ui/ui-foundation/api/public_plus_experimental_current.txt
index 2fa0f01..cd9464e 100644
--- a/ui/ui-foundation/api/public_plus_experimental_current.txt
+++ b/ui/ui-foundation/api/public_plus_experimental_current.txt
@@ -119,29 +119,54 @@
@kotlin.RequiresOptIn(message="This API is internal to library.") @kotlin.annotation.Target(allowedTargets={AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER}) public @interface InternalFoundationApi {
}
- public final class ScrollerKt {
- method @androidx.compose.Composable public static void HorizontalScroller(androidx.ui.foundation.ScrollerPosition scrollerPosition = ScrollerPosition(), androidx.ui.core.Modifier modifier = Modifier, boolean isScrollable = true, kotlin.jvm.functions.Function1<? super androidx.ui.layout.RowScope,kotlin.Unit> children);
- method @androidx.compose.Composable public static androidx.ui.foundation.ScrollerPosition ScrollerPosition(float initial = 0f, boolean isReversed = false);
- method @androidx.compose.Composable public static void VerticalScroller(androidx.ui.foundation.ScrollerPosition scrollerPosition = ScrollerPosition(), androidx.ui.core.Modifier modifier = Modifier, boolean isScrollable = true, kotlin.jvm.functions.Function1<? super androidx.ui.layout.ColumnScope,kotlin.Unit> children);
+ public final class ScrollKt {
+ method @Deprecated @androidx.compose.Composable public static void HorizontalScroller(androidx.ui.foundation.ScrollerPosition scrollerPosition = ScrollerPosition(), androidx.ui.core.Modifier modifier = Modifier, boolean isScrollable = true, kotlin.jvm.functions.Function1<? super androidx.ui.layout.RowScope,kotlin.Unit> children);
+ method @androidx.compose.Composable public static void ScrollableColumn(androidx.ui.core.Modifier modifier = Modifier, androidx.ui.foundation.ScrollState scrollState = rememberScrollState(0.0), androidx.ui.layout.Arrangement.Vertical verticalArrangement = Arrangement.Top, androidx.ui.core.Alignment.Horizontal horizontalGravity = Alignment.Start, boolean reverseScrollDirection = false, boolean isScrollEnabled = true, androidx.ui.layout.InnerPadding contentPadding = androidx.ui.layout.InnerPadding(0.dp), kotlin.jvm.functions.Function1<? super androidx.ui.layout.ColumnScope,kotlin.Unit> children);
+ method @androidx.compose.Composable public static void ScrollableRow(androidx.ui.core.Modifier modifier = Modifier, androidx.ui.foundation.ScrollState scrollState = rememberScrollState(0.0), androidx.ui.layout.Arrangement.Horizontal horizontalArrangement = Arrangement.Start, androidx.ui.core.Alignment.Vertical verticalGravity = Alignment.Top, boolean reverseScrollDirection = false, boolean isScrollEnabled = true, androidx.ui.layout.InnerPadding contentPadding = androidx.ui.layout.InnerPadding(0.dp), kotlin.jvm.functions.Function1<? super androidx.ui.layout.RowScope,kotlin.Unit> children);
+ method @Deprecated @androidx.compose.Composable public static androidx.ui.foundation.ScrollerPosition ScrollerPosition(float initial = 0f, boolean isReversed = false);
+ method @Deprecated @androidx.compose.Composable public static void VerticalScroller(androidx.ui.foundation.ScrollerPosition scrollerPosition = ScrollerPosition(), androidx.ui.core.Modifier modifier = Modifier, boolean isScrollable = true, kotlin.jvm.functions.Function1<? super androidx.ui.layout.ColumnScope,kotlin.Unit> children);
+ method public static androidx.ui.core.Modifier horizontalScroll(androidx.ui.core.Modifier, androidx.ui.foundation.ScrollState state, boolean enabled = true, boolean reverseScrolling = false);
+ method @androidx.compose.Composable public static androidx.ui.foundation.ScrollState rememberScrollState(float initial = 0f);
+ method public static androidx.ui.core.Modifier verticalScroll(androidx.ui.core.Modifier, androidx.ui.foundation.ScrollState state, boolean enabled = true, boolean reverseScrolling = false);
}
- @androidx.compose.Stable public final class ScrollerPosition {
- ctor public ScrollerPosition(androidx.ui.foundation.animation.FlingConfig flingConfig, float initial, internal boolean isReversed, androidx.animation.AnimationClockObservable animationClock);
- method public float getMaxPosition();
+ @androidx.compose.Stable public final class ScrollState {
+ ctor public ScrollState(float initial, internal androidx.ui.foundation.animation.FlingConfig flingConfig, androidx.animation.AnimationClockObservable animationClock);
+ method public float getMaxValue();
method public float getValue();
- method public boolean isAnimating();
+ method public boolean isAnimationRunning();
method public void scrollBy(float value);
method public void scrollTo(float value);
- method public void smoothScrollBy(float value, kotlin.jvm.functions.Function2<? super androidx.animation.AnimationEndReason,? super java.lang.Float,kotlin.Unit> _, _ -> });
- method public void smoothScrollTo(float value, kotlin.jvm.functions.Function2<? super androidx.animation.AnimationEndReason,? super java.lang.Float,kotlin.Unit> _, _ -> });
- property public final boolean isAnimating;
- property public final float maxPosition;
+ method public void smoothScrollBy(float value, androidx.animation.AnimationSpec<java.lang.Float> spec = androidx.animation.SpringSpec(), kotlin.jvm.functions.Function2<? super androidx.animation.AnimationEndReason,? super java.lang.Float,kotlin.Unit> _, _ -> });
+ method public void smoothScrollTo(float value, androidx.animation.AnimationSpec<java.lang.Float> spec = androidx.animation.SpringSpec(), kotlin.jvm.functions.Function2<? super androidx.animation.AnimationEndReason,? super java.lang.Float,kotlin.Unit> _, _ -> });
+ method public void stopAnimation();
+ property public final boolean isAnimationRunning;
+ property public final float maxValue;
property public final float value;
- field public static final androidx.ui.foundation.ScrollerPosition.Companion Companion;
+ field public static final androidx.ui.foundation.ScrollState.Companion Companion;
}
- public static final class ScrollerPosition.Companion {
- method @androidx.compose.Composable public androidx.ui.savedinstancestate.Saver<androidx.ui.foundation.ScrollerPosition,?> Saver(androidx.ui.foundation.animation.FlingConfig flingConfig, boolean isReversed, androidx.animation.AnimationClockObservable animationClock);
+ public static final class ScrollState.Companion {
+ method public androidx.ui.savedinstancestate.Saver<androidx.ui.foundation.ScrollState,?> Saver(androidx.ui.foundation.animation.FlingConfig flingConfig, androidx.animation.AnimationClockObservable animationClock);
+ }
+
+ @Deprecated @androidx.compose.Stable public final class ScrollerPosition {
+ ctor @Deprecated public ScrollerPosition(internal androidx.ui.foundation.animation.FlingConfig flingConfig, float initial, internal boolean isReversed, internal androidx.animation.AnimationClockObservable animationClock);
+ method @Deprecated public float getMaxPosition();
+ method @Deprecated public float getValue();
+ method @Deprecated public void scrollBy(float value);
+ method @Deprecated public void scrollTo(float value);
+ method @Deprecated public void setMaxPosition(float newMax);
+ method @Deprecated public void setValue(float value);
+ method @Deprecated public void smoothScrollBy(float value, kotlin.jvm.functions.Function2<? super androidx.animation.AnimationEndReason,? super java.lang.Float,kotlin.Unit> _, _ -> });
+ method @Deprecated public void smoothScrollTo(float value, kotlin.jvm.functions.Function2<? super androidx.animation.AnimationEndReason,? super java.lang.Float,kotlin.Unit> _, _ -> });
+ property public final float maxPosition;
+ property public final float value;
+ field @Deprecated public static final androidx.ui.foundation.ScrollerPosition.Companion Companion;
+ }
+
+ @Deprecated public static final class ScrollerPosition.Companion {
+ method @Deprecated @androidx.compose.Composable public androidx.ui.savedinstancestate.Saver<androidx.ui.foundation.ScrollerPosition,?> Saver(androidx.ui.foundation.animation.FlingConfig flingConfig, boolean isReversed, androidx.animation.AnimationClockObservable animationClock);
}
public final class Strings {
diff --git a/ui/ui-foundation/api/restricted_0.1.0-dev15.txt b/ui/ui-foundation/api/restricted_0.1.0-dev15.txt
index 2fa0f01..cd9464e 100644
--- a/ui/ui-foundation/api/restricted_0.1.0-dev15.txt
+++ b/ui/ui-foundation/api/restricted_0.1.0-dev15.txt
@@ -119,29 +119,54 @@
@kotlin.RequiresOptIn(message="This API is internal to library.") @kotlin.annotation.Target(allowedTargets={AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER}) public @interface InternalFoundationApi {
}
- public final class ScrollerKt {
- method @androidx.compose.Composable public static void HorizontalScroller(androidx.ui.foundation.ScrollerPosition scrollerPosition = ScrollerPosition(), androidx.ui.core.Modifier modifier = Modifier, boolean isScrollable = true, kotlin.jvm.functions.Function1<? super androidx.ui.layout.RowScope,kotlin.Unit> children);
- method @androidx.compose.Composable public static androidx.ui.foundation.ScrollerPosition ScrollerPosition(float initial = 0f, boolean isReversed = false);
- method @androidx.compose.Composable public static void VerticalScroller(androidx.ui.foundation.ScrollerPosition scrollerPosition = ScrollerPosition(), androidx.ui.core.Modifier modifier = Modifier, boolean isScrollable = true, kotlin.jvm.functions.Function1<? super androidx.ui.layout.ColumnScope,kotlin.Unit> children);
+ public final class ScrollKt {
+ method @Deprecated @androidx.compose.Composable public static void HorizontalScroller(androidx.ui.foundation.ScrollerPosition scrollerPosition = ScrollerPosition(), androidx.ui.core.Modifier modifier = Modifier, boolean isScrollable = true, kotlin.jvm.functions.Function1<? super androidx.ui.layout.RowScope,kotlin.Unit> children);
+ method @androidx.compose.Composable public static void ScrollableColumn(androidx.ui.core.Modifier modifier = Modifier, androidx.ui.foundation.ScrollState scrollState = rememberScrollState(0.0), androidx.ui.layout.Arrangement.Vertical verticalArrangement = Arrangement.Top, androidx.ui.core.Alignment.Horizontal horizontalGravity = Alignment.Start, boolean reverseScrollDirection = false, boolean isScrollEnabled = true, androidx.ui.layout.InnerPadding contentPadding = androidx.ui.layout.InnerPadding(0.dp), kotlin.jvm.functions.Function1<? super androidx.ui.layout.ColumnScope,kotlin.Unit> children);
+ method @androidx.compose.Composable public static void ScrollableRow(androidx.ui.core.Modifier modifier = Modifier, androidx.ui.foundation.ScrollState scrollState = rememberScrollState(0.0), androidx.ui.layout.Arrangement.Horizontal horizontalArrangement = Arrangement.Start, androidx.ui.core.Alignment.Vertical verticalGravity = Alignment.Top, boolean reverseScrollDirection = false, boolean isScrollEnabled = true, androidx.ui.layout.InnerPadding contentPadding = androidx.ui.layout.InnerPadding(0.dp), kotlin.jvm.functions.Function1<? super androidx.ui.layout.RowScope,kotlin.Unit> children);
+ method @Deprecated @androidx.compose.Composable public static androidx.ui.foundation.ScrollerPosition ScrollerPosition(float initial = 0f, boolean isReversed = false);
+ method @Deprecated @androidx.compose.Composable public static void VerticalScroller(androidx.ui.foundation.ScrollerPosition scrollerPosition = ScrollerPosition(), androidx.ui.core.Modifier modifier = Modifier, boolean isScrollable = true, kotlin.jvm.functions.Function1<? super androidx.ui.layout.ColumnScope,kotlin.Unit> children);
+ method public static androidx.ui.core.Modifier horizontalScroll(androidx.ui.core.Modifier, androidx.ui.foundation.ScrollState state, boolean enabled = true, boolean reverseScrolling = false);
+ method @androidx.compose.Composable public static androidx.ui.foundation.ScrollState rememberScrollState(float initial = 0f);
+ method public static androidx.ui.core.Modifier verticalScroll(androidx.ui.core.Modifier, androidx.ui.foundation.ScrollState state, boolean enabled = true, boolean reverseScrolling = false);
}
- @androidx.compose.Stable public final class ScrollerPosition {
- ctor public ScrollerPosition(androidx.ui.foundation.animation.FlingConfig flingConfig, float initial, internal boolean isReversed, androidx.animation.AnimationClockObservable animationClock);
- method public float getMaxPosition();
+ @androidx.compose.Stable public final class ScrollState {
+ ctor public ScrollState(float initial, internal androidx.ui.foundation.animation.FlingConfig flingConfig, androidx.animation.AnimationClockObservable animationClock);
+ method public float getMaxValue();
method public float getValue();
- method public boolean isAnimating();
+ method public boolean isAnimationRunning();
method public void scrollBy(float value);
method public void scrollTo(float value);
- method public void smoothScrollBy(float value, kotlin.jvm.functions.Function2<? super androidx.animation.AnimationEndReason,? super java.lang.Float,kotlin.Unit> _, _ -> });
- method public void smoothScrollTo(float value, kotlin.jvm.functions.Function2<? super androidx.animation.AnimationEndReason,? super java.lang.Float,kotlin.Unit> _, _ -> });
- property public final boolean isAnimating;
- property public final float maxPosition;
+ method public void smoothScrollBy(float value, androidx.animation.AnimationSpec<java.lang.Float> spec = androidx.animation.SpringSpec(), kotlin.jvm.functions.Function2<? super androidx.animation.AnimationEndReason,? super java.lang.Float,kotlin.Unit> _, _ -> });
+ method public void smoothScrollTo(float value, androidx.animation.AnimationSpec<java.lang.Float> spec = androidx.animation.SpringSpec(), kotlin.jvm.functions.Function2<? super androidx.animation.AnimationEndReason,? super java.lang.Float,kotlin.Unit> _, _ -> });
+ method public void stopAnimation();
+ property public final boolean isAnimationRunning;
+ property public final float maxValue;
property public final float value;
- field public static final androidx.ui.foundation.ScrollerPosition.Companion Companion;
+ field public static final androidx.ui.foundation.ScrollState.Companion Companion;
}
- public static final class ScrollerPosition.Companion {
- method @androidx.compose.Composable public androidx.ui.savedinstancestate.Saver<androidx.ui.foundation.ScrollerPosition,?> Saver(androidx.ui.foundation.animation.FlingConfig flingConfig, boolean isReversed, androidx.animation.AnimationClockObservable animationClock);
+ public static final class ScrollState.Companion {
+ method public androidx.ui.savedinstancestate.Saver<androidx.ui.foundation.ScrollState,?> Saver(androidx.ui.foundation.animation.FlingConfig flingConfig, androidx.animation.AnimationClockObservable animationClock);
+ }
+
+ @Deprecated @androidx.compose.Stable public final class ScrollerPosition {
+ ctor @Deprecated public ScrollerPosition(internal androidx.ui.foundation.animation.FlingConfig flingConfig, float initial, internal boolean isReversed, internal androidx.animation.AnimationClockObservable animationClock);
+ method @Deprecated public float getMaxPosition();
+ method @Deprecated public float getValue();
+ method @Deprecated public void scrollBy(float value);
+ method @Deprecated public void scrollTo(float value);
+ method @Deprecated public void setMaxPosition(float newMax);
+ method @Deprecated public void setValue(float value);
+ method @Deprecated public void smoothScrollBy(float value, kotlin.jvm.functions.Function2<? super androidx.animation.AnimationEndReason,? super java.lang.Float,kotlin.Unit> _, _ -> });
+ method @Deprecated public void smoothScrollTo(float value, kotlin.jvm.functions.Function2<? super androidx.animation.AnimationEndReason,? super java.lang.Float,kotlin.Unit> _, _ -> });
+ property public final float maxPosition;
+ property public final float value;
+ field @Deprecated public static final androidx.ui.foundation.ScrollerPosition.Companion Companion;
+ }
+
+ @Deprecated public static final class ScrollerPosition.Companion {
+ method @Deprecated @androidx.compose.Composable public androidx.ui.savedinstancestate.Saver<androidx.ui.foundation.ScrollerPosition,?> Saver(androidx.ui.foundation.animation.FlingConfig flingConfig, boolean isReversed, androidx.animation.AnimationClockObservable animationClock);
}
public final class Strings {
diff --git a/ui/ui-foundation/api/restricted_current.txt b/ui/ui-foundation/api/restricted_current.txt
index 2fa0f01..cd9464e 100644
--- a/ui/ui-foundation/api/restricted_current.txt
+++ b/ui/ui-foundation/api/restricted_current.txt
@@ -119,29 +119,54 @@
@kotlin.RequiresOptIn(message="This API is internal to library.") @kotlin.annotation.Target(allowedTargets={AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER}) public @interface InternalFoundationApi {
}
- public final class ScrollerKt {
- method @androidx.compose.Composable public static void HorizontalScroller(androidx.ui.foundation.ScrollerPosition scrollerPosition = ScrollerPosition(), androidx.ui.core.Modifier modifier = Modifier, boolean isScrollable = true, kotlin.jvm.functions.Function1<? super androidx.ui.layout.RowScope,kotlin.Unit> children);
- method @androidx.compose.Composable public static androidx.ui.foundation.ScrollerPosition ScrollerPosition(float initial = 0f, boolean isReversed = false);
- method @androidx.compose.Composable public static void VerticalScroller(androidx.ui.foundation.ScrollerPosition scrollerPosition = ScrollerPosition(), androidx.ui.core.Modifier modifier = Modifier, boolean isScrollable = true, kotlin.jvm.functions.Function1<? super androidx.ui.layout.ColumnScope,kotlin.Unit> children);
+ public final class ScrollKt {
+ method @Deprecated @androidx.compose.Composable public static void HorizontalScroller(androidx.ui.foundation.ScrollerPosition scrollerPosition = ScrollerPosition(), androidx.ui.core.Modifier modifier = Modifier, boolean isScrollable = true, kotlin.jvm.functions.Function1<? super androidx.ui.layout.RowScope,kotlin.Unit> children);
+ method @androidx.compose.Composable public static void ScrollableColumn(androidx.ui.core.Modifier modifier = Modifier, androidx.ui.foundation.ScrollState scrollState = rememberScrollState(0.0), androidx.ui.layout.Arrangement.Vertical verticalArrangement = Arrangement.Top, androidx.ui.core.Alignment.Horizontal horizontalGravity = Alignment.Start, boolean reverseScrollDirection = false, boolean isScrollEnabled = true, androidx.ui.layout.InnerPadding contentPadding = androidx.ui.layout.InnerPadding(0.dp), kotlin.jvm.functions.Function1<? super androidx.ui.layout.ColumnScope,kotlin.Unit> children);
+ method @androidx.compose.Composable public static void ScrollableRow(androidx.ui.core.Modifier modifier = Modifier, androidx.ui.foundation.ScrollState scrollState = rememberScrollState(0.0), androidx.ui.layout.Arrangement.Horizontal horizontalArrangement = Arrangement.Start, androidx.ui.core.Alignment.Vertical verticalGravity = Alignment.Top, boolean reverseScrollDirection = false, boolean isScrollEnabled = true, androidx.ui.layout.InnerPadding contentPadding = androidx.ui.layout.InnerPadding(0.dp), kotlin.jvm.functions.Function1<? super androidx.ui.layout.RowScope,kotlin.Unit> children);
+ method @Deprecated @androidx.compose.Composable public static androidx.ui.foundation.ScrollerPosition ScrollerPosition(float initial = 0f, boolean isReversed = false);
+ method @Deprecated @androidx.compose.Composable public static void VerticalScroller(androidx.ui.foundation.ScrollerPosition scrollerPosition = ScrollerPosition(), androidx.ui.core.Modifier modifier = Modifier, boolean isScrollable = true, kotlin.jvm.functions.Function1<? super androidx.ui.layout.ColumnScope,kotlin.Unit> children);
+ method public static androidx.ui.core.Modifier horizontalScroll(androidx.ui.core.Modifier, androidx.ui.foundation.ScrollState state, boolean enabled = true, boolean reverseScrolling = false);
+ method @androidx.compose.Composable public static androidx.ui.foundation.ScrollState rememberScrollState(float initial = 0f);
+ method public static androidx.ui.core.Modifier verticalScroll(androidx.ui.core.Modifier, androidx.ui.foundation.ScrollState state, boolean enabled = true, boolean reverseScrolling = false);
}
- @androidx.compose.Stable public final class ScrollerPosition {
- ctor public ScrollerPosition(androidx.ui.foundation.animation.FlingConfig flingConfig, float initial, internal boolean isReversed, androidx.animation.AnimationClockObservable animationClock);
- method public float getMaxPosition();
+ @androidx.compose.Stable public final class ScrollState {
+ ctor public ScrollState(float initial, internal androidx.ui.foundation.animation.FlingConfig flingConfig, androidx.animation.AnimationClockObservable animationClock);
+ method public float getMaxValue();
method public float getValue();
- method public boolean isAnimating();
+ method public boolean isAnimationRunning();
method public void scrollBy(float value);
method public void scrollTo(float value);
- method public void smoothScrollBy(float value, kotlin.jvm.functions.Function2<? super androidx.animation.AnimationEndReason,? super java.lang.Float,kotlin.Unit> _, _ -> });
- method public void smoothScrollTo(float value, kotlin.jvm.functions.Function2<? super androidx.animation.AnimationEndReason,? super java.lang.Float,kotlin.Unit> _, _ -> });
- property public final boolean isAnimating;
- property public final float maxPosition;
+ method public void smoothScrollBy(float value, androidx.animation.AnimationSpec<java.lang.Float> spec = androidx.animation.SpringSpec(), kotlin.jvm.functions.Function2<? super androidx.animation.AnimationEndReason,? super java.lang.Float,kotlin.Unit> _, _ -> });
+ method public void smoothScrollTo(float value, androidx.animation.AnimationSpec<java.lang.Float> spec = androidx.animation.SpringSpec(), kotlin.jvm.functions.Function2<? super androidx.animation.AnimationEndReason,? super java.lang.Float,kotlin.Unit> _, _ -> });
+ method public void stopAnimation();
+ property public final boolean isAnimationRunning;
+ property public final float maxValue;
property public final float value;
- field public static final androidx.ui.foundation.ScrollerPosition.Companion Companion;
+ field public static final androidx.ui.foundation.ScrollState.Companion Companion;
}
- public static final class ScrollerPosition.Companion {
- method @androidx.compose.Composable public androidx.ui.savedinstancestate.Saver<androidx.ui.foundation.ScrollerPosition,?> Saver(androidx.ui.foundation.animation.FlingConfig flingConfig, boolean isReversed, androidx.animation.AnimationClockObservable animationClock);
+ public static final class ScrollState.Companion {
+ method public androidx.ui.savedinstancestate.Saver<androidx.ui.foundation.ScrollState,?> Saver(androidx.ui.foundation.animation.FlingConfig flingConfig, androidx.animation.AnimationClockObservable animationClock);
+ }
+
+ @Deprecated @androidx.compose.Stable public final class ScrollerPosition {
+ ctor @Deprecated public ScrollerPosition(internal androidx.ui.foundation.animation.FlingConfig flingConfig, float initial, internal boolean isReversed, internal androidx.animation.AnimationClockObservable animationClock);
+ method @Deprecated public float getMaxPosition();
+ method @Deprecated public float getValue();
+ method @Deprecated public void scrollBy(float value);
+ method @Deprecated public void scrollTo(float value);
+ method @Deprecated public void setMaxPosition(float newMax);
+ method @Deprecated public void setValue(float value);
+ method @Deprecated public void smoothScrollBy(float value, kotlin.jvm.functions.Function2<? super androidx.animation.AnimationEndReason,? super java.lang.Float,kotlin.Unit> _, _ -> });
+ method @Deprecated public void smoothScrollTo(float value, kotlin.jvm.functions.Function2<? super androidx.animation.AnimationEndReason,? super java.lang.Float,kotlin.Unit> _, _ -> });
+ property public final float maxPosition;
+ property public final float value;
+ field @Deprecated public static final androidx.ui.foundation.ScrollerPosition.Companion Companion;
+ }
+
+ @Deprecated public static final class ScrollerPosition.Companion {
+ method @Deprecated @androidx.compose.Composable public androidx.ui.savedinstancestate.Saver<androidx.ui.foundation.ScrollerPosition,?> Saver(androidx.ui.foundation.animation.FlingConfig flingConfig, boolean isReversed, androidx.animation.AnimationClockObservable animationClock);
}
public final class Strings {
diff --git a/ui/ui-foundation/integration-tests/foundation-demos/src/main/java/androidx/ui/foundation/demos/FoundationDemos.kt b/ui/ui-foundation/integration-tests/foundation-demos/src/main/java/androidx/ui/foundation/demos/FoundationDemos.kt
index 7b74a18..520b1bb3 100644
--- a/ui/ui-foundation/integration-tests/foundation-demos/src/main/java/androidx/ui/foundation/demos/FoundationDemos.kt
+++ b/ui/ui-foundation/integration-tests/foundation-demos/src/main/java/androidx/ui/foundation/demos/FoundationDemos.kt
@@ -18,15 +18,15 @@
import androidx.ui.demos.common.ComposableDemo
import androidx.ui.demos.common.DemoCategory
-import androidx.ui.foundation.samples.ControlledHorizontalScrollerSample
+import androidx.ui.foundation.samples.ControlledScrollableRowSample
import androidx.ui.foundation.samples.DialogSample
import androidx.ui.foundation.samples.InteractionStateSample
-import androidx.ui.foundation.samples.VerticalScrollerSample
+import androidx.ui.foundation.samples.ScrollableColumnSample
val FoundationDemos = DemoCategory("Foundation", listOf(
ComposableDemo("Draggable and Scrollable") { HighLevelGesturesDemo() },
- ComposableDemo("VerticalScroller") { VerticalScrollerSample() },
- ComposableDemo("HorizontalScroller") { ControlledHorizontalScrollerSample() },
+ ComposableDemo("Scrollable Column") { ScrollableColumnSample() },
+ ComposableDemo("Controlled Scrollable Row") { ControlledScrollableRowSample() },
ComposableDemo("Dialog") { DialogSample() },
ComposableDemo("Draw Modifiers") { DrawModifiersDemo() },
ComposableDemo("Boxes") { BoxDemo() },
diff --git a/ui/ui-foundation/samples/src/main/java/androidx/ui/foundation/samples/ScrollerSamples.kt b/ui/ui-foundation/samples/src/main/java/androidx/ui/foundation/samples/ScrollerSamples.kt
index 10f793b..c27e0ee 100644
--- a/ui/ui-foundation/samples/src/main/java/androidx/ui/foundation/samples/ScrollerSamples.kt
+++ b/ui/ui-foundation/samples/src/main/java/androidx/ui/foundation/samples/ScrollerSamples.kt
@@ -18,22 +18,29 @@
import androidx.annotation.Sampled
import androidx.compose.Composable
-import androidx.compose.MutableState
-import androidx.compose.state
+import androidx.ui.core.Alignment
import androidx.ui.core.Modifier
import androidx.ui.foundation.Box
import androidx.ui.foundation.ContentGravity
-import androidx.ui.foundation.HorizontalScroller
-import androidx.ui.foundation.ScrollerPosition
+import androidx.ui.foundation.ScrollableColumn
+import androidx.ui.foundation.ScrollableRow
import androidx.ui.foundation.Text
-import androidx.ui.foundation.VerticalScroller
import androidx.ui.foundation.clickable
+import androidx.ui.foundation.drawBackground
+import androidx.ui.foundation.horizontalScroll
+import androidx.ui.foundation.rememberScrollState
+import androidx.ui.foundation.verticalScroll
import androidx.ui.graphics.Color
+import androidx.ui.graphics.HorizontalGradient
+import androidx.ui.graphics.TileMode
+import androidx.ui.graphics.VerticalGradient
import androidx.ui.layout.Column
import androidx.ui.layout.Row
+import androidx.ui.layout.fillMaxWidth
+import androidx.ui.layout.height
import androidx.ui.layout.padding
import androidx.ui.layout.preferredSize
-import androidx.ui.text.TextStyle
+import androidx.ui.layout.size
import androidx.ui.unit.dp
import androidx.ui.unit.sp
@@ -80,45 +87,85 @@
@Sampled
@Composable
-fun VerticalScrollerSample() {
- val style = TextStyle(fontSize = 30.sp)
- // Scroller will be clipped to this padding
- VerticalScroller {
+fun HorizontalScrollSample() {
+ val scrollState = rememberScrollState()
+ val gradient = HorizontalGradient(
+ listOf(Color.Red, Color.Blue, Color.Green), 0.0f, 10000.0f, TileMode.Repeated
+ )
+ Box(
+ Modifier
+ .horizontalScroll(scrollState)
+ .size(width = 10000.dp, height = 200.dp)
+ .drawBackground(gradient)
+ )
+}
+
+@Sampled
+@Composable
+fun VerticalScrollExample() {
+ val scrollState = rememberScrollState()
+ val gradient = VerticalGradient(
+ listOf(Color.Red, Color.Blue, Color.Green), 0.0f, 10000.0f, TileMode.Repeated
+ )
+ Box(
+ Modifier
+ .verticalScroll(scrollState)
+ .fillMaxWidth()
+ .height(10000.dp)
+ .drawBackground(gradient)
+ )
+}
+
+@Sampled
+@Composable
+fun ScrollableColumnSample() {
+ ScrollableColumn {
phrases.forEach { phrase ->
- Text(phrase, style)
+ Text(phrase, fontSize = 30.sp)
}
}
}
@Sampled
@Composable
-fun SimpleHorizontalScrollerSample() {
- HorizontalScroller {
- Row {
- repeat(100) { index ->
- Square(index)
- }
+fun ScrollableRowSample() {
+ ScrollableRow {
+ repeat(100) { index ->
+ Square(index)
}
}
}
@Sampled
@Composable
-fun ControlledHorizontalScrollerSample() {
- // Create and own ScrollerPosition to call `smoothScrollTo` later
- val position = ScrollerPosition()
- val scrollable = state { true }
+fun ControlledScrollableRowSample() {
+ // Create ScrollState to own it and be able to control scroll behaviour of ScrollableRow below
+ val scrollState = rememberScrollState()
Column {
- HorizontalScroller(
- scrollerPosition = position,
- isScrollable = scrollable.value
- ) {
+ ScrollableRow(scrollState = scrollState) {
repeat(1000) { index ->
Square(index)
}
}
- // Controls that will call `smoothScrollTo`, `scrollTo` or toggle `scrollable` state
- ScrollControl(position, scrollable)
+ // Controls for scrolling
+ Row(verticalGravity = Alignment.CenterVertically) {
+ Text("Scroll")
+ Button( scrollState.scrollTo(scrollState.value - 1000) }) {
+ Text("< -")
+ }
+ Button( scrollState.scrollBy(10000f) }) {
+ Text("--- >")
+ }
+ }
+ Row(verticalGravity = Alignment.CenterVertically) {
+ Text("Smooth Scroll")
+ Button( scrollState.smoothScrollTo(scrollState.value - 1000) }) {
+ Text("< -")
+ }
+ Button( scrollState.smoothScrollBy(10000f) }) {
+ Text("--- >")
+ }
+ }
}
}
@@ -134,46 +181,13 @@
}
@Composable
-private fun ScrollControl(position: ScrollerPosition, scrollable: MutableState<Boolean>) {
- Column {
- Row {
- Text("Scroll")
- SquareButton("< -", Color.Red) {
- position.scrollTo(position.value - 1000)
- }
- SquareButton("--- >", Color.Green) {
- position.scrollBy(10000f)
- }
- }
- Row {
- Text("Smooth Scroll")
- SquareButton("< -", Color.Red) {
- position.smoothScrollTo(position.value - 1000)
- }
- SquareButton("--- >", Color.Green) {
- position.smoothScrollBy(10000f)
- }
- }
- Row {
- SquareButton("Scroll: ${scrollable.value}") {
- scrollable.value = !scrollable.value
- }
- }
- }
-}
-
-@Composable
-private fun SquareButton(text: String, color: Color = Color.LightGray, onClick: () -> Unit) {
+private fun Button(onClick: () -> Unit, text: @Composable () -> Unit) {
Box(
- Modifier.padding(5.dp).preferredSize(120.dp, 60.dp).clickable(>
- backgroundColor = color,
- gravity = ContentGravity.Center
- ) {
- Text(text, fontSize = 20.sp)
- }
-}
-
-@Composable
-private fun Text(text: String, style: TextStyle) {
- Text(text, style = style, modifier = Modifier.clickable { })
+ Modifier.padding(5.dp)
+ .preferredSize(120.dp, 60.dp)
+ .clickable(>
+ .drawBackground(Color.LightGray),
+ gravity = ContentGravity.Center,
+ children = text
+ )
}
\ No newline at end of file
diff --git a/ui/ui-foundation/src/androidAndroidTest/kotlin/androidx/ui/foundation/ScrollerTest.kt b/ui/ui-foundation/src/androidAndroidTest/kotlin/androidx/ui/foundation/ScrollTest.kt
similarity index 67%
rename from ui/ui-foundation/src/androidAndroidTest/kotlin/androidx/ui/foundation/ScrollerTest.kt
rename to ui/ui-foundation/src/androidAndroidTest/kotlin/androidx/ui/foundation/ScrollTest.kt
index 138f7df..07027f9 100644
--- a/ui/ui-foundation/src/androidAndroidTest/kotlin/androidx/ui/foundation/ScrollerTest.kt
+++ b/ui/ui-foundation/src/androidAndroidTest/kotlin/androidx/ui/foundation/ScrollTest.kt
@@ -67,7 +67,7 @@
@SmallTest
@RunWith(JUnit4::class)
-class ScrollerTest {
+class ScrollTest {
@get:Rule
val composeTestRule = createComposeRule()
@@ -101,15 +101,16 @@
@Test
fun verticalScroller_SmallContent_Unscrollable() {
- val scrollerPosition = ScrollerPosition(
- FlingConfig(ExponentialDecay()),
+ val scrollState = ScrollState(
+ initial = 0f,
+ flingConfig = FlingConfig(ExponentialDecay()),
animationClock = ManualAnimationClock(0)
)
- composeVerticalScroller(scrollerPosition)
+ composeVerticalScroller(scrollState)
runOnIdle {
- assertTrue(scrollerPosition.maxPosition == 0f)
+ assertTrue(scrollState.maxValue == 0f)
}
}
@@ -126,20 +127,21 @@
@SdkSuppress(minSdkVersion = 26)
@Test
fun verticalScroller_LargeContent_ScrollToEnd() {
- val scrollerPosition = ScrollerPosition(
- FlingConfig(ExponentialDecay()),
+ val scrollState = ScrollState(
+ initial = 0f,
+ flingConfig = FlingConfig(ExponentialDecay()),
animationClock = ManualAnimationClock(0)
)
val height = 30
val scrollDistance = 10
- composeVerticalScroller(scrollerPosition, height = height)
+ composeVerticalScroller(scrollState, height = height)
validateVerticalScroller(height = height)
runOnIdle {
- assertEquals(scrollDistance.toFloat(), scrollerPosition.maxPosition)
- scrollerPosition.scrollTo(scrollDistance.toFloat())
+ assertEquals(scrollDistance.toFloat(), scrollState.maxValue)
+ scrollState.scrollTo(scrollDistance.toFloat())
}
runOnIdle {} // Just so the block below is correct
@@ -149,15 +151,15 @@
@SdkSuppress(minSdkVersion = 26)
@Test
fun verticalScroller_Reversed() {
- val scrollerPosition = ScrollerPosition(
- FlingConfig(ExponentialDecay()),
- animationClock = ManualAnimationClock(0),
- isReversed = true
+ val scrollState = ScrollState(
+ initial = 0f,
+ flingConfig = FlingConfig(ExponentialDecay()),
+ animationClock = ManualAnimationClock(0)
)
val height = 30
val expectedOffset = defaultCellSize * colors.size - height
- composeVerticalScroller(scrollerPosition, height = height)
+ composeVerticalScroller(scrollState, height = height, isReversed = true)
validateVerticalScroller(offset = expectedOffset, height = height)
}
@@ -165,19 +167,19 @@
@SdkSuppress(minSdkVersion = 26)
@Test
fun verticalScroller_LargeContent_Reversed_ScrollToEnd() {
- val scrollerPosition = ScrollerPosition(
- FlingConfig(ExponentialDecay()),
- animationClock = ManualAnimationClock(0),
- isReversed = true
+ val scrollState = ScrollState(
+ initial = 0f,
+ flingConfig = FlingConfig(ExponentialDecay()),
+ animationClock = ManualAnimationClock(0)
)
val height = 20
val scrollDistance = 10
val expectedOffset = defaultCellSize * colors.size - height - scrollDistance
- composeVerticalScroller(scrollerPosition, height = height)
+ composeVerticalScroller(scrollState, height = height, isReversed = true)
runOnIdle {
- scrollerPosition.scrollTo(scrollDistance.toFloat())
+ scrollState.scrollTo(scrollDistance.toFloat())
}
runOnIdle {} // Just so the block below is correct
@@ -210,18 +212,19 @@
val width = 30
val scrollDistance = 10
- val scrollerPosition = ScrollerPosition(
- FlingConfig(ExponentialDecay()),
+ val scrollState = ScrollState(
+ initial = 0f,
+ flingConfig = FlingConfig(ExponentialDecay()),
animationClock = ManualAnimationClock(0)
)
- composeHorizontalScroller(scrollerPosition, width = width)
+ composeHorizontalScroller(scrollState, width = width)
validateHorizontalScroller(width = width)
runOnIdle {
- assertEquals(scrollDistance.toFloat(), scrollerPosition.maxPosition)
- scrollerPosition.scrollTo(scrollDistance.toFloat())
+ assertEquals(scrollDistance.toFloat(), scrollState.maxValue)
+ scrollState.scrollTo(scrollDistance.toFloat())
}
runOnIdle {} // Just so the block below is correct
@@ -231,15 +234,15 @@
@SdkSuppress(minSdkVersion = 26)
@Test
fun horizontalScroller_reversed() {
- val scrollerPosition = ScrollerPosition(
- FlingConfig(ExponentialDecay()),
- animationClock = ManualAnimationClock(0),
- isReversed = true
+ val scrollState = ScrollState(
+ initial = 0f,
+ flingConfig = FlingConfig(ExponentialDecay()),
+ animationClock = ManualAnimationClock(0)
)
val width = 30
val expectedOffset = defaultCellSize * colors.size - width
- composeHorizontalScroller(scrollerPosition, width = width)
+ composeHorizontalScroller(scrollState, width = width, isReversed = true)
validateHorizontalScroller(offset = expectedOffset, width = width)
}
@@ -250,18 +253,18 @@
val width = 30
val scrollDistance = 10
- val scrollerPosition = ScrollerPosition(
- FlingConfig(ExponentialDecay()),
- animationClock = ManualAnimationClock(0),
- isReversed = true
+ val scrollState = ScrollState(
+ initial = 0f,
+ flingConfig = FlingConfig(ExponentialDecay()),
+ animationClock = ManualAnimationClock(0)
)
val expectedOffset = defaultCellSize * colors.size - width - scrollDistance
- composeHorizontalScroller(scrollerPosition, width = width)
+ composeHorizontalScroller(scrollState, width = width, isReversed = true)
runOnIdle {
- scrollerPosition.scrollTo(scrollDistance.toFloat())
+ scrollState.scrollTo(scrollDistance.toFloat())
}
runOnIdle {} // Just so the block below is correct
@@ -292,11 +295,13 @@
@Test
fun verticalScroller_reversed_scrollTo_scrollForward() {
createScrollableContent(
- isVertical = true, scrollerPosition = ScrollerPosition(
- FlingConfig(ExponentialDecay()),
- animationClock = ManualAnimationClock(0),
- isReversed = true
- )
+ isVertical = true,
+ scrollState = ScrollState(
+ initial = 0f,
+ flingConfig = FlingConfig(ExponentialDecay()),
+ animationClock = ManualAnimationClock(0)
+ ),
+ isReversed = true
)
onNodeWithText("50")
@@ -309,11 +314,13 @@
@Test
fun horizontalScroller_reversed_scrollTo_scrollForward() {
createScrollableContent(
- isVertical = false, scrollerPosition = ScrollerPosition(
- FlingConfig(ExponentialDecay()),
- animationClock = ManualAnimationClock(0),
- isReversed = true
- )
+ isVertical = false,
+ scrollState = ScrollState(
+ initial = 0f,
+ flingConfig = FlingConfig(ExponentialDecay()),
+ animationClock = ManualAnimationClock(0)
+ ),
+ isReversed = true
)
onNodeWithText("50")
@@ -323,6 +330,7 @@
}
@Test
+ @Ignore("When b/157687898 is fixed, performScrollTo must be adjusted to use semantic bounds")
fun verticalScroller_scrollTo_scrollBack() {
createScrollableContent(isVertical = true)
@@ -338,6 +346,7 @@
}
@Test
+ @Ignore("When b/157687898 is fixed, performScrollTo must be adjusted to use semantic bounds")
fun horizontalScroller_scrollTo_scrollBack() {
createScrollableContent(isVertical = false)
@@ -365,61 +374,63 @@
@Test
fun scroller_coerce_whenScrollTo() {
val clock = ManualAnimationClock(0)
- val scrollerPosition = ScrollerPosition(
- FlingConfig(ExponentialDecay()),
+ val scrollState = ScrollState(
+ initial = 0f,
+ flingConfig = FlingConfig(ExponentialDecay()),
animationClock = clock
)
- createScrollableContent(isVertical = true, scrollerPosition = scrollerPosition)
+ createScrollableContent(isVertical = true, scrollState = scrollState)
runOnIdle {
- assertThat(scrollerPosition.value).isEqualTo(0f)
- assertThat(scrollerPosition.maxPosition).isGreaterThan(0f)
+ assertThat(scrollState.value).isEqualTo(0f)
+ assertThat(scrollState.maxValue).isGreaterThan(0f)
}
runOnUiThread {
- scrollerPosition.scrollTo(-100f)
+ scrollState.scrollTo(-100f)
}
runOnIdle {
- assertThat(scrollerPosition.value).isEqualTo(0f)
+ assertThat(scrollState.value).isEqualTo(0f)
}
runOnUiThread {
- scrollerPosition.scrollBy(-100f)
+ scrollState.scrollBy(-100f)
}
runOnIdle {
- assertThat(scrollerPosition.value).isEqualTo(0f)
+ assertThat(scrollState.value).isEqualTo(0f)
}
runOnUiThread {
- scrollerPosition.scrollTo(scrollerPosition.maxPosition)
+ scrollState.scrollTo(scrollState.maxValue)
}
runOnIdle {
- assertThat(scrollerPosition.value).isEqualTo(scrollerPosition.maxPosition)
+ assertThat(scrollState.value).isEqualTo(scrollState.maxValue)
}
runOnUiThread {
- scrollerPosition.scrollTo(scrollerPosition.maxPosition + 1000)
+ scrollState.scrollTo(scrollState.maxValue + 1000)
}
runOnIdle {
- assertThat(scrollerPosition.value).isEqualTo(scrollerPosition.maxPosition)
+ assertThat(scrollState.value).isEqualTo(scrollState.maxValue)
}
runOnUiThread {
- scrollerPosition.scrollBy(100f)
+ scrollState.scrollBy(100f)
}
runOnIdle {
- assertThat(scrollerPosition.value).isEqualTo(scrollerPosition.maxPosition)
+ assertThat(scrollState.value).isEqualTo(scrollState.maxValue)
}
}
@Test
fun verticalScroller_LargeContent_coerceWhenMaxChanges() {
val clock = ManualAnimationClock(0)
- val scrollerPosition = ScrollerPosition(
- FlingConfig(ExponentialDecay()),
+ val scrollState = ScrollState(
+ initial = 0f,
+ flingConfig = FlingConfig(ExponentialDecay()),
animationClock = clock
)
val itemCount = mutableStateOf(100)
composeTestRule.setContent {
Stack {
- VerticalScroller(
- scrollerPosition = scrollerPosition,
+ ScrollableColumn(
+ scrollState = scrollState,
modifier = Modifier.preferredSize(100.dp).testTag(scrollerTag)
) {
for (i in 0..itemCount.value) {
@@ -430,73 +441,75 @@
}
val max = runOnIdle {
- assertThat(scrollerPosition.value).isEqualTo(0f)
- assertThat(scrollerPosition.maxPosition).isGreaterThan(0f)
- scrollerPosition.maxPosition
+ assertThat(scrollState.value).isEqualTo(0f)
+ assertThat(scrollState.maxValue).isGreaterThan(0f)
+ scrollState.maxValue
}
runOnUiThread {
- scrollerPosition.scrollTo(max)
+ scrollState.scrollTo(max)
}
runOnUiThread {
itemCount.value -= 2
}
runOnIdle {
- val newMax = scrollerPosition.maxPosition
+ val newMax = scrollState.maxValue
assertThat(newMax).isLessThan(max)
- assertThat(scrollerPosition.value).isEqualTo(newMax)
+ assertThat(scrollState.value).isEqualTo(newMax)
}
}
@Test
fun scroller_coerce_whenScrollSmoothTo() {
val clock = ManualAnimationClock(0)
- val scrollerPosition = ScrollerPosition(
- FlingConfig(ExponentialDecay()),
+ val scrollState = ScrollState(
+ initial = 0f,
+ flingConfig = FlingConfig(ExponentialDecay()),
animationClock = clock
)
- createScrollableContent(isVertical = true, scrollerPosition = scrollerPosition)
+ createScrollableContent(isVertical = true, scrollState = scrollState)
val max = runOnIdle {
- assertThat(scrollerPosition.value).isEqualTo(0f)
- assertThat(scrollerPosition.maxPosition).isGreaterThan(0f)
- scrollerPosition.maxPosition
+ assertThat(scrollState.value).isEqualTo(0f)
+ assertThat(scrollState.maxValue).isGreaterThan(0f)
+ scrollState.maxValue
}
- performWithAnimationWaitAndAssertPosition(0f, scrollerPosition, clock) {
- scrollerPosition.smoothScrollTo(-100f)
+ performWithAnimationWaitAndAssertPosition(0f, scrollState, clock) {
+ scrollState.smoothScrollTo(-100f)
}
- performWithAnimationWaitAndAssertPosition(0f, scrollerPosition, clock) {
- scrollerPosition.smoothScrollBy(-100f)
+ performWithAnimationWaitAndAssertPosition(0f, scrollState, clock) {
+ scrollState.smoothScrollBy(-100f)
}
- performWithAnimationWaitAndAssertPosition(max, scrollerPosition, clock) {
- scrollerPosition.smoothScrollTo(scrollerPosition.maxPosition)
+ performWithAnimationWaitAndAssertPosition(max, scrollState, clock) {
+ scrollState.smoothScrollTo(scrollState.maxValue)
}
- performWithAnimationWaitAndAssertPosition(max, scrollerPosition, clock) {
- scrollerPosition.smoothScrollTo(scrollerPosition.maxPosition + 1000)
+ performWithAnimationWaitAndAssertPosition(max, scrollState, clock) {
+ scrollState.smoothScrollTo(scrollState.maxValue + 1000)
}
- performWithAnimationWaitAndAssertPosition(max, scrollerPosition, clock) {
- scrollerPosition.smoothScrollBy(100f)
+ performWithAnimationWaitAndAssertPosition(max, scrollState, clock) {
+ scrollState.smoothScrollBy(100f)
}
}
@Test
fun scroller_whenFling_stopsByTouchDown() {
val clock = ManualAnimationClock(0)
- val scrollerPosition = ScrollerPosition(
- FlingConfig(ExponentialDecay()),
+ val scrollState = ScrollState(
+ initial = 0f,
+ flingConfig = FlingConfig(ExponentialDecay()),
animationClock = clock
)
- createScrollableContent(isVertical = true, scrollerPosition = scrollerPosition)
+ createScrollableContent(isVertical = true, scrollState = scrollState)
runOnIdle {
- assertThat(scrollerPosition.value).isEqualTo(0f)
- assertThat(scrollerPosition.isAnimating).isEqualTo(false)
+ assertThat(scrollState.value).isEqualTo(0f)
+ assertThat(scrollState.isAnimationRunning).isEqualTo(false)
}
onNodeWithTag(scrollerTag)
@@ -504,7 +517,7 @@
runOnIdle {
clock.clockTimeMillis += 100
- assertThat(scrollerPosition.isAnimating).isEqualTo(true)
+ assertThat(scrollState.isAnimationRunning).isEqualTo(true)
}
// TODO (matvei/jelle): this should be down, and not click to be 100% fair
@@ -512,18 +525,18 @@
.performGesture { click() }
runOnIdle {
- assertThat(scrollerPosition.isAnimating).isEqualTo(false)
+ assertThat(scrollState.isAnimationRunning).isEqualTo(false)
}
}
@Test
fun scroller_restoresScrollerPosition() {
val restorationTester = StateRestorationTester(composeTestRule)
- var scrollerPosition: ScrollerPosition? = null
+ var scrollState: ScrollState? = null
restorationTester.setContent {
- scrollerPosition = ScrollerPosition()
- VerticalScroller(scrollerPosition!!) {
+ scrollState = rememberScrollState()
+ ScrollableColumn(scrollState = scrollState!!) {
repeat(50) {
Box(Modifier.preferredHeight(100.dp))
}
@@ -531,20 +544,20 @@
}
runOnIdle {
- scrollerPosition!!.scrollTo(70f)
- scrollerPosition = null
+ scrollState!!.scrollTo(70f)
+ scrollState = null
}
restorationTester.emulateSavedInstanceStateRestore()
runOnIdle {
- assertThat(scrollerPosition!!.value).isEqualTo(70f)
+ assertThat(scrollState!!.value).isEqualTo(70f)
}
}
private fun performWithAnimationWaitAndAssertPosition(
assertValue: Float,
- scrollerPosition: ScrollerPosition,
+ scrollState: ScrollState,
clock: ManualAnimationClock,
uiAction: () -> Unit
) {
@@ -554,9 +567,10 @@
runOnIdle {
clock.clockTimeMillis += 5000
}
- onNodeWithTag(scrollerTag).awaitScrollAnimation(scrollerPosition)
+
+ onNodeWithTag(scrollerTag).awaitScrollAnimation(scrollState)
runOnIdle {
- assertThat(scrollerPosition.value).isEqualTo(assertValue)
+ assertThat(scrollState.value).isEqualTo(assertValue)
}
}
@@ -566,15 +580,16 @@
secondSwipe: GestureScope.() -> Unit
) {
val clock = ManualAnimationClock(0)
- val scrollerPosition = ScrollerPosition(
- FlingConfig(ExponentialDecay()),
+ val scrollState = ScrollState(
+ initial = 0f,
+ flingConfig = FlingConfig(ExponentialDecay()),
animationClock = clock
)
- createScrollableContent(isVertical, scrollerPosition = scrollerPosition)
+ createScrollableContent(isVertical, scrollState = scrollState)
runOnIdle {
- assertThat(scrollerPosition.value).isEqualTo(0f)
+ assertThat(scrollState.value).isEqualTo(0f)
}
onNodeWithTag(scrollerTag)
@@ -585,10 +600,10 @@
}
onNodeWithTag(scrollerTag)
- .awaitScrollAnimation(scrollerPosition)
+ .awaitScrollAnimation(scrollState)
val scrolledValue = runOnIdle {
- scrollerPosition.value
+ scrollState.value
}
assertThat(scrolledValue).isGreaterThan(0f)
@@ -600,18 +615,20 @@
}
onNodeWithTag(scrollerTag)
- .awaitScrollAnimation(scrollerPosition)
+ .awaitScrollAnimation(scrollState)
runOnIdle {
- assertThat(scrollerPosition.value).isLessThan(scrolledValue)
+ assertThat(scrollState.value).isLessThan(scrolledValue)
}
}
private fun composeVerticalScroller(
- scrollerPosition: ScrollerPosition = ScrollerPosition(
- FlingConfig(ExponentialDecay()),
+ scrollState: ScrollState = ScrollState(
+ initial = 0f,
+ flingConfig = FlingConfig(ExponentialDecay()),
animationClock = ManualAnimationClock(0)
),
+ isReversed: Boolean = false,
width: Int = defaultCrossAxisSize,
height: Int = defaultMainAxisSize,
rowHeight: Int = defaultCellSize
@@ -620,8 +637,9 @@
with(composeTestRule.density) {
composeTestRule.setContent {
Stack {
- VerticalScroller(
- scrollerPosition = scrollerPosition,
+ ScrollableColumn(
+ scrollState = scrollState,
+ reverseScrollDirection = isReversed,
modifier = Modifier
.preferredSize(width.toDp(), height.toDp())
.testTag(scrollerTag)
@@ -639,10 +657,12 @@
}
private fun composeHorizontalScroller(
- scrollerPosition: ScrollerPosition = ScrollerPosition(
- FlingConfig(ExponentialDecay()),
+ scrollState: ScrollState = ScrollState(
+ initial = 0f,
+ flingConfig = FlingConfig(ExponentialDecay()),
animationClock = ManualAnimationClock(0)
),
+ isReversed: Boolean = false,
width: Int = defaultMainAxisSize,
height: Int = defaultCrossAxisSize,
columnWidth: Int = defaultCellSize
@@ -651,8 +671,9 @@
with(composeTestRule.density) {
composeTestRule.setContent {
Stack {
- HorizontalScroller(
- scrollerPosition = scrollerPosition,
+ ScrollableRow(
+ reverseScrollDirection = isReversed,
+ scrollState = scrollState,
modifier = Modifier
.preferredSize(width.toDp(), height.toDp())
.testTag(scrollerTag)
@@ -704,8 +725,10 @@
itemCount: Int = 100,
width: Dp = 100.dp,
height: Dp = 100.dp,
- scrollerPosition: ScrollerPosition = ScrollerPosition(
- FlingConfig(ExponentialDecay()),
+ isReversed: Boolean = false,
+ scrollState: ScrollState = ScrollState(
+ initial = 0f,
+ flingConfig = FlingConfig(ExponentialDecay()),
animationClock = ManualAnimationClock(0)
)
) {
@@ -721,18 +744,22 @@
backgroundColor = Color.White
) {
if (isVertical) {
- VerticalScroller(
- scrollerPosition,
- modifier = Modifier.testTag(scrollerTag)
- ) {
- content()
+ Box(Modifier.testTag(scrollerTag)) {
+ ScrollableColumn(
+ scrollState = scrollState,
+ reverseScrollDirection = isReversed
+ ) {
+ content()
+ }
}
} else {
- HorizontalScroller(
- scrollerPosition,
- modifier = Modifier.testTag(scrollerTag)
- ) {
- content()
+ Box(Modifier.testTag(scrollerTag)) {
+ ScrollableRow(
+ scrollState = scrollState,
+ reverseScrollDirection = isReversed
+ ) {
+ content()
+ }
}
}
}
@@ -742,13 +769,13 @@
// TODO(b/147291885): This should not be needed in the future.
private fun SemanticsNodeInteraction.awaitScrollAnimation(
- scroller: ScrollerPosition
+ scroller: ScrollState
): SemanticsNodeInteraction {
val latch = CountDownLatch(1)
val handler = Handler(Looper.getMainLooper())
handler.post(object : Runnable {
override fun run() {
- if (scroller.isAnimating) {
+ if (scroller.isAnimationRunning) {
handler.post(this)
} else {
latch.countDown()
diff --git a/ui/ui-foundation/src/androidMain/kotlin/androidx/ui/foundation/animation/AndroidFlingConfig.kt b/ui/ui-foundation/src/androidMain/kotlin/androidx/ui/foundation/animation/AndroidFlingConfig.kt
index c408bce..3cfb50c 100644
--- a/ui/ui-foundation/src/androidMain/kotlin/androidx/ui/foundation/animation/AndroidFlingConfig.kt
+++ b/ui/ui-foundation/src/androidMain/kotlin/androidx/ui/foundation/animation/AndroidFlingConfig.kt
@@ -26,8 +26,8 @@
// This function will internally update the calculation of fling decay when the density changes,
// but the reference to the returned FlingConfig will not change across calls.
val density = DensityAmbient.current
- val decayAnimation = remember(density.density) { AndroidFlingDecaySpec(density) }
- return remember(decayAnimation) {
+ return remember(density.density) {
+ val decayAnimation = AndroidFlingDecaySpec(density)
FlingConfig(
decayAnimation = decayAnimation,
adjustTarget = adjustTarget
diff --git a/ui/ui-foundation/src/commonMain/kotlin/androidx/ui/foundation/Scroll.kt b/ui/ui-foundation/src/commonMain/kotlin/androidx/ui/foundation/Scroll.kt
new file mode 100644
index 0000000..386f4d51
--- /dev/null
+++ b/ui/ui-foundation/src/commonMain/kotlin/androidx/ui/foundation/Scroll.kt
@@ -0,0 +1,621 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * 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.
+ */
+@file:Suppress("DEPRECATION")
+
+package androidx.ui.foundation
+
+import androidx.animation.AnimationClockObservable
+import androidx.animation.AnimationEndReason
+import androidx.animation.AnimationSpec
+import androidx.animation.SpringSpec
+import androidx.compose.Composable
+import androidx.compose.Stable
+import androidx.compose.getValue
+import androidx.compose.mutableStateOf
+import androidx.compose.remember
+import androidx.compose.setValue
+import androidx.compose.structuralEqualityPolicy
+import androidx.ui.animation.asDisposableClock
+import androidx.ui.core.Alignment
+import androidx.ui.core.AnimationClockAmbient
+import androidx.ui.core.Constraints
+import androidx.ui.core.LayoutDirection
+import androidx.ui.core.LayoutModifier
+import androidx.ui.core.Measurable
+import androidx.ui.core.MeasureScope
+import androidx.ui.core.Modifier
+import androidx.ui.core.clipToBounds
+import androidx.ui.core.composed
+import androidx.ui.core.gesture.scrollorientationlocking.Orientation
+import androidx.ui.core.semantics.semantics
+import androidx.ui.foundation.animation.FlingConfig
+import androidx.ui.foundation.animation.defaultFlingConfig
+import androidx.ui.foundation.gestures.ScrollableController
+import androidx.ui.foundation.gestures.scrollable
+import androidx.ui.layout.Arrangement
+import androidx.ui.layout.Column
+import androidx.ui.layout.ColumnScope
+import androidx.ui.layout.Constraints
+import androidx.ui.layout.InnerPadding
+import androidx.ui.layout.Row
+import androidx.ui.layout.RowScope
+import androidx.ui.layout.padding
+import androidx.ui.savedinstancestate.Saver
+import androidx.ui.savedinstancestate.rememberSavedInstanceState
+import androidx.ui.semantics.scrollBy
+import androidx.ui.unit.dp
+import kotlin.math.roundToInt
+
+/**
+ * Create and [remember] the [ScrollState] based on the currently appropriate scroll
+ * configuration to allow changing scroll position or observing scroll behavior.
+ *
+ * Learn how to control [ScrollableColumn] or [ScrollableRow]:
+ * @sample androidx.ui.foundation.samples.ControlledScrollableRowSample
+ *
+ * @param initial initial scroller position to start with
+ */
+@Composable
+fun rememberScrollState(initial: Float = 0f): ScrollState {
+ val clock = AnimationClockAmbient.current.asDisposableClock()
+ val config = defaultFlingConfig()
+ return rememberSavedInstanceState(
+ clock, config,
+ saver = ScrollState.Saver(config, clock)
+ ) {
+ ScrollState(
+ flingConfig = config,
+ initial = initial,
+ animationClock = clock
+ )
+ }
+}
+
+/**
+ * State of the scroll. Allows the developer to change the scroll position or get current state by
+ * calling methods on this object. To be hosted and passed to [ScrollableRow], [ScrollableColumn],
+ * [Modifier.verticalScroll] or [Modifier.horizontalScroll]
+ *
+ * To create and automatically remember [ScrollState] with default parameters use
+ * [rememberScrollState].
+ *
+ * Learn how to control [ScrollableColumn] or [ScrollableRow]:
+ * @sample androidx.ui.foundation.samples.ControlledScrollableRowSample
+ *
+ * @param initial value of the scroll
+ * @param flingConfig fling configuration to use for flinging
+ * @param animationClock animation clock to run flinging and smooth scrolling on
+ */
+@Stable
+class ScrollState(
+ initial: Float,
+ internal val flingConfig: FlingConfig,
+ animationClock: AnimationClockObservable
+) {
+
+ /**
+ * current scroll position value in pixels
+ */
+ var value by mutableStateOf(initial, structuralEqualityPolicy())
+ private set
+
+ /**
+ * maximum bound for [value], or [Float.POSITIVE_INFINITY] if still unknown
+ */
+ var maxValue: Float
+ get() = _maxValueState.value
+ internal set(newMax) {
+ _maxValueState.value = newMax
+ if (value > newMax) {
+ value = newMax
+ }
+ }
+
+ private var _maxValueState = mutableStateOf(Float.POSITIVE_INFINITY, structuralEqualityPolicy())
+
+ internal val scrollableController =
+ ScrollableController(
+ flingConfig = flingConfig,
+ animationClock = animationClock,
+ consumeScrollDelta = {
+ val absolute = (value + it)
+ val newValue = absolute.coerceIn(0f, maxValue)
+ if (absolute != newValue) stopAnimation()
+ val consumed = newValue - value
+ value += consumed
+ consumed
+ })
+
+ /**
+ * Stop any ongoing animation, smooth scrolling or fling occurring on this [ScrollState]
+ */
+ fun stopAnimation() {
+ scrollableController.stopAnimation()
+ }
+
+ /**
+ * whether this [ScrollState] is currently animating/flinging
+ */
+ val isAnimationRunning
+ get() = scrollableController.isAnimationRunning
+
+ /**
+ * Smooth scroll to position in pixels
+ *
+ * @param value target value in pixels to smooth scroll to, value will be coerced to
+ * 0..maxPosition
+ * @param spec animation curve for smooth scroll animation
+ * @param onEnd callback to be invoked when smooth scroll has finished
+ */
+ fun smoothScrollTo(
+ value: Float,
+ spec: AnimationSpec<Float> = SpringSpec(),
+ onEnd: (endReason: AnimationEndReason, finishValue: Float) -> Unit = { _, _ -> }
+ ) {
+ smoothScrollBy(value - this.value, spec, onEnd)
+ }
+
+ /**
+ * Smooth scroll by some amount of pixels
+ *
+ * @param value delta in pixels to scroll by, total value will be coerced to 0..maxPosition
+ * @param spec animation curve for smooth scroll animation
+ * @param onEnd callback to be invoked when smooth scroll has finished
+ */
+ fun smoothScrollBy(
+ value: Float,
+ spec: AnimationSpec<Float> = SpringSpec(),
+ onEnd: (endReason: AnimationEndReason, finishValue: Float) -> Unit = { _, _ -> }
+ ) {
+ scrollableController.smoothScrollBy(value, spec, onEnd)
+ }
+
+ /**
+ * Instantly jump to position in pixels
+ *
+ * @param value target value in pixels to jump to, value will be coerced to 0..maxPosition
+ */
+ fun scrollTo(value: Float) {
+ this.value = value.coerceIn(0f, maxValue)
+ }
+
+ /**
+ * Instantly jump by some amount of pixels
+ *
+ * @param value delta in pixels to jump by, total value will be coerced to 0..maxPosition
+ */
+ fun scrollBy(value: Float) {
+ scrollTo(this.value + value)
+ }
+
+ companion object {
+ /**
+ * The default [Saver] implementation for [ScrollState].
+ */
+ fun Saver(
+ flingConfig: FlingConfig,
+ animationClock: AnimationClockObservable
+ ): Saver<ScrollState, *> = Saver<ScrollState, Float>(
+ save = { it.value },
+ restore = { ScrollState(it, flingConfig, animationClock) }
+ )
+ }
+}
+
+/**
+ * Variation of [Column] that scrolls when content is bigger than its height.
+ *
+ * The content of the [ScrollableColumn] is clipped to its bounds.
+ *
+ * @sample androidx.ui.foundation.samples.ScrollableColumnSample
+ *
+ * @param modifier modifier for this [ScrollableColumn]
+ * @param scrollState state of the scroll, such as current offset and max offset
+ * @param verticalArrangement The vertical arrangement of the layout's children
+ * @param horizontalGravity The horizontal gravity of the layout's children
+ * @param reverseScrollDirection reverse the direction of scrolling, when `true`, [ScrollState
+ * .value] = 0 will mean bottom, when `false`, [ScrollState.value] = 0 will mean top
+ * @param isScrollEnabled param to enable or disable touch input scrolling. If you own
+ * [ScrollState], you still can call [ScrollState.smoothScrollTo] and other methods on it.
+ * @param contentPadding convenience param to specify padding around content. This will add
+ * padding for the content after it has been clipped, which is not possible via [modifier] param
+ */
+@Composable
+fun ScrollableColumn(
+ modifier: Modifier = Modifier,
+ scrollState: ScrollState = rememberScrollState(0f),
+ verticalArrangement: Arrangement.Vertical = Arrangement.Top,
+ horizontalGravity: Alignment.Horizontal = Alignment.Start,
+ reverseScrollDirection: Boolean = false,
+ isScrollEnabled: Boolean = true,
+ contentPadding: InnerPadding = InnerPadding(0.dp),
+ children: @Composable ColumnScope.() -> Unit
+) {
+ Column(
+ modifier = modifier
+ .verticalScroll(
+ scrollState,
+ isScrollEnabled,
+ reverseScrolling = reverseScrollDirection
+ )
+ .clipToBounds()
+ .padding(contentPadding),
+ verticalArrangement = verticalArrangement,
+ horizontalGravity = horizontalGravity,
+ children = children
+ )
+}
+
+/**
+ * Variation of [Row] that scrolls when content is bigger than its width.
+ *
+ * The content of the [ScrollableRow] is clipped to its bounds.
+ *
+ * @sample androidx.ui.foundation.samples.ScrollableRowSample
+ *
+ * @param modifier modifier for this [ScrollableRow]
+ * @param scrollState state of the scroll, such as current offset and max offset
+ * @param horizontalArrangement The horizontal arrangement of the layout's children
+ * @param verticalGravity The vertical gravity of the layout's children
+ * @param reverseScrollDirection reverse the direction of scrolling, when `true`, [ScrollState
+ * .value] = 0 will mean right, when `false`, [ScrollState.value] = 0 will mean left
+ * @param isScrollEnabled param to enable or disable touch input scrolling. If you own
+ * [ScrollState], you still can call [ScrollState.smoothScrollTo] and other methods on it.
+ * @param contentPadding convenience param to specify padding around content. This will add
+ * padding for the content after it has been clipped, which is not possible via [modifier] param.
+ */
+@Composable
+fun ScrollableRow(
+ modifier: Modifier = Modifier,
+ scrollState: ScrollState = rememberScrollState(0f),
+ horizontalArrangement: Arrangement.Horizontal = Arrangement.Start,
+ verticalGravity: Alignment.Vertical = Alignment.Top,
+ reverseScrollDirection: Boolean = false,
+ isScrollEnabled: Boolean = true,
+ contentPadding: InnerPadding = InnerPadding(0.dp),
+ children: @Composable RowScope.() -> Unit
+) {
+ Row(
+ modifier = modifier
+ .horizontalScroll(
+ scrollState,
+ isScrollEnabled,
+ reverseScrolling = reverseScrollDirection
+ )
+ .clipToBounds()
+ .padding(contentPadding),
+ horizontalArrangement = horizontalArrangement,
+ verticalGravity = verticalGravity,
+ children = children
+ )
+}
+
+/**
+ * Modify element to allow to scroll vertically when height of the content is bigger than max
+ * constraints allow.
+ *
+ * @sample androidx.ui.foundation.samples.VerticalScrollExample
+ *
+ * In order to use this modifier, you need to create and own [ScrollState]
+ * @see [rememberScrollState]
+ *
+ * @param state state of the scroll
+ * @param enabled whether or not scrolling via touch input is enabled
+ * @param reverseScrolling reverse the direction of scrolling, when `true`, 0 [ScrollState.value]
+ * will mean bottom, when `false`, 0 [ScrollState.value] will mean top
+ */
+fun Modifier.verticalScroll(
+ state: ScrollState,
+ enabled: Boolean = true,
+ reverseScrolling: Boolean = false
+) = scroll(
+ state = state,
+ isScrollable = enabled,
+ reverseScrolling = reverseScrolling,
+ isVertical = true
+)
+
+/**
+ * Modify element to allow to scroll horizontally when width of the content is bigger than max
+ * constraints allow.
+ *
+ * @sample androidx.ui.foundation.samples.HorizontalScrollSample
+ *
+ * In order to use this modifier, you need to create and own [ScrollState]
+ * @see [rememberScrollState]
+ *
+ * @param state state of the scroll
+ * @param enabled whether or not scrolling via touch input is enabled
+ * @param reverseScrolling reverse the direction of scrolling, when `true`, 0 [ScrollState.value]
+ * will mean right, when `false`, 0 [ScrollState.value] will mean left
+ */
+fun Modifier.horizontalScroll(
+ state: ScrollState,
+ enabled: Boolean = true,
+ reverseScrolling: Boolean = false
+) = scroll(
+ state = state,
+ isScrollable = enabled,
+ reverseScrolling = reverseScrolling,
+ isVertical = false
+)
+
+private fun Modifier.scroll(
+ state: ScrollState,
+ reverseScrolling: Boolean,
+ isScrollable: Boolean,
+ isVertical: Boolean
+) = composed {
+ val semantics = Modifier.semantics {
+ if (isScrollable) {
+ // when b/156389287 is fixed, this should be proper scrollTo with reverse handling
+ scrollBy(action = { x: Float, y: Float ->
+ if (isVertical) {
+ state.scrollBy(y)
+ } else {
+ state.scrollBy(x)
+ }
+ return@scrollBy true
+ })
+ }
+ }
+ val scrolling = Modifier.scrollable(
+ orientation = if (isVertical) Orientation.Vertical else Orientation.Horizontal,
+ reverseDirection = !reverseScrolling,
+ enabled = isScrollable,
+ controller = state.scrollableController
+ )
+ val layout = ScrollingLayoutModifier(state, reverseScrolling, isVertical)
+ semantics.plus(scrolling).clipToBounds().plus(layout)
+}
+
+private data class ScrollingLayoutModifier(
+ val scrollerState: ScrollState,
+ val isReversed: Boolean,
+ val isVertical: Boolean
+) : LayoutModifier {
+ override fun MeasureScope.measure(
+ measurable: Measurable,
+ constraints: Constraints,
+ layoutDirection: LayoutDirection
+ ): MeasureScope.MeasureResult {
+ val childConstraints = constraints.copy(
+ maxHeight = if (isVertical) Constraints.Infinity else constraints.maxHeight,
+ maxWidth = if (isVertical) constraints.maxWidth else Constraints.Infinity
+ )
+ val placeable = measurable.measure(childConstraints)
+ val width = placeable.width.coerceAtMost(constraints.maxWidth)
+ val height = placeable.height.coerceAtMost(constraints.maxHeight)
+ val scrollHeight = placeable.height.toFloat() - height.toFloat()
+ val scrollWidth = placeable.width.toFloat() - width.toFloat()
+ val side = if (isVertical) scrollHeight else scrollWidth
+ return layout(width, height) {
+ scrollerState.maxValue = side
+ val scroll = scrollerState.value.coerceIn(0f, side)
+ val absScroll = if (isReversed) scroll - side else -scroll
+ val xOffset = if (isVertical) 0 else absScroll.roundToInt()
+ val yOffset = if (isVertical) absScroll.roundToInt() else 0
+ placeable.place(xOffset, yOffset)
+ }
+ }
+}
+
+/**
+ * Create and [remember] the state for a [VerticalScroller] or [HorizontalScroller] based on the
+ * currently appropriate scroll configuration to allow changing scroll position or observing
+ * scroll behavior.
+ *
+ * @param initial initial scroller position to start with
+ * @param isReversed whether position will be reversed, e.g. 0 will mean bottom for
+ * [VerticalScroller] and end for [HorizontalScroller]
+ */
+@Deprecated(
+ "Use rememberScrollState instead", replaceWith = ReplaceWith(
+ "rememberScrollState(initial = initial",
+ "androidx.ui.foundation.rememberScrollState"
+ )
+)
+@Composable
+fun ScrollerPosition(
+ initial: Float = 0f,
+ isReversed: Boolean = false
+): ScrollerPosition {
+ val clock = AnimationClockAmbient.current.asDisposableClock()
+ val config = defaultFlingConfig()
+ return rememberSavedInstanceState(
+ clock, config,
+ saver = ScrollerPosition.Saver(config, isReversed, clock)
+ ) {
+ ScrollerPosition(
+ flingConfig = config,
+ initial = initial,
+ animationClock = clock,
+ isReversed = isReversed
+ )
+ }
+}
+
+/**
+ * This is the state of a [VerticalScroller] and [HorizontalScroller] that
+ * allows the developer to change the scroll position by calling methods on this object.
+ *
+ * @param flingConfig configuration that specifies fling logic when scrolling ends with velocity
+ * @param initial initial scroller position in pixels to start with
+ * @param isReversed whether position will be reversed, e.g. 0 will mean bottom for
+ * [VerticalScroller] and end for [HorizontalScroller]
+ * @param animationClock clock observable to run animation on. Consider querying
+ * [AnimationClockAmbient] to get current composition value
+ */
+@Stable
+@Deprecated(
+ "Use ScrollState instead", replaceWith = ReplaceWith(
+ "ScrollState(" +
+ "initial = initial," +
+ " flingConfig = flingConfig, " +
+ "animationClock = animationClock)", "androidx.ui.foundation.ScrollState"
+ )
+)
+class ScrollerPosition(
+ /** Configuration that specifies fling logic when scrolling ends with velocity. */
+ internal val flingConfig: FlingConfig,
+ initial: Float = 0f,
+ internal val isReversed: Boolean = false,
+ internal val animationClock: AnimationClockObservable
+) {
+
+ private fun directionalValue(value: Float) = if (isReversed) value else -value
+
+ internal val state = ScrollState(initial, flingConfig, animationClock)
+
+ /**
+ * current scroller position value in pixels
+ */
+ var value: Float
+ get() = state.value
+ set(value) {
+ state.scrollTo(value)
+ }
+
+ /**
+ * maxPosition this scroller that consume this ScrollerPosition can reach in pixels, or
+ * [Float.POSITIVE_INFINITY] if still unknown
+ */
+ var maxPosition: Float
+ get() = state.maxValue
+ set(newMax) {
+ state.maxValue = newMax
+ }
+
+ /**
+ * Smooth scroll to position in pixels
+ *
+ * @param value target value in pixels to smooth scroll to, value will be coerced to
+ * 0..maxPosition
+ */
+ // TODO (malkov/tianliu) : think about allowing to scroll with custom animation timings/curves
+ fun smoothScrollTo(
+ value: Float,
+ onEnd: (endReason: AnimationEndReason, finishValue: Float) -> Unit = { _, _ -> }
+ ) {
+ smoothScrollBy(value - this.value, onEnd)
+ }
+
+ /**
+ * Smooth scroll by some amount of pixels
+ *
+ * @param value delta in pixels to scroll by, total value will be coerced to 0..maxPosition
+ */
+ fun smoothScrollBy(
+ value: Float,
+ onEnd: (endReason: AnimationEndReason, finishValue: Float) -> Unit = { _, _ -> }
+ ) {
+ state.smoothScrollBy(
+ value = directionalValue(value),
+ >
+ )
+ }
+
+ /**
+ * Instantly jump to position in pixels
+ *
+ * @param value target value in pixels to jump to, value will be coerced to 0..maxPosition
+ */
+ fun scrollTo(value: Float) {
+ this.value = value.coerceIn(0f, maxPosition)
+ }
+
+ /**
+ * Instantly jump by some amount of pixels
+ *
+ * @param value delta in pixels to jump by, total value will be coerced to 0..maxPosition
+ */
+ fun scrollBy(value: Float) {
+ scrollTo(this.value + value)
+ }
+
+ companion object {
+ /**
+ * The default [Saver] implementation for [ScrollerPosition].
+ */
+ @Composable
+ fun Saver(
+ flingConfig: FlingConfig,
+ isReversed: Boolean,
+ animationClock: AnimationClockObservable
+ ): Saver<ScrollerPosition, *> = Saver<ScrollerPosition, Float>(
+ save = { it.value },
+ restore = { ScrollerPosition(flingConfig, it, isReversed, animationClock) }
+ )
+ }
+}
+
+@Deprecated(
+ "Use ScrollableColumn instead", replaceWith = ReplaceWith(
+ "ScrollableColumn(modifier = modifier, children = children)",
+ "androidx.ui.foundation.ScrollableColumn"
+ )
+)
+@Composable
+fun VerticalScroller(
+ scrollerPosition: ScrollerPosition = ScrollerPosition(),
+ modifier: Modifier = Modifier,
+ isScrollable: Boolean = true,
+ children: @Composable ColumnScope.() -> Unit
+) {
+ Column(
+ modifier = modifier
+ .verticalScroll(scrollerPosition.state, isScrollable)
+ .clipToBounds(),
+ children = children
+ )
+}
+
+/**
+ * A container that composes all of its contents and lays it out, fitting the height of the child.
+ * If the child's width is less than the [Constraints.maxWidth], the child's width is used,
+ * or the [Constraints.maxWidth] otherwise. If the contents don't fit the width, the drag gesture
+ * allows scrolling its content horizontally. The contents of the HorizontalScroller are clipped to
+ * the HorizontalScroller's bounds.
+ *
+ * If you want to control scrolling position from the code, e.g smooth scroll to position,
+ * you must own memorized instance of [ScrollerPosition] and then use it to call `scrollTo...`
+ * functions on it. Same tactic can be applied to the [VerticalScroller]
+ *
+ * @param scrollerPosition state of this Scroller that holds current scroll position and provides
+ * user with useful methods like smooth scrolling
+ * @param modifier Modifier to be applied to the Scroller content layout
+ * @param isScrollable param to enabled or disable touch input scrolling, default is true
+ */
+@Deprecated(
+ "Use ScrollableRow instead", replaceWith = ReplaceWith(
+ "ScrollableRow(modifier = modifier, children = children)",
+ "androidx.ui.foundation.ScrollableRow"
+ )
+)
+@Composable
+fun HorizontalScroller(
+ scrollerPosition: ScrollerPosition = ScrollerPosition(),
+ modifier: Modifier = Modifier,
+ isScrollable: Boolean = true,
+ children: @Composable RowScope.() -> Unit
+) {
+ Row(
+ modifier = modifier
+ .horizontalScroll(scrollerPosition.state, isScrollable)
+ .clipToBounds(),
+ children = children
+ )
+}
\ No newline at end of file
diff --git a/ui/ui-foundation/src/commonMain/kotlin/androidx/ui/foundation/Scroller.kt b/ui/ui-foundation/src/commonMain/kotlin/androidx/ui/foundation/Scroller.kt
deleted file mode 100644
index 8b1bab8..0000000
--- a/ui/ui-foundation/src/commonMain/kotlin/androidx/ui/foundation/Scroller.kt
+++ /dev/null
@@ -1,348 +0,0 @@
-/*
- * Copyright 2019 The Android Open Source Project
- *
- * 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 androidx.ui.foundation
-
-import androidx.animation.AnimationClockObservable
-import androidx.animation.AnimationEndReason
-import androidx.compose.Composable
-import androidx.compose.ExperimentalComposeApi
-import androidx.compose.Stable
-import androidx.compose.getValue
-import androidx.compose.mutableStateOf
-import androidx.compose.remember
-import androidx.compose.setValue
-import androidx.compose.structuralEqualityPolicy
-import androidx.ui.animation.asDisposableClock
-import androidx.ui.core.AnimationClockAmbient
-import androidx.ui.core.Constraints
-import androidx.ui.core.Layout
-import androidx.ui.core.Modifier
-import androidx.ui.core.clipToBounds
-import androidx.ui.core.gesture.scrollorientationlocking.Orientation
-import androidx.ui.core.semantics.semantics
-import androidx.ui.foundation.animation.FlingConfig
-import androidx.ui.foundation.animation.defaultFlingConfig
-import androidx.ui.foundation.gestures.ScrollableController
-import androidx.ui.foundation.gestures.scrollable
-import androidx.ui.layout.Column
-import androidx.ui.layout.ColumnScope
-import androidx.ui.layout.Constraints
-import androidx.ui.layout.Row
-import androidx.ui.layout.RowScope
-import androidx.ui.savedinstancestate.Saver
-import androidx.ui.savedinstancestate.rememberSavedInstanceState
-import androidx.ui.semantics.scrollBy
-import kotlin.math.roundToInt
-
-/**
- * Create and [remember] the state for a [VerticalScroller] or [HorizontalScroller] based on the
- * currently appropriate scroll configuration to allow changing scroll position or observing
- * scroll behavior.
- *
- * @param initial initial scroller position to start with
- * @param isReversed whether position will be reversed, e.g. 0 will mean bottom for
- * [VerticalScroller] and end for [HorizontalScroller]
- */
-@Composable
-fun ScrollerPosition(
- initial: Float = 0f,
- isReversed: Boolean = false
-): ScrollerPosition {
- val clock = AnimationClockAmbient.current.asDisposableClock()
- val config = defaultFlingConfig()
- return rememberSavedInstanceState(
- clock, config,
- saver = ScrollerPosition.Saver(config, isReversed, clock)
- ) {
- ScrollerPosition(
- flingConfig = config,
- initial = initial,
- animationClock = clock,
- isReversed = isReversed
- )
- }
-}
-
-/**
- * This is the state of a [VerticalScroller] and [HorizontalScroller] that
- * allows the developer to change the scroll position by calling methods on this object.
- *
- * @param flingConfig configuration that specifies fling logic when scrolling ends with velocity
- * @param initial initial scroller position in pixels to start with
- * @param isReversed whether position will be reversed, e.g. 0 will mean bottom for
- * [VerticalScroller] and end for [HorizontalScroller]
- * @param animationClock clock observable to run animation on. Consider querying
- * [AnimationClockAmbient] to get current composition value
- */
-@Stable
-class ScrollerPosition(
- /** Configuration that specifies fling logic when scrolling ends with velocity. */
- flingConfig: FlingConfig,
- initial: Float = 0f,
- internal val isReversed: Boolean = false,
- animationClock: AnimationClockObservable
-) {
-
- private fun directionalValue(value: Float) = if (isReversed) value else -value
-
- private val consumeDelta: (Float) -> Float = {
- val reverseDelta = directionalValue(it)
- val newValue = value + reverseDelta
- val max = maxPosition
- val min = 0f
- val consumed = when {
- newValue > max -> max - value
- newValue < min -> min - value
- else -> reverseDelta
- }
- value += consumed
- directionalValue(consumed)
- }
-
- internal val scrollableController =
- ScrollableController(consumeDelta, flingConfig, animationClock)
-
- /**
- * current scroller position value in pixels
- */
- var value by mutableStateOf(
- initial,
- @OptIn(ExperimentalComposeApi::class) structuralEqualityPolicy()
- )
- private set
-
- /**
- * whether this [ScrollerPosition] is currently animating/flinging
- */
- val isAnimating
- get() = scrollableController.isAnimationRunning
-
- /**
- * maxPosition this scroller that consume this ScrollerPosition can reach in pixels, or
- * [Float.POSITIVE_INFINITY] if still unknown
- */
- var maxPosition by mutableStateOf(
- Float.POSITIVE_INFINITY,
- @OptIn(ExperimentalComposeApi::class) structuralEqualityPolicy()
- )
- private set
-
- /**
- * Smooth scroll to position in pixels
- *
- * @param value target value in pixels to smooth scroll to, value will be coerced to
- * 0..maxPosition
- */
- // TODO (malkov/tianliu) : think about allowing to scroll with custom animation timings/curves
- fun smoothScrollTo(
- value: Float,
- onEnd: (endReason: AnimationEndReason, finishValue: Float) -> Unit = { _, _ -> }
- ) {
- smoothScrollBy(value - this.value, onEnd)
- }
-
- /**
- * Smooth scroll by some amount of pixels
- *
- * @param value delta in pixels to scroll by, total value will be coerced to 0..maxPosition
- */
- fun smoothScrollBy(
- value: Float,
- onEnd: (endReason: AnimationEndReason, finishValue: Float) -> Unit = { _, _ -> }
- ) {
- scrollableController.smoothScrollBy(
- value = directionalValue(value),
- >
- )
- }
-
- /**
- * Instantly jump to position in pixels
- *
- * @param value target value in pixels to jump to, value will be coerced to 0..maxPosition
- */
- fun scrollTo(value: Float) {
- this.value = value.coerceIn(0f, maxPosition)
- }
-
- /**
- * Instantly jump by some amount of pixels
- *
- * @param value delta in pixels to jump by, total value will be coerced to 0..maxPosition
- */
- fun scrollBy(value: Float) {
- scrollTo(this.value + value)
- }
-
- internal fun updateMaxPosition(newMax: Float) {
- maxPosition = newMax
- if (value > newMax) {
- value = newMax
- }
- }
-
- companion object {
- /**
- * The default [Saver] implementation for [ScrollerPosition].
- */
- @Composable
- fun Saver(
- flingConfig: FlingConfig,
- isReversed: Boolean,
- animationClock: AnimationClockObservable
- ): Saver<ScrollerPosition, *> = Saver<ScrollerPosition, Float>(
- save = { it.value },
- restore = { ScrollerPosition(flingConfig, it, isReversed, animationClock) }
- )
- }
-}
-
-// TODO(malkov): Test behavior during animation more extensively (including pressing on the scroller
-// during an animation when b/144878730 is fixed.
-/**
- * A container that composes all of its contents and lays it out, fitting the width of the child.
- * If the child's height is less than the [Constraints.maxHeight], the child's height is used,
- * or the [Constraints.maxHeight] otherwise. If the contents don't fit the height, the drag gesture
- * allows scrolling its content vertically. The contents of the VerticalScroller are clipped to
- * the VerticalScroller's bounds.
- *
- * @sample androidx.ui.foundation.samples.VerticalScrollerSample
- *
- * @param scrollerPosition state of this Scroller that holds current scroll position and provides
- * user with useful methods like smooth scrolling
- * @param modifier Modifier to be applied to the Scroller content layout
- * @param isScrollable param to enabled or disable touch input scrolling, default is true
- */
-@Composable
-fun VerticalScroller(
- scrollerPosition: ScrollerPosition = ScrollerPosition(),
- modifier: Modifier = Modifier,
- isScrollable: Boolean = true,
- children: @Composable ColumnScope.() -> Unit
-) {
- Scroller(scrollerPosition, modifier, true, isScrollable) {
- Column(
- modifier = Modifier.clipToBounds(),
- children = children
- )
- }
-}
-
-/**
- * A container that composes all of its contents and lays it out, fitting the height of the child.
- * If the child's width is less than the [Constraints.maxWidth], the child's width is used,
- * or the [Constraints.maxWidth] otherwise. If the contents don't fit the width, the drag gesture
- * allows scrolling its content horizontally. The contents of the HorizontalScroller are clipped to
- * the HorizontalScroller's bounds.
- *
- * @sample androidx.ui.foundation.samples.SimpleHorizontalScrollerSample
- *
- * If you want to control scrolling position from the code, e.g smooth scroll to position,
- * you must own memorized instance of [ScrollerPosition] and then use it to call `scrollTo...`
- * functions on it. Same tactic can be applied to the [VerticalScroller]
- *
- * @sample androidx.ui.foundation.samples.ControlledHorizontalScrollerSample
- *
- * @param scrollerPosition state of this Scroller that holds current scroll position and provides
- * user with useful methods like smooth scrolling
- * @param modifier Modifier to be applied to the Scroller content layout
- * @param isScrollable param to enabled or disable touch input scrolling, default is true
- */
-@Composable
-fun HorizontalScroller(
- scrollerPosition: ScrollerPosition = ScrollerPosition(),
- modifier: Modifier = Modifier,
- isScrollable: Boolean = true,
- children: @Composable RowScope.() -> Unit
-) {
- Scroller(scrollerPosition, modifier, false, isScrollable) {
- Row(
- modifier = Modifier.clipToBounds(),
- children = children
- )
- }
-}
-
-@Composable
-private fun Scroller(
- scrollerPosition: ScrollerPosition,
- modifier: Modifier,
- isVertical: Boolean,
- isScrollable: Boolean,
- child: @Composable () -> Unit
-) {
- ScrollerLayout(
- scrollerPosition = scrollerPosition,
- modifier = modifier
- .semantics {
- if (isScrollable) {
- // when b/156389287 is fixed, this should be proper scrollTo with reverse handling
- scrollBy(action = { x, y ->
- if (isVertical) {
- scrollerPosition.scrollBy(y)
- } else {
- scrollerPosition.scrollBy(x)
- }
- return@scrollBy true
- })
- }
- }
- .scrollable(
- orientation = if (isVertical) Orientation.Vertical else Orientation.Horizontal,
- reverseDirection = scrollerPosition.isReversed,
- enabled = isScrollable,
- controller = scrollerPosition.scrollableController
- ),
- isVertical = isVertical,
- child = child
- )
-}
-
-@Composable
-private fun ScrollerLayout(
- scrollerPosition: ScrollerPosition,
- modifier: Modifier,
- isVertical: Boolean,
- child: @Composable () -> Unit
-) {
- Layout(
- modifier = modifier.clipToBounds(),
- children = child,
- measureBlock = { measurables, constraints ->
- val childConstraints = constraints.copy(
- maxHeight = if (isVertical) Constraints.Infinity else constraints.maxHeight,
- maxWidth = if (isVertical) constraints.maxWidth else Constraints.Infinity
- )
- require(measurables.size == 1)
- val placeable = measurables.first().measure(childConstraints)
- val width = placeable.width.coerceAtMost(constraints.maxWidth)
- val height = placeable.height.coerceAtMost(constraints.maxHeight)
- val scrollHeight = placeable.height.toFloat() - height.toFloat()
- val scrollWidth = placeable.width.toFloat() - width.toFloat()
- val side = if (isVertical) scrollHeight else scrollWidth
- layout(width, height) {
- scrollerPosition.updateMaxPosition(side)
- val scroll = scrollerPosition.value.coerceIn(0f, side)
- val absScroll =
- if (scrollerPosition.isReversed) scroll - side else -scroll
- val xOffset = if (isVertical) 0 else absScroll.roundToInt()
- val yOffset = if (isVertical) absScroll.roundToInt() else 0
- placeable.place(xOffset, yOffset)
- }
- }
- )
-}
diff --git a/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/ButtonDemo.kt b/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/ButtonDemo.kt
index 9c7df68..8ac78af 100644
--- a/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/ButtonDemo.kt
+++ b/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/ButtonDemo.kt
@@ -19,16 +19,15 @@
import androidx.compose.Composable
import androidx.ui.core.Modifier
import androidx.ui.foundation.Border
+import androidx.ui.foundation.ScrollableColumn
import androidx.ui.foundation.Text
-import androidx.ui.foundation.VerticalScroller
import androidx.ui.foundation.shape.GenericShape
import androidx.ui.graphics.Color
import androidx.ui.layout.Arrangement
-import androidx.ui.layout.Column
+import androidx.ui.layout.InnerPadding
import androidx.ui.layout.Row
import androidx.ui.layout.Spacer
import androidx.ui.layout.fillMaxWidth
-import androidx.ui.layout.padding
import androidx.ui.layout.preferredHeight
import androidx.ui.layout.preferredSize
import androidx.ui.material.Button
@@ -51,16 +50,14 @@
@Composable
fun ButtonDemo() {
- VerticalScroller {
- Column(Modifier.padding(10.dp)) {
- Buttons()
- Spacer(Modifier.preferredHeight(DefaultSpace))
- Fabs()
- Spacer(Modifier.preferredHeight(DefaultSpace))
- IconButtons()
- Spacer(Modifier.preferredHeight(DefaultSpace))
- CustomShapeButton()
- }
+ ScrollableColumn(contentPadding = InnerPadding(10.dp)) {
+ Buttons()
+ Spacer(Modifier.preferredHeight(DefaultSpace))
+ Fabs()
+ Spacer(Modifier.preferredHeight(DefaultSpace))
+ IconButtons()
+ Spacer(Modifier.preferredHeight(DefaultSpace))
+ CustomShapeButton()
}
}
diff --git a/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/DynamicThemeActivity.kt b/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/DynamicThemeActivity.kt
index 7cb0d86..f3e5f2c 100644
--- a/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/DynamicThemeActivity.kt
+++ b/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/DynamicThemeActivity.kt
@@ -27,9 +27,9 @@
import androidx.ui.core.setContent
import androidx.ui.foundation.Box
import androidx.ui.foundation.ContentGravity
-import androidx.ui.foundation.ScrollerPosition
+import androidx.ui.foundation.ScrollableColumn
import androidx.ui.foundation.Text
-import androidx.ui.foundation.VerticalScroller
+import androidx.ui.foundation.rememberScrollState
import androidx.ui.foundation.shape.corner.CircleShape
import androidx.ui.foundation.shape.corner.RoundedCornerShape
import androidx.ui.graphics.Color
@@ -85,9 +85,9 @@
@Composable
private fun DynamicThemeApp(scrollFraction: ScrollFraction, palette: ColorPalette) {
MaterialTheme(palette) {
- val scrollerPosition = ScrollerPosition()
+ val scrollState = rememberScrollState()
val fraction =
- round((scrollerPosition.value / scrollerPosition.maxPosition) * 100) / 100
+ round((scrollState.value / scrollState.maxValue) * 100) / 100
remember(fraction) { scrollFraction.value = fraction }
Scaffold(
topBar = { TopAppBar({ Text("Scroll down!") }) },
@@ -96,13 +96,13 @@
floatingActionButtonPosition = Scaffold.FabPosition.Center,
isFloatingActionButtonDocked = true,
bodyContent = { innerPadding ->
- VerticalScroller(scrollerPosition) {
+ ScrollableColumn(scrollState = scrollState, children = {
Column(Modifier.padding(innerPadding)) {
repeat(20) { index ->
Card(index)
}
}
- }
+ })
}
)
}
diff --git a/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/ElevationDemo.kt b/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/ElevationDemo.kt
index fe2a3fc..4ce5f43 100644
--- a/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/ElevationDemo.kt
+++ b/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/ElevationDemo.kt
@@ -21,12 +21,13 @@
import androidx.ui.foundation.Border
import androidx.ui.foundation.Box
import androidx.ui.foundation.ContentGravity
+import androidx.ui.foundation.ScrollableColumn
import androidx.ui.foundation.Text
-import androidx.ui.foundation.VerticalScroller
import androidx.ui.foundation.clickable
import androidx.ui.foundation.shape.corner.RoundedCornerShape
import androidx.ui.graphics.Color
import androidx.ui.layout.Column
+import androidx.ui.layout.InnerPadding
import androidx.ui.layout.fillMaxSize
import androidx.ui.layout.fillMaxWidth
import androidx.ui.layout.padding
@@ -43,11 +44,12 @@
val text = getMessage(MaterialTheme.colors.isLight)
Text(text)
}
- VerticalScroller {
- Column(Modifier.padding(25.dp).fillMaxSize()) {
- elevations.forEach { elevation ->
- ElevatedCard(elevation)
- }
+ ScrollableColumn(
+ modifier = Modifier.fillMaxSize(),
+ contentPadding = InnerPadding(25.dp)
+ ) {
+ elevations.forEach { elevation ->
+ ElevatedCard(elevation)
}
}
}
diff --git a/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/ListItemDemo.kt b/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/ListItemDemo.kt
index eeead1f..d286555 100644
--- a/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/ListItemDemo.kt
+++ b/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/ListItemDemo.kt
@@ -17,7 +17,7 @@
package androidx.ui.material.demos
import androidx.compose.Composable
-import androidx.ui.foundation.VerticalScroller
+import androidx.ui.foundation.ScrollableColumn
import androidx.ui.material.icons.Icons
import androidx.ui.material.icons.filled.Call
import androidx.ui.material.samples.OneLineListItems
@@ -34,7 +34,7 @@
val icon40 = imageResource(R.drawable.ic_account_box)
val icon56 = imageResource(R.drawable.ic_android)
val vectorIcon = Icons.Default.Call
- VerticalScroller {
+ ScrollableColumn {
OneLineListItems(icon24, icon40, icon56, vectorIcon)
TwoLineListItems(icon24, icon40)
ThreeLineListItems(icon24, vectorIcon)
@@ -45,7 +45,7 @@
fun MixedRtlLtrListItemDemo() {
val icon24 = imageResource(R.drawable.ic_bluetooth)
val icon40 = imageResource(R.drawable.ic_account_box)
- VerticalScroller {
+ ScrollableColumn {
OneLineRtlLtrListItems(icon24, icon40)
TwoLineRtlLtrListItems(icon40)
ThreeLineRtlLtrListItems(icon40)
diff --git a/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/MaterialTextField.kt b/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/MaterialTextField.kt
index fea676e..df22042 100644
--- a/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/MaterialTextField.kt
+++ b/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/MaterialTextField.kt
@@ -23,12 +23,13 @@
import androidx.ui.core.Modifier
import androidx.ui.foundation.Box
import androidx.ui.foundation.Icon
+import androidx.ui.foundation.ScrollableColumn
import androidx.ui.foundation.Text
-import androidx.ui.foundation.VerticalScroller
import androidx.ui.foundation.selection.selectable
import androidx.ui.graphics.Color
import androidx.ui.layout.Column
import androidx.ui.layout.ColumnScope.gravity
+import androidx.ui.layout.InnerPadding
import androidx.ui.layout.Row
import androidx.ui.layout.Spacer
import androidx.ui.layout.fillMaxHeight
@@ -58,148 +59,145 @@
@Composable
fun TextFieldsDemo() {
- VerticalScroller {
- Column(
- modifier = Modifier.fillMaxHeight().padding(10.dp)
- ) {
- Text("Password text field")
- PasswordFilledTextField()
- Text("Text field with leading and trailing icons")
- FilledTextFieldWithIcons()
- Text("Outlined text field")
- SimpleOutlinedTextFieldSample()
- Text("Text field with placeholder")
- FilledTextFieldWithPlaceholder()
- Text("Text field with error state handling")
- FilledTextFieldWithErrorState()
- Text("Text field with helper/error message")
- TextFieldWithHelperMessage()
- Text("Hide keyboard on IME action")
- TextFieldWithHideKeyboardOnImeAction()
- Text("TextFieldValue overload")
- FilledTextFieldSample()
- }
+ ScrollableColumn(
+ modifier = Modifier.fillMaxHeight(),
+ contentPadding = InnerPadding(10.dp)
+ ) {
+ Text("Password text field")
+ PasswordFilledTextField()
+ Text("Text field with leading and trailing icons")
+ FilledTextFieldWithIcons()
+ Text("Outlined text field")
+ SimpleOutlinedTextFieldSample()
+ Text("Text field with placeholder")
+ FilledTextFieldWithPlaceholder()
+ Text("Text field with error state handling")
+ FilledTextFieldWithErrorState()
+ Text("Text field with helper/error message")
+ TextFieldWithHelperMessage()
+ Text("Hide keyboard on IME action")
+ TextFieldWithHideKeyboardOnImeAction()
+ Text("TextFieldValue overload")
+ FilledTextFieldSample()
}
}
@Composable
fun MaterialTextFieldDemo() {
- VerticalScroller {
- Column(Modifier.padding(10.dp)) {
- var text by savedInstanceState { "" }
- var leadingChecked by savedInstanceState { false }
- var trailingChecked by savedInstanceState { false }
- val characterCounterChecked by savedInstanceState { false }
- var selectedOption by savedInstanceState { Option.None }
- var selectedTextField by savedInstanceState { TextFieldType.Filled }
+ ScrollableColumn(contentPadding = InnerPadding(10.dp)) {
+ var text by savedInstanceState { "" }
+ var leadingChecked by savedInstanceState { false }
+ var trailingChecked by savedInstanceState { false }
+ val characterCounterChecked by savedInstanceState { false }
+ var selectedOption by savedInstanceState { Option.None }
+ var selectedTextField by savedInstanceState { TextFieldType.Filled }
- val textField: @Composable () -> Unit = @Composable {
- when (selectedTextField) {
- TextFieldType.Filled ->
- FilledTextField(
- value = text,
- text = it },
- label = {
- val label =
- "Label" + if (selectedOption == Option.Error) "*" else ""
- Text(text = label)
- },
- leadingIcon = { if (leadingChecked) Icon(Icons.Filled.Favorite) },
- trailingIcon = { if (trailingChecked) Icon(Icons.Filled.Info) },
- isErrorValue = selectedOption == Option.Error
- )
- TextFieldType.Outlined ->
- OutlinedTextField(
- value = text,
- text = it },
- label = {
- val label =
- "Label" + if (selectedOption == Option.Error) "*" else ""
- Text(text = label)
- },
- leadingIcon = { if (leadingChecked) Icon(Icons.Filled.Favorite) },
- trailingIcon = { if (trailingChecked) Icon(Icons.Filled.Info) },
- isErrorValue = selectedOption == Option.Error
- )
- }
+ val textField: @Composable () -> Unit = @Composable {
+ when (selectedTextField) {
+ TextFieldType.Filled ->
+ FilledTextField(
+ value = text,
+ text = it },
+ label = {
+ val label =
+ "Label" + if (selectedOption == Option.Error) "*" else ""
+ Text(text = label)
+ },
+ leadingIcon = { if (leadingChecked) Icon(Icons.Filled.Favorite) },
+ trailingIcon = { if (trailingChecked) Icon(Icons.Filled.Info) },
+ isErrorValue = selectedOption == Option.Error
+ )
+ TextFieldType.Outlined ->
+ OutlinedTextField(
+ value = text,
+ text = it },
+ label = {
+ val label =
+ "Label" + if (selectedOption == Option.Error) "*" else ""
+ Text(text = label)
+ },
+ leadingIcon = { if (leadingChecked) Icon(Icons.Filled.Favorite) },
+ trailingIcon = { if (trailingChecked) Icon(Icons.Filled.Info) },
+ isErrorValue = selectedOption == Option.Error
+ )
}
+ }
- Box(Modifier.preferredHeight(150.dp).gravity(Alignment.CenterHorizontally)) {
- if (selectedOption == Option.None) {
- textField()
- } else {
- TextFieldWithMessage(textField, selectedOption)
- }
+ Box(Modifier.preferredHeight(150.dp).gravity(Alignment.CenterHorizontally)) {
+ if (selectedOption == Option.None) {
+ textField()
+ } else {
+ TextFieldWithMessage(textField, selectedOption)
}
+ }
+ Column {
+ Title("Text field type")
Column {
- Title("Text field type")
- Column {
- TextFieldType.values().map { it.name }.forEach { textType ->
- Row(Modifier
- .fillMaxWidth()
- .selectable(
- selected = (textType == selectedTextField.name),
- >
- selectedTextField = TextFieldType.valueOf(textType)
- }
- )
- .padding(horizontal = 16.dp)
- ) {
- RadioButton(
- selected = (textType == selectedTextField.name),
- selectedTextField = TextFieldType.valueOf(textType) }
- )
- Text(
- text = textType,
- style = MaterialTheme.typography.body1.merge(),
- modifier = Modifier.padding(start = 16.dp)
- )
- }
+ TextFieldType.values().map { it.name }.forEach { textType ->
+ Row(Modifier
+ .fillMaxWidth()
+ .selectable(
+ selected = (textType == selectedTextField.name),
+ >
+ selectedTextField = TextFieldType.valueOf(textType)
+ }
+ )
+ .padding(horizontal = 16.dp)
+ ) {
+ RadioButton(
+ selected = (textType == selectedTextField.name),
+ selectedTextField = TextFieldType.valueOf(textType) }
+ )
+ Text(
+ text = textType,
+ style = MaterialTheme.typography.body1.merge(),
+ modifier = Modifier.padding(start = 16.dp)
+ )
}
}
+ }
- Title("Options")
- OptionRow(
- title = "Leading icon",
- checked = leadingChecked,
- leadingChecked = it }
- )
- OptionRow(
- title = "Trailing icon",
- checked = trailingChecked,
- trailingChecked = it }
- )
- OptionRow(
- title = "Character counter (TODO)",
- checked = characterCounterChecked,
- enabled = false,
- /* TODO */ }
- )
+ Title("Options")
+ OptionRow(
+ title = "Leading icon",
+ checked = leadingChecked,
+ leadingChecked = it }
+ )
+ OptionRow(
+ title = "Trailing icon",
+ checked = trailingChecked,
+ trailingChecked = it }
+ )
+ OptionRow(
+ title = "Character counter (TODO)",
+ checked = characterCounterChecked,
+ enabled = false,
+ /* TODO */ }
+ )
- Spacer(Modifier.preferredHeight(20.dp))
+ Spacer(Modifier.preferredHeight(20.dp))
- Title("Assistive text")
- Column {
- Option.values().map { it.name }.forEach { text ->
- Row(Modifier
- .fillMaxWidth()
- .selectable(
- selected = (text == selectedOption.name),
- selectedOption = Option.valueOf(text) }
- )
- .padding(horizontal = 16.dp)
- ) {
- RadioButton(
- selected = (text == selectedOption.name),
- selectedOption = Option.valueOf(text) }
- )
- Text(
- text = text,
- style = MaterialTheme.typography.body1.merge(),
- modifier = Modifier.padding(start = 16.dp)
- )
- }
+ Title("Assistive text")
+ Column {
+ Option.values().map { it.name }.forEach { text ->
+ Row(Modifier
+ .fillMaxWidth()
+ .selectable(
+ selected = (text == selectedOption.name),
+ selectedOption = Option.valueOf(text) }
+ )
+ .padding(horizontal = 16.dp)
+ ) {
+ RadioButton(
+ selected = (text == selectedOption.name),
+ selectedOption = Option.valueOf(text) }
+ )
+ Text(
+ text = text,
+ style = MaterialTheme.typography.body1.merge(),
+ modifier = Modifier.padding(start = 16.dp)
+ )
}
}
}
diff --git a/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/ProgressIndicatorDemo.kt b/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/ProgressIndicatorDemo.kt
index 4331d1b..f186c0c 100644
--- a/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/ProgressIndicatorDemo.kt
+++ b/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/ProgressIndicatorDemo.kt
@@ -28,7 +28,7 @@
import androidx.compose.setValue
import androidx.ui.core.Alignment
import androidx.ui.core.Modifier
-import androidx.ui.foundation.VerticalScroller
+import androidx.ui.foundation.ScrollableColumn
import androidx.ui.graphics.Color
import androidx.ui.layout.Arrangement
import androidx.ui.layout.Row
@@ -43,7 +43,7 @@
onActive { state.start() }
onDispose { state.stop() }
- VerticalScroller {
+ ScrollableColumn {
val modifier = Modifier.weight(1f, true)
.gravity(Alignment.CenterHorizontally)
.fillMaxWidth()
diff --git a/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/SelectionControlsDemo.kt b/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/SelectionControlsDemo.kt
index 485a171..2fd4f6b 100644
--- a/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/SelectionControlsDemo.kt
+++ b/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/SelectionControlsDemo.kt
@@ -18,16 +18,15 @@
import androidx.compose.Composable
import androidx.ui.core.Modifier
+import androidx.ui.foundation.ScrollableColumn
import androidx.ui.foundation.Text
-import androidx.ui.foundation.VerticalScroller
import androidx.ui.layout.Arrangement
-import androidx.ui.layout.Column
+import androidx.ui.layout.InnerPadding
import androidx.ui.layout.Spacer
import androidx.ui.layout.height
-import androidx.ui.layout.padding
import androidx.ui.material.MaterialTheme
-import androidx.ui.material.samples.RadioGroupSample
import androidx.ui.material.samples.RadioButtonSample
+import androidx.ui.material.samples.RadioGroupSample
import androidx.ui.material.samples.SwitchSample
import androidx.ui.material.samples.TriStateCheckboxSample
import androidx.ui.unit.dp
@@ -35,19 +34,20 @@
@Composable
fun SelectionControlsDemo() {
val headerStyle = MaterialTheme.typography.h6
- VerticalScroller {
- Column(Modifier.padding(10.dp), verticalArrangement = Arrangement.SpaceEvenly) {
- Text(text = "Checkbox", style = headerStyle)
- TriStateCheckboxSample()
- Spacer(Modifier.height(16.dp))
- Text(text = "Switch", style = headerStyle)
- SwitchSample()
- Spacer(Modifier.height(16.dp))
- Text(text = "RadioButtons with custom colors", style = headerStyle)
- RadioButtonSample()
- Spacer(Modifier.height(16.dp))
- Text(text = "Radio group", style = headerStyle)
- RadioGroupSample()
- }
+ ScrollableColumn(
+ contentPadding = InnerPadding(10.dp),
+ verticalArrangement = Arrangement.SpaceEvenly
+ ) {
+ Text(text = "Checkbox", style = headerStyle)
+ TriStateCheckboxSample()
+ Spacer(Modifier.height(16.dp))
+ Text(text = "Switch", style = headerStyle)
+ SwitchSample()
+ Spacer(Modifier.height(16.dp))
+ Text(text = "RadioButtons with custom colors", style = headerStyle)
+ RadioButtonSample()
+ Spacer(Modifier.height(16.dp))
+ Text(text = "Radio group", style = headerStyle)
+ RadioGroupSample()
}
}
diff --git a/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/SnackbarDemo.kt b/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/SnackbarDemo.kt
index 26c8ba3..5879d51 100644
--- a/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/SnackbarDemo.kt
+++ b/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/SnackbarDemo.kt
@@ -18,9 +18,9 @@
import androidx.compose.Composable
import androidx.ui.core.Modifier
+import androidx.ui.foundation.ScrollableColumn
import androidx.ui.foundation.Text
-import androidx.ui.foundation.VerticalScroller
-import androidx.ui.layout.Column
+import androidx.ui.layout.InnerPadding
import androidx.ui.layout.padding
import androidx.ui.material.MaterialTheme
import androidx.ui.material.Snackbar
@@ -31,24 +31,22 @@
@Composable
fun SnackbarDemo() {
- VerticalScroller {
- Column(Modifier.padding(12.dp, 0.dp, 12.dp, 0.dp)) {
- val textSpacing = Modifier.padding(top = 12.dp, bottom = 12.dp)
- Text("Default Snackbar", modifier = textSpacing)
- SimpleSnackbar()
- Text("Snackbar with long text", modifier = textSpacing)
- Snackbar(
- text = { Text("This song already exists in the current playlist") },
- action = {
- TextButton(
- contentColor = snackbarPrimaryColorFor(MaterialTheme.colors),
- /* perform undo */ }
- ) {
- Text("ADD THIS SONG ANYWAY")
- }
- },
- actionOnNewLine = true
- )
- }
+ ScrollableColumn(contentPadding = InnerPadding(12.dp, 0.dp, 12.dp, 0.dp)) {
+ val textSpacing = Modifier.padding(top = 12.dp, bottom = 12.dp)
+ Text("Default Snackbar", modifier = textSpacing)
+ SimpleSnackbar()
+ Text("Snackbar with long text", modifier = textSpacing)
+ Snackbar(
+ text = { Text("This song already exists in the current playlist") },
+ action = {
+ TextButton(
+ contentColor = snackbarPrimaryColorFor(MaterialTheme.colors),
+ /* perform undo */ }
+ ) {
+ Text("ADD THIS SONG ANYWAY")
+ }
+ },
+ actionOnNewLine = true
+ )
}
}
diff --git a/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/TabDemo.kt b/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/TabDemo.kt
index 545d0f6..1c251d3 100644
--- a/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/TabDemo.kt
+++ b/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/TabDemo.kt
@@ -20,8 +20,8 @@
import androidx.compose.state
import androidx.ui.core.Alignment
import androidx.ui.core.Modifier
+import androidx.ui.foundation.ScrollableColumn
import androidx.ui.foundation.Text
-import androidx.ui.foundation.VerticalScroller
import androidx.ui.graphics.Color
import androidx.ui.layout.Spacer
import androidx.ui.layout.height
@@ -39,7 +39,7 @@
@Composable
fun TabDemo() {
- VerticalScroller {
+ ScrollableColumn {
val showingSimple = state { true }
val buttonText = "Show ${if (showingSimple.value) "custom" else "simple"} tabs"
diff --git a/ui/ui-material/integration-tests/material-studies/src/main/java/androidx/ui/material/studies/rally/AccountsScreen.kt b/ui/ui-material/integration-tests/material-studies/src/main/java/androidx/ui/material/studies/rally/AccountsScreen.kt
index a838d92..5fec320 100644
--- a/ui/ui-material/integration-tests/material-studies/src/main/java/androidx/ui/material/studies/rally/AccountsScreen.kt
+++ b/ui/ui-material/integration-tests/material-studies/src/main/java/androidx/ui/material/studies/rally/AccountsScreen.kt
@@ -20,7 +20,8 @@
import androidx.ui.core.Alignment
import androidx.ui.core.Modifier
import androidx.ui.foundation.Text
-import androidx.ui.foundation.VerticalScroller
+import androidx.ui.foundation.rememberScrollState
+import androidx.ui.foundation.verticalScroll
import androidx.ui.layout.Column
import androidx.ui.layout.Spacer
import androidx.ui.layout.Stack
@@ -36,39 +37,37 @@
*/
@Composable
fun AccountsBody(accounts: List<Account>) {
- VerticalScroller {
- Stack(Modifier.padding(16.dp)) {
- val accountsProportion = accounts.extractProportions { it.balance }
- val colors = accounts.map { it.color }
- AnimatedCircle(
- Modifier.preferredHeight(300.dp).gravity(Alignment.Center).fillMaxWidth(),
- accountsProportion,
- colors
+ Stack(Modifier.verticalScroll(rememberScrollState(0f)).padding(16.dp)) {
+ val accountsProportion = accounts.extractProportions { it.balance }
+ val colors = accounts.map { it.color }
+ AnimatedCircle(
+ Modifier.preferredHeight(300.dp).gravity(Alignment.Center).fillMaxWidth(),
+ accountsProportion,
+ colors
+ )
+ Column(modifier = Modifier.gravity(Alignment.Center)) {
+ Text(
+ text = "Total",
+ style = MaterialTheme.typography.body1,
+ modifier = Modifier.gravity(Alignment.CenterHorizontally)
)
- Column(modifier = Modifier.gravity(Alignment.Center)) {
- Text(
- text = "Total",
- style = MaterialTheme.typography.body1,
- modifier = Modifier.gravity(Alignment.CenterHorizontally)
- )
- Text(
- text = "$12,132.49",
- style = MaterialTheme.typography.h2,
- modifier = Modifier.gravity(Alignment.CenterHorizontally)
- )
- }
+ Text(
+ text = "$12,132.49",
+ style = MaterialTheme.typography.h2,
+ modifier = Modifier.gravity(Alignment.CenterHorizontally)
+ )
}
- Spacer(Modifier.preferredHeight(10.dp))
- Card {
- Column(modifier = Modifier.padding(12.dp)) {
- accounts.forEach { account ->
- AccountRow(
- name = account.name,
- number = account.number,
- amount = account.balance,
- color = account.color
- )
- }
+ }
+ Spacer(Modifier.preferredHeight(10.dp))
+ Card {
+ Column(modifier = Modifier.padding(12.dp)) {
+ accounts.forEach { account ->
+ AccountRow(
+ name = account.name,
+ number = account.number,
+ amount = account.balance,
+ color = account.color
+ )
}
}
}
diff --git a/ui/ui-material/integration-tests/material-studies/src/main/java/androidx/ui/material/studies/rally/BillsScreen.kt b/ui/ui-material/integration-tests/material-studies/src/main/java/androidx/ui/material/studies/rally/BillsScreen.kt
index e34f881..ecd46eb 100644
--- a/ui/ui-material/integration-tests/material-studies/src/main/java/androidx/ui/material/studies/rally/BillsScreen.kt
+++ b/ui/ui-material/integration-tests/material-studies/src/main/java/androidx/ui/material/studies/rally/BillsScreen.kt
@@ -20,7 +20,8 @@
import androidx.ui.core.Alignment
import androidx.ui.core.Modifier
import androidx.ui.foundation.Text
-import androidx.ui.foundation.VerticalScroller
+import androidx.ui.foundation.rememberScrollState
+import androidx.ui.foundation.verticalScroll
import androidx.ui.layout.Column
import androidx.ui.layout.Spacer
import androidx.ui.layout.Stack
@@ -36,39 +37,37 @@
*/
@Composable
fun BillsBody(bills: List<Bill>) {
- VerticalScroller {
- Stack(Modifier.padding(16.dp)) {
- val accountsProportion = bills.extractProportions { it.amount }
- val colors = bills.map { it.color }
- AnimatedCircle(
- Modifier.gravity(Alignment.Center).preferredHeight(300.dp).fillMaxWidth(),
- accountsProportion,
- colors
+ Stack(Modifier.verticalScroll(rememberScrollState()).padding(16.dp)) {
+ val accountsProportion = bills.extractProportions { it.amount }
+ val colors = bills.map { it.color }
+ AnimatedCircle(
+ Modifier.gravity(Alignment.Center).preferredHeight(300.dp).fillMaxWidth(),
+ accountsProportion,
+ colors
+ )
+ Column(modifier = Modifier.gravity(Alignment.Center)) {
+ Text(
+ text = "Due",
+ style = MaterialTheme.typography.body1,
+ modifier = Modifier.gravity(Alignment.CenterHorizontally)
)
- Column(modifier = Modifier.gravity(Alignment.Center)) {
- Text(
- text = "Due",
- style = MaterialTheme.typography.body1,
- modifier = Modifier.gravity(Alignment.CenterHorizontally)
- )
- Text(
- text = "$1,810.00",
- style = MaterialTheme.typography.h2,
- modifier = Modifier.gravity(Alignment.CenterHorizontally)
- )
- }
+ Text(
+ text = "$1,810.00",
+ style = MaterialTheme.typography.h2,
+ modifier = Modifier.gravity(Alignment.CenterHorizontally)
+ )
}
- Spacer(Modifier.preferredHeight(10.dp))
- Card {
- Column(modifier = Modifier.padding(12.dp)) {
- bills.forEach { bill ->
- BillRow(
- name = bill.name,
- due = bill.due,
- amount = bill.amount,
- color = bill.color
- )
- }
+ }
+ Spacer(Modifier.preferredHeight(10.dp))
+ Card {
+ Column(modifier = Modifier.padding(12.dp)) {
+ bills.forEach { bill ->
+ BillRow(
+ name = bill.name,
+ due = bill.due,
+ amount = bill.amount,
+ color = bill.color
+ )
}
}
}
diff --git a/ui/ui-material/integration-tests/material-studies/src/main/java/androidx/ui/material/studies/rally/OverviewScreen.kt b/ui/ui-material/integration-tests/material-studies/src/main/java/androidx/ui/material/studies/rally/OverviewScreen.kt
index 27f3290..da2a498 100644
--- a/ui/ui-material/integration-tests/material-studies/src/main/java/androidx/ui/material/studies/rally/OverviewScreen.kt
+++ b/ui/ui-material/integration-tests/material-studies/src/main/java/androidx/ui/material/studies/rally/OverviewScreen.kt
@@ -23,8 +23,8 @@
import androidx.compose.state
import androidx.ui.core.Alignment
import androidx.ui.core.Modifier
+import androidx.ui.foundation.ScrollableColumn
import androidx.ui.foundation.Text
-import androidx.ui.foundation.VerticalScroller
import androidx.ui.layout.Arrangement
import androidx.ui.layout.Column
import androidx.ui.layout.InnerPadding
@@ -44,14 +44,12 @@
@Composable
fun OverviewBody() {
- VerticalScroller {
- Column(Modifier.padding(16.dp)) {
- AlertCard()
- Spacer(Modifier.preferredHeight(RallyDefaultPadding))
- AccountsCard()
- Spacer(Modifier.preferredHeight(RallyDefaultPadding))
- BillsCard()
- }
+ ScrollableColumn(contentPadding = InnerPadding(16.dp)) {
+ AlertCard()
+ Spacer(Modifier.preferredHeight(RallyDefaultPadding))
+ AccountsCard()
+ Spacer(Modifier.preferredHeight(RallyDefaultPadding))
+ BillsCard()
}
}
diff --git a/ui/ui-material/samples/src/main/java/androidx/ui/material/samples/ScaffoldSamples.kt b/ui/ui-material/samples/src/main/java/androidx/ui/material/samples/ScaffoldSamples.kt
index 8ae8af9..d4d2586d 100644
--- a/ui/ui-material/samples/src/main/java/androidx/ui/material/samples/ScaffoldSamples.kt
+++ b/ui/ui-material/samples/src/main/java/androidx/ui/material/samples/ScaffoldSamples.kt
@@ -24,15 +24,13 @@
import androidx.ui.core.Modifier
import androidx.ui.foundation.Box
import androidx.ui.foundation.Icon
+import androidx.ui.foundation.ScrollableColumn
import androidx.ui.foundation.Text
-import androidx.ui.foundation.VerticalScroller
import androidx.ui.foundation.shape.corner.CircleShape
import androidx.ui.foundation.shape.corner.CutCornerShape
import androidx.ui.foundation.shape.corner.RoundedCornerShape
import androidx.ui.graphics.Color
-import androidx.ui.layout.Column
import androidx.ui.layout.fillMaxWidth
-import androidx.ui.layout.padding
import androidx.ui.layout.preferredHeight
import androidx.ui.material.BottomAppBar
import androidx.ui.material.DrawerState
@@ -82,14 +80,12 @@
)
},
bodyContent = { innerPadding ->
- VerticalScroller {
- Column(Modifier.padding(innerPadding)) {
- repeat(100) {
- Box(
- Modifier.fillMaxWidth().preferredHeight(50.dp),
- backgroundColor = colors[it % colors.size]
- )
- }
+ ScrollableColumn(contentPadding = innerPadding) {
+ repeat(100) {
+ Box(
+ Modifier.fillMaxWidth().preferredHeight(50.dp),
+ backgroundColor = colors[it % colors.size]
+ )
}
}
}
@@ -151,14 +147,12 @@
floatingActionButtonPosition = Scaffold.FabPosition.Center,
isFloatingActionButtonDocked = true,
bodyContent = { innerPadding ->
- VerticalScroller {
- Column(Modifier.padding(innerPadding)) {
- repeat(100) {
- Box(
- Modifier.fillMaxWidth().preferredHeight(50.dp),
- backgroundColor = colors[it % colors.size]
- )
- }
+ ScrollableColumn(contentPadding = innerPadding) {
+ repeat(100) {
+ Box(
+ Modifier.fillMaxWidth().preferredHeight(50.dp),
+ backgroundColor = colors[it % colors.size]
+ )
}
}
}
diff --git a/ui/ui-material/src/main/java/androidx/ui/material/Menu.kt b/ui/ui-material/src/main/java/androidx/ui/material/Menu.kt
index b801841..a009453 100644
--- a/ui/ui-material/src/main/java/androidx/ui/material/Menu.kt
+++ b/ui/ui-material/src/main/java/androidx/ui/material/Menu.kt
@@ -36,11 +36,10 @@
import androidx.ui.core.Popup
import androidx.ui.core.PopupPositionProvider
import androidx.ui.core.TransformOrigin
-import androidx.ui.unit.Position
import androidx.ui.foundation.Box
import androidx.ui.foundation.ContentGravity
import androidx.ui.foundation.ProvideTextStyle
-import androidx.ui.foundation.VerticalScroller
+import androidx.ui.foundation.ScrollableColumn
import androidx.ui.foundation.clickable
import androidx.ui.layout.ColumnScope
import androidx.ui.layout.ExperimentalLayout
@@ -54,6 +53,7 @@
import androidx.ui.unit.IntBounds
import androidx.ui.unit.IntOffset
import androidx.ui.unit.IntSize
+import androidx.ui.unit.Position
import androidx.ui.unit.dp
import androidx.ui.unit.height
import androidx.ui.unit.width
@@ -143,7 +143,7 @@
elevation = MenuElevation
) {
@OptIn(ExperimentalLayout::class)
- VerticalScroller(
+ ScrollableColumn(
modifier = dropdownModifier
.padding(vertical = DropdownMenuVerticalPadding)
.preferredWidth(IntrinsicSize.Max),
diff --git a/ui/ui-material/src/main/java/androidx/ui/material/Tab.kt b/ui/ui-material/src/main/java/androidx/ui/material/Tab.kt
index 0707adb..741d08a 100644
--- a/ui/ui-material/src/main/java/androidx/ui/material/Tab.kt
+++ b/ui/ui-material/src/main/java/androidx/ui/material/Tab.kt
@@ -43,11 +43,12 @@
import androidx.ui.foundation.Box
import androidx.ui.foundation.ContentColorAmbient
import androidx.ui.foundation.ContentGravity
-import androidx.ui.foundation.HorizontalScroller
import androidx.ui.foundation.ProvideTextStyle
-import androidx.ui.foundation.ScrollerPosition
+import androidx.ui.foundation.ScrollState
+import androidx.ui.foundation.ScrollableRow
import androidx.ui.foundation.contentColor
import androidx.ui.foundation.drawBackground
+import androidx.ui.foundation.rememberScrollState
import androidx.ui.foundation.selection.selectable
import androidx.ui.graphics.Color
import androidx.ui.layout.Row
@@ -216,10 +217,10 @@
indicatorContainer: @Composable (tabPositions: List<TabPosition>) -> Unit,
divider: @Composable () -> Unit
) {
- val scrollerPosition = ScrollerPosition()
- val scrollableTabData = remember(scrollerPosition) {
+ val scrollState = rememberScrollState()
+ val scrollableTabData = remember(scrollState) {
ScrollableTabData(
- scrollerPosition = scrollerPosition,
+ scrollState = scrollState,
selectedTab = selectedIndex
)
}
@@ -235,14 +236,11 @@
}
}
- HorizontalScroller(
- scrollerPosition = scrollerPosition,
- modifier = Modifier.fillMaxWidth()
- ) {
- val indicatorTag = "indicator"
- val dividerTag = "divider"
+ val indicatorTag = "indicator"
+ val dividerTag = "divider"
+ ScrollableRow(modifier = Modifier.fillMaxWidth(), scrollState = scrollState) {
Layout(
- {
+ children = {
tabs()
Box(Modifier.layoutId(indicatorTag), children = indicator)
Box(Modifier.layoutId(dividerTag), children = divider)
@@ -317,7 +315,7 @@
* Class holding onto state needed for [ScrollableTabRow]
*/
private class ScrollableTabData(
- private val scrollerPosition: ScrollerPosition,
+ private val scrollState: ScrollState,
private var selectedTab: Int
) {
fun onLaidOut(
@@ -332,7 +330,7 @@
// Scrolls to the tab with [tabPosition], trying to place it in the center of the
// screen or as close to the center as possible.
val calculatedOffset = it.calculateTabOffset(density, edgeOffset, tabPositions)
- scrollerPosition.smoothScrollTo(calculatedOffset)
+ scrollState.smoothScrollTo(calculatedOffset)
}
}
}
@@ -348,7 +346,7 @@
tabPositions: List<TabPosition>
): Float = with(density) {
val totalTabRowWidth = tabPositions.last().right.toIntPx() + edgeOffset
- val visibleWidth = totalTabRowWidth - scrollerPosition.maxPosition.toInt()
+ val visibleWidth = totalTabRowWidth - scrollState.maxValue.toInt()
val tabOffset = left.toIntPx()
val scrollerCenter = visibleWidth / 2
val tabWidth = width.toIntPx()
diff --git a/ui/ui-material/src/main/java/androidx/ui/material/TextFieldImpl.kt b/ui/ui-material/src/main/java/androidx/ui/material/TextFieldImpl.kt
index 029ba9e..ff2ebab 100644
--- a/ui/ui-material/src/main/java/androidx/ui/material/TextFieldImpl.kt
+++ b/ui/ui-material/src/main/java/androidx/ui/material/TextFieldImpl.kt
@@ -251,7 +251,7 @@
}
/**
- * Similar to [androidx.ui.foundation.VerticalScroller] but does not lose the minWidth constraints.
+ * Similar to [androidx.ui.foundation.ScrollableColumn] but does not lose the minWidth constraints.
*/
@VisibleForTesting
@Composable
diff --git a/ui/ui-test/src/androidTest/java/androidx/ui/test/IsDisplayedTest.kt b/ui/ui-test/src/androidTest/java/androidx/ui/test/IsDisplayedTest.kt
index 67ae035..03670aa 100644
--- a/ui/ui-test/src/androidTest/java/androidx/ui/test/IsDisplayedTest.kt
+++ b/ui/ui-test/src/androidTest/java/androidx/ui/test/IsDisplayedTest.kt
@@ -37,7 +37,7 @@
import androidx.ui.core.Modifier
import androidx.ui.core.setContent
import androidx.ui.foundation.Box
-import androidx.ui.foundation.VerticalScroller
+import androidx.ui.foundation.ScrollableColumn
import androidx.ui.graphics.Color
import androidx.ui.layout.Row
import androidx.ui.layout.Stack
@@ -108,7 +108,7 @@
@Test
fun componentInScrollable_isDisplayed() {
composeTestRule.setContent {
- VerticalScroller(modifier = Modifier.size(100.dp)) {
+ ScrollableColumn(modifier = Modifier.size(100.dp)) {
repeat(10) { Item(it, height = 30.dp) }
}
}
@@ -120,7 +120,7 @@
@Test
fun componentInScrollable_isNotDisplayed() {
composeTestRule.setContent {
- VerticalScroller(modifier = Modifier.size(100.dp)) {
+ ScrollableColumn(modifier = Modifier.size(100.dp)) {
repeat(10) { Item(it, height = 30.dp) }
}
}
diff --git a/ui/ui-text/integration-tests/ui-text-compose-demos/src/main/java/androidx/ui/text/demos/ComposeInputField.kt b/ui/ui-text/integration-tests/ui-text-compose-demos/src/main/java/androidx/ui/text/demos/ComposeInputField.kt
index 7519126..3dd01e0 100644
--- a/ui/ui-text/integration-tests/ui-text-compose-demos/src/main/java/androidx/ui/text/demos/ComposeInputField.kt
+++ b/ui/ui-text/integration-tests/ui-text-compose-demos/src/main/java/androidx/ui/text/demos/ComposeInputField.kt
@@ -19,8 +19,8 @@
import androidx.compose.Composable
import androidx.compose.key
import androidx.compose.state
+import androidx.ui.foundation.ScrollableColumn
import androidx.ui.foundation.TextField
-import androidx.ui.foundation.VerticalScroller
import androidx.ui.input.ImeAction
import androidx.ui.input.KeyboardType
import androidx.ui.input.TextFieldValue
@@ -51,7 +51,7 @@
@Composable
fun InputFieldDemo() {
- VerticalScroller {
+ ScrollableColumn {
TagLine(tag = "simple editing")
EditLine()
TagLine(tag = "simple editing2")
diff --git a/ui/ui-text/integration-tests/ui-text-compose-demos/src/main/java/androidx/ui/text/demos/ComposeInputFieldFocusTransition.kt b/ui/ui-text/integration-tests/ui-text-compose-demos/src/main/java/androidx/ui/text/demos/ComposeInputFieldFocusTransition.kt
index 9d3ed06..0eb9253 100644
--- a/ui/ui-text/integration-tests/ui-text-compose-demos/src/main/java/androidx/ui/text/demos/ComposeInputFieldFocusTransition.kt
+++ b/ui/ui-text/integration-tests/ui-text-compose-demos/src/main/java/androidx/ui/text/demos/ComposeInputFieldFocusTransition.kt
@@ -19,8 +19,8 @@
import androidx.compose.Composable
import androidx.compose.state
import androidx.ui.core.focus.FocusModifier
+import androidx.ui.foundation.ScrollableColumn
import androidx.ui.foundation.TextField
-import androidx.ui.foundation.VerticalScroller
import androidx.ui.graphics.Color
import androidx.ui.input.ImeAction
import androidx.ui.input.TextFieldValue
@@ -32,7 +32,7 @@
fun TextFieldFocusTransition() {
val focusModifiers = List(6) { FocusModifier() }
- VerticalScroller {
+ ScrollableColumn {
TextFieldWithFocusId(focusModifiers[0], focusModifiers[1])
TextFieldWithFocusId(focusModifiers[1], focusModifiers[2])
TextFieldWithFocusId(focusModifiers[2], focusModifiers[3])
diff --git a/ui/ui-text/integration-tests/ui-text-compose-demos/src/main/java/androidx/ui/text/demos/ComposeInputFieldTrickyUseCase.kt b/ui/ui-text/integration-tests/ui-text-compose-demos/src/main/java/androidx/ui/text/demos/ComposeInputFieldTrickyUseCase.kt
index 1944a0e..012c2ec 100644
--- a/ui/ui-text/integration-tests/ui-text-compose-demos/src/main/java/androidx/ui/text/demos/ComposeInputFieldTrickyUseCase.kt
+++ b/ui/ui-text/integration-tests/ui-text-compose-demos/src/main/java/androidx/ui/text/demos/ComposeInputFieldTrickyUseCase.kt
@@ -17,8 +17,8 @@
package androidx.ui.text.demos
import androidx.compose.Composable
+import androidx.ui.foundation.ScrollableColumn
import androidx.ui.foundation.TextField
-import androidx.ui.foundation.VerticalScroller
import androidx.ui.input.KeyboardType
import androidx.ui.input.TextFieldValue
import androidx.ui.savedinstancestate.savedInstanceState
@@ -27,7 +27,7 @@
@Composable
fun InputFieldTrickyUseCase() {
- VerticalScroller {
+ ScrollableColumn {
TagLine(tag = "don't set if non number is added")
RejectNonDigits()
diff --git a/ui/ui-text/integration-tests/ui-text-compose-demos/src/main/java/androidx/ui/text/demos/ComposeMultiParagraph.kt b/ui/ui-text/integration-tests/ui-text-compose-demos/src/main/java/androidx/ui/text/demos/ComposeMultiParagraph.kt
index 60cb5ff..f16a0d0 100644
--- a/ui/ui-text/integration-tests/ui-text-compose-demos/src/main/java/androidx/ui/text/demos/ComposeMultiParagraph.kt
+++ b/ui/ui-text/integration-tests/ui-text-compose-demos/src/main/java/androidx/ui/text/demos/ComposeMultiParagraph.kt
@@ -17,8 +17,8 @@
package androidx.ui.text.demos
import androidx.compose.Composable
+import androidx.ui.foundation.ScrollableColumn
import androidx.ui.foundation.Text
-import androidx.ui.foundation.VerticalScroller
import androidx.ui.text.AnnotatedString
import androidx.ui.text.ParagraphStyle
import androidx.ui.text.TextStyle
@@ -33,7 +33,7 @@
@Composable
fun MultiParagraphDemo() {
- VerticalScroller {
+ ScrollableColumn {
TagLine(tag = "multiple paragraphs basic")
TextDemoParagraph()
TagLine(tag = "multiple paragraphs TextAlign")
diff --git a/ui/ui-text/integration-tests/ui-text-compose-demos/src/main/java/androidx/ui/text/demos/ComposeText.kt b/ui/ui-text/integration-tests/ui-text-compose-demos/src/main/java/androidx/ui/text/demos/ComposeText.kt
index 7234018..245a5667 100644
--- a/ui/ui-text/integration-tests/ui-text-compose-demos/src/main/java/androidx/ui/text/demos/ComposeText.kt
+++ b/ui/ui-text/integration-tests/ui-text-compose-demos/src/main/java/androidx/ui/text/demos/ComposeText.kt
@@ -18,8 +18,8 @@
import androidx.compose.Composable
import androidx.ui.core.Modifier
+import androidx.ui.foundation.ScrollableColumn
import androidx.ui.foundation.Text
-import androidx.ui.foundation.VerticalScroller
import androidx.ui.geometry.Offset
import androidx.ui.graphics.Color
import androidx.ui.graphics.Shadow
@@ -61,7 +61,7 @@
@Composable
fun TextDemo() {
- VerticalScroller {
+ ScrollableColumn {
TagLine(tag = "color, fontSize, fontWeight and fontStyle")
TextDemoBasic()
TagLine(
diff --git a/ui/ui-text/integration-tests/ui-text-compose-demos/src/main/java/androidx/ui/text/demos/ComposeTextSelection.kt b/ui/ui-text/integration-tests/ui-text-compose-demos/src/main/java/androidx/ui/text/demos/ComposeTextSelection.kt
index ccf6119..b4b6134 100644
--- a/ui/ui-text/integration-tests/ui-text-compose-demos/src/main/java/androidx/ui/text/demos/ComposeTextSelection.kt
+++ b/ui/ui-text/integration-tests/ui-text-compose-demos/src/main/java/androidx/ui/text/demos/ComposeTextSelection.kt
@@ -21,14 +21,14 @@
import androidx.ui.core.Modifier
import androidx.ui.core.selection.Selection
import androidx.ui.core.selection.SelectionContainer
+import androidx.ui.foundation.ScrollableColumn
import androidx.ui.foundation.Text
-import androidx.ui.foundation.VerticalScroller
import androidx.ui.graphics.Color
+import androidx.ui.intl.LocaleList
import androidx.ui.layout.Column
import androidx.ui.layout.Row
import androidx.ui.layout.fillMaxHeight
import androidx.ui.layout.fillMaxWidth
-import androidx.ui.intl.LocaleList
import androidx.ui.text.SpanStyle
import androidx.ui.text.TextStyle
import androidx.ui.text.annotatedString
@@ -38,7 +38,7 @@
@Composable
fun TextSelectionDemo() {
- VerticalScroller {
+ ScrollableColumn {
TagLine(tag = "selection")
TextDemoSelection()
TagLine(tag = "selection with string input")
diff --git a/ui/ui-text/integration-tests/ui-text-compose-demos/src/main/java/androidx/ui/text/demos/ComposeTextSelectionSample.kt b/ui/ui-text/integration-tests/ui-text-compose-demos/src/main/java/androidx/ui/text/demos/ComposeTextSelectionSample.kt
index 8e04a21..84e248f 100644
--- a/ui/ui-text/integration-tests/ui-text-compose-demos/src/main/java/androidx/ui/text/demos/ComposeTextSelectionSample.kt
+++ b/ui/ui-text/integration-tests/ui-text-compose-demos/src/main/java/androidx/ui/text/demos/ComposeTextSelectionSample.kt
@@ -22,8 +22,8 @@
import androidx.ui.core.selection.Selection
import androidx.ui.core.selection.SelectionContainer
import androidx.ui.foundation.Box
+import androidx.ui.foundation.ScrollableColumn
import androidx.ui.foundation.Text
-import androidx.ui.foundation.VerticalScroller
import androidx.ui.graphics.Color
import androidx.ui.layout.Column
import androidx.ui.layout.Row
@@ -73,7 +73,7 @@
@Composable
fun TextSelectionSample() {
val selection = state<Selection?> { null }
- VerticalScroller {
+ ScrollableColumn {
SelectionContainer(
selection = selection.value,
selection.value = it }
diff --git a/ui/ui-text/integration-tests/ui-text-compose-demos/src/main/java/androidx/ui/text/demos/ComposeVariousInputField.kt b/ui/ui-text/integration-tests/ui-text-compose-demos/src/main/java/androidx/ui/text/demos/ComposeVariousInputField.kt
index c18c442..01351ca 100644
--- a/ui/ui-text/integration-tests/ui-text-compose-demos/src/main/java/androidx/ui/text/demos/ComposeVariousInputField.kt
+++ b/ui/ui-text/integration-tests/ui-text-compose-demos/src/main/java/androidx/ui/text/demos/ComposeVariousInputField.kt
@@ -25,9 +25,9 @@
import androidx.ui.core.id
import androidx.ui.core.layoutId
import androidx.ui.foundation.Box
+import androidx.ui.foundation.ScrollableColumn
import androidx.ui.foundation.Text
import androidx.ui.foundation.TextField
-import androidx.ui.foundation.VerticalScroller
import androidx.ui.foundation.drawBackground
import androidx.ui.geometry.Rect
import androidx.ui.graphics.Color
@@ -38,9 +38,9 @@
import androidx.ui.input.TextFieldValue
import androidx.ui.input.TransformedText
import androidx.ui.input.VisualTransformation
-import androidx.ui.text.AnnotatedString
import androidx.ui.intl.LocaleList
import androidx.ui.savedinstancestate.savedInstanceState
+import androidx.ui.text.AnnotatedString
import androidx.ui.text.TextLayoutResult
import androidx.ui.text.TextRange
import androidx.ui.text.TextStyle
@@ -181,7 +181,7 @@
@Composable
fun VariousInputFieldDemo() {
- VerticalScroller {
+ ScrollableColumn {
TagLine(tag = "Capitalization")
VariousEditLine(
keyboardType = KeyboardType.Ascii,
diff --git a/ui/ui-text/integration-tests/ui-text-compose-demos/src/main/java/androidx/ui/text/demos/InteractiveText.kt b/ui/ui-text/integration-tests/ui-text-compose-demos/src/main/java/androidx/ui/text/demos/InteractiveText.kt
index 2315b7e..8063f46 100644
--- a/ui/ui-text/integration-tests/ui-text-compose-demos/src/main/java/androidx/ui/text/demos/InteractiveText.kt
+++ b/ui/ui-text/integration-tests/ui-text-compose-demos/src/main/java/androidx/ui/text/demos/InteractiveText.kt
@@ -19,8 +19,8 @@
import androidx.compose.Composable
import androidx.compose.state
import androidx.ui.foundation.ClickableText
+import androidx.ui.foundation.ScrollableColumn
import androidx.ui.foundation.Text
-import androidx.ui.foundation.VerticalScroller
import androidx.ui.text.AnnotatedString
@Composable
@@ -31,7 +31,7 @@
@Composable
fun TextOnClick() {
val clickedOffset = state { -1 }
- VerticalScroller {
+ ScrollableColumn {
Text("Clicked Offset: ${clickedOffset.value}")
ClickableText(
text = AnnotatedString("Click Me")
diff --git a/ui/ui-text/integration-tests/ui-text-compose-demos/src/main/java/androidx/ui/text/demos/TextFieldWIthScroller.kt b/ui/ui-text/integration-tests/ui-text-compose-demos/src/main/java/androidx/ui/text/demos/TextFieldWIthScroller.kt
index efcb7fd..ab7feb5 100644
--- a/ui/ui-text/integration-tests/ui-text-compose-demos/src/main/java/androidx/ui/text/demos/TextFieldWIthScroller.kt
+++ b/ui/ui-text/integration-tests/ui-text-compose-demos/src/main/java/androidx/ui/text/demos/TextFieldWIthScroller.kt
@@ -19,18 +19,20 @@
import androidx.compose.Composable
import androidx.compose.state
import androidx.ui.core.Modifier
+import androidx.ui.foundation.ScrollableColumn
import androidx.ui.foundation.TextField
-import androidx.ui.foundation.VerticalScroller
import androidx.ui.input.TextFieldValue
import androidx.ui.layout.padding
import androidx.ui.unit.dp
@Composable
fun TextFieldWithScrollerDemo() {
- VerticalScroller {
- val state = state { TextFieldValue(
- text = List(100) { "Line: $it" }.joinToString("\n")
- ) }
+ ScrollableColumn {
+ val state = state {
+ TextFieldValue(
+ text = List(100) { "Line: $it" }.joinToString("\n")
+ )
+ }
TextField(
value = state.value,
state.value = it },