One State View

OneStateView is a custom view that you can use in xml files, this view is intended to manage the state you get when you want to handle events such as loading, errors or if there is empty data. OneStateView can also be customized according to your case and needs. For example:

<com.wahidabd.library.decoration.onestateview.OneStateView
    android:id="@+id/view_state"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:osv_default="content"
    app:osv_empty="@layout/layout_empty"
    app:osv_error="@layout/layout_error"
    app:osv_loading="@layout/default_loading_layout">
    
    <TextView
        android:id="@+id/tv_result"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:text="Default"
        android:layout_gravity="center"
        android:textSize="28sp" />
</com.wahidabd.library.decoration.onestateview.OneStateView>
with(binding) {
    btnDefault.onClick {
        viewState.showContent()
    }

    btnLoading.onClick {
        viewState.showLoading()
    }

    btnEmpty.onClick {
        viewState.showEmpty()
    }

    btnError.onClick {
        viewState.showError()
    }
}

And if you need an event listener to handle actions, you can create a function according to your needs. First create the xml file you want to use. For example

<?xml version="1.0" encoding="utf-8"?>
<androidx.appcompat.widget.LinearLayoutCompat xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/error_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical"
    android:padding="@dimen/dimen_16dp">

    <ImageView
        android:id="@+id/img_error"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:layout_marginHorizontal="32dp"
        android:scaleType="fitCenter"
        tools:src="@drawable/abc_vector_test" />

    <TextView
        android:id="@+id/tv_title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:layout_marginTop="16dp"
        android:gravity="center_horizontal"
        android:text="Error"
        android:textStyle="bold" />

    <TextView
        android:id="@+id/tv_error"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:layout_marginTop="8dp"
        android:gravity="center_horizontal"
        android:text="@string/error" />

    <Button
        android:id="@+id/btn_error"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:layout_marginTop="8dp"
        android:text="Retry"
        android:textSize="14sp" />
</androidx.appcompat.widget.LinearLayoutCompat>

The, create extension function for the xml file

fun OneStateView.showCustomErrorState(
    message: String = emptyString(),
    onRetry: (() -> Unit)? = null
) {
    viewState = OneStateView.OneViewState.ERROR
    val binding = LayoutErrorBinding.inflate(this.context.layoutInflater)
    this.setViewForState(binding.root, OneStateView.OneViewState.ERROR, false)

    if (message.isNotEmpty()) {
        binding.tvError.text = message
    }

    binding.btnError.onClick {
        onRetry?.invoke()
    }
}

Then, you can call it on the view and handle what action you want to perform. For example

viewState.showCustomErrorState("This is error message") {
    showToast("Button error clicked")
}

You can see an example of its use here.

Result:

Last updated