Skip to content

Commit

Permalink
Pager composable (google#209)
Browse files Browse the repository at this point in the history
* Initial import of Pager

* Tidy up content scope

* Add API file for Pager

* Add skeleton for pager sample

* Add working sample

* Use pointerInput() for touch handling

* Add animated scroll support

* Extract scroll threshold to val

* Move away from using Animatable

We now use the base level suspending animation functions, along with a
MutatorMutex. This tidies up the animation and touch handling.

* Tidy up state wrapper properties

* Simplify selectionState property

* Fix fling cancellation

* First attempt at cancellation support

* Code style

* Mostly working

* Doc typo

* Initial RTL support

* First test (failing)

* Working first test

* Add more tests

Now testing swiping

* Add comments to Pager tests

* Add more swiping tests

* Tidy up fling from touch hand-off

* Add kdoc

* Add @sample to Pager

* Add basic Pager doc page

* Update API files

* Tweak wording

* Basic semantic/a11y support

* Add (broken) support for a11y scrolls

* Increase offscreenLimit on sample

* Extract out pointer input handling

We have now split out the pointer input handling to 2 sides: raw event
handling which maps raw events to higher-level events
(PagerPointerEvent), and then a receiving side which updates the UI as
required from the PagerPointerEvents.

Internally this is done through a Channel, allowing appropriate queueing
on both the sending and receiving sides.

* Fix flinging in RTL after event changes

* Tidy up logging

* Add rememberPagerState()

- Also added `Saver` for state
- Fixed `pageCount` actually being a count
- Sprinkled annotations on params

* Update to AGP 7.0.0-alpha09

Had to disable some Lint warnings, due to the
mismatches with libraries

* Disable unsafe lint errors in :paging

* Trying out the new Modifier.draggable (google#235)

* Trying out the new Modifier.draggable
* Turn on startDragImmediately = true
* Turn off debug logging

* Mark the Pager API as experimental

* API improvements

- Made pageCount a mandatory parameter
- Renamed SelectionState values to be clearer

* Fix pageCount usage in PagerTest

* Tidy up offset handling

We now enforce that the offset is always in the range
of 0f..1f, and move the page as appropriate as we scroll.

* Improve flinging after normalization

* Use velocities in swiping tests

* Try and fix swipeWithVelocity() for CI

* Tidy up test utils

* Remove SelectionState

Not needed once we move to scrollable()

* Tidy up dependencies

* Mark PagerState and PagerScope as @stable

* Check input parameters for [animate]scrollToPage

* Add parameter value checking

* Use page index rather than PageData for key

* Fix currentPage coerce

* Fix Flow layout tests

* Test fixes for CI

- Use a 'Nexus 5X' emulator profile
- Store logs when running tests on CI
- Tweak Gradle JVM args for CI
- Store each API levels logs
- Build tests before running
- Increase size of test images
- Add tolerance to Picasso tests

* Rename Pager to HorizontalPager

This will allow us to add a VerticalPager later
without an API rename.

* Migrate Pager to com.google package name

* Add pager docs to site nav

* Tweak Pager POM description

* Turn debugging logging off
  • Loading branch information
chrisbanes committed Mar 15, 2021
2 parents c93c99e + d98a81c commit d567602
Show file tree
Hide file tree
Showing 40 changed files with 1,746 additions and 191 deletions.
3 changes: 1 addition & 2 deletions .github/ci-gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,8 @@
# limitations under the License.
#

org.gradle.daemon=false
org.gradle.parallel=true
org.gradle.jvmargs=-Xmx5120m
org.gradle.jvmargs=-Xmx4096m -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError
org.gradle.workers.max=2

kotlin.compiler.execution.strategy=in-process
24 changes: 16 additions & 8 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -92,27 +92,35 @@ jobs:
~/.gradle/caches/build-cache-*
key: gradle-${{ hashFiles('checksum.txt') }}

- name: Build tests
run: ./gradlew assembleDebugAndroidTest --scan

- name: Run tests
uses: reactivecircus/android-emulator-runner@v2
with:
api-level: ${{ matrix.api-level }}
script: ./gradlew --scan connectedCheck
profile: Nexus 5X
script: |
adb logcat > logcat.txt &
./gradlew --scan connectedCheck
- name: Clean secrets
if: always()
run: release/signing-cleanup.sh

- name: Copy test results
- name: Upload logs
if: always()
run: |
mkdir -p junit
find . -type f -regex ".*/build/test-results/.*xml" -exec cp {} junit/ \;
uses: actions/upload-artifact@v2
with:
name: logs-${{ matrix.api-level }}
path: logcat.txt

- name: Upload test results
if: always()
uses: actions/upload-artifact@v1
uses: actions/upload-artifact@v2
with:
name: junit-results
path: junit
name: test-results-${{ matrix.api-level }}
path: "**/build/outputs/*/connected/*.xml"

deploy:
if: github.event_name == 'push' # only deploy for pushed commits (not PRs)
Expand Down
3 changes: 0 additions & 3 deletions appcompat-theme/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -68,13 +68,10 @@ android {

dependencies {
implementation Libs.AndroidX.coreKtx
implementation Libs.AndroidX.Compose.runtime
implementation Libs.AndroidX.Compose.material

api Libs.AndroidX.appcompat

implementation Libs.Kotlin.stdlib

androidTestImplementation Libs.junit
androidTestImplementation Libs.AndroidX.Compose.test
androidTestImplementation Libs.AndroidX.Test.rules
Expand Down
3 changes: 3 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,9 @@ subprojects {
// Add Android SDK packages
noAndroidSdkLink.set(false)

// Add samples from :sample module
samples.from(rootProject.file("sample/src/main/java/"))

// AndroidX + Compose docs
externalDocumentationLink {
url.set(new URL("https://developer.android.com/reference/"))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ object Libs {

const val ui = "androidx.compose.ui:ui:${version}"
const val material = "androidx.compose.material:material:${version}"
const val iconsExtended = "androidx.compose.material:material-icons-extended:${version}"

const val util = "androidx.compose.ui:ui-util:${version}"
const val tooling = "androidx.ui:ui-tooling:${version}"
Expand All @@ -95,7 +96,7 @@ object Libs {

const val lifecycleKtx = "androidx.lifecycle:lifecycle-runtime-ktx:2.3.0"

const val coreAlpha = "androidx.core:core:1.5.0-beta02"
const val core1_5_0 = "androidx.core:core:1.5.0-beta02"

object Activity {
const val activityCompose = "androidx.activity:activity-compose:1.3.0-alpha04"
Expand Down
2 changes: 0 additions & 2 deletions coil/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,8 @@ dependencies {
api Libs.Coil.coil

implementation Libs.AndroidX.coreKtx
implementation Libs.AndroidX.Compose.runtime
implementation Libs.AndroidX.Compose.foundation

implementation Libs.Kotlin.stdlib
implementation Libs.Coroutines.android

// ======================
Expand Down
89 changes: 89 additions & 0 deletions docs/pager.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# Paging layouts

[![Maven Central](https://img.shields.io/maven-central/v/com.google.accompanist/accompanist-pager)](https://search.maven.org/search?q=g:com.google.accompanist)

A library which provides paging layouts for Jetpack Compose. If you've used Android's [`ViewPager`](https://developer.android.com/reference/kotlin/androidx/viewpager/widget/ViewPager) before, it has similar properties.

<video width="300" controls loop>
<source src="demo.mp4" type="video/mp4">
Your browser does not support the video tag.
</video>

!!! warning
The pager layouts are currently experimental and the APIs could change at any time.
All of the APIs are marked with the `@ExperimentalPagerApi` annotation.

The simplest usage looks like the following:

``` kotlin
// Display 10 items
val pagerState = rememberPagerState(pageCount = 10)

HorizontalPager(state = pagerState) { page ->
// Our page content
Text(
text = "Page: $page",
modifier = Modifier.fillMaxWidth()
)
}
```

## Lazy creation

Pages in a `HorizontalPager` are lazily created and laid-out as required by the layout. As the user scrolls through pages, any pages which are no longer required are removed from the content.

### Offscreen Limit

HorizontalPager allows the setting of the `offscreenLimit`, which defines the number of pages that should be retained on either side of the current page. Pages beyond this limit will be removed, and then recreated when needed. This value defaults to `1`, but can be increased to enable pre-loading of more content:

```kotlin
HorizontalPager(
state = pagerState,
offscreenLimit = 2,
) { page ->
// ...
}
```

---

## Usage

``` groovy
repositories {
mavenCentral()
}
dependencies {
implementation "com.google.accompanist:accompanist-pager:<version>"
}
```

### Library Snapshots

Snapshots of the current development version of this library are available, which track the latest commit. See [here](../using-snapshot-version) for more information on how to use them.

---

## Contributions

Please contribute! We will gladly review any pull requests.
Make sure to read the [Contributing](../contributing) page first though.

## License

```
Copyright 2021 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
```
Binary file added docs/pager/demo.mp4
Binary file not shown.
6 changes: 0 additions & 6 deletions flowlayout/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -70,22 +70,16 @@ android {
}

dependencies {
implementation Libs.AndroidX.Compose.runtime
implementation Libs.AndroidX.Compose.foundation
implementation Libs.AndroidX.Compose.util

implementation Libs.Kotlin.stdlib

// ======================
// Test dependencies
// ======================

androidTestImplementation Libs.junit
androidTestImplementation Libs.truth

// FIXME: Only needed for alpha12
androidTestImplementation Libs.AndroidX.Activity.activityCompose

androidTestImplementation Libs.AndroidX.Compose.test
androidTestImplementation Libs.AndroidX.Compose.ui
androidTestImplementation Libs.AndroidX.Test.rules
Expand Down
Loading

0 comments on commit d567602

Please sign in to comment.