π A simple way to implement applications using observable streams
βββ βββ βββββββ ββββββββββββ βββββββ βββ ββββ ββββ ββββββ ββββββββββββββββ
βββ βββββββββββββββββββββββββ ββββββββ βββ βββββ βββββββββββββββββββββββββββββ
βββββββ βββ βββ βββ βββ βββββββββ ββββββββββββββββββββββββββββ βββββ ββββββ
βββββββ βββ βββ βββ βββ ββββββββββββββββββββββββββββββββββββββ βββββ ββββββ
βββ ββββββββββββ βββ ββββββββββββββ ββββββ βββ βββ ββββββ βββββββββββββββββββ
βββ βββ βββββββ βββ ββββββββββββββ βββββ βββ ββββββ βββββββββββββββββββ
Recommend create class as comparable like
data
class
data class HelloModel(
val name: String = ""
)
class HelloFragment : BaseFragment(), MazeListener<HelloModel> {
override val layoutId: Int = R.layout.fragment_hello
// Don't be in lifecycle of `Fragment`/`Activity`
// In this case, `BaseFragment` is set to `retainInstance = true` basically
// Set initial view model
private val maze by lazy { Maze(HelloModel()) }
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
// Attach maze with user events
// Event.id is used to filter in `main` function
maze.attach(this, arrayOf(
toolbar.navigationClicks()
.map { ClickEvent(R.id.homeAsUp) },
inputName.textChanges()
.map { TextChangeEvent(R.id.inputName, it) }
))
}
override fun onDestroyView() {
// Detach
maze.detach()
super.onDestroyView()
}
// Implement main function
override fun main(sources: Sources<HelloModel>) = helloMain(sources)
// Render view model
override fun render(prev: HelloModel, curr: HelloModel) {
val hello = getString(R.string.hello_message)
textHello.text = hello.format(curr.name)
}
// Navigate somethings
override fun navigate(navigation: Navigation) {
when (navigation) {
is Back -> activity?.onBackPressed()
}
}
// Cleanup if Activity is finished
override fun finish() = maze.finish()
// Handle errors
override fun error(t: Throwable) {
t.printStackTrace()
}
}
Implement main logic using Observable
s
fun helloMain(sources: Sources<HelloModel>): Sinks<HelloModel> {
val model = sources.event
.textChanges(R.id.inputName)
.map(CharSequence::toString)
.withLatestFrom(sources.model,
BiFunction { name: String, model: HelloModel ->
model.copy(name = name)
})
.cacheWithInitialCapacity(1)
val navigation = sources.event
.clicks(R.id.homeAsUp)
.map { Back() }
// `model` must be `ObservableCache`
return Sinks(model, navigation)
}
You can extend Navigation
s and/or Event
s if you want
Please refer to default
Navigation
s,
Event
s
repositories {
jcenter()
}
compile "com.importre:kotlin-maze:$maze_version"
testCompile "com.importre:kotlin-maze-test:$maze_version"
Apache 2.0 Β© Jaewe Heo