From a694246a56e877b452a85528e7cff0043fe0f1d0 Mon Sep 17 00:00:00 2001 From: Daniele Date: Wed, 22 Sep 2021 08:20:33 +0200 Subject: [PATCH] Conversion to MVVM completed --- .../detail/GeofavoriteDetailActivity.java | 10 ++-- .../GeofavoriteDetailActivityViewModel.java | 26 ++------- .../activity/main/MainActivity.java | 6 +- .../activity/main/MainActivityViewModel.java | 26 ++------- .../repository/GeofavoriteRepository.java | 56 +++++++++++-------- .../nextcloudmaps/utils/SingleLiveEvent.java | 44 +++++++++++++++ 6 files changed, 93 insertions(+), 75 deletions(-) create mode 100644 app/src/main/java/it/danieleverducci/nextcloudmaps/utils/SingleLiveEvent.java diff --git a/app/src/main/java/it/danieleverducci/nextcloudmaps/activity/detail/GeofavoriteDetailActivity.java b/app/src/main/java/it/danieleverducci/nextcloudmaps/activity/detail/GeofavoriteDetailActivity.java index d106083..25e0269 100644 --- a/app/src/main/java/it/danieleverducci/nextcloudmaps/activity/detail/GeofavoriteDetailActivity.java +++ b/app/src/main/java/it/danieleverducci/nextcloudmaps/activity/detail/GeofavoriteDetailActivity.java @@ -125,14 +125,14 @@ public class GeofavoriteDetailActivity extends AppCompatActivity implements Loca mViewHolder.setUpdating(updating); } }); - mViewModel.getIsFailed().observe(this, new Observer() { + mViewModel.getOnFinished().observe(this, new Observer() { @Override - public void onChanged(@Nullable Boolean failed) { - if(failed){ - Toast.makeText(GeofavoriteDetailActivity.this, R.string.error_saving_geofavorite, Toast.LENGTH_SHORT).show(); - } else { + public void onChanged(@Nullable Boolean success) { + if(success){ Toast.makeText(GeofavoriteDetailActivity.this, R.string.geofavorite_saved, Toast.LENGTH_SHORT).show(); finish(); + } else { + Toast.makeText(GeofavoriteDetailActivity.this, R.string.error_saving_geofavorite, Toast.LENGTH_SHORT).show(); } } }); diff --git a/app/src/main/java/it/danieleverducci/nextcloudmaps/activity/detail/GeofavoriteDetailActivityViewModel.java b/app/src/main/java/it/danieleverducci/nextcloudmaps/activity/detail/GeofavoriteDetailActivityViewModel.java index 80d38b2..71c2011 100644 --- a/app/src/main/java/it/danieleverducci/nextcloudmaps/activity/detail/GeofavoriteDetailActivityViewModel.java +++ b/app/src/main/java/it/danieleverducci/nextcloudmaps/activity/detail/GeofavoriteDetailActivityViewModel.java @@ -7,14 +7,11 @@ import androidx.lifecycle.ViewModel; import it.danieleverducci.nextcloudmaps.model.Geofavorite; import it.danieleverducci.nextcloudmaps.repository.GeofavoriteRepository; -public class GeofavoriteDetailActivityViewModel extends ViewModel implements GeofavoriteRepository.OnFinished { +public class GeofavoriteDetailActivityViewModel extends ViewModel { private GeofavoriteRepository mRepo; - private MutableLiveData mIsUpdating = new MutableLiveData<>(); - private MutableLiveData mIsFailed = new MutableLiveData<>(); public void init() { mRepo = GeofavoriteRepository.getInstance(); - mRepo.setOnFinishedListener(this); } public Geofavorite getGeofavorite(int id) { @@ -27,26 +24,11 @@ public class GeofavoriteDetailActivityViewModel extends ViewModel implements Geo public LiveData getIsUpdating(){ - return mIsUpdating; + return mRepo.isUpdating(); } - public LiveData getIsFailed(){ - return mIsFailed; + public LiveData getOnFinished(){ + return mRepo.onFinished(); } - @Override - public void onLoading() { - mIsUpdating.postValue(true); - } - @Override - public void onSuccess() { - mIsUpdating.postValue(false); - mIsFailed.postValue(false); - } - - @Override - public void onFailure() { - mIsUpdating.postValue(false); - mIsFailed.postValue(true); - } } diff --git a/app/src/main/java/it/danieleverducci/nextcloudmaps/activity/main/MainActivity.java b/app/src/main/java/it/danieleverducci/nextcloudmaps/activity/main/MainActivity.java index b595be2..ec045d7 100644 --- a/app/src/main/java/it/danieleverducci/nextcloudmaps/activity/main/MainActivity.java +++ b/app/src/main/java/it/danieleverducci/nextcloudmaps/activity/main/MainActivity.java @@ -144,10 +144,10 @@ public class MainActivity extends AppCompatActivity implements OnSortingOrderLis } } }); - mMainActivityViewModel.getIsFailed().observe(this, new Observer() { + mMainActivityViewModel.getOnFinished().observe(this, new Observer() { @Override - public void onChanged(@Nullable Boolean aBoolean) { - if(aBoolean){ + public void onChanged(@Nullable Boolean success) { + if(!success){ Toast.makeText(MainActivity.this, R.string.list_geofavorite_connection_error, Toast.LENGTH_LONG).show(); } } diff --git a/app/src/main/java/it/danieleverducci/nextcloudmaps/activity/main/MainActivityViewModel.java b/app/src/main/java/it/danieleverducci/nextcloudmaps/activity/main/MainActivityViewModel.java index 0dc11c7..0624349 100644 --- a/app/src/main/java/it/danieleverducci/nextcloudmaps/activity/main/MainActivityViewModel.java +++ b/app/src/main/java/it/danieleverducci/nextcloudmaps/activity/main/MainActivityViewModel.java @@ -9,14 +9,11 @@ import java.util.List; import it.danieleverducci.nextcloudmaps.model.Geofavorite; import it.danieleverducci.nextcloudmaps.repository.GeofavoriteRepository; -public class MainActivityViewModel extends ViewModel implements GeofavoriteRepository.OnFinished { +public class MainActivityViewModel extends ViewModel { private GeofavoriteRepository mRepo; - private MutableLiveData mIsUpdating = new MutableLiveData<>(); - private MutableLiveData mIsFailed = new MutableLiveData<>(); public void init() { mRepo = GeofavoriteRepository.getInstance(); - mRepo.setOnFinishedListener(this); } public LiveData> getGeofavorites(){ @@ -33,26 +30,11 @@ public class MainActivityViewModel extends ViewModel implements GeofavoriteRepos } public LiveData getIsUpdating(){ - return mIsUpdating; + return mRepo.isUpdating(); } - public LiveData getIsFailed(){ - return mIsFailed; + public LiveData getOnFinished(){ + return mRepo.onFinished(); } - @Override - public void onLoading() { - mIsUpdating.postValue(true); - } - @Override - public void onSuccess() { - mIsUpdating.postValue(false); - mIsFailed.postValue(false); - } - - @Override - public void onFailure() { - mIsUpdating.postValue(false); - mIsFailed.postValue(true); - } } diff --git a/app/src/main/java/it/danieleverducci/nextcloudmaps/repository/GeofavoriteRepository.java b/app/src/main/java/it/danieleverducci/nextcloudmaps/repository/GeofavoriteRepository.java index a4939fc..ce95c44 100644 --- a/app/src/main/java/it/danieleverducci/nextcloudmaps/repository/GeofavoriteRepository.java +++ b/app/src/main/java/it/danieleverducci/nextcloudmaps/repository/GeofavoriteRepository.java @@ -11,6 +11,7 @@ import java.util.List; import it.danieleverducci.nextcloudmaps.api.ApiProvider; import it.danieleverducci.nextcloudmaps.model.Geofavorite; +import it.danieleverducci.nextcloudmaps.utils.SingleLiveEvent; import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; @@ -20,9 +21,11 @@ import retrofit2.Response; */ public class GeofavoriteRepository { + private static final String TAG = "GeofavoriteRepository"; private static GeofavoriteRepository instance; private MutableLiveData> mGeofavorites; - private OnFinished listener; + private MutableLiveData mIsUpdating = new MutableLiveData<>(false); + private SingleLiveEvent mOnFinished = new SingleLiveEvent<>(); public static GeofavoriteRepository getInstance() { if(instance == null){ @@ -39,8 +42,16 @@ public class GeofavoriteRepository { return mGeofavorites; } + public MutableLiveData isUpdating() { + return mIsUpdating; + } + + public SingleLiveEvent onFinished() { + return mOnFinished; + } + public void updateGeofavorites() { - if (listener != null) listener.onLoading(); + mIsUpdating.postValue(true); // Obtain geofavorites Call> call = ApiProvider.getAPI().getGeofavorites(); call.enqueue(new Callback>() { @@ -48,7 +59,8 @@ public class GeofavoriteRepository { public void onResponse(@NonNull Call> call, @NonNull Response> response) { if (response.isSuccessful() && response.body() != null) { mGeofavorites.postValue(response.body()); - if (listener != null) listener.onSuccess(); + mIsUpdating.postValue(false); + mOnFinished.postValue(true); } else { onFailure(call, new Throwable("Dataset is empty")); } @@ -56,7 +68,8 @@ public class GeofavoriteRepository { @Override public void onFailure(@NonNull Call> call, @NonNull Throwable t) { - if (listener != null) listener.onFailure(); + mIsUpdating.postValue(false); + mOnFinished.postValue(false); } }); } @@ -70,6 +83,7 @@ public class GeofavoriteRepository { } public void saveGeofavorite(Geofavorite geofav) { + mIsUpdating.postValue(true); Call call; if (geofav.getId() == 0) { // New geofavorite @@ -88,21 +102,25 @@ public class GeofavoriteRepository { } geofavs.add(geofav); mGeofavorites.postValue(geofavs); - if (listener != null) listener.onSuccess(); - } else if (listener != null) { - listener.onFailure(); + mIsUpdating.postValue(false); + mOnFinished.postValue(true); + } else { + mIsUpdating.postValue(false); + mOnFinished.postValue(false); } } @Override public void onFailure(Call call, Throwable t) { - if (listener != null) listener.onFailure(); + Log.e(TAG, t.getMessage()); + mIsUpdating.postValue(false); + mOnFinished.postValue(false); } }); } public void deleteGeofavorite(Geofavorite geofav) { - if (listener != null) listener.onLoading(); + mIsUpdating.postValue(true); // Delete Geofavorite Call call = ApiProvider.getAPI().deleteGeofavorite(geofav.getId()); call.enqueue(new Callback() { @@ -111,29 +129,21 @@ public class GeofavoriteRepository { List geofavs = mGeofavorites.getValue(); if (geofavs.remove(geofav)) { mGeofavorites.postValue(geofavs); - if (listener != null) listener.onSuccess(); + mIsUpdating.postValue(false); + mOnFinished.postValue(true); } else { // Should never happen - if (listener != null) listener.onFailure(); + mIsUpdating.postValue(false); + mOnFinished.postValue(false); } } @Override public void onFailure(Call call, Throwable t) { - if (listener != null) listener.onFailure(); + mIsUpdating.postValue(false); + mOnFinished.postValue(false); } }); } - public void setOnFinishedListener(OnFinished listener) { - this.listener = listener; - } - - public interface OnFinished { - void onLoading(); - void onSuccess(); - void onFailure(); - } - - } diff --git a/app/src/main/java/it/danieleverducci/nextcloudmaps/utils/SingleLiveEvent.java b/app/src/main/java/it/danieleverducci/nextcloudmaps/utils/SingleLiveEvent.java new file mode 100644 index 0000000..8f71166 --- /dev/null +++ b/app/src/main/java/it/danieleverducci/nextcloudmaps/utils/SingleLiveEvent.java @@ -0,0 +1,44 @@ +package it.danieleverducci.nextcloudmaps.utils; + +import androidx.annotation.MainThread; +import androidx.annotation.NonNull; +import androidx.lifecycle.LifecycleOwner; +import androidx.lifecycle.MutableLiveData; +import androidx.lifecycle.Observer; +import java.util.concurrent.atomic.AtomicBoolean; + +/** + * Events implementation in LiveData + * From: https://gist.github.com/teegarcs/319a3e7e4736a0cce8eba2216c52b0ca#file-singleliveevent + * @param + */ +public class SingleLiveEvent extends MutableLiveData { + AtomicBoolean mPending = new AtomicBoolean(false); + + @MainThread + @Override + public void setValue(T value) { + mPending.set(true); + super.setValue(value); + } + + @MainThread + @Override + public void observe(@NonNull LifecycleOwner owner, @NonNull Observer observer) { + super.observe(owner, new Observer() { + @Override + public void onChanged(T t) { + if (mPending.compareAndSet(true, false)) { + observer.onChanged(t); + } + } + }); + } + + /** + * Util function for Void implementations. + */ + public void call() { + setValue(null); + } +}