WIP implementing MVVM

This commit is contained in:
Daniele
2021-09-21 09:25:28 +02:00
parent cf7f96efad
commit 8b7e89f43b
8 changed files with 254 additions and 104 deletions
@@ -37,6 +37,8 @@ import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.content.res.AppCompatResources;
import androidx.core.app.ActivityCompat;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import androidx.preference.PreferenceManager;
import org.osmdroid.api.IMapController;
@@ -48,9 +50,11 @@ import org.threeten.bp.format.DateTimeFormatter;
import org.threeten.bp.format.FormatStyle;
import java.util.Date;
import java.util.List;
import it.danieleverducci.nextcloudmaps.R;
import it.danieleverducci.nextcloudmaps.activity.main.MainActivity;
import it.danieleverducci.nextcloudmaps.activity.main.MainActivityViewModel;
import it.danieleverducci.nextcloudmaps.api.ApiProvider;
import it.danieleverducci.nextcloudmaps.databinding.ActivityGeofavoriteDetailBinding;
import it.danieleverducci.nextcloudmaps.model.Geofavorite;
@@ -68,6 +72,7 @@ public class GeofavoriteDetailActivity extends AppCompatActivity implements Loca
private ViewHolder mViewHolder;
private Geofavorite mGeofavorite;
private GeofavoriteDetailActivityViewModel mViewModel;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
@@ -112,9 +117,31 @@ public class GeofavoriteDetailActivity extends AppCompatActivity implements Loca
}
});
if (getIntent().hasExtra(ARG_GEOFAVORITE)) {
mViewModel = new ViewModelProvider(this).get(GeofavoriteDetailActivityViewModel.class);
mViewModel.init();
mViewModel.getIsUpdating().observe(this, new Observer<Boolean>() {
@Override
public void onChanged(@Nullable Boolean updating) {
mViewHolder.setUpdating(updating);
}
});
mViewModel.getIsFailed().observe(this, new Observer<Boolean>() {
@Override
public void onChanged(@Nullable Boolean failed) {
if(failed){
Toast.makeText(GeofavoriteDetailActivity.this, R.string.error_saving_geofavorite, Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(GeofavoriteDetailActivity.this, R.string.geofavorite_saved, Toast.LENGTH_SHORT).show();
finish();
}
}
});
if (getIntent().hasExtra(ARG_GEOFAVORITE) && getIntent().getIntExtra(ARG_GEOFAVORITE, 0) != 0) {
// Opening geofavorite from list
mGeofavorite = (Geofavorite) getIntent().getSerializableExtra(ARG_GEOFAVORITE);
mGeofavorite = mViewModel.getGeofavorite(
getIntent().getIntExtra(ARG_GEOFAVORITE, 0)
);
mViewHolder.hideAccuracy();
} else {
// New geofavorite
@@ -169,35 +196,7 @@ public class GeofavoriteDetailActivity extends AppCompatActivity implements Loca
return;
}
Call<Geofavorite> call;
if (mGeofavorite.getId() == 0) {
// New geofavorite
call = ApiProvider.getAPI().createGeofavorite(mGeofavorite);
} else {
// Update existing geofavorite
call = ApiProvider.getAPI().updateGeofavorite(mGeofavorite.getId(), mGeofavorite);
}
call.enqueue(new Callback<Geofavorite>() {
@Override
public void onResponse(Call<Geofavorite> call, Response<Geofavorite> response) {
if (response.isSuccessful())
finish();
else
onGeofavoriteSaveFailed();
}
@Override
public void onFailure(Call<Geofavorite> call, Throwable t) {
onGeofavoriteSaveFailed();
Log.e(TAG, "Unable to update geofavorite: " + t.getMessage());
}
});
}
private void onGeofavoriteSaveFailed() {
runOnUiThread(() ->
Toast.makeText(GeofavoriteDetailActivity.this, R.string.error_saving_geofavorite, Toast.LENGTH_SHORT).show()
);
mViewModel.saveGeofavorite(mGeofavorite);
}
/**
@@ -334,6 +333,10 @@ public class GeofavoriteDetailActivity extends AppCompatActivity implements Loca
item.setDateModified(System.currentTimeMillis() / 1000);
}
public void setUpdating(boolean updating) {
binding.progress.setVisibility(updating ? View.VISIBLE : View.GONE);
}
public void setAccuracy(float accuracy) {
binding.accuracyTv.setText(getString(R.string.accuracy).replace("{accuracy}", ((int)accuracy) + ""));
// Color the accuracy background with a scale from red (MINIMUM_ACCEPTABLE_ACCURACY) to green (0 meters)
@@ -0,0 +1,52 @@
package it.danieleverducci.nextcloudmaps.activity.detail;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
import it.danieleverducci.nextcloudmaps.model.Geofavorite;
import it.danieleverducci.nextcloudmaps.repository.GeofavoriteRepository;
public class GeofavoriteDetailActivityViewModel extends ViewModel implements GeofavoriteRepository.OnFinished {
private GeofavoriteRepository mRepo;
private MutableLiveData<Boolean> mIsUpdating = new MutableLiveData<>();
private MutableLiveData<Boolean> mIsFailed = new MutableLiveData<>();
public void init() {
mRepo = GeofavoriteRepository.getInstance();
mRepo.setOnFinishedListener(this);
}
public Geofavorite getGeofavorite(int id) {
return mRepo.getGeofavorite(id);
}
public void saveGeofavorite(Geofavorite geofav) {
mRepo.saveGeofavorite(geofav);
}
public LiveData<Boolean> getIsUpdating(){
return mIsUpdating;
}
public LiveData<Boolean> getIsFailed(){
return mIsFailed;
}
@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);
}
}
@@ -67,9 +67,6 @@ import androidx.lifecycle.Observer;
public class MainActivity extends AppCompatActivity implements OnSortingOrderListener {
private static final int INTENT_ADD = 100;
private static final int INTENT_EDIT = 200;
private static final String TAG = "MainActivity";
private static final String NAVIGATION_KEY_ADD_GEOFAVORITE = "add";
@@ -98,8 +95,6 @@ public class MainActivity extends AppCompatActivity implements OnSortingOrderLis
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mMainActivityViewModel = new ViewModelProvider(this).get(MainActivityViewModel.class);
mMainActivityViewModel.init();
preferences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
int sortRule = preferences.getInt(getString(R.string.setting_sort_by), SORT_BY_CREATED);
@@ -135,8 +130,39 @@ public class MainActivity extends AppCompatActivity implements OnSortingOrderLis
recyclerView.setAdapter(geofavoriteAdapter);
geofavoriteAdapter.setSortRule(sortRule);
mMainActivityViewModel = new ViewModelProvider(this).get(MainActivityViewModel.class);
mMainActivityViewModel.init();
mMainActivityViewModel.getIsUpdating().observe(this, new Observer<Boolean>() {
@Override
public void onChanged(@Nullable Boolean aBoolean) {
if(aBoolean){
swipeRefresh.setRefreshing(true);
}
else{
swipeRefresh.setRefreshing(false);
}
}
});
mMainActivityViewModel.getIsFailed().observe(this, new Observer<Boolean>() {
@Override
public void onChanged(@Nullable Boolean aBoolean) {
if(aBoolean){
Toast.makeText(MainActivity.this, R.string.list_geofavorite_connection_error, Toast.LENGTH_LONG).show();
}
}
});
mMainActivityViewModel.getGeofavorites().observe(this, new Observer<List<Geofavorite>>() {
@Override
public void onChanged(List<Geofavorite> geofavorites) {
geofavoriteAdapter.setGeofavoriteList(geofavorites);
}
});
mMainActivityViewModel.updateGeofavorites();
swipeRefresh = findViewById(R.id.swipe_refresh);
swipeRefresh.setOnRefreshListener(() -> updateGeofavorites());
swipeRefresh.setOnRefreshListener(() ->
mMainActivityViewModel.updateGeofavorites());
fab = findViewById(R.id.add);
fab.setOnClickListener(view -> addGeofavorite());
@@ -188,14 +214,6 @@ public class MainActivity extends AppCompatActivity implements OnSortingOrderLis
updateGridIcon(gridViewEnabled);
}
@Override
protected void onStart() {
super.onStart();
// Update list
mMainActivityViewModel.getGeofavorites().observe(this, this);
}
private void setupNavigationMenu() {
ArrayList<NavigationItem> navItems = new ArrayList<>();
@@ -238,19 +256,10 @@ public class MainActivity extends AppCompatActivity implements OnSortingOrderLis
SortingOrderDialogFragment.newInstance(sortOrder).show(fragmentTransaction, SortingOrderDialogFragment.SORTING_ORDER_FRAGMENT);
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == INTENT_ADD && resultCode == RESULT_OK) {
mMainActivityViewModel.getGeofavorites().observe(this, this);
} else if (requestCode == INTENT_EDIT && resultCode == RESULT_OK) {
mMainActivityViewModel.getGeofavorites().observe(this, this);
}
}
private void addGeofavorite() {
startActivityForResult(
new Intent(this, GeofavoriteDetailActivity.class), INTENT_ADD);
startActivity(
new Intent(this, GeofavoriteDetailActivity.class)
);
}
private void show_about() {
@@ -263,13 +272,6 @@ public class MainActivity extends AppCompatActivity implements OnSortingOrderLis
startActivity(intent);
}
// @Override
// public void onErrorLoading(String message) {
// Toast.makeText(MainActivity.this, R.string.list_geofavorite_connection_error, Toast.LENGTH_LONG).show();
// Log.e(TAG, "Unable to obtain geofavorites list: " + message);
// }
@Override
public void onSortingOrderChosen(int sortSelection) {
geofavoriteAdapter.setSortRule(sortSelection);
@@ -308,9 +310,8 @@ public class MainActivity extends AppCompatActivity implements OnSortingOrderLis
.setTitle(R.string.dialog_delete_title)
.setPositiveButton(R.string.dialog_delete_delete, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// TODO presenter.deleteGeofavorite(item.getId());
mMainActivityViewModel.deleteGeofavorite(item);
dialog.dismiss();
// Callback is onGeofavoriteDeleted
}
})
.setNegativeButton(R.string.dialog_delete_cancel, new DialogInterface.OnClickListener() {
@@ -324,30 +325,8 @@ public class MainActivity extends AppCompatActivity implements OnSortingOrderLis
private void showGeofavoriteDetailActivity(Geofavorite item) {
Intent i = new Intent(this, GeofavoriteDetailActivity.class);
i.putExtra(GeofavoriteDetailActivity.ARG_GEOFAVORITE, item);
i.putExtra(GeofavoriteDetailActivity.ARG_GEOFAVORITE, item.getId());
startActivity(i);
}
private void updateGeofavorites() {
mMainActivityViewModel.getGeofavorites().observe(this, new Observer<List<Geofavorite>>() {
@Override
public void onChanged(List<Geofavorite> geofavorites) {
geofavoriteAdapter.setGeofavoriteList(geofavorites);
}
});
// TODO: è possibile registrare un solo listener?
mMainActivityViewModel.getIsUpdating().observe(this, new Observer<Boolean>() {
@Override
public void onChanged(@Nullable Boolean aBoolean) {
if(aBoolean){
swipeRefresh.setRefreshing(true);
}
else{
swipeRefresh.setRefreshing(false);
}
}
});
}
}
@@ -9,25 +9,50 @@ import java.util.List;
import it.danieleverducci.nextcloudmaps.model.Geofavorite;
import it.danieleverducci.nextcloudmaps.repository.GeofavoriteRepository;
public class MainActivityViewModel extends ViewModel {
private MutableLiveData<List<Geofavorite>> mGeofavorites;
public class MainActivityViewModel extends ViewModel implements GeofavoriteRepository.OnFinished {
private GeofavoriteRepository mRepo;
private MutableLiveData<Boolean> mIsUpdating = new MutableLiveData<>();
private MutableLiveData<Boolean> mIsFailed = new MutableLiveData<>();
public void init() {
if (mGeofavorites != null)
return;
mRepo = GeofavoriteRepository.getInstance();
mGeofavorites = mRepo.getGeofavorites();
mRepo.setOnFinishedListener(this);
}
public LiveData<List<Geofavorite>> getGeofavorites(){
return mGeofavorites;
mRepo.updateGeofavorites();
return mRepo.getGeofavorites();
}
public void updateGeofavorites() {
mRepo.updateGeofavorites();
}
public void deleteGeofavorite(Geofavorite geofav) {
mRepo.deleteGeofavorite(geofav);
}
public LiveData<Boolean> getIsUpdating(){
return mIsUpdating;
}
public LiveData<Boolean> getIsFailed(){
return mIsFailed;
}
@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);
}
}