Merge "Include pixel 4a (5G) in InvalidVideoProfilesQuirk" into androidx-main
diff --git a/compose/foundation/foundation/api/public_plus_experimental_current.txt b/compose/foundation/foundation/api/public_plus_experimental_current.txt
index 8717a03..33b5d9d 100644
--- a/compose/foundation/foundation/api/public_plus_experimental_current.txt
+++ b/compose/foundation/foundation/api/public_plus_experimental_current.txt
@@ -975,14 +975,16 @@
   }
 
   @androidx.compose.foundation.ExperimentalFoundationApi public final class PagerDefaults {
-    method @androidx.compose.runtime.Composable public androidx.compose.foundation.gestures.snapping.SnapFlingBehavior flingBehavior(androidx.compose.foundation.pager.PagerState state, optional androidx.compose.foundation.pager.PagerSnapDistance pagerSnapDistance, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> lowVelocityAnimationSpec, optional androidx.compose.animation.core.DecayAnimationSpec<java.lang.Float> highVelocityAnimationSpec, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> snapAnimationSpec);
+    method @androidx.compose.runtime.Composable public androidx.compose.foundation.gestures.snapping.SnapFlingBehavior flingBehavior(androidx.compose.foundation.pager.PagerState state, optional androidx.compose.foundation.pager.PagerSnapDistance pagerSnapDistance, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> lowVelocityAnimationSpec, optional androidx.compose.animation.core.DecayAnimationSpec<java.lang.Float> highVelocityAnimationSpec, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> snapAnimationSpec, optional float snapVelocityThreshold);
     method public androidx.compose.ui.input.nestedscroll.NestedScrollConnection pageNestedScrollConnection(androidx.compose.foundation.gestures.Orientation orientation);
     field public static final androidx.compose.foundation.pager.PagerDefaults INSTANCE;
   }
 
   public final class PagerKt {
-    method @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Composable public static void HorizontalPager(int pageCount, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.foundation.pager.PagerState state, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.pager.PageSize pageSize, optional int beyondBoundsPageCount, optional float pageSpacing, optional androidx.compose.ui.Alignment.Vertical verticalAlignment, optional androidx.compose.foundation.gestures.snapping.SnapFlingBehavior flingBehavior, optional boolean userScrollEnabled, optional boolean reverseLayout, optional kotlin.jvm.functions.Function1<? super java.lang.Integer,?>? key, optional androidx.compose.ui.input.nestedscroll.NestedScrollConnection pageNestedScrollConnection, kotlin.jvm.functions.Function1<? super java.lang.Integer,kotlin.Unit> pageContent);
-    method @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Composable public static void VerticalPager(int pageCount, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.foundation.pager.PagerState state, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.pager.PageSize pageSize, optional int beyondBoundsPageCount, optional float pageSpacing, optional androidx.compose.ui.Alignment.Horizontal horizontalAlignment, optional androidx.compose.foundation.gestures.snapping.SnapFlingBehavior flingBehavior, optional boolean userScrollEnabled, optional boolean reverseLayout, optional kotlin.jvm.functions.Function1<? super java.lang.Integer,?>? key, optional androidx.compose.ui.input.nestedscroll.NestedScrollConnection pageNestedScrollConnection, kotlin.jvm.functions.Function1<? super java.lang.Integer,kotlin.Unit> pageContent);
+    method @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Composable public static void HorizontalPager(androidx.compose.foundation.pager.PagerState state, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.pager.PageSize pageSize, optional int beyondBoundsPageCount, optional float pageSpacing, optional androidx.compose.ui.Alignment.Vertical verticalAlignment, optional androidx.compose.foundation.gestures.snapping.SnapFlingBehavior flingBehavior, optional boolean userScrollEnabled, optional boolean reverseLayout, optional kotlin.jvm.functions.Function1<? super java.lang.Integer,?>? key, optional androidx.compose.ui.input.nestedscroll.NestedScrollConnection pageNestedScrollConnection, kotlin.jvm.functions.Function1<? super java.lang.Integer,kotlin.Unit> pageContent);
+    method @Deprecated @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Composable public static void HorizontalPager(int pageCount, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.foundation.pager.PagerState state, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.pager.PageSize pageSize, optional int beyondBoundsPageCount, optional float pageSpacing, optional androidx.compose.ui.Alignment.Vertical verticalAlignment, optional androidx.compose.foundation.gestures.snapping.SnapFlingBehavior flingBehavior, optional boolean userScrollEnabled, optional boolean reverseLayout, optional kotlin.jvm.functions.Function1<? super java.lang.Integer,?>? key, optional androidx.compose.ui.input.nestedscroll.NestedScrollConnection pageNestedScrollConnection, kotlin.jvm.functions.Function1<? super java.lang.Integer,kotlin.Unit> pageContent);
+    method @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Composable public static void VerticalPager(androidx.compose.foundation.pager.PagerState state, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.pager.PageSize pageSize, optional int beyondBoundsPageCount, optional float pageSpacing, optional androidx.compose.ui.Alignment.Horizontal horizontalAlignment, optional androidx.compose.foundation.gestures.snapping.SnapFlingBehavior flingBehavior, optional boolean userScrollEnabled, optional boolean reverseLayout, optional kotlin.jvm.functions.Function1<? super java.lang.Integer,?>? key, optional androidx.compose.ui.input.nestedscroll.NestedScrollConnection pageNestedScrollConnection, kotlin.jvm.functions.Function1<? super java.lang.Integer,kotlin.Unit> pageContent);
+    method @Deprecated @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Composable public static void VerticalPager(int pageCount, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.foundation.pager.PagerState state, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.pager.PageSize pageSize, optional int beyondBoundsPageCount, optional float pageSpacing, optional androidx.compose.ui.Alignment.Horizontal horizontalAlignment, optional androidx.compose.foundation.gestures.snapping.SnapFlingBehavior flingBehavior, optional boolean userScrollEnabled, optional boolean reverseLayout, optional kotlin.jvm.functions.Function1<? super java.lang.Integer,?>? key, optional androidx.compose.ui.input.nestedscroll.NestedScrollConnection pageNestedScrollConnection, kotlin.jvm.functions.Function1<? super java.lang.Integer,kotlin.Unit> pageContent);
   }
 
   @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Stable public interface PagerSnapDistance {
@@ -994,40 +996,39 @@
     method public androidx.compose.foundation.pager.PagerSnapDistance atMost(int pages);
   }
 
-  @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Stable public final class PagerState implements androidx.compose.foundation.gestures.ScrollableState {
+  @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Stable public abstract class PagerState implements androidx.compose.foundation.gestures.ScrollableState {
     ctor public PagerState(optional int initialPage, optional float initialPageOffsetFraction);
-    method public suspend Object? animateScrollToPage(int page, optional float pageOffsetFraction, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, optional kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public final suspend Object? animateScrollToPage(int page, optional float pageOffsetFraction, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, optional kotlin.coroutines.Continuation<? super kotlin.Unit>);
     method public float dispatchRawDelta(float delta);
-    method public int getCurrentPage();
-    method public float getCurrentPageOffsetFraction();
-    method public int getInitialPage();
-    method public float getInitialPageOffsetFraction();
-    method public androidx.compose.foundation.interaction.InteractionSource getInteractionSource();
-    method public int getSettledPage();
-    method public int getTargetPage();
+    method public final boolean getCanScrollBackward();
+    method public final boolean getCanScrollForward();
+    method public final int getCurrentPage();
+    method public final float getCurrentPageOffsetFraction();
+    method public final int getInitialPage();
+    method public final float getInitialPageOffsetFraction();
+    method public final androidx.compose.foundation.interaction.InteractionSource getInteractionSource();
+    method public abstract int getPageCount();
+    method public final int getSettledPage();
+    method public final int getTargetPage();
     method public boolean isScrollInProgress();
     method public suspend Object? scroll(androidx.compose.foundation.MutatePriority scrollPriority, kotlin.jvm.functions.Function2<? super androidx.compose.foundation.gestures.ScrollScope,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> block, kotlin.coroutines.Continuation<? super kotlin.Unit>);
-    method public suspend Object? scrollToPage(int page, optional float pageOffsetFraction, optional kotlin.coroutines.Continuation<? super kotlin.Unit>);
-    property public boolean canScrollBackward;
-    property public boolean canScrollForward;
+    method public final suspend Object? scrollToPage(int page, optional float pageOffsetFraction, optional kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    property public final boolean canScrollBackward;
+    property public final boolean canScrollForward;
     property public final int currentPage;
     property public final float currentPageOffsetFraction;
     property public final int initialPage;
     property public final float initialPageOffsetFraction;
     property public final androidx.compose.foundation.interaction.InteractionSource interactionSource;
     property public boolean isScrollInProgress;
+    property public abstract int pageCount;
     property public final int settledPage;
     property public final int targetPage;
-    field public static final androidx.compose.foundation.pager.PagerState.Companion Companion;
-  }
-
-  public static final class PagerState.Companion {
-    method public androidx.compose.runtime.saveable.Saver<androidx.compose.foundation.pager.PagerState,?> getSaver();
-    property public final androidx.compose.runtime.saveable.Saver<androidx.compose.foundation.pager.PagerState,?> Saver;
   }
 
   public final class PagerStateKt {
-    method @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Composable public static androidx.compose.foundation.pager.PagerState rememberPagerState(optional int initialPage, optional float initialPageOffsetFraction);
+    method @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Composable public static androidx.compose.foundation.pager.PagerState rememberPagerState(optional int initialPage, optional float initialPageOffsetFraction, kotlin.jvm.functions.Function0<java.lang.Integer> pageCount);
+    method @Deprecated @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Composable public static androidx.compose.foundation.pager.PagerState rememberPagerState(optional int initialPage, optional float initialPageOffsetFraction);
   }
 
 }
diff --git a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/pager/PagerCarrouselDemos.kt b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/pager/PagerCarrouselDemos.kt
index a55b0aa..5b43150 100644
--- a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/pager/PagerCarrouselDemos.kt
+++ b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/pager/PagerCarrouselDemos.kt
@@ -55,13 +55,12 @@
 @OptIn(ExperimentalFoundationApi::class)
 @Composable
 private fun HorizontalCarrouselDemo() {
-    val pagerState = rememberPagerState()
+    val pagerState = rememberPagerState { PagesCount }
 
     Column(modifier = Modifier.fillMaxSize()) {
         HorizontalPager(
             modifier = Modifier,
             state = pagerState,
-            pageCount = PagesCount,
             pageSize = PageSize.Fixed(200.dp)
         ) {
             CarrouselItem(it, Orientation.Vertical)
@@ -73,13 +72,12 @@
 @OptIn(ExperimentalFoundationApi::class)
 @Composable
 private fun VerticalCarrouselDemo() {
-    val pagerState = rememberPagerState()
+    val pagerState = rememberPagerState { PagesCount }
 
     Column(modifier = Modifier.fillMaxSize(), horizontalAlignment = Alignment.CenterHorizontally) {
         VerticalPager(
             modifier = Modifier.weight(0.9f),
             state = pagerState,
-            pageCount = PagesCount,
             pageSize = PageSize.Fixed(200.dp)
         ) {
             CarrouselItem(it, Orientation.Horizontal)
@@ -91,13 +89,12 @@
 @OptIn(ExperimentalFoundationApi::class)
 @Composable
 private fun HorizontalCustomPageSizeDemo() {
-    val pagerState = rememberPagerState()
+    val pagerState = rememberPagerState { PagesCount }
 
     Column(modifier = Modifier.fillMaxSize()) {
         HorizontalPager(
             modifier = Modifier,
             state = pagerState,
-            pageCount = PagesCount,
             pageSize = ThreePagesPerViewport,
             pageSpacing = 8.dp
         ) {
@@ -110,13 +107,12 @@
 @OptIn(ExperimentalFoundationApi::class)
 @Composable
 private fun HorizontalCustomPageSizeWithCustomMaxScrollDemo() {
-    val pagerState = rememberPagerState()
+    val pagerState = rememberPagerState { PagesCount }
 
     Column(modifier = Modifier.fillMaxSize()) {
         HorizontalPager(
             modifier = Modifier,
             state = pagerState,
-            pageCount = PagesCount,
             pageSize = ThreePagesPerViewport,
             pageSpacing = 8.dp,
             flingBehavior = PagerDefaults.flingBehavior(
diff --git a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/pager/PagerDemos.kt b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/pager/PagerDemos.kt
index 49473eb8..45a08b6 100644
--- a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/pager/PagerDemos.kt
+++ b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/pager/PagerDemos.kt
@@ -72,11 +72,10 @@
 @OptIn(ExperimentalFoundationApi::class)
 @Composable
 private fun VerticalPagerDemo() {
-    val pagerState = rememberPagerState()
+    val pagerState = rememberPagerState { PagesCount }
     VerticalPager(
         modifier = Modifier.fillMaxSize(),
         state = pagerState,
-        pageCount = PagesCount
     ) {
         PagerItem(it)
     }
@@ -85,12 +84,11 @@
 @OptIn(ExperimentalFoundationApi::class)
 @Composable
 internal fun HorizontalPagerDemo() {
-    val pagerState = rememberPagerState()
+    val pagerState = rememberPagerState { PagesCount }
 
     HorizontalPager(
         modifier = Modifier.fillMaxSize(),
         state = pagerState,
-        pageCount = PagesCount
     ) {
         PagerItem(it)
     }
diff --git a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/pager/PagerStateInteractionsDemos.kt b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/pager/PagerStateInteractionsDemos.kt
index 48202c2..5922b08 100644
--- a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/pager/PagerStateInteractionsDemos.kt
+++ b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/pager/PagerStateInteractionsDemos.kt
@@ -46,13 +46,12 @@
 @OptIn(ExperimentalFoundationApi::class)
 @Composable
 private fun StateDrivenPage() {
-    val pagerState = rememberPagerState()
+    val pagerState = rememberPagerState { PagesCount }
 
     Column(modifier = Modifier.fillMaxSize()) {
         HorizontalPager(
             modifier = Modifier.weight(0.9f),
-            state = pagerState,
-            pageCount = PagesCount
+            state = pagerState
         ) {
             PagerItem(it)
         }
@@ -63,13 +62,12 @@
 @OptIn(ExperimentalFoundationApi::class)
 @Composable
 private fun StateDrivenPageWithMonitor() {
-    val pagerState = rememberPagerState()
+    val pagerState = rememberPagerState { PagesCount }
 
     Column(modifier = Modifier.fillMaxSize()) {
         HorizontalPager(
             modifier = Modifier.weight(0.8f),
-            state = pagerState,
-            pageCount = PagesCount
+            state = pagerState
         ) {
             PagerItem(it)
         }
@@ -81,12 +79,11 @@
 @OptIn(ExperimentalFoundationApi::class)
 @Composable
 private fun StateMonitoringPager() {
-    val pagerState = rememberPagerState()
+    val pagerState = rememberPagerState { PagesCount }
     Column(modifier = Modifier.fillMaxSize()) {
         HorizontalPager(
             modifier = Modifier.weight(0.9f),
-            state = pagerState,
-            pageCount = PagesCount
+            state = pagerState
         ) {
             PagerItem(it)
         }
@@ -107,7 +104,7 @@
 @OptIn(ExperimentalFoundationApi::class)
 @Composable
 private fun StateMonitoringCustomPageSize() {
-    val pagerState = rememberPagerState()
+    val pagerState = rememberPagerState { PagesCount }
 
     val fling = PagerDefaults.flingBehavior(
         state = pagerState, PagerSnapDistance.atMost(3)
@@ -117,7 +114,6 @@
         HorizontalPager(
             modifier = Modifier.weight(0.9f),
             state = pagerState,
-            pageCount = PagesCount,
             pageSize = PageSize.Fixed(96.dp),
             flingBehavior = fling
         ) {
diff --git a/compose/foundation/foundation/samples/src/main/java/androidx/compose/foundation/samples/PagerSamples.kt b/compose/foundation/foundation/samples/src/main/java/androidx/compose/foundation/samples/PagerSamples.kt
index bed4f40..b95aeb5 100644
--- a/compose/foundation/foundation/samples/src/main/java/androidx/compose/foundation/samples/PagerSamples.kt
+++ b/compose/foundation/foundation/samples/src/main/java/androidx/compose/foundation/samples/PagerSamples.kt
@@ -30,8 +30,8 @@
 import androidx.compose.foundation.pager.PageSize
 import androidx.compose.foundation.pager.VerticalPager
 import androidx.compose.foundation.pager.rememberPagerState
-import androidx.compose.material.Text
 import androidx.compose.material.Button
+import androidx.compose.material.Text
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.rememberCoroutineScope
 import androidx.compose.ui.Alignment
@@ -47,9 +47,10 @@
 @Composable
 fun SimpleHorizontalPagerSample() {
     // Creates a 1-pager/viewport horizontal pager with single page snapping
+    val state = rememberPagerState { 10 }
     HorizontalPager(
+        state = state,
         modifier = Modifier.fillMaxSize(),
-        pageCount = 10
     ) { page ->
         Box(
             modifier = Modifier
@@ -69,9 +70,10 @@
 @Composable
 fun SimpleVerticalPagerSample() {
     // Creates a 1-pager/viewport vertical pager with single page snapping
+    val state = rememberPagerState { 10 }
     VerticalPager(
-        modifier = Modifier.fillMaxSize(),
-        pageCount = 10
+        state = state,
+        modifier = Modifier.fillMaxSize()
     ) { page ->
         Box(
             modifier = Modifier
@@ -91,11 +93,10 @@
 @Composable
 fun PagerWithStateSample() {
     // You can use PagerState to define an initial page
-    val state = rememberPagerState(initialPage = 5)
+    val state = rememberPagerState(initialPage = 5) { 10 }
     HorizontalPager(
         modifier = Modifier.fillMaxSize(),
-        state = state,
-        pageCount = 10
+        state = state
     ) { page ->
         Box(
             modifier = Modifier
@@ -129,9 +130,10 @@
         }
     }
 
+    val state = rememberPagerState { 10 }
     HorizontalPager(
+        state = state,
         modifier = Modifier.fillMaxSize(),
-        pageCount = 10,
         pageSize = CustomPageSize
     ) { page ->
         Box(
@@ -151,12 +153,11 @@
 @Sampled
 @Composable
 fun ObservingStateChangesInPagerStateSample() {
-    val pagerState = rememberPagerState()
+    val pagerState = rememberPagerState { 10 }
     Column(modifier = Modifier.fillMaxSize()) {
         HorizontalPager(
             modifier = Modifier.weight(0.9f),
-            state = pagerState,
-            pageCount = 10
+            state = pagerState
         ) { page ->
             Box(
                 modifier = Modifier
@@ -169,9 +170,11 @@
                 Text(text = page.toString(), fontSize = 32.sp)
             }
         }
-        Column(modifier = Modifier
-            .weight(0.1f)
-            .fillMaxWidth()) {
+        Column(
+            modifier = Modifier
+                .weight(0.1f)
+                .fillMaxWidth()
+        ) {
             Text(text = "Current Page: ${pagerState.currentPage}")
             Text(text = "Target Page: ${pagerState.targetPage}")
             Text(text = "Settled Page Offset: ${pagerState.settledPage}")
@@ -183,13 +186,12 @@
 @Sampled
 @Composable
 fun AnimateScrollPageSample() {
-    val state = rememberPagerState()
+    val state = rememberPagerState { 10 }
     val animationScope = rememberCoroutineScope()
     Column {
         HorizontalPager(
             modifier = Modifier.weight(0.7f),
-            state = state,
-            pageCount = 10
+            state = state
         ) { page ->
             Box(
                 modifier = Modifier
@@ -203,7 +205,11 @@
             }
         }
 
-        Box(modifier = Modifier.weight(0.3f).fillMaxWidth(), contentAlignment = Alignment.Center) {
+        Box(
+            modifier = Modifier
+                .weight(0.3f)
+                .fillMaxWidth(), contentAlignment = Alignment.Center
+        ) {
             Button(onClick = {
                 animationScope.launch {
                     state.animateScrollToPage(state.currentPage + 1)
@@ -219,13 +225,12 @@
 @Sampled
 @Composable
 fun ScrollToPageSample() {
-    val state = rememberPagerState()
+    val state = rememberPagerState { 10 }
     val scrollScope = rememberCoroutineScope()
     Column {
         HorizontalPager(
             modifier = Modifier.height(400.dp),
-            state = state,
-            pageCount = 10
+            state = state
         ) { page ->
             Box(
                 modifier = Modifier
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/pager/BasePagerTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/pager/BasePagerTest.kt
index 514a0b9..1905bee 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/pager/BasePagerTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/pager/BasePagerTest.kt
@@ -23,6 +23,7 @@
 import androidx.compose.foundation.background
 import androidx.compose.foundation.focusable
 import androidx.compose.foundation.gestures.Orientation
+import androidx.compose.foundation.gestures.snapping.MinFlingVelocityDp
 import androidx.compose.foundation.gestures.snapping.SnapFlingBehavior
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.PaddingValues
@@ -69,6 +70,7 @@
     lateinit var focusManager: FocusManager
     lateinit var firstItemFocusRequester: FocusRequester
     var composeView: View? = null
+    lateinit var pagerState: PagerState
 
     fun TouchInjectionScope.swipeWithVelocityAcrossMainAxis(velocity: Float, delta: Float? = null) {
         val end = if (delta == null) {
@@ -107,9 +109,10 @@
         }
 
     internal fun createPager(
-        state: PagerState,
-        modifier: Modifier = Modifier,
+        initialPage: Int = 0,
+        initialPageOffsetFraction: Float = 0f,
         pageCount: () -> Int = { DefaultPageCount },
+        modifier: Modifier = Modifier,
         offscreenPageLimit: Int = config.beyondBoundsPageCount,
         pageSize: () -> PageSize = { PageSize.Fill },
         userScrollEnabled: Boolean = true,
@@ -119,17 +122,22 @@
         contentPadding: PaddingValues = config.mainAxisContentPadding,
         pageSpacing: Dp = config.pageSpacing,
         reverseLayout: Boolean = config.reverseLayout,
+        snapVelocityThreshold: Dp = MinFlingVelocityDp,
         key: ((index: Int) -> Any)? = null,
         pageContent: @Composable (page: Int) -> Unit = { Page(index = it) }
     ) {
 
         rule.setContent {
+            val state = rememberPagerState(initialPage, initialPageOffsetFraction, pageCount).also {
+                pagerState = it
+            }
             composeView = LocalView.current
             focusManager = LocalFocusManager.current
             val flingBehavior =
                 PagerDefaults.flingBehavior(
                     state = state,
-                    pagerSnapDistance = snappingPage
+                    pagerSnapDistance = snappingPage,
+                    snapVelocityThreshold = snapVelocityThreshold
                 )
             CompositionLocalProvider(
                 LocalLayoutDirection provides config.layoutDirection,
@@ -142,7 +150,6 @@
                         .nestedScroll(nestedScrollConnection)
                 ) {
                     HorizontalOrVerticalPager(
-                        pageCount = pageCount(),
                         state = state,
                         beyondBoundsPageCount = offscreenPageLimit,
                         modifier = modifier
@@ -259,8 +266,7 @@
     @OptIn(ExperimentalFoundationApi::class)
     @Composable
     internal fun HorizontalOrVerticalPager(
-        pageCount: Int,
-        state: PagerState = rememberPagerState(),
+        state: PagerState = rememberPagerState(pageCount = { DefaultPageCount }),
         modifier: Modifier = Modifier,
         userScrollEnabled: Boolean = true,
         reverseLayout: Boolean = false,
@@ -274,7 +280,6 @@
     ) {
         if (vertical) {
             VerticalPager(
-                pageCount = pageCount,
                 state = state,
                 modifier = modifier,
                 userScrollEnabled = userScrollEnabled,
@@ -289,7 +294,6 @@
             )
         } else {
             HorizontalPager(
-                pageCount = pageCount,
                 state = state,
                 modifier = modifier,
                 userScrollEnabled = userScrollEnabled,
@@ -370,7 +374,3 @@
     PaddingValues(start = 16.dp),
     PaddingValues(end = 16.dp)
 )
-
-open class SingleOrientationPagerTest(
-    orientation: Orientation
-) : BasePagerTest(ParamConfig(orientation))
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/pager/EmptyPagerTests.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/pager/EmptyPagerTests.kt
index 1680009..3527b40 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/pager/EmptyPagerTests.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/pager/EmptyPagerTests.kt
@@ -33,10 +33,8 @@
     @Test
     fun checkNoPagesArePlaced() {
         // Arrange
-        val state = PagerState()
-
         // Act
-        createPager(state = state, modifier = Modifier.fillMaxSize(), pageCount = { 0 })
+        createPager(pageCount = { 0 }, modifier = Modifier.fillMaxSize())
 
         // Assert
         rule.onNodeWithTag("0").assertDoesNotExist()
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/pager/PageLayoutPositionOnScrollingTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/pager/PageLayoutPositionOnScrollingTest.kt
index bd96983..6531eba 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/pager/PageLayoutPositionOnScrollingTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/pager/PageLayoutPositionOnScrollingTest.kt
@@ -38,8 +38,7 @@
     @Test
     fun swipeForwardAndBackward_verifyPagesAreLaidOutCorrectly() {
         // Arrange
-        val state = PagerState()
-        createPager(state = state, modifier = Modifier.fillMaxSize())
+        createPager(modifier = Modifier.fillMaxSize())
         val delta = pagerSize * 0.4f * scrollForwardSign
 
         // Act and Assert - forward
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/pager/PageSizeTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/pager/PageSizeTest.kt
index eebddc6..988a695 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/pager/PageSizeTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/pager/PageSizeTest.kt
@@ -36,10 +36,9 @@
     @Test
     fun pageSizeFill_onlySnappedItemIsDisplayed() {
         // Arrange
-        val state = PagerState(5)
 
         // Act
-        createPager(state = state, modifier = Modifier.fillMaxSize())
+        createPager(initialPage = 5, modifier = Modifier.fillMaxSize())
 
         // Assert
         rule.onNodeWithTag("4").assertDoesNotExist()
@@ -51,7 +50,6 @@
     @Test
     fun pagerSizeCustom_visibleItemsAreWithinViewport() {
         // Arrange
-        val state = PagerState(5)
         val pagerMode = object : PageSize {
             override fun Density.calculateMainAxisPageSize(
                 availableSpace: Int,
@@ -63,7 +61,7 @@
 
         // Act
         createPager(
-            state = state,
+            initialPage = 5,
             modifier = Modifier.crossAxisSize(200.dp),
             offscreenPageLimit = 0,
             pageSize = { pagerMode }
@@ -71,14 +69,14 @@
 
         // Assert
         rule.runOnIdle {
-            val visibleItems = state.layoutInfo.visiblePagesInfo.size
+            val visibleItems = pagerState.layoutInfo.visiblePagesInfo.size
             val pageCount = with(rule.density) {
                 (pagerSize / (pageSize + config.pageSpacing.roundToPx()))
             } + 1
             Truth.assertThat(visibleItems).isEqualTo(pageCount)
         }
 
-        for (pageIndex in 5 until state.layoutInfo.visiblePagesInfo.size + 4) {
+        for (pageIndex in 5 until pagerState.layoutInfo.visiblePagesInfo.size + 4) {
             confirmPageIsInCorrectPosition(5, pageIndex)
         }
     }
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/pager/PagerAccessibilityTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/pager/PagerAccessibilityTest.kt
index ff8f42c..06cd075 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/pager/PagerAccessibilityTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/pager/PagerAccessibilityTest.kt
@@ -52,24 +52,22 @@
 
     @Test
     fun accessibilityScroll_scrollToPage() {
-        val state = PagerState()
-        createPager(state, offscreenPageLimit = 1)
+        createPager(offscreenPageLimit = 1)
 
-        rule.runOnIdle { assertThat(state.currentPage).isEqualTo(0) }
+        rule.runOnIdle { assertThat(pagerState.currentPage).isEqualTo(0) }
 
         rule.onNodeWithTag("1").assertExists()
         rule.onNodeWithTag("1").performScrollTo()
 
-        rule.runOnIdle { assertThat(state.currentPage).isEqualTo(1) }
-        rule.runOnIdle { assertThat(state.currentPageOffsetFraction).isEqualTo(0.0f) }
+        rule.runOnIdle { assertThat(pagerState.currentPage).isEqualTo(1) }
+        rule.runOnIdle { assertThat(pagerState.currentPageOffsetFraction).isEqualTo(0.0f) }
     }
 
     @Test
     fun accessibilityPaging_animateScrollToPage() {
-        val state = PagerState(initialPage = 5)
-        createPager(state)
+        createPager(initialPage = 5, pageCount = { DefaultPageCount })
 
-        rule.runOnIdle { assertThat(state.currentPage).isEqualTo(5) }
+        rule.runOnIdle { assertThat(pagerState.currentPage).isEqualTo(5) }
 
         val actionBackward = if (vertical) {
             android.R.id.accessibilityActionPageUp
@@ -86,8 +84,8 @@
         }
 
         // Go to the previous page
-        rule.runOnIdle { assertThat(state.currentPage).isEqualTo(4) }
-        rule.runOnIdle { assertThat(state.currentPageOffsetFraction).isEqualTo(0.0f) }
+        rule.runOnIdle { assertThat(pagerState.currentPage).isEqualTo(4) }
+        rule.runOnIdle { assertThat(pagerState.currentPageOffsetFraction).isEqualTo(0.0f) }
 
         val actionForward = if (vertical) {
             android.R.id.accessibilityActionPageDown
@@ -104,16 +102,15 @@
         }
 
         // Go to the next page
-        rule.runOnIdle { assertThat(state.currentPage).isEqualTo(5) }
-        rule.runOnIdle { assertThat(state.currentPageOffsetFraction).isEqualTo(0.0f) }
+        rule.runOnIdle { assertThat(pagerState.currentPage).isEqualTo(5) }
+        rule.runOnIdle { assertThat(pagerState.currentPageOffsetFraction).isEqualTo(0.0f) }
     }
 
     @Test
     fun userScrollEnabledIsOff_shouldNotAllowPageAccessibilityActions() {
         // Arrange
-        val state = PagerState()
         createPager(
-            state = state,
+            pageCount = { DefaultPageCount },
             userScrollEnabled = false,
             modifier = Modifier.fillMaxSize()
         )
@@ -129,23 +126,22 @@
     @Test
     fun focusScroll_forwardAndBackward_shouldGoToPage_pageShouldBeCorrectlyPlaced() {
         // Arrange
-        val state = PagerState()
-        createPager(state)
+        createPager(pageCount = { DefaultPageCount })
         rule.runOnIdle { firstItemFocusRequester.requestFocus() }
 
         // Act: move forward
         rule.runOnIdle { focusManager.moveFocus(FocusDirection.Next) }
 
         // Assert
-        rule.runOnIdle { assertThat(state.currentPage).isEqualTo(1) }
-        rule.runOnIdle { assertThat(state.currentPageOffsetFraction).isEqualTo(0.0f) }
+        rule.runOnIdle { assertThat(pagerState.currentPage).isEqualTo(1) }
+        rule.runOnIdle { assertThat(pagerState.currentPageOffsetFraction).isEqualTo(0.0f) }
 
         // Act: move backward
         rule.runOnIdle { focusManager.moveFocus(FocusDirection.Previous) }
 
         // Assert
-        rule.runOnIdle { assertThat(state.currentPage).isEqualTo(0) }
-        rule.runOnIdle { assertThat(state.currentPageOffsetFraction).isEqualTo(0.0f) }
+        rule.runOnIdle { assertThat(pagerState.currentPage).isEqualTo(0) }
+        rule.runOnIdle { assertThat(pagerState.currentPageOffsetFraction).isEqualTo(0.0f) }
     }
 
     private fun <T> SemanticsNodeInteraction.withSemanticsNode(block: SemanticsNode.() -> T): T {
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/pager/PagerContentPaddingTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/pager/PagerContentPaddingTest.kt
index 66adc7b..3ca1e45 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/pager/PagerContentPaddingTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/pager/PagerContentPaddingTest.kt
@@ -74,12 +74,10 @@
 
     @Test
     fun contentPaddingIsApplied() {
-        val state = PagerState()
         val containerSize = pageTotalSize * 2
         val largePaddingSize = pageTotalSize
 
         createPager(
-            state = state,
             modifier = Modifier
                 .requiredSize(containerSize)
                 .testTag(PagerTag),
@@ -104,7 +102,7 @@
             .assertCrossAxisSizeIsEqualTo(containerSize - smallPaddingSize * 2)
             .assertMainAxisSizeIsEqualTo(pageTotalSize)
 
-        state.scrollBy(largePaddingSize)
+        pagerState.scrollBy(largePaddingSize)
 
         rule.onNodeWithTag(PageTag)
             .assertStartPositionInRootIsEqualTo(0.dp)
@@ -113,10 +111,7 @@
 
     @Test
     fun contentPaddingIsNotAffectingScrollPosition() {
-        val state = PagerState()
-
         createPager(
-            state = state,
             modifier = Modifier
                 .requiredSize(pageTotalSize * 2)
                 .testTag(PagerTag),
@@ -132,19 +127,17 @@
             )
         }
 
-        state.assertScrollPosition(0, 0.dp)
+        pagerState.assertScrollPosition(0, 0.dp)
 
-        state.scrollBy(pageTotalSize)
+        pagerState.scrollBy(pageTotalSize)
 
-        state.assertScrollPosition(0, pageTotalSize)
+        pagerState.assertScrollPosition(0, pageTotalSize)
     }
 
     @Test
     fun scrollForwardItemWithinStartPaddingDisplayed() {
-        val state = PagerState()
         val padding = pageTotalSize * 1.5f
         createPager(
-            state = state,
             modifier = Modifier
                 .requiredSize(padding * 2 + pageTotalSize)
                 .testTag(PagerTag),
@@ -166,9 +159,9 @@
         rule.onNodeWithTag("2")
             .assertStartPositionInRootIsEqualTo(pageTotalSize * 2 + padding)
 
-        state.scrollBy(padding)
+        pagerState.scrollBy(padding)
 
-        state.assertScrollPosition(1, padding - pageTotalSize)
+        pagerState.assertScrollPosition(1, padding - pageTotalSize)
 
         rule.onNodeWithTag("0")
             .assertStartPositionInRootIsEqualTo(0.dp)
@@ -182,10 +175,8 @@
 
     @Test
     fun scrollBackwardItemWithinStartPaddingDisplayed() {
-        val state = PagerState()
         val padding = pageTotalSize * 1.5f
         createPager(
-            state = state,
             modifier = Modifier
                 .requiredSize(padding * 2 + pageTotalSize)
                 .testTag(PagerTag),
@@ -200,10 +191,10 @@
             )
         }
 
-        state.scrollBy(pageTotalSize * 3)
-        state.scrollBy(-pageTotalSize * 1.5f)
+        pagerState.scrollBy(pageTotalSize * 3)
+        pagerState.scrollBy(-pageTotalSize * 1.5f)
 
-        state.assertScrollPosition(1, pageTotalSize * 0.5f)
+        pagerState.assertScrollPosition(1, pageTotalSize * 0.5f)
 
         rule.onNodeWithTag("0")
             .assertStartPositionInRootIsEqualTo(pageTotalSize * 1.5f - padding)
@@ -217,10 +208,8 @@
 
     @Test
     fun scrollForwardTillTheEnd() {
-        val state = PagerState()
         val padding = pageTotalSize * 1.5f
         createPager(
-            state = state,
             modifier = Modifier
                 .requiredSize(padding * 2 + pageTotalSize)
                 .testTag(PagerTag),
@@ -235,9 +224,9 @@
             )
         }
 
-        state.scrollBy(pageTotalSize * 3)
+        pagerState.scrollBy(pageTotalSize * 3)
 
-        state.assertScrollPosition(3, 0.dp)
+        pagerState.assertScrollPosition(3, 0.dp)
 
         rule.onNodeWithTag("1")
             .assertStartPositionInRootIsEqualTo(pageTotalSize - padding)
@@ -247,9 +236,9 @@
             .assertStartPositionInRootIsEqualTo(pageTotalSize * 3 - padding)
 
         // there are no space to scroll anymore, so it should change nothing
-        state.scrollBy(10.dp)
+        pagerState.scrollBy(10.dp)
 
-        state.assertScrollPosition(3, 0.dp)
+        pagerState.assertScrollPosition(3, 0.dp)
 
         rule.onNodeWithTag("1")
             .assertStartPositionInRootIsEqualTo(pageTotalSize - padding)
@@ -261,10 +250,8 @@
 
     @Test
     fun scrollForwardTillTheEndAndABitBack() {
-        val state = PagerState()
         val padding = pageTotalSize * 1.5f
         createPager(
-            state = state,
             modifier = Modifier
                 .requiredSize(padding * 2 + pageTotalSize)
                 .testTag(PagerTag),
@@ -279,10 +266,10 @@
             )
         }
 
-        state.scrollBy(pageTotalSize * 3)
-        state.scrollBy(-pageTotalSize / 2)
+        pagerState.scrollBy(pageTotalSize * 3)
+        pagerState.scrollBy(-pageTotalSize / 2)
 
-        state.assertScrollPosition(2, pageTotalSize / 2)
+        pagerState.assertScrollPosition(2, pageTotalSize / 2)
 
         rule.onNodeWithTag("1")
             .assertStartPositionInRootIsEqualTo(pageTotalSize * 1.5f - padding)
@@ -295,15 +282,16 @@
     @Test
     fun contentPaddingAndWrapContent() {
         rule.setContent {
+            val state = rememberPagerState { 1 }
             Box(modifier = Modifier.testTag(ContainerTag)) {
                 HorizontalOrVerticalPager(
+                    state = state,
                     contentPadding = PaddingValues(
                         beforeContentCrossAxis = 2.dp,
                         beforeContent = 4.dp,
                         afterContentCrossAxis = 6.dp,
                         afterContent = 8.dp
                     ),
-                    pageCount = 1,
                     pageSize = PageSize.Fixed(pageTotalSize)
                 ) {
                     Spacer(
@@ -331,15 +319,16 @@
     @Test
     fun contentPaddingAndNoContent() {
         rule.setContent {
+            val state = rememberPagerState { 0 }
             Box(modifier = Modifier.testTag(ContainerTag)) {
                 HorizontalOrVerticalPager(
+                    state = state,
                     contentPadding = PaddingValues(
                         beforeContentCrossAxis = 2.dp,
                         beforeContent = 4.dp,
                         afterContentCrossAxis = 6.dp,
                         afterContent = 8.dp
                     ),
-                    pageCount = 0,
                     pageSize = PageSize.Fixed(pageTotalSize)
                 ) { }
             }
@@ -355,15 +344,16 @@
     @Test
     fun contentPaddingAndZeroSizedItem() {
         rule.setContent {
+            val state = rememberPagerState { 1 }
             Box(modifier = Modifier.testTag(ContainerTag)) {
                 HorizontalOrVerticalPager(
+                    state = state,
                     contentPadding = PaddingValues(
                         beforeContentCrossAxis = 2.dp,
                         beforeContent = 4.dp,
                         afterContentCrossAxis = 6.dp,
                         afterContent = 8.dp
                     ),
-                    pageCount = 1,
                     pageSize = PageSize.Fixed(0.dp)
                 ) {
                     Box { }
@@ -383,10 +373,8 @@
         val topPadding = pageTotalSize * 2
         val bottomPadding = pageTotalSize / 2
         val listSize = pageTotalSize * 3
-        val state = PagerState()
         createPager(
             reverseLayout = true,
-            state = state,
             modifier = Modifier.requiredSize(listSize),
             contentPadding = PaddingValues(
                 beforeContent = topPadding,
@@ -411,7 +399,7 @@
             .assertStartPositionInRootIsEqualTo(-pageTotalSize / 2)
 
         // Scroll to the top.
-        state.scrollBy(pageTotalSize * 2.5f)
+        pagerState.scrollBy(pageTotalSize * 2.5f)
 
         rule.onNodeWithTag("2").assertStartPositionInRootIsEqualTo(topPadding)
         // Shouldn't be visible
@@ -424,10 +412,8 @@
         val topPadding = pageTotalSize * 2
         val bottomPadding = pageTotalSize * 2
         val listSize = pageTotalSize * 3
-        val state = PagerState()
         createPager(
             reverseLayout = true,
-            state = state,
             modifier = Modifier.requiredSize(listSize),
             contentPadding = PaddingValues(
                 beforeContent = topPadding,
@@ -449,7 +435,7 @@
         rule.onNodeWithTag("1").assertDoesNotExist()
 
         // Scroll to the top.
-        state.scrollBy(pageTotalSize * 5f)
+        pagerState.scrollBy(pageTotalSize * 5f)
 
         rule.onNodeWithTag("2").assertStartPositionInRootIsEqualTo(topPadding)
         // Shouldn't be visible
@@ -461,7 +447,7 @@
     fun overscrollWithContentPadding() {
         lateinit var state: PagerState
         rule.setContent {
-            state = rememberPagerState()
+            state = rememberPagerState { 2 }
             Box(
                 modifier = Modifier
                     .testTag(ContainerTag)
@@ -470,7 +456,6 @@
                 HorizontalOrVerticalPager(
                     state = state,
                     contentPadding = PaddingValues(mainAxis = smallPaddingSize),
-                    pageCount = 2,
                     pageSize = PageSize.Fixed(pageTotalSize)
                 ) {
                     Box(
@@ -512,7 +497,7 @@
     fun totalPaddingLargerParentSize_initialState() {
         lateinit var state: PagerState
         rule.setContent {
-            state = rememberPagerState()
+            state = rememberPagerState() { 4 }
             Box(
                 modifier = Modifier
                     .testTag(ContainerTag)
@@ -521,7 +506,6 @@
                 HorizontalOrVerticalPager(
                     state = state,
                     contentPadding = PaddingValues(mainAxis = pageTotalSize),
-                    pageCount = 4,
                     pageSize = PageSize.Fixed(pageTotalSize)
                 ) {
                     Box(
@@ -550,7 +534,7 @@
     fun totalPaddingLargerParentSize_scrollByPadding() {
         lateinit var state: PagerState
         rule.setContent {
-            state = rememberPagerState()
+            state = rememberPagerState { 4 }
             Box(
                 modifier = Modifier
                     .testTag(ContainerTag)
@@ -559,7 +543,6 @@
                 HorizontalOrVerticalPager(
                     state = state,
                     contentPadding = PaddingValues(mainAxis = pageTotalSize),
-                    pageCount = 4,
                     pageSize = PageSize.Fixed(pageTotalSize)
                 ) {
                     Box(
@@ -592,7 +575,7 @@
     fun totalPaddingLargerParentSize_scrollToLastItem() {
         lateinit var state: PagerState
         rule.setContent {
-            state = rememberPagerState()
+            state = rememberPagerState { 4 }
             Box(
                 modifier = Modifier
                     .testTag(ContainerTag)
@@ -601,7 +584,6 @@
                 HorizontalOrVerticalPager(
                     state = state,
                     contentPadding = PaddingValues(mainAxis = pageTotalSize),
-                    pageCount = 4,
                     pageSize = PageSize.Fixed(pageTotalSize)
                 ) {
                     Box(
@@ -634,7 +616,7 @@
     fun totalPaddingLargerParentSize_scrollToLastItemByDelta() {
         lateinit var state: PagerState
         rule.setContent {
-            state = rememberPagerState()
+            state = rememberPagerState { 4 }
             Box(
                 modifier = Modifier
                     .testTag(ContainerTag)
@@ -644,7 +626,6 @@
                     state = state,
                     contentPadding = PaddingValues(mainAxis = pageTotalSize),
                     pageSize = PageSize.Fixed(pageTotalSize),
-                    pageCount = 4
                 ) {
                     Box(
                         Modifier
@@ -677,7 +658,7 @@
         // the whole end content padding is displayed
         lateinit var state: PagerState
         rule.setContent {
-            state = rememberPagerState()
+            state = rememberPagerState { 4 }
             Box(
                 modifier = Modifier
                     .testTag(ContainerTag)
@@ -686,8 +667,7 @@
                 HorizontalOrVerticalPager(
                     state = state,
                     contentPadding = PaddingValues(mainAxis = pageTotalSize),
-                    pageSize = PageSize.Fixed(pageTotalSize),
-                    pageCount = 4
+                    pageSize = PageSize.Fixed(pageTotalSize)
                 ) {
                     Box(
                         Modifier
@@ -716,7 +696,7 @@
     fun eachPaddingLargerParentSize_initialState() {
         lateinit var state: PagerState
         rule.setContent {
-            state = rememberPagerState()
+            state = rememberPagerState { 4 }
             Box(
                 modifier = Modifier
                     .testTag(ContainerTag)
@@ -725,8 +705,7 @@
                 HorizontalOrVerticalPager(
                     state = state,
                     contentPadding = PaddingValues(mainAxis = pageTotalSize * 2),
-                    pageSize = PageSize.Fixed(pageTotalSize),
-                    pageCount = 4
+                    pageSize = PageSize.Fixed(pageTotalSize)
                 ) {
                     Box(
                         Modifier
@@ -751,7 +730,7 @@
     fun eachPaddingLargerParentSize_scrollByPadding() {
         lateinit var state: PagerState
         rule.setContent {
-            state = rememberPagerState()
+            state = rememberPagerState { 4 }
             Box(
                 modifier = Modifier
                     .testTag(ContainerTag)
@@ -760,8 +739,7 @@
                 HorizontalOrVerticalPager(
                     state = state,
                     contentPadding = PaddingValues(mainAxis = pageTotalSize * 2),
-                    pageSize = PageSize.Fixed(pageTotalSize),
-                    pageCount = 4
+                    pageSize = PageSize.Fixed(pageTotalSize)
                 ) {
                     Box(
                         Modifier
@@ -793,7 +771,7 @@
     fun eachPaddingLargerParentSize_scrollToLastItem() {
         lateinit var state: PagerState
         rule.setContent {
-            state = rememberPagerState()
+            state = rememberPagerState { 4 }
             Box(
                 modifier = Modifier
                     .testTag(ContainerTag)
@@ -802,8 +780,7 @@
                 HorizontalOrVerticalPager(
                     state = state,
                     contentPadding = PaddingValues(mainAxis = pageTotalSize * 2),
-                    pageSize = PageSize.Fixed(pageTotalSize),
-                    pageCount = 4
+                    pageSize = PageSize.Fixed(pageTotalSize)
                 ) {
                     Box(
                         Modifier
@@ -838,7 +815,7 @@
     fun eachPaddingLargerParentSize_scrollToLastItemByDelta() {
         lateinit var state: PagerState
         rule.setContent {
-            state = rememberPagerState()
+            state = rememberPagerState { 4 }
             Box(
                 modifier = Modifier
                     .testTag(ContainerTag)
@@ -847,8 +824,7 @@
                 HorizontalOrVerticalPager(
                     state = state,
                     contentPadding = PaddingValues(mainAxis = pageTotalSize * 2),
-                    pageSize = PageSize.Fixed(pageTotalSize),
-                    pageCount = 4
+                    pageSize = PageSize.Fixed(pageTotalSize)
                 ) {
                     Box(
                         Modifier
@@ -884,7 +860,7 @@
         // only the end content padding is displayed
         lateinit var state: PagerState
         rule.setContent {
-            state = rememberPagerState()
+            state = rememberPagerState { 4 }
             Box(
                 modifier = Modifier
                     .testTag(ContainerTag)
@@ -893,8 +869,7 @@
                 HorizontalOrVerticalPager(
                     state = state,
                     contentPadding = PaddingValues(mainAxis = pageTotalSize * 2),
-                    pageSize = PageSize.Fixed(pageTotalSize),
-                    pageCount = 4
+                    pageSize = PageSize.Fixed(pageTotalSize)
                 ) {
                     Box(
                         Modifier
@@ -925,7 +900,7 @@
         val padding = PaddingValues(start = 20.dp, end = 8.dp)
         lateinit var state: PagerState
         rule.setContent {
-            state = rememberPagerState()
+            state = rememberPagerState { 4 }
             CompositionLocalProvider(LocalLayoutDirection provides LayoutDirection.Rtl) {
                 HorizontalOrVerticalPager(
                     modifier = Modifier
@@ -933,7 +908,6 @@
                         .mainAxisSize(pageTotalSize * 2),
                     state = state,
                     contentPadding = padding,
-                    pageCount = 4,
                     pageSize = PageSize.Fixed(pageTotalSize)
                 ) {
                     Box(
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/pager/PagerContentTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/pager/PagerContentTest.kt
index 2c60da4..4f02a20 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/pager/PagerContentTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/pager/PagerContentTest.kt
@@ -16,10 +16,10 @@
 
 package androidx.compose.foundation.pager
 
+import android.os.Build
 import androidx.compose.foundation.ExperimentalFoundationApi
 import androidx.compose.foundation.ScrollState
 import androidx.compose.foundation.background
-import androidx.compose.foundation.gestures.Orientation
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.Column
 import androidx.compose.foundation.layout.PaddingValues
@@ -30,31 +30,39 @@
 import androidx.compose.foundation.layout.width
 import androidx.compose.foundation.rememberScrollState
 import androidx.compose.foundation.verticalScroll
+import androidx.compose.testutils.assertPixels
 import androidx.compose.ui.Modifier
-import androidx.compose.ui.draw.drawWithContent
+import androidx.compose.ui.draw.drawBehind
+import androidx.compose.ui.geometry.Offset
+import androidx.compose.ui.geometry.Size
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.platform.testTag
+import androidx.compose.ui.test.captureToImage
+import androidx.compose.ui.test.junit4.createComposeRule
 import androidx.compose.ui.test.onNodeWithTag
 import androidx.compose.ui.test.performTouchInput
 import androidx.compose.ui.test.swipe
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.zIndex
+import androidx.test.filters.SdkSuppress
 import com.google.common.truth.Truth
-import kotlin.test.assertContentEquals
 import kotlin.test.assertTrue
+import org.junit.Rule
 import org.junit.Test
 
-class PagerContentTest : SingleOrientationPagerTest(Orientation.Horizontal) {
+class PagerContentTest {
+
+    @get:Rule
+    val rule = createComposeRule()
 
     @OptIn(ExperimentalFoundationApi::class)
     @Test
     fun pageContent_makeSureContainerOwnsOutsideModifiers() {
         // Arrange
-        val state = PagerState()
+        lateinit var state: PagerState
         rule.setContent {
-            HorizontalOrVerticalPager(
-                pageCount = 10,
-                state = state,
+            HorizontalPager(
+                state = rememberPagerState { 10 }.also { state = it },
                 contentPadding = PaddingValues(horizontal = 32.dp),
                 pageSpacing = 4.dp,
                 modifier = Modifier
@@ -82,45 +90,51 @@
 
     @OptIn(ExperimentalFoundationApi::class)
     @Test
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
     fun pageContent_makeSureInnerModifiersAreAppliedToPages() {
         // Arrange
-        val state = PagerState()
-        val drawingList = mutableListOf<Int>()
+        val colors = listOf(Color.Blue, Color.Green, Color.Red)
         rule.setContent {
-            HorizontalOrVerticalPager(
-                pageCount = 10,
-                state = state,
+            HorizontalPager(
+                state = rememberPagerState { colors.size },
                 modifier = Modifier
-                    .width(100.dp)
-                    .testTag("pager"),
-                pageSize = PageSize.Fixed(10.dp)
+                    .width(6.dp)
+                    .testTag(PagerTestTag),
+                pageSize = PageSize.Fixed(2.dp)
             ) { page ->
+                val color = colors[page]
                 Box(
                     modifier = Modifier
-                        .background(Color.Black)
-                        .size(100.dp)
-                        .zIndex(if (page % 2 == 0) 100f else 50f)
-                        .drawWithContent {
-                            drawingList.add(page)
-                        }
                         .testTag(page.toString())
+                        .width(2.dp)
+                        .height(6.dp)
+                        .zIndex(if (color == Color.Green) 1f else 0f)
+                        .drawBehind {
+                            drawRect(
+                                color,
+                                topLeft = Offset(-10.dp.toPx(), -10.dp.toPx()),
+                                size = Size(20.dp.toPx(), 20.dp.toPx())
+                            )
+                        }
                 )
             }
         }
 
-        rule.runOnIdle {
-            assertContentEquals(drawingList, listOf(1, 3, 5, 7, 9, 0, 2, 4, 6, 8))
-        }
+        rule.onNodeWithTag(PagerTestTag)
+            .captureToImage()
+            .assertPixels { Color.Green }
     }
 
     @OptIn(ExperimentalFoundationApi::class)
     @Test
     fun scrollableState_isScrollableWhenChangingPages() {
         val states = mutableMapOf<Int, ScrollState>()
-        val pagerState = PagerState()
+        val pagerState = PagerStateImpl(
+            initialPage = 0,
+            initialPageOffsetFraction = 0.0f,
+            updatedPageCount = { 2 })
         rule.setContent {
             HorizontalPager(
-                pageCount = 2,
                 state = pagerState,
                 modifier = Modifier
                     .testTag("pager")
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/pager/PagerCrossAxisTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/pager/PagerCrossAxisTest.kt
index 33cc710..e9c8ddf 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/pager/PagerCrossAxisTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/pager/PagerCrossAxisTest.kt
@@ -54,8 +54,7 @@
         rule.setContent {
             InfiniteAxisRootComposable {
                 HorizontalOrVerticalPager(
-                    pageCount = DefaultPageCount,
-                    state = rememberPagerState(),
+                    state = rememberPagerState(pageCount = { DefaultPageCount }),
                     modifier = Modifier
                         .fillMaxHeight()
                         .fillMaxWidth()
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/pager/PagerLayoutInfoTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/pager/PagerLayoutInfoTest.kt
index a2b44b83..b9975e5 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/pager/PagerLayoutInfoTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/pager/PagerLayoutInfoTest.kt
@@ -57,10 +57,7 @@
 
     @Test
     fun visiblePagesAreCorrect() {
-        val state = PagerState()
-
         createPager(
-            state,
             modifier = Modifier.requiredSize(pageSizeDp * 3.5f),
             pageCount = { 5 },
             pageSize = { PageSize.Fixed(pageSizeDp) }
@@ -68,16 +65,13 @@
             Box(Modifier.requiredSize(pageSizeDp))
         }
         rule.runOnIdle {
-            state.layoutInfo.assertVisiblePages(count = 4)
+            pagerState.layoutInfo.assertVisiblePages(count = 4)
         }
     }
 
     @Test
     fun visiblePagesAreCorrectAfterScroll() {
-        val state = PagerState()
-
         createPager(
-            state,
             modifier = Modifier.requiredSize(pageSizeDp * 3.5f),
             pageCount = { 5 },
             pageSize = { PageSize.Fixed(pageSizeDp) }
@@ -87,11 +81,11 @@
 
         rule.runOnIdle {
             runBlocking {
-                state.scrollToPage(1)
-                state.scrollBy(10f)
+                pagerState.scrollToPage(1)
+                pagerState.scrollBy(10f)
             }
 
-            state.layoutInfo.assertVisiblePages(
+            pagerState.layoutInfo.assertVisiblePages(
                 count = 4,
                 startIndex = 1,
                 startOffset = -10
@@ -101,10 +95,7 @@
 
     @Test
     fun visiblePagesAreCorrectWithSpacing() {
-        val state = PagerState()
-
         createPager(
-            state,
             modifier = Modifier.requiredSize(pageSizeDp * 3.5f),
             pageCount = { 5 },
             pageSpacing = pageSizeDp,
@@ -114,22 +105,20 @@
         }
 
         rule.runOnIdle {
-            state.layoutInfo.assertVisiblePages(count = 2, spacing = pageSizePx)
+            pagerState.layoutInfo.assertVisiblePages(count = 2, spacing = pageSizePx)
         }
     }
 
     @Test
     fun visiblePagesAreObservableWhenWeScroll() {
-        val state = PagerState()
         val currentInfo = StableRef<PagerLayoutInfo?>(null)
         createPager(
-            state,
             modifier = Modifier.requiredSize(pageSizeDp * 3.5f),
             pageCount = { 5 },
             pageSize = { PageSize.Fixed(pageSizeDp) },
             additionalContent = {
-                LaunchedEffect(key1 = state) {
-                    snapshotFlow { state.layoutInfo }.collect {
+                LaunchedEffect(key1 = pagerState) {
+                    snapshotFlow { pagerState.layoutInfo }.collect {
                         currentInfo.value = it
                     }
                 }
@@ -142,7 +131,7 @@
             // empty it here and scrolling should invoke observingFun again
             currentInfo.value = null
             runBlocking {
-                state.scrollToPage(1)
+                pagerState.scrollToPage(1)
             }
         }
 
@@ -154,17 +143,15 @@
 
     @Test
     fun visiblePagesAreObservableWhenResize() {
-        val state = PagerState()
         var pageSize by mutableStateOf(PageSize.Fixed(pageSizeDp * 2))
         var currentInfo: PagerLayoutInfo? = null
 
         @Composable
         fun observingFun() {
-            currentInfo = state.layoutInfo
+            currentInfo = pagerState.layoutInfo
         }
 
         createPager(
-            state,
             pageCount = { 1 },
             pageSize = { pageSize },
             additionalContent = { observingFun() }
@@ -190,10 +177,7 @@
     @Test
     fun totalCountIsCorrect() {
         var count by mutableStateOf(10)
-        val state = PagerState()
-
         createPager(
-            state,
             pageCount = { count },
             pageSize = { PageSize.Fixed(10.dp) }
         ) {
@@ -201,12 +185,12 @@
         }
 
         rule.runOnIdle {
-            assertThat(state.layoutInfo.pagesCount).isEqualTo(10)
+            assertThat(pagerState.layoutInfo.pagesCount).isEqualTo(10)
             count = 20
         }
 
         rule.runOnIdle {
-            assertThat(state.layoutInfo.pagesCount).isEqualTo(20)
+            assertThat(pagerState.layoutInfo.pagesCount).isEqualTo(20)
         }
     }
 
@@ -214,10 +198,7 @@
     fun viewportOffsetsAndSizeAreCorrect() {
         val sizePx = 45
         val sizeDp = with(rule.density) { sizePx.toDp() }
-        val state = PagerState()
-
         createPager(
-            state,
             modifier = Modifier
                 .mainAxisSize(sizeDp)
                 .crossAxisSize(sizeDp * 2),
@@ -228,9 +209,9 @@
         }
 
         rule.runOnIdle {
-            assertThat(state.layoutInfo.viewportStartOffset).isEqualTo(0)
-            assertThat(state.layoutInfo.viewportEndOffset).isEqualTo(sizePx)
-            assertThat(state.layoutInfo.viewportSize).isEqualTo(
+            assertThat(pagerState.layoutInfo.viewportStartOffset).isEqualTo(0)
+            assertThat(pagerState.layoutInfo.viewportEndOffset).isEqualTo(sizePx)
+            assertThat(pagerState.layoutInfo.viewportSize).isEqualTo(
                 if (vertical) IntSize(sizePx * 2, sizePx) else IntSize(sizePx, sizePx * 2)
             )
         }
@@ -249,10 +230,8 @@
         val afterContentPaddingDp = with(rule.density) {
             if (!reverseLayout) endPaddingPx.toDp() else startPaddingPx.toDp()
         }
-        val state = PagerState()
 
         createPager(
-            state,
             modifier = Modifier
                 .mainAxisSize(sizeDp)
                 .crossAxisSize(sizeDp * 2),
@@ -269,10 +248,10 @@
         }
 
         rule.runOnIdle {
-            assertThat(state.layoutInfo.viewportStartOffset).isEqualTo(-startPaddingPx)
-            assertThat(state.layoutInfo.viewportEndOffset).isEqualTo(sizePx - startPaddingPx)
-            assertThat(state.layoutInfo.afterContentPadding).isEqualTo(endPaddingPx)
-            assertThat(state.layoutInfo.viewportSize).isEqualTo(
+            assertThat(pagerState.layoutInfo.viewportStartOffset).isEqualTo(-startPaddingPx)
+            assertThat(pagerState.layoutInfo.viewportEndOffset).isEqualTo(sizePx - startPaddingPx)
+            assertThat(pagerState.layoutInfo.afterContentPadding).isEqualTo(endPaddingPx)
+            assertThat(pagerState.layoutInfo.viewportSize).isEqualTo(
                 if (vertical) IntSize(sizePx * 2, sizePx) else IntSize(sizePx, sizePx * 2)
             )
         }
@@ -280,10 +259,7 @@
 
     @Test
     fun emptyPagesInVisiblePagesInfo() {
-        val state = PagerState()
-
         createPager(
-            state,
             pageCount = { 2 },
             pageSize = { PageSize.Fixed(pageSizeDp) }
         ) {
@@ -291,9 +267,9 @@
         }
 
         rule.runOnIdle {
-            assertThat(state.layoutInfo.visiblePagesInfo.size).isEqualTo(2)
-            assertThat(state.layoutInfo.visiblePagesInfo.first().index).isEqualTo(0)
-            assertThat(state.layoutInfo.visiblePagesInfo.last().index).isEqualTo(1)
+            assertThat(pagerState.layoutInfo.visiblePagesInfo.size).isEqualTo(2)
+            assertThat(pagerState.layoutInfo.visiblePagesInfo.first().index).isEqualTo(0)
+            assertThat(pagerState.layoutInfo.visiblePagesInfo.last().index).isEqualTo(1)
         }
     }
 
@@ -310,10 +286,8 @@
         val afterContentPaddingDp = with(rule.density) {
             if (!reverseLayout) endPaddingPx.toDp() else startPaddingPx.toDp()
         }
-        val state = PagerState()
 
         createPager(
-            state,
             modifier = Modifier
                 .mainAxisSize(sizeDp)
                 .crossAxisSize(sizeDp * 2),
@@ -328,11 +302,11 @@
         ) {}
 
         rule.runOnIdle {
-            assertThat(state.layoutInfo.viewportStartOffset).isEqualTo(-startPaddingPx)
-            assertThat(state.layoutInfo.viewportEndOffset).isEqualTo(sizePx - startPaddingPx)
-            assertThat(state.layoutInfo.beforeContentPadding).isEqualTo(startPaddingPx)
-            assertThat(state.layoutInfo.afterContentPadding).isEqualTo(endPaddingPx)
-            assertThat(state.layoutInfo.viewportSize).isEqualTo(
+            assertThat(pagerState.layoutInfo.viewportStartOffset).isEqualTo(-startPaddingPx)
+            assertThat(pagerState.layoutInfo.viewportEndOffset).isEqualTo(sizePx - startPaddingPx)
+            assertThat(pagerState.layoutInfo.beforeContentPadding).isEqualTo(startPaddingPx)
+            assertThat(pagerState.layoutInfo.afterContentPadding).isEqualTo(endPaddingPx)
+            assertThat(pagerState.layoutInfo.viewportSize).isEqualTo(
                 if (vertical) IntSize(sizePx * 2, sizePx) else IntSize(sizePx, sizePx * 2)
             )
         }
@@ -351,10 +325,8 @@
         val afterContentPaddingDp = with(rule.density) {
             if (!reverseLayout) endPaddingPx.toDp() else startPaddingPx.toDp()
         }
-        val state = PagerState()
 
         createPager(
-            state,
             modifier = Modifier
                 .mainAxisSize(sizeDp)
                 .crossAxisSize(sizeDp * 2),
@@ -371,11 +343,11 @@
         }
 
         rule.runOnIdle {
-            assertThat(state.layoutInfo.viewportStartOffset).isEqualTo(-startPaddingPx)
-            assertThat(state.layoutInfo.viewportEndOffset).isEqualTo(sizePx - startPaddingPx)
-            assertThat(state.layoutInfo.beforeContentPadding).isEqualTo(startPaddingPx)
-            assertThat(state.layoutInfo.afterContentPadding).isEqualTo(endPaddingPx)
-            assertThat(state.layoutInfo.viewportSize).isEqualTo(
+            assertThat(pagerState.layoutInfo.viewportStartOffset).isEqualTo(-startPaddingPx)
+            assertThat(pagerState.layoutInfo.viewportEndOffset).isEqualTo(sizePx - startPaddingPx)
+            assertThat(pagerState.layoutInfo.beforeContentPadding).isEqualTo(startPaddingPx)
+            assertThat(pagerState.layoutInfo.afterContentPadding).isEqualTo(endPaddingPx)
+            assertThat(pagerState.layoutInfo.viewportSize).isEqualTo(
                 if (vertical) IntSize(sizePx * 2, sizePx) else IntSize(sizePx, sizePx * 2)
             )
         }
@@ -383,10 +355,7 @@
 
     @Test
     fun reverseLayoutIsCorrect() {
-        val state = PagerState()
-
         createPager(
-            state,
             modifier = Modifier.requiredSize(pageSizeDp * 3.5f),
             pageCount = { 5 },
             pageSize = { PageSize.Fixed(pageSizeDp) }
@@ -395,17 +364,13 @@
         }
 
         rule.runOnIdle {
-            assertThat(state.layoutInfo.reverseLayout).isEqualTo(param.reverseLayout)
+            assertThat(pagerState.layoutInfo.reverseLayout).isEqualTo(param.reverseLayout)
         }
     }
 
     @Test
     fun orientationIsCorrect() {
-
-        val state = PagerState()
-
         createPager(
-            state,
             modifier = Modifier.requiredSize(pageSizeDp * 3.5f),
             pageCount = { 5 },
             pageSize = { PageSize.Fixed(pageSizeDp) }
@@ -414,7 +379,7 @@
         }
 
         rule.runOnIdle {
-            assertThat(state.layoutInfo.orientation)
+            assertThat(pagerState.layoutInfo.orientation)
                 .isEqualTo(if (vertical) Orientation.Vertical else Orientation.Horizontal)
         }
     }
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/pager/PagerNestedScrollContentTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/pager/PagerNestedScrollContentTest.kt
index ffa4aed..78b2758 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/pager/PagerNestedScrollContentTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/pager/PagerNestedScrollContentTest.kt
@@ -20,7 +20,6 @@
 import androidx.compose.foundation.gestures.ScrollableDefaults
 import androidx.compose.foundation.layout.Arrangement
 import androidx.compose.foundation.layout.Box
-import androidx.compose.foundation.layout.PaddingValues
 import androidx.compose.foundation.layout.fillMaxSize
 import androidx.compose.foundation.layout.size
 import androidx.compose.foundation.lazy.LazyList
@@ -35,10 +34,10 @@
 import androidx.compose.ui.unit.Velocity
 import androidx.compose.ui.unit.dp
 import androidx.test.filters.LargeTest
-import org.junit.Assert.assertEquals
 import com.google.common.truth.Truth.assertThat
 import kotlin.math.absoluteValue
 import kotlinx.coroutines.runBlocking
+import org.junit.Assert.assertEquals
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.junit.runners.Parameterized
@@ -54,8 +53,7 @@
     @Test
     fun nestedScrollContent_shouldNotPropagateUnconsumedFlings() {
         // Arrange
-        val pagerState = PagerState()
-        createPager(pagerState) {
+        createPager(pageCount = { DefaultPageCount }) {
             LazyList(
                 modifier = Modifier.fillMaxSize(),
                 contentPadding = PaddingValues(0.dp),
@@ -93,7 +91,6 @@
     @Test
     fun nestedScrollContent_shouldPropagateCrossAxisUnconsumedFlings() {
         // Arrange
-        val pagerState = PagerState()
         var postFlingVelocity = Velocity.Zero
         val dataCapturingConnection = object : NestedScrollConnection {
             override suspend fun onPostFling(consumed: Velocity, available: Velocity): Velocity {
@@ -101,7 +98,10 @@
                 return Velocity.Zero
             }
         }
-        createPager(pagerState, nestedScrollConnection = dataCapturingConnection) {
+        createPager(
+            pageCount = { DefaultPageCount },
+            nestedScrollConnection = dataCapturingConnection
+        ) {
             LazyList(
                 modifier = Modifier.fillMaxSize(),
                 contentPadding = PaddingValues(0.dp),
@@ -141,9 +141,8 @@
     @Test
     fun nestedScrollContent_shouldPropagateScrollCorrectly() {
         // Arrange
-        val pagerState = PagerState()
         val lazyListState = LazyListState(9)
-        createPager(pagerState) {
+        createPager(pageCount = { DefaultPageCount }) {
             LazyList(
                 modifier = Modifier.fillMaxSize(),
                 contentPadding = PaddingValues(0.dp),
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/pager/PagerOffscreenPageLimitPlacingTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/pager/PagerOffscreenPageLimitPlacingTest.kt
index 4e93b07..aaf1a6f 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/pager/PagerOffscreenPageLimitPlacingTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/pager/PagerOffscreenPageLimitPlacingTest.kt
@@ -36,8 +36,11 @@
     @Test
     fun offscreenPageLimitIsUsed_shouldPlaceMoreItemsThanVisibleOnesAsWeScroll() {
         // Arrange
-        val state = PagerState()
-        createPager(state = state, modifier = Modifier.fillMaxSize(), offscreenPageLimit = 1)
+        createPager(
+            pageCount = { DefaultPageCount },
+            modifier = Modifier.fillMaxSize(),
+            offscreenPageLimit = 1
+        )
         val delta = pagerSize * 1.4f * scrollForwardSign
 
         repeat(DefaultAnimationRepetition) {
@@ -50,25 +53,29 @@
             // Next page was placed
             rule.runOnIdle {
                 Truth.assertThat(placed).contains(
-                    (state.currentPage + 1)
+                    (pagerState.currentPage + 1)
                         .coerceAtMost(DefaultPageCount - 1)
                 )
             }
         }
         rule.waitForIdle()
-        confirmPageIsInCorrectPosition(state.currentPage)
+        confirmPageIsInCorrectPosition(pagerState.currentPage)
     }
 
     @Test
     fun offscreenPageLimitIsUsed_shouldPlaceMoreItemsThanVisibleOnes() {
         // Arrange
         val initialIndex = 5
-        val state = PagerState(initialIndex)
 
         // Act
-        createPager(state = state, modifier = Modifier.fillMaxSize(), offscreenPageLimit = 2)
-        val firstVisible = state.layoutInfo.visiblePagesInfo.first().index
-        val lastVisible = state.layoutInfo.visiblePagesInfo.last().index
+        createPager(
+            initialPage = initialIndex,
+            pageCount = { DefaultPageCount },
+            modifier = Modifier.fillMaxSize(),
+            offscreenPageLimit = 2
+        )
+        val firstVisible = pagerState.layoutInfo.visiblePagesInfo.first().index
+        val lastVisible = pagerState.layoutInfo.visiblePagesInfo.last().index
         // Assert
         rule.runOnIdle {
             Truth.assertThat(placed).contains(firstVisible - 2)
@@ -85,15 +92,19 @@
     @Test
     fun offscreenPageLimitIsNotUsed_shouldNotPlaceMoreItemsThanVisibleOnes() {
         // Arrange
-        val state = PagerState(5)
 
         // Act
-        createPager(state = state, modifier = Modifier.fillMaxSize(), offscreenPageLimit = 0)
+        createPager(
+            initialPage = 5,
+            pageCount = { DefaultPageCount },
+            modifier = Modifier.fillMaxSize(),
+            offscreenPageLimit = 0
+        )
 
         // Assert
         rule.waitForIdle()
-        val firstVisible = state.layoutInfo.visiblePagesInfo.first().index
-        val lastVisible = state.layoutInfo.visiblePagesInfo.last().index
+        val firstVisible = pagerState.layoutInfo.visiblePagesInfo.first().index
+        val lastVisible = pagerState.layoutInfo.visiblePagesInfo.last().index
         Truth.assertThat(placed).doesNotContain(firstVisible - 1)
         Truth.assertThat(placed).contains(5)
         Truth.assertThat(placed).doesNotContain(lastVisible + 1)
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/pager/PagerPinnableContainerTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/pager/PagerPinnableContainerTest.kt
index a56661e..abd50db 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/pager/PagerPinnableContainerTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/pager/PagerPinnableContainerTest.kt
@@ -18,10 +18,10 @@
 
 import androidx.compose.foundation.ExperimentalFoundationApi
 import androidx.compose.foundation.background
-import androidx.compose.foundation.gestures.Orientation
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.layout.width
 import androidx.compose.foundation.lazy.list.assertIsNotPlaced
 import androidx.compose.foundation.lazy.list.assertIsPlaced
 import androidx.compose.runtime.Composable
@@ -37,6 +37,7 @@
 import androidx.compose.ui.layout.PinnableContainer.PinnedHandle
 import androidx.compose.ui.platform.testTag
 import androidx.compose.ui.test.assertIsNotDisplayed
+import androidx.compose.ui.test.junit4.createComposeRule
 import androidx.compose.ui.test.onNodeWithTag
 import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.dp
@@ -44,18 +45,22 @@
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.runBlocking
 import org.junit.Before
+import org.junit.Rule
 import org.junit.Test
 
 @OptIn(ExperimentalFoundationApi::class)
 @MediumTest
-class PagerPinnableContainerTest :
-    SingleOrientationPagerTest(orientation = Orientation.Horizontal) {
+class PagerPinnableContainerTest {
+
+    @get:Rule
+    val rule = createComposeRule()
 
     private var pinnableContainer: PinnableContainer? = null
 
     private var pageSizeDp = Dp.Unspecified
 
     private val composed = mutableSetOf<Int>()
+    private lateinit var pagerState: PagerState
 
     @Before
     fun setup() {
@@ -81,13 +86,11 @@
 
     @Test
     fun pinnedPageIsComposedAndPlacedWhenScrolledOut() {
-        val state = PagerState()
         // Arrange.
         rule.setContent {
-            HorizontalOrVerticalPager(
-                state = state,
+            HorizontalPager(
+                state = rememberPagerState { 100 }.also { pagerState = it },
                 modifier = Modifier.size(pageSizeDp * 2),
-                pageCount = 100,
                 pageSize = PageSize.Fixed(pageSizeDp)
             ) { page ->
                 if (page == 1) {
@@ -104,7 +107,7 @@
         rule.runOnIdle {
             assertThat(composed).contains(1)
             runBlocking {
-                state.scrollToPage(3)
+                pagerState.scrollToPage(3)
             }
         }
 
@@ -126,13 +129,11 @@
 
     @Test
     fun pagesBetweenPinnedAndCurrentVisibleAreNotComposed() {
-        val state = PagerState()
         // Arrange.
         rule.setContent {
-            HorizontalOrVerticalPager(
-                state = state,
+            HorizontalPager(
+                state = rememberPagerState { 100 }.also { pagerState = it },
                 modifier = Modifier.size(pageSizeDp * 2),
-                pageCount = 100,
                 pageSize = PageSize.Fixed(pageSizeDp)
             ) { page ->
                 if (page == 1) {
@@ -148,7 +149,7 @@
 
         rule.runOnIdle {
             runBlocking {
-                state.scrollToPage(4)
+                pagerState.scrollToPage(4)
             }
         }
 
@@ -168,13 +169,11 @@
 
     @Test
     fun pinnedPageAfterVisibleOnesIsComposedAndPlacedWhenScrolledOut() {
-        val state = PagerState()
         // Arrange.
         rule.setContent {
-            HorizontalOrVerticalPager(
-                state = state,
+            HorizontalPager(
+                state = rememberPagerState { 100 }.also { pagerState = it },
                 modifier = Modifier.size(pageSizeDp * 2),
-                pageCount = 100,
                 pageSize = PageSize.Fixed(pageSizeDp)
             ) { page ->
                 if (page == 4) {
@@ -186,7 +185,7 @@
 
         rule.runOnIdle {
             runBlocking {
-                state.scrollToPage(4)
+                pagerState.scrollToPage(4)
             }
         }
 
@@ -202,7 +201,7 @@
 
         rule.runOnIdle {
             runBlocking {
-                state.scrollToPage(0)
+                pagerState.scrollToPage(0)
             }
         }
 
@@ -223,13 +222,11 @@
 
     @Test
     fun pinnedPageCanBeUnpinned() {
-        val state = PagerState()
         // Arrange.
         rule.setContent {
-            HorizontalOrVerticalPager(
-                state = state,
+            HorizontalPager(
+                state = rememberPagerState { 100 }.also { pagerState = it },
                 modifier = Modifier.size(pageSizeDp * 2),
-                pageCount = 100,
                 pageSize = PageSize.Fixed(pageSizeDp)
             ) { page ->
                 if (page == 1) {
@@ -245,7 +242,7 @@
 
         rule.runOnIdle {
             runBlocking {
-                state.scrollToPage(3)
+                pagerState.scrollToPage(3)
             }
         }
 
@@ -269,11 +266,10 @@
 
     @Test
     fun pinnedPageIsStillPinnedWhenReorderedAndNotVisibleAnymore() {
-        val state = PagerState()
         var list by mutableStateOf(listOf(0, 1, 2, 3, 4))
         // Arrange.
         rule.setContent {
-            Pager(state, list, 2, 3)
+            Pager(list, 2, 3)
         }
 
         rule.runOnIdle {
@@ -299,11 +295,10 @@
     }
 
     @Composable
-    fun Pager(state: PagerState, dataset: List<Int>, pinnedPage: Int, visiblePages: Int) {
-        HorizontalOrVerticalPager(
-            state = state,
-            modifier = Modifier.mainAxisSize(pageSizeDp * visiblePages),
-            pageCount = dataset.size,
+    fun Pager(dataset: List<Int>, pinnedPage: Int, visiblePages: Int) {
+        HorizontalPager(
+            state = rememberPagerState { dataset.size },
+            modifier = Modifier.width(pageSizeDp * visiblePages),
             pageSize = PageSize.Fixed(pageSizeDp),
             key = { dataset[it] }
         ) { page ->
@@ -316,13 +311,17 @@
 
     @Test
     fun unpinnedWhenPagerStateChanges() {
-        var state by mutableStateOf(PagerState(initialPage = 2))
+        var state by mutableStateOf(
+            PagerStateImpl(
+                initialPage = 2,
+                initialPageOffsetFraction = 0f,
+                updatedPageCount = { 100 })
+        )
         // Arrange.
         rule.setContent {
-            HorizontalOrVerticalPager(
+            HorizontalPager(
                 state = state,
                 modifier = Modifier.size(pageSizeDp * 2),
-                pageCount = 100,
                 pageSize = PageSize.Fixed(pageSizeDp)
             ) { page ->
                 if (page == 2) {
@@ -350,7 +349,10 @@
 
         rule.runOnIdle {
             assertThat(composed).contains(2)
-            state = PagerState()
+            state = PagerStateImpl(
+                initialPage = 0,
+                initialPageOffsetFraction = 0f,
+                updatedPageCount = { 100 })
         }
 
         rule.waitUntil {
@@ -364,13 +366,17 @@
 
     @Test
     fun pinAfterPagerStateChange() {
-        var state by mutableStateOf(PagerState())
+        var state by mutableStateOf(
+            PagerStateImpl(
+                initialPage = 0,
+                initialPageOffsetFraction = 0f,
+                updatedPageCount = { 100 })
+        )
         // Arrange.
         rule.setContent {
-            HorizontalOrVerticalPager(
+            HorizontalPager(
                 state = state,
                 modifier = Modifier.size(pageSizeDp * 2),
-                pageCount = 100,
                 pageSize = PageSize.Fixed(pageSizeDp)
             ) { page ->
                 if (page == 0) {
@@ -381,7 +387,10 @@
         }
 
         rule.runOnIdle {
-            state = PagerState()
+            state = PagerStateImpl(
+                initialPage = 0,
+                initialPageOffsetFraction = 0f,
+                updatedPageCount = { 100 })
         }
 
         rule.runOnIdle {
@@ -407,13 +416,12 @@
 
     @Test
     fun pagesArePinnedBasedOnGlobalIndexes() {
-        val state = PagerState(initialPage = 3)
         // Arrange.
+        lateinit var state: PagerState
         rule.setContent {
-            HorizontalOrVerticalPager(
-                state = state,
+            HorizontalPager(
+                state = rememberPagerState(initialPage = 3) { 100 }.also { state = it },
                 modifier = Modifier.size(pageSizeDp * 2),
-                pageCount = 100,
                 pageSize = PageSize.Fixed(pageSizeDp)
             ) { page ->
                 if (page == 3) {
@@ -451,14 +459,13 @@
 
     @Test
     fun pinnedPageIsRemovedWhenNotVisible() {
-        val state = PagerState(initialPage = 3)
+        lateinit var state: PagerState
         var pageCount by mutableStateOf(10)
         // Arrange.
         rule.setContent {
-            HorizontalOrVerticalPager(
-                state = state,
+            HorizontalPager(
+                state = rememberPagerState(initialPage = 3) { pageCount }.also { state = it },
                 modifier = Modifier.size(pageSizeDp * 2),
-                pageCount = pageCount,
                 pageSize = PageSize.Fixed(pageSizeDp)
             ) { page ->
                 if (page == 3) {
@@ -496,11 +503,10 @@
 
     @Test
     fun pinnedPageIsRemovedWhenVisible() {
-        val state = PagerState()
         var pages by mutableStateOf(listOf(0, 1, 2))
         // Arrange.
         rule.setContent {
-            Pager(state = state, dataset = pages, pinnedPage = 1, visiblePages = 2)
+            Pager(dataset = pages, pinnedPage = 1, visiblePages = 2)
         }
 
         rule.runOnIdle {
@@ -522,13 +528,11 @@
 
     @Test
     fun pinnedMultipleTimes() {
-        val state = PagerState(0)
         // Arrange.
         rule.setContent {
-            HorizontalOrVerticalPager(
-                state = state,
+            HorizontalPager(
+                state = rememberPagerState { 100 }.also { pagerState = it },
                 modifier = Modifier.size(pageSizeDp * 2),
-                pageCount = 100,
                 pageSize = PageSize.Fixed(pageSizeDp)
             ) { page ->
                 if (page == 1) {
@@ -549,7 +553,7 @@
             handles.add(requireNotNull(pinnableContainer).pin())
             assertThat(composed).contains(0)
             runBlocking {
-                state.scrollToPage(3)
+                pagerState.scrollToPage(3)
             }
         }
 
@@ -583,8 +587,8 @@
         // Arrange.
         rule.setContent {
             CompositionLocalProvider(LocalPinnableContainer provides parentContainer) {
-                HorizontalOrVerticalPager(
-                    pageCount = 1,
+                HorizontalPager(
+                    state = rememberPagerState { 1 },
                     pageSize = PageSize.Fixed(pageSizeDp)
                 ) {
                     pinnableContainer = LocalPinnableContainer.current
@@ -627,8 +631,8 @@
         // Arrange.
         rule.setContent {
             CompositionLocalProvider(LocalPinnableContainer provides parentContainer) {
-                HorizontalOrVerticalPager(
-                    pageCount = 1,
+                HorizontalPager(
+                    state = rememberPagerState { 1 },
                     pageSize = PageSize.Fixed(pageSizeDp)
                 ) {
                     pinnableContainer = LocalPinnableContainer.current
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/pager/PagerPrefetcherTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/pager/PagerPrefetcherTest.kt
index cedcfd6..18ab68b 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/pager/PagerPrefetcherTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/pager/PagerPrefetcherTest.kt
@@ -52,7 +52,6 @@
 
     var pageSizePx = 30
     val pageSizeDp = with(rule.density) { pageSizePx.toDp() }
-    lateinit var state: PagerState
 
     @Test
     fun notPrefetchingForwardInitially() {
@@ -76,7 +75,7 @@
         val preFetchIndex = 2
         rule.runOnIdle {
             runBlocking {
-                state.scrollBy(5f)
+                pagerState.scrollBy(5f)
             }
         }
 
@@ -94,7 +93,7 @@
 
         rule.runOnIdle {
             runBlocking {
-                state.scrollBy(-5f)
+                pagerState.scrollBy(-5f)
             }
         }
 
@@ -113,7 +112,7 @@
 
         rule.runOnIdle {
             runBlocking {
-                state.scrollBy(5f)
+                pagerState.scrollBy(5f)
             }
         }
         var prefetchIndex = initialIndex + 2
@@ -126,8 +125,8 @@
 
         rule.runOnIdle {
             runBlocking {
-                state.scrollBy(-2f)
-                state.scrollBy(-1f)
+                pagerState.scrollBy(-2f)
+                pagerState.scrollBy(-1f)
             }
         }
 
@@ -146,7 +145,7 @@
 
         rule.runOnIdle {
             runBlocking {
-                state.scrollBy(5f)
+                pagerState.scrollBy(5f)
             }
         }
 
@@ -154,8 +153,8 @@
 
         rule.runOnIdle {
             runBlocking {
-                state.scrollBy(pageSizePx / 2f)
-                state.scrollBy(pageSizePx / 2f)
+                pagerState.scrollBy(pageSizePx / 2f)
+                pagerState.scrollBy(pageSizePx / 2f)
             }
         }
 
@@ -177,7 +176,7 @@
 
         rule.runOnIdle {
             runBlocking {
-                state.scrollBy(-5f)
+                pagerState.scrollBy(-5f)
             }
         }
 
@@ -185,8 +184,8 @@
 
         rule.runOnIdle {
             runBlocking {
-                state.scrollBy(-pageSizePx / 2f)
-                state.scrollBy(-pageSizePx / 2f)
+                pagerState.scrollBy(-pageSizePx / 2f)
+                pagerState.scrollBy(-pageSizePx / 2f)
             }
         }
 
@@ -207,7 +206,7 @@
 
         rule.runOnIdle {
             runBlocking {
-                state.scrollBy(5f)
+                pagerState.scrollBy(5f)
             }
         }
 
@@ -222,8 +221,8 @@
 
         rule.runOnIdle {
             runBlocking {
-                state.scrollBy(-2f)
-                state.scrollBy(-1f)
+                pagerState.scrollBy(-2f)
+                pagerState.scrollBy(-1f)
             }
         }
 
@@ -259,7 +258,7 @@
 
         rule.runOnIdle {
             runBlocking {
-                state.scrollBy(5f)
+                pagerState.scrollBy(5f)
             }
         }
 
@@ -273,7 +272,7 @@
 
         rule.runOnIdle {
             runBlocking {
-                state.scrollBy(-2f)
+                pagerState.scrollBy(-2f)
             }
         }
 
@@ -298,11 +297,10 @@
             ) { constraints ->
                 val placeable = if (emit) {
                     subcompose(Unit) {
-                        state = rememberPagerState()
+                        pagerState = rememberPagerState { 1000 }
                         HorizontalOrVerticalPager(
                             modifier = Modifier.mainAxisSize(pageSizeDp * 1.5f),
-                            state = state,
-                            pageCount = 1000
+                            state = pagerState
                         ) {
                             Spacer(
                                 Modifier
@@ -328,7 +326,7 @@
         rule.runOnIdle {
             // this will schedule the prefetching
             runBlocking(AutoTestFrameClock()) {
-                state.scrollBy(pageSize.toFloat())
+                pagerState.scrollBy(pageSize.toFloat())
             }
             // then we synchronously dispose LazyColumn
             emit = false
@@ -342,11 +340,10 @@
     fun snappingToOtherPositionWhilePrefetchIsScheduled() {
         val composedItems = mutableListOf<Int>()
         rule.setContent {
-            state = rememberPagerState()
+            pagerState = rememberPagerState { 1000 }
             HorizontalOrVerticalPager(
                 modifier = Modifier.mainAxisSize(pageSizeDp * 1.5f),
-                state = state,
-                pageCount = 1000
+                state = pagerState
             ) {
                 composedItems.add(it)
                 Spacer(
@@ -367,10 +364,10 @@
             runBlocking(AutoTestFrameClock()) {
                 // this will move the viewport so pages 1 and 2 are visible
                 // and schedule a prefetching for 3
-                state.scrollBy(pageSize.toFloat())
+                pagerState.scrollBy(pageSize.toFloat())
                 // then we move so that pages 100 and 101 are visible.
                 // this should cancel the prefetch for 3
-                state.scrollToPage(100)
+                pagerState.scrollToPage(100)
             }
         }
 
@@ -393,14 +390,14 @@
             runBlocking(AutoTestFrameClock()) {
                 // this will move the viewport so pages 1-2 are visible
                 // and schedule a prefetching for 3
-                state.scrollBy(pageSizePx.toFloat())
+                pagerState.scrollBy(pageSizePx.toFloat())
 
                 // move viewport by screen size to pages 4-5, so page 3 is just behind
                 // the first visible page
-                state.scrollBy(pageSizePx * 3f)
+                pagerState.scrollBy(pageSizePx * 3f)
 
                 // move scroll further to pages 5-6, so page 3 is reused
-                state.scrollBy(pageSizePx.toFloat())
+                pagerState.scrollBy(pageSizePx.toFloat())
             }
         }
 
@@ -409,7 +406,7 @@
         rule.runOnIdle {
             runBlocking(AutoTestFrameClock()) {
                 // scroll again to ensure page 3 was dropped
-                state.scrollBy(pageSizePx * 100f)
+                pagerState.scrollBy(pageSizePx * 100f)
             }
         }
 
@@ -439,16 +436,13 @@
         reverseLayout: Boolean = false,
         contentPadding: PaddingValues = PaddingValues(0.dp)
     ) {
-        state = PagerState(
-            initialPage = initialPage,
-            initialPageOffsetFraction = initialPageOffsetFraction
-        )
         createPager(
-            state = state,
             modifier = Modifier.mainAxisSize(pageSizeDp * 1.5f),
             reverseLayout = reverseLayout,
             contentPadding = contentPadding,
             offscreenPageLimit = paramConfig.beyondBoundsPageCount,
+            initialPage = initialPage,
+            initialPageOffsetFraction = initialPageOffsetFraction,
             pageCount = { 100 },
             pageSize = {
                 object : PageSize {
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/pager/PagerScrollingTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/pager/PagerScrollingTest.kt
index 14eabb4..3d81073 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/pager/PagerScrollingTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/pager/PagerScrollingTest.kt
@@ -39,10 +39,12 @@
 ) : BasePagerTest(config) {
 
     @Test
-    fun swipeWithLowVelocity_shouldBounceBack() {
+    fun swipeWithLowVelocity_defaultVelocityThreshold_shouldBounceBack() {
         // Arrange
-        val state = PagerState(5)
-        createPager(state = state, modifier = Modifier.fillMaxSize())
+        createPager(
+            initialPage = 5,
+            modifier = Modifier.fillMaxSize()
+        )
         val delta = pagerSize * 0.4f * scrollForwardSign
 
         // Act - forward
@@ -73,10 +75,52 @@
     }
 
     @Test
-    fun swipeWithHighVelocity_shouldGoToNextPage() {
+    fun swipeWithLowVelocity_customVelocityThreshold_shouldBounceBack() {
         // Arrange
         val state = PagerState(5)
-        createPager(state = state, modifier = Modifier.fillMaxSize())
+        val snapVelocityThreshold = 200.dp
+        createPager(
+            state = state,
+            modifier = Modifier.fillMaxSize(),
+            snapVelocityThreshold = snapVelocityThreshold
+        )
+        val delta = pagerSize * 0.4f * scrollForwardSign
+
+        // Act - forward
+        onPager().performTouchInput {
+            swipeWithVelocityAcrossMainAxis(
+                with(rule.density) { 0.5f * snapVelocityThreshold.toPx() },
+                delta
+            )
+        }
+        rule.waitForIdle()
+
+        // Assert
+        rule.onNodeWithTag("5").assertIsDisplayed()
+        confirmPageIsInCorrectPosition(5)
+
+        // Act - backward
+        onPager().performTouchInput {
+            swipeWithVelocityAcrossMainAxis(
+                with(rule.density) { 0.5f * snapVelocityThreshold.toPx() },
+                delta * -1
+            )
+        }
+        rule.waitForIdle()
+
+        // Assert
+        rule.onNodeWithTag("5").assertIsDisplayed()
+        confirmPageIsInCorrectPosition(5)
+    }
+
+    @Test
+    fun swipeWithHighVelocity_defaultVelocityTreshold_shouldGoToNextPage() {
+        // Arrange
+        createPager(
+            initialPage = 5,
+
+            modifier = Modifier.fillMaxSize()
+        )
         // make sure the scroll distance is not enough to go to next page
         val delta = pagerSize * 0.4f * scrollForwardSign
 
@@ -108,10 +152,53 @@
     }
 
     @Test
-    fun swipeWithHighVelocity_overHalfPage_shouldGoToNextPage() {
+    fun swipeWithHighVelocity_customVelocityThreshold_shouldGoToNextPage() {
         // Arrange
         val state = PagerState(5)
-        createPager(state = state, modifier = Modifier.fillMaxSize())
+        val snapVelocityThreshold = 200.dp
+        createPager(
+            state = state,
+            modifier = Modifier.fillMaxSize(),
+            snapVelocityThreshold = snapVelocityThreshold
+        )
+        // make sure the scroll distance is not enough to go to next page
+        val delta = pagerSize * 0.4f * scrollForwardSign
+
+        // Act - forward
+        onPager().performTouchInput {
+            swipeWithVelocityAcrossMainAxis(
+                with(rule.density) { 1.1f * snapVelocityThreshold.toPx() },
+                delta
+            )
+        }
+        rule.waitForIdle()
+
+        // Assert
+        rule.onNodeWithTag("6").assertIsDisplayed()
+        confirmPageIsInCorrectPosition(6)
+
+        // Act - backward
+        onPager().performTouchInput {
+            swipeWithVelocityAcrossMainAxis(
+                with(rule.density) { 1.1f * snapVelocityThreshold.toPx() },
+                delta * -1
+            )
+        }
+        rule.waitForIdle()
+
+        // Assert
+        rule.onNodeWithTag("5").assertIsDisplayed()
+        confirmPageIsInCorrectPosition(5)
+    }
+
+    @Test
+    fun swipeWithHighVelocity_overHalfPage_shouldGoToNextPage() {
+        // Arrange
+        createPager(
+            initialPage = 5,
+
+            modifier = Modifier.fillMaxSize()
+        )
         // make sure the scroll distance is not enough to go to next page
         val delta = pagerSize * 0.8f * scrollForwardSign
 
@@ -145,8 +232,11 @@
     @Test
     fun scrollWithoutVelocity_shouldSettlingInClosestPage() {
         // Arrange
-        val state = PagerState(5)
-        createPager(state = state, modifier = Modifier.fillMaxSize())
+        createPager(
+            initialPage = 5,
+
+            modifier = Modifier.fillMaxSize()
+        )
         // This will scroll 1 whole page before flinging
         val delta = pagerSize * 1.4f * scrollForwardSign
 
@@ -157,9 +247,9 @@
         rule.waitForIdle()
 
         // Assert
-        assertThat(state.currentPage).isAtMost(7)
-        rule.onNodeWithTag("${state.currentPage}").assertIsDisplayed()
-        confirmPageIsInCorrectPosition(state.currentPage)
+        assertThat(pagerState.currentPage).isAtMost(7)
+        rule.onNodeWithTag("${pagerState.currentPage}").assertIsDisplayed()
+        confirmPageIsInCorrectPosition(pagerState.currentPage)
 
         // Act - backward
         onPager().performTouchInput {
@@ -168,21 +258,20 @@
         rule.waitForIdle()
 
         // Assert
-        assertThat(state.currentPage).isAtLeast(5)
-        rule.onNodeWithTag("${state.currentPage}").assertIsDisplayed()
-        confirmPageIsInCorrectPosition(state.currentPage)
+        assertThat(pagerState.currentPage).isAtLeast(5)
+        rule.onNodeWithTag("${pagerState.currentPage}").assertIsDisplayed()
+        confirmPageIsInCorrectPosition(pagerState.currentPage)
     }
 
     @Test
     fun scrollWithSameVelocity_shouldYieldSameResult_forward() {
         // Arrange
         var initialPage = 1
-        val state = PagerState(initialPage)
         createPager(
             pageSize = { PageSize.Fixed(200.dp) },
-            state = state,
-            modifier = Modifier.fillMaxSize(),
+            initialPage = initialPage,
             pageCount = { 100 },
+            modifier = Modifier.fillMaxSize(),
             snappingPage = PagerSnapDistance.atMost(3)
         )
         // This will scroll 0.5 page before flinging
@@ -194,13 +283,13 @@
         }
         rule.waitForIdle()
 
-        val pageDisplacement = state.currentPage - initialPage
+        val pageDisplacement = pagerState.currentPage - initialPage
 
         // Repeat starting from different places
         // reset
         initialPage = 10
         rule.runOnIdle {
-            runBlocking { state.scrollToPage(initialPage) }
+            runBlocking { pagerState.scrollToPage(initialPage) }
         }
 
         onPager().performTouchInput {
@@ -208,11 +297,11 @@
         }
         rule.waitForIdle()
 
-        assertThat(state.currentPage - initialPage).isEqualTo(pageDisplacement)
+        assertThat(pagerState.currentPage - initialPage).isEqualTo(pageDisplacement)
 
         initialPage = 50
         rule.runOnIdle {
-            runBlocking { state.scrollToPage(initialPage) }
+            runBlocking { pagerState.scrollToPage(initialPage) }
         }
 
         onPager().performTouchInput {
@@ -220,19 +309,18 @@
         }
         rule.waitForIdle()
 
-        assertThat(state.currentPage - initialPage).isEqualTo(pageDisplacement)
+        assertThat(pagerState.currentPage - initialPage).isEqualTo(pageDisplacement)
     }
 
     @Test
     fun scrollWithSameVelocity_shouldYieldSameResult_backward() {
         // Arrange
         var initialPage = 90
-        val state = PagerState(initialPage)
         createPager(
             pageSize = { PageSize.Fixed(200.dp) },
-            state = state,
-            modifier = Modifier.fillMaxSize(),
+            initialPage = initialPage,
             pageCount = { 100 },
+            modifier = Modifier.fillMaxSize(),
             snappingPage = PagerSnapDistance.atMost(3)
         )
         // This will scroll 0.5 page before flinging
@@ -244,13 +332,13 @@
         }
         rule.waitForIdle()
 
-        val pageDisplacement = state.currentPage - initialPage
+        val pageDisplacement = pagerState.currentPage - initialPage
 
         // Repeat starting from different places
         // reset
         initialPage = 70
         rule.runOnIdle {
-            runBlocking { state.scrollToPage(initialPage) }
+            runBlocking { pagerState.scrollToPage(initialPage) }
         }
 
         onPager().performTouchInput {
@@ -258,11 +346,11 @@
         }
         rule.waitForIdle()
 
-        assertThat(state.currentPage - initialPage).isEqualTo(pageDisplacement)
+        assertThat(pagerState.currentPage - initialPage).isEqualTo(pageDisplacement)
 
         initialPage = 30
         rule.runOnIdle {
-            runBlocking { state.scrollToPage(initialPage) }
+            runBlocking { pagerState.scrollToPage(initialPage) }
         }
 
         onPager().performTouchInput {
@@ -270,7 +358,7 @@
         }
         rule.waitForIdle()
 
-        assertThat(state.currentPage - initialPage).isEqualTo(pageDisplacement)
+        assertThat(pagerState.currentPage - initialPage).isEqualTo(pageDisplacement)
     }
 
     companion object {
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/pager/PagerStateTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/pager/PagerStateTest.kt
index 6e5d7ee..6b97a8e 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/pager/PagerStateTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/pager/PagerStateTest.kt
@@ -26,6 +26,8 @@
 import androidx.compose.runtime.rememberCoroutineScope
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.geometry.Offset
+import androidx.compose.ui.layout.onSizeChanged
+import androidx.compose.ui.platform.testTag
 import androidx.compose.ui.test.assertIsDisplayed
 import androidx.compose.ui.test.junit4.StateRestorationTester
 import androidx.compose.ui.test.onNodeWithTag
@@ -51,7 +53,7 @@
     @Test
     fun pagerStateNotAttached_shouldReturnDefaultValues_andChangeAfterAttached() = runBlocking {
         // Arrange
-        val state = PagerState(initialPage = 5, initialPageOffsetFraction = 0.2f)
+        val state = PagerStateImpl(5, 0.2f) { DefaultPageCount }
 
         assertThat(state.currentPage).isEqualTo(5)
         assertThat(state.currentPageOffsetFraction).isEqualTo(0.2f)
@@ -59,7 +61,21 @@
         val currentPage = derivedStateOf { state.currentPage }
         val currentPageOffsetFraction = derivedStateOf { state.currentPageOffsetFraction }
 
-        createPager(state = state, modifier = Modifier.fillMaxSize())
+        rule.setContent {
+            HorizontalOrVerticalPager(
+                state = state,
+                modifier = Modifier
+                    .fillMaxSize()
+                    .testTag(PagerTestTag)
+                    .onSizeChanged { pagerSize = if (vertical) it.height else it.width },
+                pageSize = PageSize.Fill,
+                reverseLayout = config.reverseLayout,
+                pageSpacing = config.pageSpacing,
+                contentPadding = config.mainAxisContentPadding,
+            ) {
+                Page(index = it)
+            }
+        }
 
         withContext(Dispatchers.Main + AutoTestFrameClock()) {
             state.scrollToPage(state.currentPage + 1)
@@ -74,16 +90,15 @@
     @Test
     fun scrollToPage_shouldPlacePagesCorrectly() = runBlocking {
         // Arrange
-        val state = PagerState()
-        createPager(state = state, modifier = Modifier.fillMaxSize())
+        createPager(modifier = Modifier.fillMaxSize())
 
         // Act and Assert
         repeat(DefaultAnimationRepetition) {
-            assertThat(state.currentPage).isEqualTo(it)
+            assertThat(pagerState.currentPage).isEqualTo(it)
             withContext(Dispatchers.Main + AutoTestFrameClock()) {
-                state.scrollToPage(state.currentPage + 1)
+                pagerState.scrollToPage(pagerState.currentPage + 1)
             }
-            confirmPageIsInCorrectPosition(state.currentPage)
+            confirmPageIsInCorrectPosition(pagerState.currentPage)
         }
     }
 
@@ -91,314 +106,312 @@
     @Test
     fun scrollToPage_usedOffset_shouldPlacePagesCorrectly() = runBlocking {
         // Arrange
-        val state = PagerState()
+
         suspend fun scrollToPageWithOffset(page: Int, offset: Float) {
             withContext(Dispatchers.Main + AutoTestFrameClock()) {
-                state.scrollToPage(page, offset)
+                pagerState.scrollToPage(page, offset)
             }
         }
 
         // Arrange
-        createPager(state = state, modifier = Modifier.fillMaxSize())
+        createPager(modifier = Modifier.fillMaxSize())
 
         // Act
         scrollToPageWithOffset(10, 0.5f)
 
         // Assert
-        confirmPageIsInCorrectPosition(state.currentPage, 10, pageOffset = 0.5f)
+        confirmPageIsInCorrectPosition(pagerState.currentPage, 10, pageOffset = 0.5f)
 
         // Act
         scrollToPageWithOffset(4, 0.2f)
 
         // Assert
-        confirmPageIsInCorrectPosition(state.currentPage, 4, pageOffset = 0.2f)
+        confirmPageIsInCorrectPosition(pagerState.currentPage, 4, pageOffset = 0.2f)
 
         // Act
         scrollToPageWithOffset(12, -0.4f)
 
         // Assert
-        confirmPageIsInCorrectPosition(state.currentPage, 12, pageOffset = -0.4f)
+        confirmPageIsInCorrectPosition(pagerState.currentPage, 12, pageOffset = -0.4f)
 
         // Act
         scrollToPageWithOffset(DefaultPageCount - 1, 0.5f)
 
         // Assert
-        confirmPageIsInCorrectPosition(state.currentPage, DefaultPageCount - 1)
+        confirmPageIsInCorrectPosition(pagerState.currentPage, DefaultPageCount - 1)
 
         // Act
         scrollToPageWithOffset(0, -0.5f)
 
         // Assert
-        confirmPageIsInCorrectPosition(state.currentPage, 0)
+        confirmPageIsInCorrectPosition(pagerState.currentPage, 0)
     }
 
     @Test
     fun scrollToPage_longSkipShouldNotPlaceIntermediatePages() = runBlocking {
         // Arrange
-        val state = PagerState()
-        createPager(state = state, modifier = Modifier.fillMaxSize())
+
+        createPager(modifier = Modifier.fillMaxSize())
 
         // Act
-        assertThat(state.currentPage).isEqualTo(0)
+        assertThat(pagerState.currentPage).isEqualTo(0)
         withContext(Dispatchers.Main + AutoTestFrameClock()) {
-            state.scrollToPage(DefaultPageCount - 1)
+            pagerState.scrollToPage(DefaultPageCount - 1)
         }
 
         // Assert
         rule.runOnIdle {
-            assertThat(state.currentPage).isEqualTo(DefaultPageCount - 1)
+            assertThat(pagerState.currentPage).isEqualTo(DefaultPageCount - 1)
             assertThat(placed).doesNotContain(DefaultPageCount / 2 - 1)
             assertThat(placed).doesNotContain(DefaultPageCount / 2)
             assertThat(placed).doesNotContain(DefaultPageCount / 2 + 1)
         }
-        confirmPageIsInCorrectPosition(state.currentPage)
+        confirmPageIsInCorrectPosition(pagerState.currentPage)
     }
 
     @Test
     fun animateScrollToPage_shouldPlacePagesCorrectly() = runBlocking {
         // Arrange
-        val state = PagerState()
-        createPager(state = state, modifier = Modifier.fillMaxSize())
+
+        createPager(modifier = Modifier.fillMaxSize())
 
         // Act and Assert
         repeat(DefaultAnimationRepetition) {
-            assertThat(state.currentPage).isEqualTo(it)
+            assertThat(pagerState.currentPage).isEqualTo(it)
             withContext(Dispatchers.Main + AutoTestFrameClock()) {
-                state.animateScrollToPage(state.currentPage + 1)
+                pagerState.animateScrollToPage(pagerState.currentPage + 1)
             }
-            confirmPageIsInCorrectPosition(state.currentPage)
+            confirmPageIsInCorrectPosition(pagerState.currentPage)
         }
     }
 
     @Test
     fun animateScrollToPage_usedOffset_shouldPlacePagesCorrectly() = runBlocking {
         // Arrange
-        val state = PagerState()
+
         suspend fun animateScrollToPageWithOffset(page: Int, offset: Float) {
             withContext(Dispatchers.Main + AutoTestFrameClock()) {
-                state.animateScrollToPage(page, offset)
+                pagerState.animateScrollToPage(page, offset)
             }
         }
 
         // Arrange
-        createPager(state = state, modifier = Modifier.fillMaxSize())
+        createPager(modifier = Modifier.fillMaxSize())
 
         // Act
         animateScrollToPageWithOffset(10, 0.5f)
 
         // Assert
-        confirmPageIsInCorrectPosition(state.currentPage, 10, pageOffset = 0.5f)
+        confirmPageIsInCorrectPosition(pagerState.currentPage, 10, pageOffset = 0.5f)
 
         // Act
         animateScrollToPageWithOffset(4, 0.2f)
 
         // Assert
-        confirmPageIsInCorrectPosition(state.currentPage, 4, pageOffset = 0.2f)
+        confirmPageIsInCorrectPosition(pagerState.currentPage, 4, pageOffset = 0.2f)
 
         // Act
         animateScrollToPageWithOffset(12, -0.4f)
 
         // Assert
-        confirmPageIsInCorrectPosition(state.currentPage, 12, pageOffset = -0.4f)
+        confirmPageIsInCorrectPosition(pagerState.currentPage, 12, pageOffset = -0.4f)
 
         // Act
         animateScrollToPageWithOffset(DefaultPageCount - 1, 0.5f)
 
         // Assert
-        confirmPageIsInCorrectPosition(state.currentPage, DefaultPageCount - 1)
+        confirmPageIsInCorrectPosition(pagerState.currentPage, DefaultPageCount - 1)
 
         // Act
         animateScrollToPageWithOffset(0, -0.5f)
 
         // Assert
-        confirmPageIsInCorrectPosition(state.currentPage, 0)
+        confirmPageIsInCorrectPosition(pagerState.currentPage, 0)
     }
 
     @Test
     fun animateScrollToPage_longSkipShouldNotPlaceIntermediatePages() = runBlocking {
         // Arrange
-        val state = PagerState()
-        createPager(state = state, modifier = Modifier.fillMaxSize())
+
+        createPager(modifier = Modifier.fillMaxSize())
 
         // Act
-        assertThat(state.currentPage).isEqualTo(0)
+        assertThat(pagerState.currentPage).isEqualTo(0)
         withContext(Dispatchers.Main + AutoTestFrameClock()) {
-            state.animateScrollToPage(DefaultPageCount - 1)
+            pagerState.animateScrollToPage(DefaultPageCount - 1)
         }
 
         // Assert
         rule.runOnIdle {
-            assertThat(state.currentPage).isEqualTo(DefaultPageCount - 1)
+            assertThat(pagerState.currentPage).isEqualTo(DefaultPageCount - 1)
             assertThat(placed).doesNotContain(DefaultPageCount / 2 - 1)
             assertThat(placed).doesNotContain(DefaultPageCount / 2)
             assertThat(placed).doesNotContain(DefaultPageCount / 2 + 1)
         }
-        confirmPageIsInCorrectPosition(state.currentPage)
+        confirmPageIsInCorrectPosition(pagerState.currentPage)
     }
 
     @Test
     fun scrollToPage_shouldCoerceWithinRange() = runBlocking {
         // Arrange
-        val state = PagerState()
-        createPager(state = state, modifier = Modifier.fillMaxSize())
+
+        createPager(modifier = Modifier.fillMaxSize())
 
         // Act
-        assertThat(state.currentPage).isEqualTo(0)
+        assertThat(pagerState.currentPage).isEqualTo(0)
         withContext(Dispatchers.Main + AutoTestFrameClock()) {
-            state.scrollToPage(DefaultPageCount)
+            pagerState.scrollToPage(DefaultPageCount)
         }
 
         // Assert
-        rule.runOnIdle { assertThat(state.currentPage).isEqualTo(DefaultPageCount - 1) }
+        rule.runOnIdle { assertThat(pagerState.currentPage).isEqualTo(DefaultPageCount - 1) }
 
         // Act
         withContext(Dispatchers.Main + AutoTestFrameClock()) {
-            state.scrollToPage(-1)
+            pagerState.scrollToPage(-1)
         }
 
         // Assert
-        rule.runOnIdle { assertThat(state.currentPage).isEqualTo(0) }
+        rule.runOnIdle { assertThat(pagerState.currentPage).isEqualTo(0) }
     }
 
     @Test
     fun scrollToPage_usingLaunchedEffect() {
-        val state = PagerState()
-        createPager(state, additionalContent = {
-            LaunchedEffect(state) {
-                state.scrollToPage(10)
+
+        createPager(additionalContent = {
+            LaunchedEffect(pagerState) {
+                pagerState.scrollToPage(10)
             }
         })
         rule.waitForIdle()
-        assertThat(state.currentPage).isEqualTo(10)
+        assertThat(pagerState.currentPage).isEqualTo(10)
         confirmPageIsInCorrectPosition(10)
     }
 
     @Test
     fun scrollToPageWithOffset_usingLaunchedEffect() {
-        val state = PagerState()
-        createPager(state, additionalContent = {
-            LaunchedEffect(state) {
-                state.scrollToPage(10, 0.4f)
+        createPager(additionalContent = {
+            LaunchedEffect(pagerState) {
+                pagerState.scrollToPage(10, 0.4f)
             }
         })
         rule.waitForIdle()
-        assertThat(state.currentPage).isEqualTo(10)
+        assertThat(pagerState.currentPage).isEqualTo(10)
         confirmPageIsInCorrectPosition(10, pageOffset = 0.4f)
     }
 
     @Test
     fun animateScrollToPage_shouldCoerceWithinRange() = runBlocking {
         // Arrange
-        val state = PagerState()
-        createPager(state = state, modifier = Modifier.fillMaxSize())
+
+        createPager(modifier = Modifier.fillMaxSize())
 
         // Act
-        assertThat(state.currentPage).isEqualTo(0)
+        assertThat(pagerState.currentPage).isEqualTo(0)
         withContext(Dispatchers.Main + AutoTestFrameClock()) {
-            state.animateScrollToPage(DefaultPageCount)
+            pagerState.animateScrollToPage(DefaultPageCount)
         }
 
         // Assert
-        rule.runOnIdle { assertThat(state.currentPage).isEqualTo(DefaultPageCount - 1) }
+        rule.runOnIdle { assertThat(pagerState.currentPage).isEqualTo(DefaultPageCount - 1) }
 
         // Act
         withContext(Dispatchers.Main + AutoTestFrameClock()) {
-            state.animateScrollToPage(-1)
+            pagerState.animateScrollToPage(-1)
         }
 
         // Assert
-        rule.runOnIdle { assertThat(state.currentPage).isEqualTo(0) }
+        rule.runOnIdle { assertThat(pagerState.currentPage).isEqualTo(0) }
     }
 
     @Test
     fun animateScrollToPage_moveToSamePageWithOffset_shouldScroll() = runBlocking {
         // Arrange
-        val state = PagerState(initialPage = 5)
-        createPager(state = state, modifier = Modifier.fillMaxSize())
+        createPager(initialPage = 5, modifier = Modifier.fillMaxSize())
 
         // Act
-        assertThat(state.currentPage).isEqualTo(5)
+        assertThat(pagerState.currentPage).isEqualTo(5)
 
         withContext(Dispatchers.Main + AutoTestFrameClock()) {
-            state.animateScrollToPage(5, 0.4f)
+            pagerState.animateScrollToPage(5, 0.4f)
         }
 
         // Assert
-        rule.runOnIdle { assertThat(state.currentPage).isEqualTo(5) }
-        rule.runOnIdle { assertThat(state.currentPageOffsetFraction).isWithin(0.01f).of(0.4f) }
+        rule.runOnIdle { assertThat(pagerState.currentPage).isEqualTo(5) }
+        rule.runOnIdle { assertThat(pagerState.currentPageOffsetFraction).isWithin(0.01f).of(0.4f) }
     }
 
     @Test
     fun animateScrollToPage_withPassedAnimation() = runBlocking {
         // Arrange
-        val state = PagerState()
-        createPager(state = state, modifier = Modifier.fillMaxSize())
+
+        createPager(modifier = Modifier.fillMaxSize())
         val differentAnimation: AnimationSpec<Float> = tween()
 
         // Act and Assert
         repeat(DefaultAnimationRepetition) {
-            assertThat(state.currentPage).isEqualTo(it)
+            assertThat(pagerState.currentPage).isEqualTo(it)
             withContext(Dispatchers.Main + AutoTestFrameClock()) {
-                state.animateScrollToPage(
-                    state.currentPage + 1,
+                pagerState.animateScrollToPage(
+                    pagerState.currentPage + 1,
                     animationSpec = differentAnimation
                 )
             }
-            confirmPageIsInCorrectPosition(state.currentPage)
+            confirmPageIsInCorrectPosition(pagerState.currentPage)
         }
     }
 
     @Test
     fun animatedScrollToPage_usingLaunchedEffect() {
-        val state = PagerState()
-        createPager(state, additionalContent = {
-            LaunchedEffect(state) {
-                state.animateScrollToPage(10)
+
+        createPager(additionalContent = {
+            LaunchedEffect(pagerState) {
+                pagerState.animateScrollToPage(10)
             }
         })
         rule.waitForIdle()
-        assertThat(state.currentPage).isEqualTo(10)
+        assertThat(pagerState.currentPage).isEqualTo(10)
         confirmPageIsInCorrectPosition(10)
     }
 
     @Test
     fun animatedScrollToPageWithOffset_usingLaunchedEffect() {
-        val state = PagerState()
-        createPager(state, additionalContent = {
-            LaunchedEffect(state) {
-                state.animateScrollToPage(10, 0.4f)
+
+        createPager(additionalContent = {
+            LaunchedEffect(pagerState) {
+                pagerState.animateScrollToPage(10, 0.4f)
             }
         })
         rule.waitForIdle()
-        assertThat(state.currentPage).isEqualTo(10)
+        assertThat(pagerState.currentPage).isEqualTo(10)
         confirmPageIsInCorrectPosition(10, pageOffset = 0.4f)
     }
 
     @Test
     fun animatedScrollToPage_viewPortNumberOfPages_usingLaunchedEffect_shouldNotPlaceALlPages() {
-        val state = PagerState()
-        createPager(state, additionalContent = {
-            LaunchedEffect(state) {
-                state.animateScrollToPage(DefaultPageCount - 1)
+
+        createPager(additionalContent = {
+            LaunchedEffect(pagerState) {
+                pagerState.animateScrollToPage(DefaultPageCount - 1)
             }
         })
         rule.waitForIdle()
         // Assert
         rule.runOnIdle {
-            assertThat(state.currentPage).isEqualTo(DefaultPageCount - 1)
+            assertThat(pagerState.currentPage).isEqualTo(DefaultPageCount - 1)
             assertThat(placed).doesNotContain(DefaultPageCount / 2 - 1)
             assertThat(placed).doesNotContain(DefaultPageCount / 2)
             assertThat(placed).doesNotContain(DefaultPageCount / 2 + 1)
         }
-        confirmPageIsInCorrectPosition(state.currentPage)
+        confirmPageIsInCorrectPosition(pagerState.currentPage)
     }
 
     @Test
     fun currentPage_shouldChangeWhenClosestPageToSnappedPositionChanges() {
         // Arrange
-        val state = PagerState()
-        createPager(state = state, modifier = Modifier.fillMaxSize())
-        var previousCurrentPage = state.currentPage
+
+        createPager(modifier = Modifier.fillMaxSize())
+        var previousCurrentPage = pagerState.currentPage
 
         // Act
         // Move less than half an item
@@ -414,15 +427,15 @@
 
         // Assert
         rule.runOnIdle {
-            assertThat(state.currentPage).isEqualTo(previousCurrentPage)
+            assertThat(pagerState.currentPage).isEqualTo(previousCurrentPage)
         }
         // Release pointer
         onPager().performTouchInput { up() }
 
         rule.runOnIdle {
-            previousCurrentPage = state.currentPage
+            previousCurrentPage = pagerState.currentPage
         }
-        confirmPageIsInCorrectPosition(state.currentPage)
+        confirmPageIsInCorrectPosition(pagerState.currentPage)
 
         // Arrange
         // Pass closest to snap position threshold (over half an item)
@@ -440,24 +453,22 @@
 
         // Assert
         rule.runOnIdle {
-            assertThat(state.currentPage).isEqualTo(previousCurrentPage + 1)
+            assertThat(pagerState.currentPage).isEqualTo(previousCurrentPage + 1)
         }
 
         onPager().performTouchInput { up() }
         rule.waitForIdle()
-        confirmPageIsInCorrectPosition(state.currentPage)
+        confirmPageIsInCorrectPosition(pagerState.currentPage)
     }
 
     @Test
     fun targetPage_performScrollBelowThreshold_shouldNotShowNextPage() {
         // Arrange
-        val state = PagerState()
         createPager(
-            state = state,
             modifier = Modifier.fillMaxSize(),
             snappingPage = PagerSnapDistance.atMost(3)
         )
-        rule.runOnIdle { assertThat(state.targetPage).isEqualTo(state.currentPage) }
+        rule.runOnIdle { assertThat(pagerState.targetPage).isEqualTo(pagerState.currentPage) }
 
         rule.mainClock.autoAdvance = false
         // Act
@@ -465,7 +476,7 @@
         val forwardDelta =
             scrollForwardSign.toFloat() * with(rule.density) { DefaultPositionThreshold.toPx() / 2 }
 
-        var previousTargetPage = state.targetPage
+        var previousTargetPage = pagerState.targetPage
 
         onPager().performTouchInput {
             down(layoutStart)
@@ -473,12 +484,12 @@
         }
 
         // Assert
-        assertThat(state.targetPage).isEqualTo(previousTargetPage)
+        assertThat(pagerState.targetPage).isEqualTo(previousTargetPage)
 
         // Reset
         rule.mainClock.autoAdvance = true
         onPager().performTouchInput { up() }
-        rule.runOnIdle { assertThat(state.targetPage).isEqualTo(state.currentPage) }
+        rule.runOnIdle { assertThat(pagerState.targetPage).isEqualTo(pagerState.currentPage) }
 
         // Act
         // Moving more than threshold
@@ -486,7 +497,7 @@
             -DefaultPositionThreshold.toPx() / 2
         }
 
-        previousTargetPage = state.targetPage
+        previousTargetPage = pagerState.targetPage
 
         onPager().performTouchInput {
             down(layoutStart)
@@ -494,19 +505,17 @@
         }
 
         // Assert
-        assertThat(state.targetPage).isEqualTo(previousTargetPage)
+        assertThat(pagerState.targetPage).isEqualTo(previousTargetPage)
     }
 
     @Test
     fun targetPage_performScroll_shouldShowNextPage() {
         // Arrange
-        val state = PagerState()
         createPager(
-            state = state,
             modifier = Modifier.fillMaxSize(),
             snappingPage = PagerSnapDistance.atMost(3)
         )
-        rule.runOnIdle { assertThat(state.targetPage).isEqualTo(state.currentPage) }
+        rule.runOnIdle { assertThat(pagerState.targetPage).isEqualTo(pagerState.currentPage) }
 
         rule.mainClock.autoAdvance = false
         // Act
@@ -518,15 +527,15 @@
         }
 
         // Assert
-        assertThat(state.targetPage).isEqualTo(state.currentPage + 1)
-        assertThat(state.targetPage).isNotEqualTo(state.currentPage)
+        assertThat(pagerState.targetPage).isEqualTo(pagerState.currentPage + 1)
+        assertThat(pagerState.targetPage).isNotEqualTo(pagerState.currentPage)
 
         // Reset
         rule.mainClock.autoAdvance = true
         onPager().performTouchInput { up() }
-        rule.runOnIdle { assertThat(state.targetPage).isEqualTo(state.currentPage) }
+        rule.runOnIdle { assertThat(pagerState.targetPage).isEqualTo(pagerState.currentPage) }
         rule.runOnIdle {
-            runBlocking { state.scrollToPage(5) }
+            runBlocking { pagerState.scrollToPage(5) }
         }
 
         rule.mainClock.autoAdvance = false
@@ -539,117 +548,113 @@
         }
 
         // Assert
-        assertThat(state.targetPage).isEqualTo(state.currentPage - 1)
-        assertThat(state.targetPage).isNotEqualTo(state.currentPage)
+        assertThat(pagerState.targetPage).isEqualTo(pagerState.currentPage - 1)
+        assertThat(pagerState.targetPage).isNotEqualTo(pagerState.currentPage)
 
         rule.mainClock.autoAdvance = true
         onPager().performTouchInput { up() }
-        rule.runOnIdle { assertThat(state.targetPage).isEqualTo(state.currentPage) }
+        rule.runOnIdle { assertThat(pagerState.targetPage).isEqualTo(pagerState.currentPage) }
     }
 
     @Test
     fun targetPage_performingFling_shouldGoToPredictedPage() {
         // Arrange
-        val state = PagerState()
+
         createPager(
-            state = state,
             modifier = Modifier.fillMaxSize(),
             snappingPage = PagerSnapDistance.atMost(3)
         )
-        rule.runOnIdle { assertThat(state.targetPage).isEqualTo(state.currentPage) }
+        rule.runOnIdle { assertThat(pagerState.targetPage).isEqualTo(pagerState.currentPage) }
 
         rule.mainClock.autoAdvance = false
         // Act
         // Moving forward
-        var previousTarget = state.targetPage
+        var previousTarget = pagerState.targetPage
         val forwardDelta = pagerSize * scrollForwardSign.toFloat()
         onPager().performTouchInput {
             swipeWithVelocityAcrossMainAxis(20000f, forwardDelta)
         }
-        rule.mainClock.advanceTimeUntil { state.targetPage != previousTarget }
-        var flingOriginIndex = state.firstVisiblePageInfo?.index ?: 0
+        rule.mainClock.advanceTimeUntil { pagerState.targetPage != previousTarget }
+        var flingOriginIndex = pagerState.firstVisiblePage
         // Assert
-        assertThat(state.targetPage).isEqualTo(flingOriginIndex + 3)
-        assertThat(state.targetPage).isNotEqualTo(state.currentPage)
+        assertThat(pagerState.targetPage).isEqualTo(flingOriginIndex + 3)
+        assertThat(pagerState.targetPage).isNotEqualTo(pagerState.currentPage)
 
         rule.mainClock.autoAdvance = true
-        rule.runOnIdle { assertThat(state.targetPage).isEqualTo(state.currentPage) }
+        rule.runOnIdle { assertThat(pagerState.targetPage).isEqualTo(pagerState.currentPage) }
         rule.mainClock.autoAdvance = false
         // Act
         // Moving backward
-        previousTarget = state.targetPage
+        previousTarget = pagerState.targetPage
         val backwardDelta = -pagerSize * scrollForwardSign.toFloat()
         onPager().performTouchInput {
             swipeWithVelocityAcrossMainAxis(20000f, backwardDelta)
         }
-        rule.mainClock.advanceTimeUntil { state.targetPage != previousTarget }
+        rule.mainClock.advanceTimeUntil { pagerState.targetPage != previousTarget }
 
         // Assert
-        flingOriginIndex = (state.firstVisiblePageInfo?.index ?: 0) + 1
-        assertThat(state.targetPage).isEqualTo(flingOriginIndex - 3)
-        assertThat(state.targetPage).isNotEqualTo(state.currentPage)
+        flingOriginIndex = pagerState.firstVisiblePage + 1
+        assertThat(pagerState.targetPage).isEqualTo(flingOriginIndex - 3)
+        assertThat(pagerState.targetPage).isNotEqualTo(pagerState.currentPage)
 
         rule.mainClock.autoAdvance = true
-        rule.runOnIdle { assertThat(state.targetPage).isEqualTo(state.currentPage) }
+        rule.runOnIdle { assertThat(pagerState.targetPage).isEqualTo(pagerState.currentPage) }
     }
 
     @Test
     fun targetPage_shouldReflectTargetWithAnimation() {
         // Arrange
-        val state = PagerState()
+
         createPager(
-            state = state,
             modifier = Modifier.fillMaxSize()
         )
-        rule.runOnIdle { assertThat(state.targetPage).isEqualTo(state.currentPage) }
+        rule.runOnIdle { assertThat(pagerState.targetPage).isEqualTo(pagerState.currentPage) }
 
         rule.mainClock.autoAdvance = false
         // Act
         // Moving forward
-        var previousTarget = state.targetPage
+        var previousTarget = pagerState.targetPage
         rule.runOnIdle {
             scope.launch {
-                state.animateScrollToPage(DefaultPageCount - 1)
+                pagerState.animateScrollToPage(DefaultPageCount - 1)
             }
         }
-        rule.mainClock.advanceTimeUntil { state.targetPage != previousTarget }
+        rule.mainClock.advanceTimeUntil { pagerState.targetPage != previousTarget }
 
         // Assert
-        assertThat(state.targetPage).isEqualTo(DefaultPageCount - 1)
-        assertThat(state.targetPage).isNotEqualTo(state.currentPage)
+        assertThat(pagerState.targetPage).isEqualTo(DefaultPageCount - 1)
+        assertThat(pagerState.targetPage).isNotEqualTo(pagerState.currentPage)
 
         rule.mainClock.autoAdvance = true
-        rule.runOnIdle { assertThat(state.targetPage).isEqualTo(state.currentPage) }
+        rule.runOnIdle { assertThat(pagerState.targetPage).isEqualTo(pagerState.currentPage) }
         rule.mainClock.autoAdvance = false
 
         // Act
         // Moving backward
-        previousTarget = state.targetPage
+        previousTarget = pagerState.targetPage
         rule.runOnIdle {
             scope.launch {
-                state.animateScrollToPage(0)
+                pagerState.animateScrollToPage(0)
             }
         }
-        rule.mainClock.advanceTimeUntil { state.targetPage != previousTarget }
+        rule.mainClock.advanceTimeUntil { pagerState.targetPage != previousTarget }
 
         // Assert
-        assertThat(state.targetPage).isEqualTo(0)
-        assertThat(state.targetPage).isNotEqualTo(state.currentPage)
+        assertThat(pagerState.targetPage).isEqualTo(0)
+        assertThat(pagerState.targetPage).isNotEqualTo(pagerState.currentPage)
 
         rule.mainClock.autoAdvance = true
-        rule.runOnIdle { assertThat(state.targetPage).isEqualTo(state.currentPage) }
+        rule.runOnIdle { assertThat(pagerState.targetPage).isEqualTo(pagerState.currentPage) }
     }
 
     @Test
     fun settledPage_onAnimationScroll_shouldChangeOnScrollFinishedOnly() {
         // Arrange
-        val state = PagerState()
         var settledPageChanges = 0
         createPager(
-            state = state,
             modifier = Modifier.fillMaxSize(),
             additionalContent = {
-                LaunchedEffect(key1 = state.settledPage) {
+                LaunchedEffect(key1 = pagerState.settledPage) {
                     settledPageChanges++
                 }
             }
@@ -657,51 +662,49 @@
 
         // Settle page changed once for first composition
         rule.runOnIdle {
-            assertThat(state.settledPage).isEqualTo(state.currentPage)
+            assertThat(pagerState.settledPage).isEqualTo(pagerState.currentPage)
             assertTrue { settledPageChanges == 1 }
         }
 
         settledPageChanges = 0
-        val previousSettled = state.settledPage
+        val previousSettled = pagerState.settledPage
         rule.mainClock.autoAdvance = false
         // Act
         // Moving forward
         rule.runOnIdle {
             scope.launch {
-                state.animateScrollToPage(DefaultPageCount - 1)
+                pagerState.animateScrollToPage(DefaultPageCount - 1)
             }
         }
 
         // Settled page shouldn't change whilst scroll is in progress.
-        assertTrue { state.isScrollInProgress }
+        assertTrue { pagerState.isScrollInProgress }
         assertTrue { settledPageChanges == 0 }
-        assertThat(state.settledPage).isEqualTo(previousSettled)
+        assertThat(pagerState.settledPage).isEqualTo(previousSettled)
 
         rule.mainClock.advanceTimeUntil { settledPageChanges != 0 }
 
         rule.runOnIdle {
-            assertTrue { !state.isScrollInProgress }
-            assertThat(state.settledPage).isEqualTo(state.currentPage)
+            assertTrue { !pagerState.isScrollInProgress }
+            assertThat(pagerState.settledPage).isEqualTo(pagerState.currentPage)
         }
     }
 
     @Test
     fun settledPage_onGestureScroll_shouldChangeOnScrollFinishedOnly() {
         // Arrange
-        val state = PagerState()
         var settledPageChanges = 0
         createPager(
-            state = state,
             modifier = Modifier.fillMaxSize(),
             additionalContent = {
-                LaunchedEffect(key1 = state.settledPage) {
+                LaunchedEffect(key1 = pagerState.settledPage) {
                     settledPageChanges++
                 }
             }
         )
 
         settledPageChanges = 0
-        val previousSettled = state.settledPage
+        val previousSettled = pagerState.settledPage
         rule.mainClock.autoAdvance = false
         // Act
         // Moving forward
@@ -711,27 +714,26 @@
         }
 
         // Settled page shouldn't change whilst scroll is in progress.
-        assertTrue { state.isScrollInProgress }
+        assertTrue { pagerState.isScrollInProgress }
         assertTrue { settledPageChanges == 0 }
-        assertThat(state.settledPage).isEqualTo(previousSettled)
+        assertThat(pagerState.settledPage).isEqualTo(previousSettled)
 
         rule.mainClock.advanceTimeUntil { settledPageChanges != 0 }
 
         rule.runOnIdle {
-            assertTrue { !state.isScrollInProgress }
-            assertThat(state.settledPage).isEqualTo(state.currentPage)
+            assertTrue { !pagerState.isScrollInProgress }
+            assertThat(pagerState.settledPage).isEqualTo(pagerState.currentPage)
         }
     }
 
     @Test
     fun currentPageOffset_shouldReflectScrollingOfCurrentPage() {
         // Arrange
-        val state = PagerState(DefaultPageCount / 2)
-        createPager(state = state, modifier = Modifier.fillMaxSize())
+        createPager(initialPage = DefaultPageCount / 2, modifier = Modifier.fillMaxSize())
 
         // No offset initially
         rule.runOnIdle {
-            assertThat(state.currentPageOffsetFraction).isWithin(0.01f).of(0f)
+            assertThat(pagerState.currentPageOffsetFraction).isWithin(0.01f).of(0f)
         }
 
         // Act
@@ -746,7 +748,7 @@
         }
 
         rule.runOnIdle {
-            assertThat(state.currentPageOffsetFraction).isWithin(0.1f).of(0.25f)
+            assertThat(pagerState.currentPageOffsetFraction).isWithin(0.1f).of(0.25f)
         }
 
         onPager().performTouchInput { up() }
@@ -755,13 +757,13 @@
         // Reset
         rule.runOnIdle {
             scope.launch {
-                state.scrollToPage(DefaultPageCount / 2)
+                pagerState.scrollToPage(DefaultPageCount / 2)
             }
         }
 
         // No offset initially (again)
         rule.runOnIdle {
-            assertThat(state.currentPageOffsetFraction).isWithin(0.01f).of(0f)
+            assertThat(pagerState.currentPageOffsetFraction).isWithin(0.01f).of(0f)
         }
 
         // Act
@@ -776,23 +778,22 @@
         }
 
         rule.runOnIdle {
-            assertThat(state.currentPageOffsetFraction).isWithin(0.1f).of(-0.25f)
+            assertThat(pagerState.currentPageOffsetFraction).isWithin(0.1f).of(-0.25f)
         }
     }
 
     @Test
     fun initialPageOnPagerState_shouldDisplayThatPageFirst() {
         // Arrange
-        val state = PagerState(5)
 
         // Act
-        createPager(state = state, modifier = Modifier.fillMaxSize())
+        createPager(initialPage = 5, modifier = Modifier.fillMaxSize())
 
         // Assert
         rule.onNodeWithTag("4").assertDoesNotExist()
         rule.onNodeWithTag("5").assertIsDisplayed()
         rule.onNodeWithTag("6").assertDoesNotExist()
-        confirmPageIsInCorrectPosition(state.currentPage)
+        confirmPageIsInCorrectPosition(pagerState.currentPage)
     }
 
     @Test
@@ -801,11 +802,10 @@
         val tester = StateRestorationTester(rule)
         lateinit var state: PagerState
         tester.setContent {
-            state = rememberPagerState()
+            state = rememberPagerState(pageCount = { DefaultPageCount })
             scope = rememberCoroutineScope()
             HorizontalOrVerticalPager(
                 state = state,
-                pageCount = DefaultPageCount,
                 modifier = Modifier.fillMaxSize()
             ) {
                 Page(it)
@@ -838,27 +838,27 @@
     @Test
     fun scrollTo_beforeFirstLayout_shouldWaitForStateAndLayoutSetting() {
         // Arrange
-        val state = PagerState(0)
+
         rule.mainClock.autoAdvance = false
 
         // Act
-        createPager(state = state, modifier = Modifier.fillMaxSize(), additionalContent = {
-            LaunchedEffect(state) {
-                state.scrollToPage(5)
+        createPager(modifier = Modifier.fillMaxSize(), additionalContent = {
+            LaunchedEffect(pagerState) {
+                pagerState.scrollToPage(5)
             }
         })
 
         // Assert
-        assertThat(state.currentPage).isEqualTo(5)
+        assertThat(pagerState.currentPage).isEqualTo(5)
     }
 
     @Test
     fun currentPageOffsetFraction_shouldNeverBeNan() {
         rule.setContent {
-            val state = rememberPagerState()
+            val state = rememberPagerState(pageCount = { 10 })
             // Read state in composition, should never be Nan
             assertFalse { state.currentPageOffsetFraction.isNaN() }
-            HorizontalOrVerticalPager(pageCount = 10, state = state) {
+            HorizontalOrVerticalPager(state = state) {
                 Page(index = it)
             }
         }
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/pager/PagerSwipeEdgeTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/pager/PagerSwipeEdgeTest.kt
index 7a5a1bc..8926c1f 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/pager/PagerSwipeEdgeTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/pager/PagerSwipeEdgeTest.kt
@@ -38,8 +38,7 @@
     @Test
     fun swipePageTowardsEdge_shouldNotMove() {
         // Arrange
-        val state = PagerState()
-        createPager(state = state, modifier = Modifier.fillMaxSize())
+        createPager(modifier = Modifier.fillMaxSize())
         val delta = pagerSize * 0.4f * scrollForwardSign
 
         // Act - backward
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/pager/PagerTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/pager/PagerTest.kt
index 24b1450..753c0a2 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/pager/PagerTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/pager/PagerTest.kt
@@ -20,12 +20,16 @@
 import androidx.compose.foundation.layout.fillMaxSize
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.ui.Modifier
+import androidx.compose.ui.composed
+import androidx.compose.ui.layout.onSizeChanged
+import androidx.compose.ui.platform.testTag
 import androidx.compose.ui.test.assertIsDisplayed
 import androidx.compose.ui.test.onNodeWithTag
 import androidx.compose.ui.test.performTouchInput
 import androidx.test.filters.LargeTest
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.launch
+import kotlinx.coroutines.runBlocking
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -44,9 +48,8 @@
     @Test
     fun userScrollEnabledIsOff_shouldNotAllowGestureScroll() {
         // Arrange
-        val state = PagerState()
+
         createPager(
-            state = state,
             userScrollEnabled = false,
             modifier = Modifier.fillMaxSize()
         )
@@ -56,7 +59,7 @@
 
         // Assert
         rule.runOnIdle {
-            assertThat(state.currentPage).isEqualTo(0)
+            assertThat(pagerState.currentPage).isEqualTo(0)
         }
 
         confirmPageIsInCorrectPosition(0, 0)
@@ -65,9 +68,8 @@
     @Test
     fun userScrollEnabledIsOff_shouldAllowAnimationScroll() {
         // Arrange
-        val state = PagerState()
+
         createPager(
-            state = state,
             userScrollEnabled = false,
             modifier = Modifier.fillMaxSize()
         )
@@ -75,13 +77,13 @@
         // Act
         rule.runOnIdle {
             scope.launch {
-                state.animateScrollToPage(5)
+                pagerState.animateScrollToPage(5)
             }
         }
 
         // Assert
         rule.runOnIdle {
-            assertThat(state.currentPage).isEqualTo(5)
+            assertThat(pagerState.currentPage).isEqualTo(5)
         }
         confirmPageIsInCorrectPosition(5)
     }
@@ -89,9 +91,8 @@
     @Test
     fun userScrollEnabledIsOn_shouldAllowGestureScroll() {
         // Arrange
-        val state = PagerState(5)
         createPager(
-            state = state,
+            initialPage = 5,
             userScrollEnabled = true,
             modifier = Modifier.fillMaxSize()
         )
@@ -99,25 +100,24 @@
         onPager().performTouchInput { swipeWithVelocityAcrossMainAxis(1000f) }
 
         rule.runOnIdle {
-            assertThat(state.currentPage).isNotEqualTo(5)
+            assertThat(pagerState.currentPage).isNotEqualTo(5)
         }
-        confirmPageIsInCorrectPosition(state.currentPage)
+        confirmPageIsInCorrectPosition(pagerState.currentPage)
     }
 
     @Test
     fun pageCount_pagerOnlyContainsGivenPageCountItems() {
         // Arrange
-        val state = PagerState()
 
         // Act
-        createPager(state = state, modifier = Modifier.fillMaxSize())
+        createPager(modifier = Modifier.fillMaxSize())
 
         // Assert
         repeat(DefaultPageCount) {
             rule.onNodeWithTag("$it").assertIsDisplayed()
             rule.runOnIdle {
                 scope.launch {
-                    state.scroll {
+                    pagerState.scroll {
                         scrollBy(pagerSize.toFloat())
                     }
                 }
@@ -130,12 +130,10 @@
     @Test
     fun mutablePageCount_assertPagesAreChangedIfCountIsChanged() {
         // Arrange
-        val state = PagerState()
         val pageCount = mutableStateOf(2)
         createPager(
-            state = state,
+            pageCount = { pageCount.value },
             modifier = Modifier.fillMaxSize(),
-            pageCount = { pageCount.value }
         )
 
         rule.onNodeWithTag("3").assertDoesNotExist()
@@ -149,7 +147,7 @@
             rule.onNodeWithTag("$it").assertIsDisplayed()
             rule.runOnIdle {
                 scope.launch {
-                    state.scroll {
+                    pagerState.scroll {
                         scrollBy(pagerSize.toFloat())
                     }
                 }
@@ -158,6 +156,100 @@
         }
     }
 
+    @Test
+    fun pageCount_readBeforeCompositionIsAccurate() {
+        // Arrange
+        val pageCount = mutableStateOf(2)
+        val state = PagerStateImpl(0, 0f) { pageCount.value }
+        assertThat(state.pageCount).isEqualTo(pageCount.value)
+        rule.setContent {
+            HorizontalOrVerticalPager(
+                state = state,
+                modifier = Modifier
+                    .fillMaxSize()
+                    .testTag(PagerTestTag)
+                    .onSizeChanged { pagerSize = if (vertical) it.height else it.width },
+                pageSize = PageSize.Fill,
+                reverseLayout = config.reverseLayout,
+                pageSpacing = config.pageSpacing,
+                contentPadding = config.mainAxisContentPadding,
+            ) {
+                Page(index = it)
+            }
+        }
+
+        rule.runOnIdle { pageCount.value = 5 }
+        assertThat(state.pageCount).isEqualTo(pageCount.value)
+    }
+
+    @Test
+    fun pageCount_changeInCountDoesNotCausePagerToRecompose() {
+        // Arrange
+        var recomposeCount = 0
+        val pageCount = mutableStateOf(2)
+        val state = PagerStateImpl(0, 0f) { pageCount.value }
+        assertThat(state.pageCount).isEqualTo(pageCount.value)
+
+        rule.setContent {
+            HorizontalOrVerticalPager(
+                state = state,
+                modifier = Modifier
+                    .fillMaxSize()
+                    .testTag(PagerTestTag)
+                    .composed {
+                        recomposeCount++
+                        Modifier
+                    },
+                pageSize = PageSize.Fill,
+                reverseLayout = config.reverseLayout,
+                pageSpacing = config.pageSpacing,
+                contentPadding = config.mainAxisContentPadding,
+            ) {
+                Page(index = it)
+            }
+        }
+
+        assertThat(recomposeCount).isEqualTo(1)
+        rule.runOnIdle { pageCount.value = 5 } // change count
+        assertThat(state.pageCount).isEqualTo(pageCount.value)
+        assertThat(recomposeCount).isEqualTo(1)
+    }
+
+    @Test
+    fun pageCountDecreased_currentPageIsAdjustedAccordingly() {
+        // Arrange
+        val pageCount = mutableStateOf(5)
+        val state = PagerStateImpl(0, 0f) { pageCount.value }
+        assertThat(state.pageCount).isEqualTo(pageCount.value)
+
+        rule.setContent {
+            HorizontalOrVerticalPager(
+                state = state,
+                modifier = Modifier
+                    .fillMaxSize()
+                    .testTag(PagerTestTag),
+                pageSize = PageSize.Fill,
+                reverseLayout = config.reverseLayout,
+                pageSpacing = config.pageSpacing,
+                contentPadding = config.mainAxisContentPadding,
+            ) {
+                Page(index = it)
+            }
+        }
+
+        rule.runOnIdle {
+            runBlocking {
+                state.scrollToPage(3)
+            }
+        }
+        rule.runOnIdle { assertThat(state.currentPage).isEqualTo(3) }
+        pageCount.value = 2 // change count, less than current page
+        rule.runOnIdle {
+            assertThat(state.pageCount).isEqualTo(pageCount.value)
+            assertThat(state.currentPage).isEqualTo(1) // last page
+        }
+    }
+
     companion object {
         @JvmStatic
         @Parameterized.Parameters(name = "{0}")
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/LazyLayoutPager.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/LazyLayoutPager.kt
index ce3dd25..9f00444 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/LazyLayoutPager.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/LazyLayoutPager.kt
@@ -37,9 +37,11 @@
 import androidx.compose.foundation.lazy.layout.lazyLayoutSemantics
 import androidx.compose.foundation.overscroll
 import androidx.compose.runtime.Composable
+import androidx.compose.runtime.derivedStateOf
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.remember
 import androidx.compose.runtime.rememberUpdatedState
+import androidx.compose.runtime.structuralEqualityPolicy
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
@@ -53,8 +55,6 @@
 internal fun Pager(
     /** Modifier to be applied for the inner layout */
     modifier: Modifier,
-    /** The amount of Pages that will be present in this Pager **/
-    pageCount: Int,
     /** State controlling the scroll position */
     state: PagerState,
     /** The inner padding to be added for the whole content(not for each individual page) */
@@ -94,9 +94,8 @@
     val pagerItemProvider = rememberPagerItemProvider(
         state = state,
         pageContent = pageContent,
-        key = key,
-        pageCount = pageCount
-    )
+        key = key
+    ) { state.pageCount }
 
     val beyondBoundsInfo = remember { LazyListBeyondBoundsInfo() }
 
@@ -111,7 +110,7 @@
         horizontalAlignment = horizontalAlignment,
         verticalAlignment = verticalAlignment,
         itemProvider = pagerItemProvider,
-        pageCount = pageCount,
+        pageCount = { state.pageCount },
         beyondBoundsInfo = beyondBoundsInfo
     )
 
@@ -172,10 +171,11 @@
     val state: PagerState,
     latestContent: () -> (@Composable (page: Int) -> Unit),
     key: ((index: Int) -> Any)?,
-    pageCount: Int
+    pageCount: () -> Int
 ) : LazyLayoutItemProvider {
-    private val pagerContent =
-        PagerLayoutIntervalContent(latestContent(), key = key, pageCount = pageCount)
+    private val pagerContent by derivedStateOf(structuralEqualityPolicy()) {
+        PagerLayoutIntervalContent(latestContent(), key = key, pageCount = pageCount())
+    }
     private val keyToIndexMap: LazyLayoutKeyIndexMap by NearestRangeKeyIndexMapState(
         firstVisibleItemIndex = { state.firstVisiblePage },
         slidingWindowSize = { NearestItemsSlidingWindowSize },
@@ -203,8 +203,8 @@
     val key: ((index: Int) -> Any)?,
     val pageCount: Int
 ) : LazyLayoutIntervalContent<PagerIntervalContent>() {
-    override val intervals: IntervalList<PagerIntervalContent>
-        get() = MutableIntervalList<PagerIntervalContent>().apply {
+    override val intervals: IntervalList<PagerIntervalContent> =
+        MutableIntervalList<PagerIntervalContent>().apply {
             addInterval(pageCount, PagerIntervalContent(key = key, item = pageContent))
         }
 }
@@ -221,7 +221,7 @@
     state: PagerState,
     pageContent: @Composable (page: Int) -> Unit,
     key: ((index: Int) -> Any)?,
-    pageCount: Int
+    pageCount: () -> Int
 ): PagerLazyLayoutItemProvider {
     val latestContent = rememberUpdatedState(pageContent)
     return remember(state, latestContent, key, pageCount) {
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/Pager.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/Pager.kt
index 0c55052..c2d2fc5 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/Pager.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/Pager.kt
@@ -28,6 +28,7 @@
 import androidx.compose.foundation.gestures.FlingBehavior
 import androidx.compose.foundation.gestures.Orientation
 import androidx.compose.foundation.gestures.ScrollScope
+import androidx.compose.foundation.gestures.snapping.MinFlingVelocityDp
 import androidx.compose.foundation.gestures.snapping.SnapFlingBehavior
 import androidx.compose.foundation.gestures.snapping.SnapLayoutInfoProvider
 import androidx.compose.foundation.layout.PaddingValues
@@ -72,6 +73,84 @@
  * Please refer to the sample to learn how to use this API.
  * @sample androidx.compose.foundation.samples.SimpleHorizontalPagerSample
  *
+ * @param state The state to control this pager
+ * @param modifier A modifier instance to be applied to this Pager outer layout
+ * @param contentPadding a padding around the whole content. This will add padding for the
+ * content after it has been clipped, which is not possible via [modifier] param. You can use it
+ * to add a padding before the first page or after the last one. Use [pageSpacing] to add spacing
+ * between the pages.
+ * @param pageSize Use this to change how the pages will look like inside this pager.
+ * @param beyondBoundsPageCount Pages to load before and after the list of visible
+ * pages. Note: Be aware that using a large value for [beyondBoundsPageCount] will cause a lot of
+ * pages to be composed, measured and placed which will defeat the purpose of using lazy loading.
+ * This should be used as an optimization to pre-load a couple of pages before and after the visible
+ * ones.
+ * @param pageSpacing The amount of space to be used to separate the pages in this Pager
+ * @param verticalAlignment How pages are aligned vertically in this Pager.
+ * @param flingBehavior The [FlingBehavior] to be used for post scroll gestures.
+ * @param userScrollEnabled whether the scrolling via the user gestures or accessibility actions
+ * is allowed. You can still scroll programmatically using [PagerState.scroll] even when it is
+ * disabled.
+ * @param reverseLayout reverse the direction of scrolling and layout.
+ * @param key a stable and unique key representing the item. When you specify the key the scroll
+ * position will be maintained based on the key, which means if you add/remove items before the
+ * current visible item the item with the given key will be kept as the first visible one.
+ * @param pageNestedScrollConnection A [NestedScrollConnection] that dictates how this [Pager]
+ * behaves with nested lists. The default behavior will see [Pager] to consume all nested deltas.
+ * @param pageContent This Pager's page Composable.
+ */
+@Composable
+@ExperimentalFoundationApi
+fun HorizontalPager(
+    state: PagerState,
+    modifier: Modifier = Modifier,
+    contentPadding: PaddingValues = PaddingValues(0.dp),
+    pageSize: PageSize = PageSize.Fill,
+    beyondBoundsPageCount: Int = 0,
+    pageSpacing: Dp = 0.dp,
+    verticalAlignment: Alignment.Vertical = Alignment.CenterVertically,
+    flingBehavior: SnapFlingBehavior = PagerDefaults.flingBehavior(state = state),
+    userScrollEnabled: Boolean = true,
+    reverseLayout: Boolean = false,
+    key: ((index: Int) -> Any)? = null,
+    pageNestedScrollConnection: NestedScrollConnection = PagerDefaults.pageNestedScrollConnection(
+        Orientation.Horizontal
+    ),
+    pageContent: @Composable (page: Int) -> Unit
+) {
+    Pager(
+        state = state,
+        modifier = modifier,
+        contentPadding = contentPadding,
+        pageSize = pageSize,
+        beyondBoundsPageCount = beyondBoundsPageCount,
+        pageSpacing = pageSpacing,
+        orientation = Orientation.Horizontal,
+        verticalAlignment = verticalAlignment,
+        horizontalAlignment = Alignment.CenterHorizontally,
+        flingBehavior = flingBehavior,
+        userScrollEnabled = userScrollEnabled,
+        reverseLayout = reverseLayout,
+        key = key,
+        pageNestedScrollConnection = pageNestedScrollConnection,
+        pageContent = pageContent
+    )
+}
+
+/**
+ * A Pager that scrolls horizontally. Pages are lazily placed in accordance to the available
+ * viewport size. By definition, pages in a [Pager] have the same size, defined by [pageSize] and
+ * use a snap animation (provided by [flingBehavior] to scroll pages into a specific position). You
+ * can use [beyondBoundsPageCount] to place more pages before and after the visible pages.
+ *
+ * If you need snapping with pages of different size, you can use a [SnapFlingBehavior] with a
+ * [SnapLayoutInfoProvider] adapted to a LazyList.
+ * @see androidx.compose.foundation.gestures.snapping.SnapLayoutInfoProvider for the implementation
+ * of a [SnapLayoutInfoProvider] that uses [androidx.compose.foundation.lazy.LazyListState].
+ *
+ * Please refer to the sample to learn how to use this API.
+ * @sample androidx.compose.foundation.samples.SimpleHorizontalPagerSample
+ *
  * @param pageCount The number of pages this Pager will contain
  * @param modifier A modifier instance to be applied to this Pager outer layout
  * @param state The state to control this pager
@@ -99,12 +178,38 @@
  * behaves with nested lists. The default behavior will see [Pager] to consume all nested deltas.
  * @param pageContent This Pager's page Composable.
  */
+@Deprecated(
+    "Please use the overload without pageCount. pageCount should be provided " +
+        "through PagerState.", ReplaceWith(
+        """HorizontalPager(
+            modifier = modifier,
+            state = state,
+            pageSpacing = pageSpacing,
+            horizontalAlignment = horizontalAlignment,
+            userScrollEnabled = userScrollEnabled,
+            reverseLayout = reverseLayout,
+            contentPadding = contentPadding,
+            beyondBoundsPageCount = beyondBoundsPageCount,
+            pageSize = pageSize,
+            flingBehavior = flingBehavior,
+            key = key,
+            pageNestedScrollConnection = pageNestedScrollConnection,
+            pageContent = pageContent
+        )""",
+        imports = arrayOf(
+            "androidx.compose.foundation.gestures.Orientation",
+            "androidx.compose.foundation.layout.PaddingValues",
+            "androidx.compose.foundation.pager.PageSize",
+            "androidx.compose.foundation.pager.PagerDefaults"
+        )
+    )
+)
 @Composable
 @ExperimentalFoundationApi
 fun HorizontalPager(
     pageCount: Int,
     modifier: Modifier = Modifier,
-    state: PagerState = rememberPagerState(),
+    state: PagerState = rememberPagerState { pageCount },
     contentPadding: PaddingValues = PaddingValues(0.dp),
     pageSize: PageSize = PageSize.Fill,
     beyondBoundsPageCount: Int = 0,
@@ -120,22 +225,99 @@
     pageContent: @Composable (page: Int) -> Unit
 ) {
     Pager(
-        modifier = modifier,
-        pageCount = pageCount,
         state = state,
+        modifier = modifier,
         contentPadding = contentPadding,
-        reverseLayout = reverseLayout,
-        orientation = Orientation.Horizontal,
-        flingBehavior = flingBehavior,
-        userScrollEnabled = userScrollEnabled,
         pageSize = pageSize,
         beyondBoundsPageCount = beyondBoundsPageCount,
         pageSpacing = pageSpacing,
-        pageContent = pageContent,
-        pageNestedScrollConnection = pageNestedScrollConnection,
+        orientation = Orientation.Horizontal,
         verticalAlignment = verticalAlignment,
         horizontalAlignment = Alignment.CenterHorizontally,
-        key = key
+        flingBehavior = flingBehavior,
+        userScrollEnabled = userScrollEnabled,
+        reverseLayout = reverseLayout,
+        key = key,
+        pageNestedScrollConnection = pageNestedScrollConnection,
+        pageContent = pageContent
+    )
+}
+
+/**
+ * A Pager that scrolls vertically. Pages are lazily placed in accordance to the available
+ * viewport size. By definition, pages in a [Pager] have the same size, defined by [pageSize] and
+ * use a snap animation (provided by [flingBehavior] to scroll pages into a specific position). You
+ * can use [beyondBoundsPageCount] to place more pages before and after the visible pages.
+ *
+ * If you need snapping with pages of different size, you can use a [SnapFlingBehavior] with a
+ * [SnapLayoutInfoProvider] adapted to a LazyList.
+ * @see androidx.compose.foundation.gestures.snapping.SnapLayoutInfoProvider for the implementation
+ * of a [SnapLayoutInfoProvider] that uses [androidx.compose.foundation.lazy.LazyListState].
+ *
+ * Please refer to the sample to learn how to use this API.
+ * @sample androidx.compose.foundation.samples.SimpleVerticalPagerSample
+ *
+ * @param state The state to control this pager
+ * @param modifier A modifier instance to be apply to this Pager outer layout
+ * @param contentPadding a padding around the whole content. This will add padding for the
+ * content after it has been clipped, which is not possible via [modifier] param. You can use it
+ * to add a padding before the first page or after the last one. Use [pageSpacing] to add spacing
+ * between the pages.
+ * @param pageSize Use this to change how the pages will look like inside this pager.
+ * @param beyondBoundsPageCount Pages to load before and after the list of visible
+ * pages. Note: Be aware that using a large value for [beyondBoundsPageCount] will cause a lot of
+ * pages to be composed, measured and placed which will defeat the purpose of using lazy loading.
+ * This should be used as an optimization to pre-load a couple of pages before and after the visible
+ * ones.
+ * @param pageSpacing The amount of space to be used to separate the pages in this Pager
+ * @param horizontalAlignment How pages are aligned horizontally in this Pager.
+ * @param flingBehavior The [FlingBehavior] to be used for post scroll gestures.
+ * @param userScrollEnabled whether the scrolling via the user gestures or accessibility actions
+ * is allowed. You can still scroll programmatically using [PagerState.scroll] even when it is
+ * disabled.
+ * @param reverseLayout reverse the direction of scrolling and layout.
+ * @param key a stable and unique key representing the item. When you specify the key the scroll
+ * position will be maintained based on the key, which means if you add/remove items before the
+ * current visible item the item with the given key will be kept as the first visible one.
+ * @param pageNestedScrollConnection A [NestedScrollConnection] that dictates how this [Pager] behaves
+ * with nested lists. The default behavior will see [Pager] to consume all nested deltas.
+ * @param pageContent This Pager's page Composable.
+ */
+@Composable
+@ExperimentalFoundationApi
+fun VerticalPager(
+    state: PagerState,
+    modifier: Modifier = Modifier,
+    contentPadding: PaddingValues = PaddingValues(0.dp),
+    pageSize: PageSize = PageSize.Fill,
+    beyondBoundsPageCount: Int = 0,
+    pageSpacing: Dp = 0.dp,
+    horizontalAlignment: Alignment.Horizontal = Alignment.CenterHorizontally,
+    flingBehavior: SnapFlingBehavior = PagerDefaults.flingBehavior(state = state),
+    userScrollEnabled: Boolean = true,
+    reverseLayout: Boolean = false,
+    key: ((index: Int) -> Any)? = null,
+    pageNestedScrollConnection: NestedScrollConnection = PagerDefaults.pageNestedScrollConnection(
+        Orientation.Vertical
+    ),
+    pageContent: @Composable (page: Int) -> Unit
+) {
+    Pager(
+        state = state,
+        modifier = modifier,
+        contentPadding = contentPadding,
+        pageSize = pageSize,
+        beyondBoundsPageCount = beyondBoundsPageCount,
+        pageSpacing = pageSpacing,
+        orientation = Orientation.Vertical,
+        verticalAlignment = Alignment.CenterVertically,
+        horizontalAlignment = horizontalAlignment,
+        flingBehavior = flingBehavior,
+        userScrollEnabled = userScrollEnabled,
+        reverseLayout = reverseLayout,
+        key = key,
+        pageNestedScrollConnection = pageNestedScrollConnection,
+        pageContent = pageContent
     )
 }
 
@@ -180,12 +362,38 @@
  * with nested lists. The default behavior will see [Pager] to consume all nested deltas.
  * @param pageContent This Pager's page Composable.
  */
+@Deprecated(
+    "Please use the overload without pageCount. pageCount should be provided " +
+        "through PagerState.", ReplaceWith(
+        """VerticalPager(
+            modifier = modifier,
+            state = state,
+            pageSpacing = pageSpacing,
+            horizontalAlignment = horizontalAlignment,
+            userScrollEnabled = userScrollEnabled,
+            reverseLayout = reverseLayout,
+            contentPadding = contentPadding,
+            beyondBoundsPageCount = beyondBoundsPageCount,
+            pageSize = pageSize,
+            flingBehavior = flingBehavior,
+            key = key,
+            pageNestedScrollConnection = pageNestedScrollConnection,
+            pageContent = pageContent
+        )""",
+        imports = arrayOf(
+            "androidx.compose.foundation.gestures.Orientation",
+            "androidx.compose.foundation.layout.PaddingValues",
+            "androidx.compose.foundation.pager.PageSize",
+            "androidx.compose.foundation.pager.PagerDefaults"
+        )
+    )
+)
 @Composable
 @ExperimentalFoundationApi
 fun VerticalPager(
     pageCount: Int,
     modifier: Modifier = Modifier,
-    state: PagerState = rememberPagerState(),
+    state: PagerState = rememberPagerState { pageCount },
     contentPadding: PaddingValues = PaddingValues(0.dp),
     pageSize: PageSize = PageSize.Fill,
     beyondBoundsPageCount: Int = 0,
@@ -201,22 +409,21 @@
     pageContent: @Composable (page: Int) -> Unit
 ) {
     Pager(
-        modifier = modifier,
-        pageCount = pageCount,
         state = state,
+        modifier = modifier,
         contentPadding = contentPadding,
-        reverseLayout = reverseLayout,
-        orientation = Orientation.Vertical,
-        flingBehavior = flingBehavior,
-        userScrollEnabled = userScrollEnabled,
         pageSize = pageSize,
         beyondBoundsPageCount = beyondBoundsPageCount,
         pageSpacing = pageSpacing,
-        pageContent = pageContent,
-        pageNestedScrollConnection = pageNestedScrollConnection,
+        orientation = Orientation.Vertical,
         verticalAlignment = Alignment.CenterVertically,
         horizontalAlignment = horizontalAlignment,
-        key = key
+        flingBehavior = flingBehavior,
+        userScrollEnabled = userScrollEnabled,
+        reverseLayout = reverseLayout,
+        key = key,
+        pageNestedScrollConnection = pageNestedScrollConnection,
+        pageContent = pageContent
     )
 }
 
@@ -285,11 +492,17 @@
      * @param highVelocityAnimationSpec The animation spec used to approach the target offset. When
      * the fling velocity is large enough. Large enough means large enough to naturally decay.
      * @param snapAnimationSpec The animation spec used to finally snap to the position.
+     * @param snapVelocityThreshold The minimum velocity required for a fling to be considered
+     * high enough to make pages animate through [lowVelocityAnimationSpec] and
+     * [highVelocityAnimationSpec].
      *
      * @return An instance of [FlingBehavior] that will perform Snapping to the next page by
      * default. The animation will be governed by the post scroll velocity and we'll use either
      * [lowVelocityAnimationSpec] or [highVelocityAnimationSpec] to approach the snapped position
-     * and the last step of the animation will be performed by [snapAnimationSpec].
+     * and the last step of the animation will be performed by [snapAnimationSpec]. If a velocity
+     * is not high enough (lower than [snapVelocityThreshold]) the pager will use
+     * [snapAnimationSpec] to reach the snapped position. If the velocity is high enough, we'll
+     * use the logic described in [highVelocityAnimationSpec] and [lowVelocityAnimationSpec].
      */
     @Composable
     fun flingBehavior(
@@ -301,6 +514,7 @@
         ),
         highVelocityAnimationSpec: DecayAnimationSpec<Float> = rememberSplineBasedDecay(),
         snapAnimationSpec: AnimationSpec<Float> = spring(stiffness = Spring.StiffnessMediumLow),
+        snapVelocityThreshold: Dp = MinFlingVelocityDp
     ): SnapFlingBehavior {
         val density = LocalDensity.current
 
@@ -322,7 +536,8 @@
                 lowVelocityAnimationSpec = lowVelocityAnimationSpec,
                 highVelocityAnimationSpec = highVelocityAnimationSpec,
                 snapAnimationSpec = snapAnimationSpec,
-                density = density
+                density = density,
+                shortSnapVelocityThreshold = snapVelocityThreshold
             )
         }
     }
@@ -457,9 +672,11 @@
             val effectivePageSizePx = pagerState.pageSize + pagerState.pageSpacing
             val animationOffsetPx =
                 decayAnimationSpec.calculateTargetValue(0f, initialVelocity)
-            val startPage = pagerState.firstVisiblePageInfo?.let {
-                if (initialVelocity < 0) it.index + 1 else it.index
-            } ?: pagerState.currentPage
+            val startPage = if (initialVelocity < 0) {
+                pagerState.firstVisiblePage + 1
+            } else {
+                pagerState.firstVisiblePage
+            }
 
             val scrollOffset =
                 layoutInfo.visiblePagesInfo.fastFirstOrNull { it.index == startPage }?.offset ?: 0
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/PagerMeasure.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/PagerMeasure.kt
index 78aa13a..6785dea 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/PagerMeasure.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/PagerMeasure.kt
@@ -64,11 +64,8 @@
 ): PagerMeasureResult {
     require(beforeContentPadding >= 0)
     require(afterContentPadding >= 0)
-
     val pageSizeWithSpacing = (pageAvailableSize + spaceBetweenPages).coerceAtLeast(0)
-
     debugLog { "Remeasuring..." }
-
     return if (pageCount <= 0) {
         PagerMeasureResult(
             visiblePagesInfo = emptyList(),
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/PagerMeasurePolicy.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/PagerMeasurePolicy.kt
index f535064..0c56d50 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/PagerMeasurePolicy.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/PagerMeasurePolicy.kt
@@ -50,7 +50,7 @@
     pageSize: PageSize,
     horizontalAlignment: Alignment.Horizontal?,
     verticalAlignment: Alignment.Vertical?,
-    pageCount: Int,
+    pageCount: () -> Int,
     beyondBoundsInfo: LazyListBeyondBoundsInfo
 ) = remember<LazyLayoutMeasureScope.(Constraints) -> MeasureResult>(
     contentPadding,
@@ -156,7 +156,7 @@
             beforeContentPadding = beforeContentPadding,
             afterContentPadding = afterContentPadding,
             constraints = contentConstraints,
-            pageCount = pageCount,
+            pageCount = pageCount(),
             spaceBetweenPages = spaceBetweenPages,
             mainAxisAvailableSize = mainAxisAvailableSize,
             visualPageOffset = visualItemOffset,
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/PagerState.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/PagerState.kt
index 04e021f..3906300 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/PagerState.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/PagerState.kt
@@ -61,15 +61,92 @@
  * @param initialPageOffsetFraction The offset of the initial page as a fraction of the page size.
  * This should vary between -0.5 and 0.5 and indicates how to offset the initial page from the
  * snapped position.
+ * @param pageCount The amount of pages this Pager will have.
  */
 @ExperimentalFoundationApi
 @Composable
 fun rememberPagerState(
     initialPage: Int = 0,
+    initialPageOffsetFraction: Float = 0f,
+    pageCount: () -> Int
+): PagerState {
+    return rememberSaveable(saver = PagerStateImpl.Saver) {
+        PagerStateImpl(
+            initialPage,
+            initialPageOffsetFraction,
+            pageCount
+        )
+    }.apply {
+        pageCountState.value = pageCount
+    }
+}
+
+/**
+ * Creates and remember a [PagerState] to be used with a [Pager]
+ *
+ * Please refer to the sample to learn how to use this API.
+ * @sample androidx.compose.foundation.samples.PagerWithStateSample
+ *
+ * @param initialPage The pager that should be shown first.
+ * @param initialPageOffsetFraction The offset of the initial page as a fraction of the page size.
+ * This should vary between -0.5 and 0.5 and indicates how to offset the initial page from the
+ * snapped position.
+ */
+@Deprecated(
+    "Please use the overload where you can provide a source of truth for the pageCount.",
+    ReplaceWith(
+        """rememberPagerState(
+                initialPage = initialPage,
+                initialPageOffsetFraction = initialPageOffsetFraction
+            ){
+                // provide pageCount
+            }"""
+    )
+)
+@ExperimentalFoundationApi
+@Composable
+fun rememberPagerState(
+    initialPage: Int = 0,
     initialPageOffsetFraction: Float = 0f
 ): PagerState {
-    return rememberSaveable(saver = PagerState.Saver) {
-        PagerState(initialPage = initialPage, initialPageOffsetFraction = initialPageOffsetFraction)
+    return rememberSaveable(saver = PagerStateImpl.Saver) {
+        PagerStateImpl(
+            initialPage = initialPage,
+            initialPageOffsetFraction = initialPageOffsetFraction
+        ) { 0 }
+    }
+}
+
+@ExperimentalFoundationApi
+internal class PagerStateImpl(
+    initialPage: Int,
+    initialPageOffsetFraction: Float,
+    updatedPageCount: () -> Int
+) : PagerState(initialPage, initialPageOffsetFraction) {
+
+    var pageCountState = mutableStateOf(updatedPageCount)
+    override val pageCount: Int get() = pageCountState.value.invoke()
+
+    companion object {
+        /**
+         * To keep current page and current page offset saved
+         */
+        val Saver: Saver<PagerStateImpl, *> = listSaver(
+            save = {
+                listOf(
+                    it.currentPage,
+                    it.currentPageOffsetFraction,
+                    it.pageCount
+                )
+            },
+            restore = {
+                PagerStateImpl(
+                    initialPage = it[0] as Int,
+                    initialPageOffsetFraction = it[1] as Float,
+                    updatedPageCount = { it[2] as Int }
+                )
+            }
+        )
     }
 }
 
@@ -81,11 +158,16 @@
  */
 @ExperimentalFoundationApi
 @Stable
-class PagerState(
+abstract class PagerState(
     val initialPage: Int = 0,
     val initialPageOffsetFraction: Float = 0f
 ) : ScrollableState {
 
+    /**
+     * The total amount of pages present in this pager
+     */
+    abstract val pageCount: Int
+
     init {
         require(initialPageOffsetFraction in -0.5..0.5) {
             "initialPageOffsetFraction $initialPageOffsetFraction is " +
@@ -166,18 +248,6 @@
             minThreshold / pageSize.toFloat()
         }
 
-    internal val pageCount: Int
-        get() = pagerLayoutInfoState.value.pagesCount
-
-    internal val firstVisiblePageInfo: PageInfo?
-        get() = visiblePages.lastOrNull {
-            density.calculateDistanceToDesiredSnapPosition(
-                pagerLayoutInfoState.value,
-                it,
-                SnapAlignmentStartToStart
-            ) <= 0
-        }
-
     private val distanceToSnapPosition: Float
         get() = layoutInfo.closestPageToSnapPosition?.let {
             density.calculateDistanceToDesiredSnapPosition(
@@ -422,9 +492,9 @@
     override val isScrollInProgress: Boolean
         get() = scrollableState.isScrollInProgress
 
-    override var canScrollForward: Boolean by mutableStateOf(false)
+    final override var canScrollForward: Boolean by mutableStateOf(false)
         private set
-    override var canScrollBackward: Boolean by mutableStateOf(false)
+    final override var canScrollBackward: Boolean by mutableStateOf(false)
         private set
 
     /**
@@ -529,26 +599,6 @@
             }
         }
     }
-
-    companion object {
-        /**
-         * To keep current page and current page offset saved
-         */
-        val Saver: Saver<PagerState, *> = listSaver(
-            save = {
-                listOf(
-                    it.currentPage,
-                    it.currentPageOffsetFraction
-                )
-            },
-            restore = {
-                PagerState(
-                    initialPage = it[0] as Int,
-                    initialPageOffsetFraction = it[1] as Float
-                )
-            }
-        )
-    }
 }
 
 @OptIn(ExperimentalFoundationApi::class)
diff --git a/compose/integration-tests/macrobenchmark-target/src/main/java/androidx/compose/integration/macrobenchmark/target/PagerActivity.kt b/compose/integration-tests/macrobenchmark-target/src/main/java/androidx/compose/integration/macrobenchmark/target/PagerActivity.kt
index a9466ca..c7e90d4 100644
--- a/compose/integration-tests/macrobenchmark-target/src/main/java/androidx/compose/integration/macrobenchmark/target/PagerActivity.kt
+++ b/compose/integration-tests/macrobenchmark-target/src/main/java/androidx/compose/integration/macrobenchmark/target/PagerActivity.kt
@@ -44,7 +44,7 @@
         val itemCount = intent.getIntExtra(ExtraItemCount, 3000)
 
         setContent {
-            val pagerState = rememberPagerState()
+            val pagerState = rememberPagerState { itemCount }
             Box(
                 modifier = Modifier
                     .fillMaxSize(),
@@ -56,8 +56,7 @@
                         .semantics { contentDescription = "Pager" }
                         .background(Color.White),
                     state = pagerState,
-                    pageSize = PageSize.Fill,
-                    pageCount = itemCount
+                    pageSize = PageSize.Fill
                 ) {
                     PagerItem(it)
                 }
diff --git a/compose/integration-tests/macrobenchmark-target/src/main/java/androidx/compose/integration/macrobenchmark/target/PagerAsCarouselActivity.kt b/compose/integration-tests/macrobenchmark-target/src/main/java/androidx/compose/integration/macrobenchmark/target/PagerAsCarouselActivity.kt
index 50fc66b..df252e7 100644
--- a/compose/integration-tests/macrobenchmark-target/src/main/java/androidx/compose/integration/macrobenchmark/target/PagerAsCarouselActivity.kt
+++ b/compose/integration-tests/macrobenchmark-target/src/main/java/androidx/compose/integration/macrobenchmark/target/PagerAsCarouselActivity.kt
@@ -45,7 +45,7 @@
         val itemCount = intent.getIntExtra(ExtraItemCount, 3000)
 
         setContent {
-            val pagerState = rememberPagerState()
+            val pagerState = rememberPagerState { itemCount }
             Box(
                 modifier = Modifier
                     .fillMaxSize()
@@ -57,7 +57,6 @@
                         .semantics { contentDescription = "Carousel" }
                         .background(Color.White),
                     state = pagerState,
-                    pageCount = itemCount,
                     pageSize = PageSize.Fixed(200.dp)
                 ) {
                     PagerItem(it)
diff --git a/development/project-creator/create_project.py b/development/project-creator/create_project.py
index 8a121f8..7b0ddc4 100755
--- a/development/project-creator/create_project.py
+++ b/development/project-creator/create_project.py
@@ -151,9 +151,15 @@
 
 def generate_package_name(group_id, artifact_id):
     final_group_id_word = group_id.split(".")[-1]
-    artifact_id_suffix = artifact_id.replace(final_group_id_word, "")
+    artifact_id_suffix = re.sub(r"\b%s\b" % final_group_id_word, "", artifact_id)
     artifact_id_suffix = artifact_id_suffix.replace("-", ".")
-    return group_id + artifact_id_suffix
+    if (final_group_id_word == artifact_id):
+      return group_id +  artifact_id_suffix
+    elif (final_group_id_word != artifact_id):
+      if ("." in artifact_id_suffix):
+        return group_id +  artifact_id_suffix
+      else:
+        return group_id + "." + artifact_id_suffix
 
 def validate_name(group_id, artifact_id):
     if not group_id.startswith("androidx."):
diff --git a/paging/paging-compose/samples/src/main/java/androidx/paging/compose/samples/PagingFoundationSample.kt b/paging/paging-compose/samples/src/main/java/androidx/paging/compose/samples/PagingFoundationSample.kt
index 8b55ca8..27b2fac 100644
--- a/paging/paging-compose/samples/src/main/java/androidx/paging/compose/samples/PagingFoundationSample.kt
+++ b/paging/paging-compose/samples/src/main/java/androidx/paging/compose/samples/PagingFoundationSample.kt
@@ -54,13 +54,12 @@
 @Sampled
 @Composable
 public fun PagingWithHorizontalPager() {
-    val pagerState = rememberPagerState()
     val lazyPagingItems = pager.collectAsLazyPagingItems()
+    val pagerState = rememberPagerState { lazyPagingItems.itemCount }
 
     HorizontalPager(
         modifier = Modifier.fillMaxSize(),
         state = pagerState,
-        pageCount = lazyPagingItems.itemCount,
         pageSize = PageSize.Fixed(200.dp),
         key = lazyPagingItems.itemKey { it }
     ) { index ->
@@ -72,13 +71,12 @@
 @OptIn(ExperimentalFoundationApi::class)
 @Composable
 public fun PagingWithVerticalPager() {
-    val pagerState = rememberPagerState()
     val lazyPagingItems = pager.collectAsLazyPagingItems()
+    val pagerState = rememberPagerState { lazyPagingItems.itemCount }
 
     VerticalPager(
         modifier = Modifier.fillMaxSize(),
         state = pagerState,
-        pageCount = lazyPagingItems.itemCount,
         pageSize = PageSize.Fixed(200.dp),
         key = lazyPagingItems.itemKey { it }
     ) { index ->