Trying basic MVVM implementation based on https://github.com/mitchtabian/MVVMExample1
This commit is contained in:
parent
b9dbde7f7c
commit
cf7f96efad
@ -82,17 +82,6 @@ public class GeofavoriteAdapter extends RecyclerView.Adapter<GeofavoriteAdapter.
|
||||
return geofavoriteListFiltered.get(position);
|
||||
}
|
||||
|
||||
public void removeById(int id) {
|
||||
for (Geofavorite g : geofavoriteList) {
|
||||
if (g.getId() == id) {
|
||||
geofavoriteList.remove(g);
|
||||
geofavoriteListFiltered.remove(g);
|
||||
break;
|
||||
}
|
||||
}
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public int getSortRule() {
|
||||
return sortRule;
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.appcompat.widget.AppCompatImageButton;
|
||||
@ -35,6 +36,7 @@ import androidx.core.view.GravityCompat;
|
||||
import androidx.drawerlayout.widget.DrawerLayout;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
import androidx.fragment.app.FragmentTransaction;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
import androidx.preference.PreferenceManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import androidx.recyclerview.widget.StaggeredGridLayoutManager;
|
||||
@ -61,8 +63,9 @@ import static android.view.View.VISIBLE;
|
||||
import static it.danieleverducci.nextcloudmaps.activity.main.GeofavoriteAdapter.*;
|
||||
import static it.danieleverducci.nextcloudmaps.activity.main.GeofavoriteAdapter.SORT_BY_CREATED;
|
||||
import static it.danieleverducci.nextcloudmaps.activity.main.GeofavoriteAdapter.SORT_BY_TITLE;
|
||||
import androidx.lifecycle.Observer;
|
||||
|
||||
public class MainActivity extends AppCompatActivity implements MainView, OnSortingOrderListener {
|
||||
public class MainActivity extends AppCompatActivity implements OnSortingOrderListener {
|
||||
|
||||
private static final int INTENT_ADD = 100;
|
||||
private static final int INTENT_EDIT = 200;
|
||||
@ -84,9 +87,9 @@ public class MainActivity extends AppCompatActivity implements MainView, OnSorti
|
||||
private StaggeredGridLayoutManager layoutManager;
|
||||
private FloatingActionButton fab;
|
||||
|
||||
private MainPresenter presenter;
|
||||
private GeofavoriteAdapter geofavoriteAdapter;
|
||||
private ItemClickListener rvItemClickListener;
|
||||
private MainActivityViewModel mMainActivityViewModel;
|
||||
|
||||
NavigationAdapter navigationCommonAdapter;
|
||||
|
||||
@ -95,6 +98,8 @@ public class MainActivity extends AppCompatActivity implements MainView, OnSorti
|
||||
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);
|
||||
@ -104,8 +109,6 @@ public class MainActivity extends AppCompatActivity implements MainView, OnSorti
|
||||
layoutManager = new StaggeredGridLayoutManager(gridViewEnabled ? 2 : 1, StaggeredGridLayoutManager.VERTICAL);
|
||||
recyclerView.setLayoutManager(layoutManager);
|
||||
|
||||
presenter = new MainPresenter(this);
|
||||
|
||||
rvItemClickListener = new ItemClickListener() {
|
||||
@Override
|
||||
public void onItemClick(Geofavorite item) {
|
||||
@ -133,7 +136,7 @@ public class MainActivity extends AppCompatActivity implements MainView, OnSorti
|
||||
geofavoriteAdapter.setSortRule(sortRule);
|
||||
|
||||
swipeRefresh = findViewById(R.id.swipe_refresh);
|
||||
swipeRefresh.setOnRefreshListener(() -> presenter.getGeofavorites());
|
||||
swipeRefresh.setOnRefreshListener(() -> updateGeofavorites());
|
||||
|
||||
fab = findViewById(R.id.add);
|
||||
fab.setOnClickListener(view -> addGeofavorite());
|
||||
@ -190,7 +193,7 @@ public class MainActivity extends AppCompatActivity implements MainView, OnSorti
|
||||
super.onStart();
|
||||
|
||||
// Update list
|
||||
presenter.getGeofavorites();
|
||||
mMainActivityViewModel.getGeofavorites().observe(this, this);
|
||||
}
|
||||
|
||||
private void setupNavigationMenu() {
|
||||
@ -239,9 +242,9 @@ public class MainActivity extends AppCompatActivity implements MainView, OnSorti
|
||||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
if (requestCode == INTENT_ADD && resultCode == RESULT_OK) {
|
||||
presenter.getGeofavorites();
|
||||
mMainActivityViewModel.getGeofavorites().observe(this, this);
|
||||
} else if (requestCode == INTENT_EDIT && resultCode == RESULT_OK) {
|
||||
presenter.getGeofavorites();
|
||||
mMainActivityViewModel.getGeofavorites().observe(this, this);
|
||||
}
|
||||
}
|
||||
|
||||
@ -260,35 +263,12 @@ public class MainActivity extends AppCompatActivity implements MainView, OnSorti
|
||||
startActivity(intent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showLoading() {
|
||||
swipeRefresh.setRefreshing(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hideLoading() {
|
||||
swipeRefresh.setRefreshing(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGetResult(List<Geofavorite> geofavorite_list) {
|
||||
geofavoriteAdapter.setGeofavoriteList(geofavorite_list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGeofavoriteDeleted(int id) {
|
||||
// Update list
|
||||
runOnUiThread(() -> {
|
||||
geofavoriteAdapter.removeById(id);
|
||||
Toast.makeText(MainActivity.this, R.string.list_geofavorite_deleted, Toast.LENGTH_LONG).show();
|
||||
});
|
||||
}
|
||||
|
||||
@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 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) {
|
||||
@ -328,7 +308,7 @@ public class MainActivity extends AppCompatActivity implements MainView, OnSorti
|
||||
.setTitle(R.string.dialog_delete_title)
|
||||
.setPositiveButton(R.string.dialog_delete_delete, new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int id) {
|
||||
presenter.deleteGeofavorite(item.getId());
|
||||
// TODO presenter.deleteGeofavorite(item.getId());
|
||||
dialog.dismiss();
|
||||
// Callback is onGeofavoriteDeleted
|
||||
}
|
||||
@ -348,4 +328,26 @@ public class MainActivity extends AppCompatActivity implements MainView, OnSorti
|
||||
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);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
package it.danieleverducci.nextcloudmaps.activity.main;
|
||||
|
||||
import androidx.lifecycle.LiveData;
|
||||
import androidx.lifecycle.MutableLiveData;
|
||||
import androidx.lifecycle.ViewModel;
|
||||
|
||||
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;
|
||||
private GeofavoriteRepository mRepo;
|
||||
private MutableLiveData<Boolean> mIsUpdating = new MutableLiveData<>();
|
||||
|
||||
public void init() {
|
||||
if (mGeofavorites != null)
|
||||
return;
|
||||
|
||||
mRepo = GeofavoriteRepository.getInstance();
|
||||
mGeofavorites = mRepo.getGeofavorites();
|
||||
}
|
||||
|
||||
public LiveData<List<Geofavorite>> getGeofavorites(){
|
||||
return mGeofavorites;
|
||||
}
|
||||
|
||||
public LiveData<Boolean> getIsUpdating(){
|
||||
return mIsUpdating;
|
||||
}
|
||||
}
|
@ -1,89 +0,0 @@
|
||||
/*
|
||||
* Nextcloud Maps Geofavorites for Android
|
||||
*
|
||||
* @copyright Copyright (c) 2020 John Doe <john@doe.com>
|
||||
* @author John Doe <john@doe.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package it.danieleverducci.nextcloudmaps.activity.main;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import it.danieleverducci.nextcloudmaps.api.ApiProvider;
|
||||
import it.danieleverducci.nextcloudmaps.model.Geofavorite;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
import retrofit2.Response;
|
||||
|
||||
public class MainPresenter {
|
||||
private MainView view;
|
||||
|
||||
public MainPresenter(MainView view) {
|
||||
this.view = view;
|
||||
}
|
||||
|
||||
public void getGeofavorites() {
|
||||
view.showLoading();
|
||||
Call<List<Geofavorite>> call = ApiProvider.getAPI().getGeofavorites();
|
||||
call.enqueue(new Callback<List<Geofavorite>>() {
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<List<Geofavorite>> call, @NonNull Response<List<Geofavorite>> response) {
|
||||
((AppCompatActivity) view).runOnUiThread(() -> {
|
||||
view.hideLoading();
|
||||
if (response.isSuccessful() && response.body() != null) {
|
||||
view.onGetResult(response.body());
|
||||
} else {
|
||||
((AppCompatActivity) view).runOnUiThread(() -> {
|
||||
view.hideLoading();
|
||||
view.onErrorLoading(response.raw().message());
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<List<Geofavorite>> call, @NonNull Throwable t) {
|
||||
((AppCompatActivity) view).runOnUiThread(() -> {
|
||||
view.hideLoading();
|
||||
view.onErrorLoading(t.getLocalizedMessage());
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void deleteGeofavorite(int id) {
|
||||
view.showLoading();
|
||||
Call<Geofavorite> call = ApiProvider.getAPI().deleteGeofavorite(id);
|
||||
call.enqueue(new Callback<Geofavorite>() {
|
||||
@Override
|
||||
public void onResponse(Call<Geofavorite> call, Response<Geofavorite> response) {
|
||||
view.hideLoading();
|
||||
view.onGeofavoriteDeleted(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Call<Geofavorite> call, Throwable t) {
|
||||
view.hideLoading();
|
||||
view.onErrorLoading(t.getLocalizedMessage());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
/*
|
||||
* Nextcloud Maps Geofavorites for Android
|
||||
*
|
||||
* @copyright Copyright (c) 2020 John Doe <john@doe.com>
|
||||
* @author John Doe <john@doe.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package it.danieleverducci.nextcloudmaps.activity.main;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import it.danieleverducci.nextcloudmaps.model.Geofavorite;
|
||||
|
||||
public interface MainView {
|
||||
void showLoading();
|
||||
void hideLoading();
|
||||
void onGetResult(List<Geofavorite> geofavorites);
|
||||
void onGeofavoriteDeleted(int id);
|
||||
void onErrorLoading(String message);
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
package it.danieleverducci.nextcloudmaps.repository;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.lifecycle.MutableLiveData;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import it.danieleverducci.nextcloudmaps.api.ApiProvider;
|
||||
import it.danieleverducci.nextcloudmaps.model.Geofavorite;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
import retrofit2.Response;
|
||||
|
||||
/**
|
||||
* Singleton pattern
|
||||
*/
|
||||
public class GeofavoriteRepository {
|
||||
|
||||
private static GeofavoriteRepository instance;
|
||||
private ArrayList<Geofavorite> dataSet = new ArrayList<>();
|
||||
|
||||
public static GeofavoriteRepository getInstance() {
|
||||
if(instance == null){
|
||||
instance = new GeofavoriteRepository();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
public MutableLiveData<List<Geofavorite>> getGeofavorites(){
|
||||
// Obtain geofavorites
|
||||
Call<List<Geofavorite>> call = ApiProvider.getAPI().getGeofavorites();
|
||||
call.enqueue(new Callback<List<Geofavorite>>() {
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<List<Geofavorite>> call, @NonNull Response<List<Geofavorite>> response) {
|
||||
if (response.isSuccessful() && response.body() != null) {
|
||||
dataSet.addAll(response.body());
|
||||
} else {
|
||||
onFailure(call, new Throwable("Dataset is empty"));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<List<Geofavorite>> call, @NonNull Throwable t) {
|
||||
// TODO
|
||||
}
|
||||
});
|
||||
|
||||
MutableLiveData<List<Geofavorite>> data = new MutableLiveData<>();
|
||||
data.setValue(dataSet);
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user