GithubHelp home page GithubHelp logo

tchigher / flowbinding Goto Github PK

View Code? Open in Web Editor NEW

This project forked from reactivecircus/flowbinding

0.0 0.0 0.0 394 KB

Kotlin Coroutines Flow binding APIs for Android's platform and unbundled UI widgets, inspired by RxBinding.

Home Page: https://reactivecircus.github.io/FlowBinding/

License: Apache License 2.0

Shell 0.22% Kotlin 99.78%

flowbinding's Introduction

FlowBinding

CircleCI Build Status Maven Central Android API License

Kotlin Flow binding APIs for Android's platform and unbundled UI widgets, inspired by RxBinding.

Flow is (conceptually) a reactive streams implementation provided by the kotlinx-coroutines-core artifact.

FlowBinding offers an extensive set of extension functions that turn traditional callbacks / listeners on Android UI widgets into the Flow type.

Article

Blog post published in Kotlin Weekly #170 - Binding Android UI with Kotlin Flow

Download

Dependencies are hosted on Maven Central.

Latest version:

def flowbinding_version = "0.8.0"

Platform Bindings

implementation "io.github.reactivecircus.flowbinding:flowbinding-android:${flowbinding_version}"

AndroidX Bindings

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}"
implementation "io.github.reactivecircus.flowbinding:flowbinding-navigation:${flowbinding_version}"
implementation "io.github.reactivecircus.flowbinding:flowbinding-preference:${flowbinding_version}"
implementation "io.github.reactivecircus.flowbinding:flowbinding-recyclerview:${flowbinding_version}"
implementation "io.github.reactivecircus.flowbinding:flowbinding-swiperefreshlayout:${flowbinding_version}"
implementation "io.github.reactivecircus.flowbinding:flowbinding-viewpager2:${flowbinding_version}"

Material Components Bindings

implementation "io.github.reactivecircus.flowbinding:flowbinding-material:${flowbinding_version}"

Snapshots of the development version are available in Sonatype's snapshots repository.

Usage

Binding UI Events

To observe click events on an Android View:

findViewById<Button>(R.id.button)
    .clicks() // binding API available in flowbinding-android
    .onEach {
        // handle button clicked
    }
    .launchIn(uiScope)

Binding Scope

launchIn(scope) is a shorthand for scope.launch { flow.collect() } provided by the kotlinx-coroutines-core library.

This uiScope in the example above is a CoroutineScope that defines the lifecycle of this Flow. The binding implementation will respect this scope by unregistering the callback / listener automatically when the scope is cancelled.

In the context of Android lifecycle this means the uiScope passed in here should be a scope that's bound to the Lifecycle of the view the widget lives in.

androidx.lifecycle:lifecycle-runtime-ktx:2.2.0 introduced an extension property LifecycleOwner.lifecycleScope: LifecycleCoroutineScope which will be cancelled when the Lifecycle is destroyed.

In an Activity it might look something like this:

class ExampleActivity : AppCompatActivity() {
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_example)

        findViewById<ViewPager2>(R.id.viewPager)
            .pageSelections() // binding API available in flowbinding-viewpager2
            .onEach { pagePosition ->
                // handle pagePosition
            }
            .launchIn(lifecycleScope) // provided by lifecycle-runtime-ktx 
            
    }
}

Note that with FlowBinding you no longer need to unregister / remove listeners or callbacks in onDestroy() as this is done automatically for you.

Binding UI Events with Additional Information

Some UI widgets might hold a state internally which you might want to observe with a Flow.

For example with a TabLayout you might want to observe and react to the Tab selection events. In this case the binding API returns a Flow of custom TabLayoutSelectionEvent type which contains the currently selected Tab:

tabLayout.tabSelectionEvents()
    .filterIsInstance<TabLayoutSelectionEvent.TabSelected>() // only care about TabSelected events
    .onEach { event ->
        // sync selected tab title to some other UI element
        selectedTabTitle.text = event.tab.text
    }
    .launchIn(uiScope)

Eager Mode

In some cases you might want the Flow to emit the current value immediately when the Flow is collected.

For example a Slider might have a default value which was set in XML, and we want to bind the current value of the Slider to some other UI element as soon as the screen is launched without the value of the slider being changed by user.

The binding APIs for this kind of widgets have an optional emitImmediately: Boolean parameter which controls whether to emit the current value immediately on flow collection:

slider.valueChanges(emitImmediately = true)
    .onEach { value ->
        // handle value
    }
    .launchIn(uiScope)

Additional Samples

All binding APIs are documented with Example of usage.

All bindings are covered by instrumented tests which you may want to refer to.

Roadmap

Our goal is to provide most of the bindings provided by RxBinding, while shifting our focus to supporting more modern AndroidX APIs such as ViewPager2 and the new components in Material Components as they become available.

List of all bindings available:

Please feel free to create an issue if you think a useful binding is missing or you want a new binding added to the library.

Credits

This library is inspired by RxBinding which provides RxJava binding APIs for Android's UI widgets.

Many thanks to RxBinding's author Jake Wharton and its contributors.

License

Copyright 2019 Yang Chen

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

flowbinding's People

Contributors

hoc081098 avatar ychescale9 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.