Показать/скрыть ProgessBar из ViewModel с помощью привязки данных — MVVM

При получении ответа от веб-службы я хотел бы показать/скрыть индикатор выполнения, используя ViewModel и dataBinding. В настоящее время у меня есть функция loginOnClicked в ViewModel, связанная напрямую с моим макетом XML.

Я хочу создать индикатор выполнения и реализовать его в функции loginOnClicked и обновить видимость на основе этого. Может ли кто-нибудь помочь мне с этим?

логинАктивность

class loginActivity : AppCompatActivity(),SignupResultCallBack {

            override fun onSucces(message: String) {
                Toast.makeText(this,message, Toast.LENGTH_SHORT)
                        .show()
            }

            override fun onError(message: String) {
                Toast.makeText(this,message, Toast.LENGTH_SHORT)
                        .show()
            }


            override fun onCreate(savedInstanceState: Bundle?) {
                super.onCreate(savedInstanceState)
               // setContentView(R.layout.activity_login)



     val activityLoginBinding=DataBindingUtil.setContentView<ActivityLoginBinding(this,R.layout.activity_login)
       activityLoginBinding.viewModel=of(this,LoginViewModelFactory(this)).get(LoginViewModel::class.java)



   link_signup.setOnClickListener() {
        var intent=Intent(this@loginActivity,signupActivity::class.java)
                    startActivity(intent)
                    finish()
                }

                var test=activityLoginBinding.viewModel!!.progBar()
                if (test)
                    progressBar?.visibility=View.VISIBLE

                else
                    progressBar?.visibility=View.GONE

            }
        }

ViewModel

    class LoginViewModel(private var listener: SignupResultCallBack): ViewModel() {
        private val loginUser:UserRequest



        init {
            this.loginUser= UserRequest("","")
        }

         fun loginOnCLicked(v:View){
             var editLogin: Int = loginUser.isDataValid()
                         if (editLogin == 0)
                         listener.onError("entrer votre email")
                        else
                         if (editLogin == 1)
                         listener.onError("email invalide")
                        else
                         if (editLogin == 2)
                         listener.onError("mot de passe invalide")
                        else
                         if (editLogin == 3)
                             listener.onError("entrer votre mot de passe")
                         else
                             if (editLogin == 4)
                                 listener.onError("champs vides")
                             else


                             {
                                 RetrofitClient.instance.loginUser(UserRequest(loginUser.getEmail(), loginUser.getPassword())).enqueue(object : Callback<DefaultResponse> {
                                     override fun onFailure(call: Call<DefaultResponse>, t: Throwable) {
                                         listener.onError("t.message")

                                     }

                                     override fun onResponse(call: Call<DefaultResponse>, response: Response<DefaultResponse>) {

                                         if (response.code() == 400)
                                             listener.onSucces("login or password invalid")
                                         else if (response.code() == 200)
                                             listener.onSucces("success login")


                                     }

                                 })

               }

         }



}

логин.xml

<?xml version = "1.0" encoding = "utf-8"?>
    <layout xmlns:android = "http://schemas.android.com/apk/res/android"
        xmlns:app = "http://schemas.android.com/apk/res-auto"
        xmlns:tools = "http://schemas.android.com/tools">
        <data>
            <variable
                name = "viewModel"
                type = "com.example.rahma.alerteaccidentapp.vm.login.LoginViewModel"/>

        </data>



        <RelativeLayout
            android:layout_width = "match_parent"
            android:layout_height = "match_parent"
            android:background = "@color/colorBackground"
             tools:context = ".ui.login.loginActivity">


            <Button
                android:id = "@+id/btn_connexion"
                android:layout_width = "match_parent"
                android:layout_height = "wrap_content"
                android:layout_marginTop = "30dp"
                android:background = "@drawable/btn_round"
                android:text = "Connexion"
                android:onClick = "@{viewModel::loginOnCLicked}"

                android:layout_marginLeft = "20dp"
                android:layout_marginRight = "20dp"
                android:layout_below = "@id/password_Edit"
                android:textAppearance = "@style/MySerifBoldbtn"
                android:textColor = "@android:color/background_light"
                />



        </RelativeLayout>


    </layout>  
5
0
6 037
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Сначала отвечая на ваш точный вопрос, добавляя индикатор выполнения к загрузке веб-службы.

Создайте объект MutableLiveData в вашей модели LoginViewModel.

public MutableLiveData<Integer> progress = new MutableLiveData<>();

внутри вашего метода loginOnClicked

fun loginOnCLicked(v:View){

    progress.setValue(0); //View.VISIBLE

   .

   .

   .

   progress.setValue(8); //View.GONE

}

Добавьте индикатор выполнения в макет с привязкой данных

<ProgressBar
                android:id = "@+id/progressBar"
                style = "?android:attr/progressBarStyleLarge"
                android:layout_width = "wrap_content"
                android:layout_height = "wrap_content"
                android:layout_gravity = "center_horizontal"
                android:layout_marginTop = "8dp"
                android:visibility = "@{viewModel.progress}" />

Надеюсь это поможет.

Кстати, я бы попросил вас изменить реализацию прослушивателя для случая успеха/ошибки веб-сервиса на LiveData. Это способ MVVM делать что-то без ссылки на Activity в ViewModel.

Я пробовал это решение, и кажется, что это не сработает, если onclick() находится внутри модели представления.

Cyd 12.02.2020 08:44

Я добавлял знак равенства (=) после «@». Я делал это так android:visibility = "@ = {viewModel.progress}", что выдавало мне эту ошибку. Удаление этого знака равенства устранило проблему. Теперь это выглядит так android:visibility = "@{viewModel.progress}"

Bugs Happen 25.01.2021 05:53

Другие вопросы по теме