Last active
July 3, 2017 10:05
-
-
Save nectarine/a195daf0ebe0ad0786a8704fbe3e4507 to your computer and use it in GitHub Desktop.
Android MVVM with Custom State Widget
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<declare-styleable name="ElementStatus"> | |
<attr name="state_on" format="boolean" /> | |
<attr name="state_loading" format="boolean" /> | |
</declare-styleable> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="utf-8"?> | |
<selector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> | |
<item android:drawable="@drawable/round_rectangle_status_on" app:state_loading="true" /> | |
<item android:drawable="@drawable/round_rectangle_status_on" app:state_on="true" /> | |
<item android:drawable="@drawable/round_rectangle_status_off" /> | |
</selector> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
abstract class ElementViewModel<T : Element> : RxViewModel() { | |
lateinit var element: T | |
protected fun initialize(element: T) { | |
this.element = element | |
isOn.set(element.isOn()) | |
onStatusUpdate() | |
} | |
val isEnabled: ObservableField<Boolean> = ObservableField() | |
val isLoading: ObservableField<Boolean> = ObservableField(false) | |
val isOn: ObservableField<Boolean> = ObservableField() | |
open fun onStatusToggle(button: View) { | |
val currentStatus = element.status | |
if (element.isOn()) { | |
element.off() | |
} else { | |
element.on() | |
} | |
addDisposables( | |
apiRepository.modifyElementStatus(element, element.status!!) | |
.compose(UiModel.apiRequestTransformer) | |
.subscribe({ | |
if (it is UiModel.Loading) { | |
isLoading.set(true) | |
button.isEnabled = false | |
} else { | |
if (it is UiModel.Failure) { | |
ToastUtils.show(R.string.formatter_element_status_control_failed, element.getDisplayName()) | |
element.status = currentStatus | |
} | |
isLoading.set(false) | |
isOn.set(element.isOn()) | |
button.isEnabled = true | |
onStatusUpdate() | |
} | |
}) | |
) | |
} | |
open fun onStatusUpdate() { | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="utf-8"?> | |
<layout> | |
<data> | |
<variable | |
name="vm" | |
type="com.acciio.homeapp.ui.main.home.viewmodel.LightViewModel" /> | |
</data> | |
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" | |
xmlns:app="http://schemas.android.com/apk/res-auto" | |
android:layout_width="match_parent" | |
android:layout_height="112dp"> | |
<TextView | |
android:id="@+id/textView8" | |
style="@style/Text.Caption2.CardDesc" | |
android:layout_width="wrap_content" | |
android:layout_height="wrap_content" | |
android:layout_marginEnd="8dp" | |
android:layout_marginStart="8dp" | |
android:layout_marginTop="16dp" | |
android:text="@{vm.statusText}" | |
app:layout_constraintEnd_toStartOf="@+id/guideline6" | |
app:layout_constraintStart_toStartOf="@+id/guideline" | |
app:layout_constraintTop_toTopOf="parent" /> | |
<android.support.constraint.Guideline | |
android:id="@+id/guideline" | |
android:layout_width="wrap_content" | |
android:layout_height="wrap_content" | |
android:orientation="vertical" | |
app:layout_constraintGuide_begin="16dp" /> | |
<android.support.constraint.Guideline | |
android:id="@+id/guideline6" | |
android:layout_width="wrap_content" | |
android:layout_height="wrap_content" | |
android:orientation="vertical" | |
app:layout_constraintGuide_end="16dp" /> | |
<com.acciio.homeapp.custom.view.state.StateImageButton | |
android:id="@+id/imageButton" | |
android:layout_width="0dp" | |
android:layout_height="60dp" | |
android:layout_marginEnd="8dp" | |
android:layout_marginStart="8dp" | |
android:layout_marginTop="4dp" | |
android:background="@drawable/background_element_status" | |
android:onClick="@{(v) -> vm.onStatusToggle(v)}" | |
android:scaleType="center" | |
android:src="@drawable/icon_light_status" | |
app:layout_constraintEnd_toStartOf="@+id/guideline6" | |
app:layout_constraintStart_toStartOf="@+id/guideline" | |
app:layout_constraintTop_toBottomOf="@+id/textView8" | |
app:state_loading="@{safeUnbox(vm.isLoading)}" | |
app:state_on="@{safeUnbox(vm.isOn)}" /> | |
</android.support.constraint.ConstraintLayout> | |
</layout> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
object ViewBindingAdapter { | |
@JvmStatic | |
@BindingAdapter("app:state_loading") | |
fun setLoading(view: StateImageButton, isLoading: Boolean) { | |
view.isLoading = isLoading | |
} | |
@JvmStatic | |
@BindingAdapter("app:state_on") | |
fun setStatus(view: StateImageButton, isOn: Boolean) { | |
view.isOn = isOn | |
} | |
@JvmStatic | |
@BindingAdapter("app:state_loading") | |
fun setLoading(view: StateButton, isLoading: Boolean) { | |
view.isLoading = isLoading | |
} | |
@JvmStatic | |
@BindingAdapter("app:state_on") | |
fun setStatus(view: StateButton, isOn: Boolean) { | |
view.isOn = isOn | |
} | |
@JvmStatic | |
@BindingAdapter("app:error") | |
fun setError(view: TextInputLayout, error: String) { | |
view.error = error | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment