Skip to content

Commit

Permalink
update logic
Browse files Browse the repository at this point in the history
  • Loading branch information
Alex committed Aug 1, 2020
1 parent 77c26be commit 8601d23
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 88 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,16 @@ package com.alexdeww.reactiveviewmodel.widget

import android.view.View
import androidx.annotation.CallSuper
import com.alexdeww.reactiveviewmodel.core.property.State
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.core.BackpressureStrategy
import io.reactivex.rxjava3.core.Flowable
import io.reactivex.rxjava3.core.Observable
import io.reactivex.rxjava3.disposables.CompositeDisposable
import io.reactivex.rxjava3.disposables.Disposable

typealias OnVisibleChangeAction = (isVisible: Boolean) -> Unit

abstract class BaseVisualControl<T>(
initialValue: T
) : BaseControl() {
Expand All @@ -18,42 +22,48 @@ abstract class BaseVisualControl<T>(

val actionChangeValue = action<T>()

protected open fun transformObservable(observable: Observable<T>): Observable<T> = observable

@CallSuper
protected open fun onChangedValue(newValue: T) {
value.consumer.accept(newValue)
}

init {
actionChangeValue
.observable
.filter { it != value.value }
.let { transformObservable(it) }
.filter { it != value.value }
.subscribe(::onChangedValue)
}

}
fun <T> State<T>.toViewFlowable(): Flowable<T> = this
.observable
.toFlowable(BackpressureStrategy.LATEST)
.observeOn(AndroidSchedulers.mainThread())

internal fun <T> BaseVisualControl<T>.commonBindTo(
view: View,
invisibleState: Int
): Disposable = CompositeDisposable().apply {
add(
isEnabled
.observable
.toFlowable(BackpressureStrategy.LATEST)
.observeOn(AndroidSchedulers.mainThread())
.filter { it != view.isEnabled }
.subscribe { view.isEnabled = it }
)

add(
isVisible
.observable
.toFlowable(BackpressureStrategy.LATEST)
.observeOn(AndroidSchedulers.mainThread())
.filter { it != (view.visibility == View.VISIBLE) }
.subscribe { view.visibility = if (it) View.VISIBLE else invisibleState }
)
}
fun defaultBindTo(
view: View,
invisibleState: Int = View.GONE,
onVisibleChange: OnVisibleChangeAction? = null
): Disposable = CompositeDisposable().apply {
add(
isEnabled
.toViewFlowable()
.subscribe { view.isEnabled = it }
)

add(
isVisible
.toViewFlowable()
.subscribe {
when {
onVisibleChange != null -> onVisibleChange.invoke(it)
else -> view.visibility = if (it) View.VISIBLE else invisibleState
}
}
)
}

protected open fun transformObservable(observable: Observable<T>): Observable<T> = observable

@CallSuper
protected open fun onChangedValue(newValue: T) {
value.consumer.accept(newValue)
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ package com.alexdeww.reactiveviewmodel.widget
import android.annotation.SuppressLint
import android.view.View
import android.widget.CompoundButton
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.core.BackpressureStrategy
import io.reactivex.rxjava3.core.Observable
import io.reactivex.rxjava3.disposables.CompositeDisposable
import io.reactivex.rxjava3.disposables.Disposable
Expand All @@ -18,16 +16,15 @@ fun checkControl(initialChecked: Boolean = false): CheckControl = CheckControl(i

fun CheckControl.bindTo(
compoundButton: CompoundButton,
invisibleState: Int = View.GONE
invisibleState: Int = View.GONE,
onVisibleChange: OnVisibleChangeAction? = null
): Disposable {
var editing = false
return CompositeDisposable().apply {
add(commonBindTo(compoundButton, invisibleState))
add(defaultBindTo(compoundButton, invisibleState, onVisibleChange))
add(
value
.observable
.toFlowable(BackpressureStrategy.LATEST)
.observeOn(AndroidSchedulers.mainThread())
.toViewFlowable()
.subscribe {
editing = true
compoundButton.isChecked = it
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,45 +40,18 @@ fun inputControl(
formatter: FormatterAction? = null
): InputControl = InputControl(initialText, hideErrorOnUserInput, formatter)


private val EditText.textChanges: Observable<CharSequence>
get() = Observable
.create { emitter ->
val listener = object : TextWatcher {
override fun afterTextChanged(s: Editable?) {
/* nothing */
}

override fun beforeTextChanged(
s: CharSequence?,
start: Int,
count: Int,
after: Int
) {
/* nothing */
}

override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
if (s != null) emitter.onNext(s)
}
}
addTextChangedListener(listener)
emitter.setCancellable { removeTextChangedListener(listener) }
}

fun InputControl.bindTo(
editText: EditText,
useError: Boolean = false,
invisibleState: Int = View.GONE
invisibleState: Int = View.GONE,
onVisibleChange: OnVisibleChangeAction? = null
): Disposable {
var editing = false
return CompositeDisposable().apply {
add(commonBindTo(editText, invisibleState))
add(defaultBindTo(editText, invisibleState, onVisibleChange))
add(
value
.observable
.toFlowable(BackpressureStrategy.LATEST)
.observeOn(AndroidSchedulers.mainThread())
.toViewFlowable()
.subscribe {
val editable = editText.text
if (!it!!.contentEquals(editable)) {
Expand All @@ -98,9 +71,7 @@ fun InputControl.bindTo(
if (useError) {
add(
error
.observable
.toFlowable(BackpressureStrategy.LATEST)
.observeOn(AndroidSchedulers.mainThread())
.toViewFlowable()
.subscribe { s -> editText.error = s.takeIf { it.isNotEmpty() } }
)
}
Expand All @@ -118,9 +89,10 @@ fun InputControl.bindTo(
fun InputControl.bindTo(
textInputLayout: TextInputLayout,
useError: Boolean = false,
invisibleState: Int = View.GONE
invisibleState: Int = View.GONE,
onVisibleChange: OnVisibleChangeAction? = null
): Disposable = CompositeDisposable().apply {
add(bindTo(textInputLayout.editText!!, false, invisibleState))
add(bindTo(textInputLayout.editText!!, false, invisibleState, onVisibleChange))
if (useError) {
add(
error
Expand All @@ -130,4 +102,28 @@ fun InputControl.bindTo(
.subscribe { s -> textInputLayout.error = s.takeIf { it.isNotEmpty() } }
)
}
}
}

private val EditText.textChanges: Observable<CharSequence>
get() = Observable.create { emitter ->
val listener = object : TextWatcher {
override fun afterTextChanged(s: Editable?) {
/* nothing */
}

override fun beforeTextChanged(
s: CharSequence?,
start: Int,
count: Int,
after: Int
) {
/* nothing */
}

override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
if (s != null) emitter.onNext(s)
}
}
addTextChangedListener(listener)
emitter.setCancellable { removeTextChangedListener(listener) }
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ package com.alexdeww.reactiveviewmodel.widget
import android.annotation.SuppressLint
import android.view.View
import android.widget.RatingBar
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.core.BackpressureStrategy
import io.reactivex.rxjava3.core.Observable
import io.reactivex.rxjava3.disposables.CompositeDisposable
import io.reactivex.rxjava3.disposables.Disposable
Expand All @@ -16,24 +14,17 @@ class RatingControl internal constructor(

fun ratingControl(initialValue: Float = 0f): RatingControl = RatingControl(initialValue)

private val RatingBar.ratingBarChange: Observable<Float>
get() = Observable.create { emitter ->
setOnRatingBarChangeListener { _, rating, _ -> emitter.onNext(rating) }
emitter.setCancellable { onRatingBarChangeListener = null }
}

fun RatingControl.bindTo(
ratingBar: RatingBar,
invisibleState: Int = View.GONE
invisibleState: Int = View.GONE,
onVisibleChange: OnVisibleChangeAction? = null
): Disposable {
var editing = false
return CompositeDisposable().apply {
add(commonBindTo(ratingBar, invisibleState))
add(defaultBindTo(ratingBar, invisibleState, onVisibleChange))
add(
value
.observable
.toFlowable(BackpressureStrategy.LATEST)
.observeOn(AndroidSchedulers.mainThread())
.toViewFlowable()
.subscribe {
editing = true
ratingBar.rating = it
Expand All @@ -48,4 +39,10 @@ fun RatingControl.bindTo(
.subscribe(actionChangeValue.consumer)
)
}
}
}

private val RatingBar.ratingBarChange: Observable<Float>
get() = Observable.create { emitter ->
setOnRatingBarChangeListener { _, rating, _ -> emitter.onNext(rating) }
emitter.setCancellable { onRatingBarChangeListener = null }
}

0 comments on commit 8601d23

Please sign in to comment.