Пример входа в систему с использованием Retrofit, MVVM, LiveData в Android - PullRequest
0 голосов
/ 11 мая 2019

Я проверил эту статью , но наблюдаю изменения ответа в 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 в простом примере входа в систему. Пожалуйста помоги!

1 Ответ

0 голосов
/ 11 мая 2019

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

в 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();
        }

    }
...