Пример входа с использованием Retrofit, MVVM, LiveData в android

Я проверил эту статью, но заметил изменения ответа в MainActivity.

Вот мой код для LoginRepo

public MutableLiveData<LoginResponseModel> checkLogin(LoginRequestModel loginRequestModel) {
    final MutableLiveData<LoginResponseModel> data = new MutableLiveData<>();
    Map<String, String> params = new HashMap<>();
    params.put("email", loginRequestModel.getEmail());
    params.put("password", loginRequestModel.getPassword());
    apiService.checkLogin(params)
            .enqueue(new Callback<LoginResponseModel>() {
                @Override
                public void onResponse(Call<LoginResponseModel> call, Response<LoginResponseModel> response) {
                    if (response.isSuccessful()) {
                        data.setValue(response.body());
                        Log.i("Response ", response.body().getMessage());
                    }
                }

                @Override
                public void onFailure(Call<LoginResponseModel> call, Throwable t) {
                    data.setValue(null);
                }
            });
    return data;
}

Вот мой код LoginViewModel

public class LoginViewModel extends ViewModel {


public MutableLiveData<String> emailAddress = new MutableLiveData<>();
public MutableLiveData<String> password = new MutableLiveData<>();
Map<String, String> params = new HashMap<>();
LoginRepo loginRepo;

private MutableLiveData<LoginResponseModel> loginResponseModelMutableLiveData;


public LiveData<LoginResponseModel> getUser() {
    if (loginResponseModelMutableLiveData == null) {
        loginResponseModelMutableLiveData = new MutableLiveData<>();
        loginRepo = LoginRepo.getInstance();
    }

    return loginResponseModelMutableLiveData;
}


//This method is using Retrofit to get the JSON data from URL
private void checkLogin(LoginRequestModel loginRequestModel) {
    loginResponseModelMutableLiveData = loginRepo.checkLogin(loginRequestModel);
}

public void onLoginClick(View view) {
    LoginRequestModel loginRequestModel = new LoginRequestModel();
    loginRequestModel.setEmail(emailAddress.getValue());
    loginRequestModel.setPassword(password.getValue());
    params.put("email", loginRequestModel.getEmail());
    params.put("password", loginRequestModel.getPassword());
    checkLogin(loginRequestModel);
}

}

Вот мой код для LoginActivity

 private LoginViewModel loginViewModel;
private ActivityMainBinding binding;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    loginViewModel = ViewModelProviders.of(this).get(LoginViewModel.class);
    binding = DataBindingUtil.setContentView(LoginActivity.this, R.layout.activity_main);
    binding.setLifecycleOwner(this);
    binding.setLoginViewModel(loginViewModel);
    loginViewModel.getUser().observe(this, new Observer<LoginResponseModel>() {
        @Override
        public void onChanged(@Nullable LoginResponseModel loginUser) {
            if (loginUser != null) {
                binding.lblEmailAnswer.setText(loginUser.getUser().getId());
                Toast.makeText(getApplicationContext(), loginUser.getUser().getId(), Toast.LENGTH_SHORT).show();
            }

        }
    });

}

onLoginClick, используемый в LoginViewModel, использует LiveData.

Ответ от api в порядке. Но onchange() не показано, как использовать LiveData с использованием шаблона MVVM в простом примере входа в систему. Пожалуйста помоги!


person Shubham Agrawal    schedule 11.05.2019    source источник


Ответы (1)


Вот то, что я пробовал использовать ваши классы, просто изменив модификацию на фоновый поток, чтобы подождать 5 секунд, а затем установить данные (вам нужно подтвердить успешный ответ, поскольку вы не меняете данные, если он не работает, и, следовательно, если loginResponseModel null, тогда он войдет в метод onChanged, но ничего не сделает, так как у вас нет условия, если оно равно null) вот что я сделал

в Main Activity -> onCreate () я только что создал модель просмотра и наблюдал за mutableLiveData

myViewModel.onLoginClick(null);
        myViewModel.simpleModelMutableLiveData.observe(this, new Observer<String>() {
            @Override
            public void onChanged(@Nullable String s) {
                if(s==null)
                  Log.v("testinggg","test - onChanged --- Null " );
                else
                    Log.v("testinggg","test - onChanged --- s -> "+s );
            }
        });

Тогда вот ViewModel ->, в котором у вас будет сама MutableLiveData с именем simpleModelMutableLiveData

     MutableLiveData<String> simpleModelMutableLiveData;


    public LiveData<String> getUser() {
        if (simpleModelMutableLiveData == null) {
            simpleModelMutableLiveData = new MutableLiveData<>();

        }

        return simpleModelMutableLiveData;
    }

  // this method will return Object of MutableLiveData<String> and let the simpleModelMutableLiveData be the returned object
    private void checkLogin(String placeholder) {
        simpleModelMutableLiveData = MyRepo.checkLogin(placeholder);
    }

    public void onLoginClick(View view) {

        checkLogin("test");
    }

и, наконец, метод Repo, в котором я верну MutableLiveData и позволю simpleModelMutableLiveData быть возвратом и инициировать фоновый поток с использованием runnable, который будет ждать 5 секунд, прежде чем он установит значение с помощью обработчика (в вашем случае вам нужно будет установить значение данных после постановки в очередь внутри переопределенных методов onResponse и onFailure)

следующее

public static MutableLiveData<String> checkLogin(String test) {
        final MutableLiveData<String> data = new MutableLiveData<>();


        Runnable r = new Runnable() {
            public void run() {
                runYourBackgroundTaskHere(data);
            }
        };

        new Thread(r).start();



        return data;
    }

     private static void runYourBackgroundTaskHere(final MutableLiveData<String> data) {

        try {
            Thread.sleep(5000);
//            Handler handler  = new Handler();
            new Handler(Looper.getMainLooper()).post(new Runnable() {
                @Override
                public void run() {
                    // things to do on the main thread

                /* Here i set the data to sss and then null and when 
                   you check the logcat and type the keyword used for 
                   logging which is "testinggg" 
                   you will find it show sss and then null which means 
                   it has entered the onChanged and showed you the log */

                    data.setValue("sss"); 
                    data.setValue(null);
                }
            });

        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }
person Hossam Eldeen Onsy    schedule 11.05.2019
comment
Это не сработало. onLoginClick() метод используется в XML-файле как привязка данных. - person Shubham Agrawal; 11.05.2019
comment
о, если вы используете привязку для щелчка, измените onLoginClick () на onLoginClick (представление просмотра), и я отредактирую ответ @ShubhamAgrawal - person Hossam Eldeen Onsy; 11.05.2019
comment
Я также видел в других сообщениях, где у них есть что-то вроде забавного onLoginClick (view: View) {} внутри модели просмотра, а затем связывается с XML. Но где-то еще я читал, что View никогда не следует передавать ViewModel. Я смущен! - person Suyash Dixit; 25.01.2020