Skip to content

Commit

Permalink
Add flowbinding-activity with a binding for OnBackPressedDispatcher.
Browse files Browse the repository at this point in the history
  • Loading branch information
ychescale9 committed Jan 23, 2020
1 parent 82c9800 commit 33f625c
Show file tree
Hide file tree
Showing 12 changed files with 155 additions and 0 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ implementation "io.github.reactivecircus.flowbinding:flowbinding-android:${flowb
### AndroidX Bindings

```groovy
implementation "io.github.reactivecircus.flowbinding:flowbinding-activity:${flowbinding_version}"
implementation "io.github.reactivecircus.flowbinding:flowbinding-appcompat:${flowbinding_version}"
implementation "io.github.reactivecircus.flowbinding:flowbinding-core:${flowbinding_version}"
implementation "io.github.reactivecircus.flowbinding:flowbinding-drawerlayout:${flowbinding_version}"
Expand Down Expand Up @@ -147,6 +148,7 @@ Our goal is to provide most of the bindings provided by **RxBinding**, while shi
List of all bindings available:

* [Platform bindings][flowbinding-android]
* [AndroidX Activity bindings][flowbinding-activity]
* [AndroidX AppCompat bindings][flowbinding-appcompat]
* [AndroidX Core bindings][flowbinding-core]
* [AndroidX DrawerLayout bindings][flowbinding-drawerlayout]
Expand Down Expand Up @@ -192,6 +194,7 @@ limitations under the License.
[flow]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/
[kotlinx-coroutines]: https://github.com/Kotlin/kotlinx.coroutines
[flowbinding-android]: flowbinding-android/
[flowbinding-activity]: flowbinding-activity/
[flowbinding-appcompat]: flowbinding-appcompat/
[flowbinding-core]: flowbinding-core/
[flowbinding-drawerlayout]: flowbinding-drawerlayout/
Expand Down
19 changes: 19 additions & 0 deletions flowbinding-activity/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# FlowBinding Activity

This module provides bindings for the **AndroidX Activity** library.

## Transitive Dependency

`androidx.activity:activity-ktx`

## Download

```groovy
implementation "io.github.reactivecircus.flowbinding:flowbinding-activity:${flowbinding_version}"
```

## Available Bindings

```kotlin
fun OnBackPressedDispatcher.backPresses(enabled: Boolean): Flow<Unit>
```
26 changes: 26 additions & 0 deletions flowbinding-activity/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
plugins {
id 'flowbinding-plugin'
id 'com.android.library'
id 'kotlin-android'
id 'com.vanniktech.maven.publish'
id 'io.github.reactivecircus.firestorm'
}

android {
defaultConfig {
testApplicationId 'reactivecircus.flowbinding.activity.test'
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
}

dependencies {
implementation project(':flowbinding-common')

implementation "androidx.activity:activity-ktx:${versions.androidx.activity}"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:${versions.kotlinx.coroutines}"

lintChecks project(":lint-rules")

androidTestImplementation project(':testing-infra')
androidTestImplementation project(':flowbinding-activity:fixtures')
}
13 changes: 13 additions & 0 deletions flowbinding-activity/fixtures/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
plugins {
id 'flowbinding-plugin'
id 'com.android.library'
id 'kotlin-android'
}

android.buildFeatures.viewBinding = true

dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:${versions.kotlin}"
implementation "androidx.activity:activity-ktx:${versions.androidx.activity}"
implementation "androidx.fragment:fragment:${versions.androidx.fragment}"
}
1 change: 1 addition & 0 deletions flowbinding-activity/fixtures/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<manifest package="reactivecircus.flowbinding.activity.fixtures" />
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package reactivecircus.flowbinding.activity.fixtures

import androidx.fragment.app.Fragment

class ActivityFragment : Fragment(R.layout.fragment_activity)
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" />
4 changes: 4 additions & 0 deletions flowbinding-activity/gradle.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
POM_ARTIFACT_ID=flowbinding-activity
POM_NAME=FlowBinding Activity
POM_DESCRIPTION=Kotlin Flow binding APIs for AndroidX Activity
POM_PACKAGING=aar
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package reactivecircus.flowbinding.activity

import androidx.test.filters.LargeTest
import org.amshove.kluent.shouldEqual
import org.junit.Test
import reactivecircus.blueprint.testing.action.pressBack
import reactivecircus.flowbinding.activity.fixtures.ActivityFragment
import reactivecircus.flowbinding.testing.FlowRecorder
import reactivecircus.flowbinding.testing.launchTest
import reactivecircus.flowbinding.testing.recordWith

@LargeTest
class OnBackPressedDispatcherBackPressedFlowTest {

@Test
fun onBackPressedDispatcherBackPresses() {
launchTest<ActivityFragment> {
val recorder = FlowRecorder<Unit>(testScope)
fragment.requireActivity().onBackPressedDispatcher.backPresses(owner = fragment).recordWith(recorder)

pressBack()
recorder.takeValue() shouldEqual Unit
recorder.assertNoMoreValues()

cancelTestScope()

pressBack()
recorder.assertNoMoreValues()
}
}
}
1 change: 1 addition & 0 deletions flowbinding-activity/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<manifest package="reactivecircus.flowbinding.activity" />
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package reactivecircus.flowbinding.activity

import androidx.activity.OnBackPressedCallback
import androidx.activity.OnBackPressedDispatcher
import androidx.annotation.CheckResult
import androidx.lifecycle.LifecycleOwner
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.callbackFlow
import kotlinx.coroutines.flow.conflate
import reactivecircus.flowbinding.common.checkMainThread
import reactivecircus.flowbinding.common.safeOffer

/**
* Create a [Flow] of on back pressed events on the [OnBackPressedDispatcher] instance.
*
* @param owner the LifecycleOwner which controls when the callback should be invoked.
*
* Note: Created flow keeps a strong reference to the [OnBackPressedDispatcher] instance
* until the coroutine that launched the flow collector is cancelled.
*
* Example of usage:
*
* ```
* onBackPressedDispatcher.backPresses(lifecycleOwner)
* .onEach {
* // handle back pressed
* }
* .launchIn(uiScope)
* ```
*/
@CheckResult
@UseExperimental(ExperimentalCoroutinesApi::class)
fun OnBackPressedDispatcher.backPresses(owner: LifecycleOwner): Flow<Unit> =
callbackFlow<Unit> {
checkMainThread()
val callback = object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
safeOffer(Unit)
}
}
addCallback(owner, callback)
awaitClose { callback.remove() }
}.conflate()
3 changes: 3 additions & 0 deletions settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ include(":flowbinding-common")
include(":flowbinding-android")
includeProject(":flowbinding-android:fixtures", "flowbinding-android/fixtures")

include(":flowbinding-activity")
includeProject(":flowbinding-activity:fixtures", "flowbinding-activity/fixtures")

include(":flowbinding-appcompat")
includeProject(":flowbinding-appcompat:fixtures", "flowbinding-appcompat/fixtures")

Expand Down

0 comments on commit 33f625c

Please sign in to comment.