Separated list logic from application logic, support for multiple list fragments
This commit is contained in:
parent
a1d6f1dabe
commit
fa65c33ec6
@ -3,7 +3,6 @@ package it.danieleverducci.nextcloudmaps.activity.main;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
|
||||||
import androidx.lifecycle.LiveData;
|
import androidx.lifecycle.LiveData;
|
||||||
import androidx.lifecycle.MutableLiveData;
|
|
||||||
import androidx.lifecycle.ViewModel;
|
import androidx.lifecycle.ViewModel;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -11,7 +10,7 @@ import java.util.List;
|
|||||||
import it.danieleverducci.nextcloudmaps.model.Geofavorite;
|
import it.danieleverducci.nextcloudmaps.model.Geofavorite;
|
||||||
import it.danieleverducci.nextcloudmaps.repository.GeofavoriteRepository;
|
import it.danieleverducci.nextcloudmaps.repository.GeofavoriteRepository;
|
||||||
|
|
||||||
public class MainActivityViewModel extends ViewModel {
|
public class GeofavoritesFragmentViewModel extends ViewModel {
|
||||||
private GeofavoriteRepository mRepo;
|
private GeofavoriteRepository mRepo;
|
||||||
|
|
||||||
public void init(Context applicationContext) {
|
public void init(Context applicationContext) {
|
@ -17,7 +17,6 @@
|
|||||||
|
|
||||||
package it.danieleverducci.nextcloudmaps.activity.main;
|
package it.danieleverducci.nextcloudmaps.activity.main;
|
||||||
|
|
||||||
import android.content.DialogInterface;
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
@ -27,20 +26,18 @@ import android.view.View;
|
|||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.appcompat.app.AlertDialog;
|
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
|
||||||
import androidx.appcompat.widget.AppCompatImageButton;
|
import androidx.appcompat.widget.AppCompatImageButton;
|
||||||
import androidx.appcompat.widget.AppCompatImageView;
|
import androidx.appcompat.widget.AppCompatImageView;
|
||||||
import androidx.appcompat.widget.SearchView;
|
import androidx.appcompat.widget.SearchView;
|
||||||
import androidx.appcompat.widget.Toolbar;
|
import androidx.appcompat.widget.Toolbar;
|
||||||
import androidx.core.view.GravityCompat;
|
import androidx.core.view.GravityCompat;
|
||||||
import androidx.drawerlayout.widget.DrawerLayout;
|
import androidx.drawerlayout.widget.DrawerLayout;
|
||||||
|
import androidx.fragment.app.Fragment;
|
||||||
import androidx.fragment.app.FragmentManager;
|
import androidx.fragment.app.FragmentManager;
|
||||||
import androidx.fragment.app.FragmentTransaction;
|
import androidx.fragment.app.FragmentTransaction;
|
||||||
import androidx.lifecycle.ViewModelProvider;
|
import androidx.lifecycle.ViewModelProvider;
|
||||||
import androidx.preference.PreferenceManager;
|
import androidx.preference.PreferenceManager;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
import androidx.recyclerview.widget.StaggeredGridLayoutManager;
|
|
||||||
|
|
||||||
import com.google.android.material.card.MaterialCardView;
|
import com.google.android.material.card.MaterialCardView;
|
||||||
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||||
@ -58,9 +55,9 @@ import it.danieleverducci.nextcloudmaps.activity.main.NavigationAdapter.Navigati
|
|||||||
import it.danieleverducci.nextcloudmaps.activity.main.SortingOrderDialogFragment.OnSortingOrderListener;
|
import it.danieleverducci.nextcloudmaps.activity.main.SortingOrderDialogFragment.OnSortingOrderListener;
|
||||||
import it.danieleverducci.nextcloudmaps.activity.mappicker.MapPickerActivity;
|
import it.danieleverducci.nextcloudmaps.activity.mappicker.MapPickerActivity;
|
||||||
import it.danieleverducci.nextcloudmaps.api.ApiProvider;
|
import it.danieleverducci.nextcloudmaps.api.ApiProvider;
|
||||||
|
import it.danieleverducci.nextcloudmaps.fragments.GeofavoriteListFragment;
|
||||||
|
import it.danieleverducci.nextcloudmaps.fragments.GeofavoritesFragment;
|
||||||
import it.danieleverducci.nextcloudmaps.model.Geofavorite;
|
import it.danieleverducci.nextcloudmaps.model.Geofavorite;
|
||||||
import it.danieleverducci.nextcloudmaps.utils.GeoUriParser;
|
|
||||||
import it.danieleverducci.nextcloudmaps.utils.IntentGenerator;
|
|
||||||
import it.danieleverducci.nextcloudmaps.utils.SettingsManager;
|
import it.danieleverducci.nextcloudmaps.utils.SettingsManager;
|
||||||
|
|
||||||
import static android.view.View.GONE;
|
import static android.view.View.GONE;
|
||||||
@ -71,7 +68,7 @@ import static it.danieleverducci.nextcloudmaps.activity.main.GeofavoriteAdapter.
|
|||||||
import androidx.lifecycle.Observer;
|
import androidx.lifecycle.Observer;
|
||||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
|
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
|
||||||
|
|
||||||
public class MainActivity extends NextcloudMapsStyledActivity implements OnSortingOrderListener {
|
public class MainActivity extends NextcloudMapsStyledActivity {
|
||||||
|
|
||||||
private static final String TAG = "MainActivity";
|
private static final String TAG = "MainActivity";
|
||||||
|
|
||||||
@ -80,21 +77,12 @@ public class MainActivity extends NextcloudMapsStyledActivity implements OnSorti
|
|||||||
private static final String NAVIGATION_KEY_SHOW_ABOUT = "about";
|
private static final String NAVIGATION_KEY_SHOW_ABOUT = "about";
|
||||||
private static final String NAVIGATION_KEY_SWITCH_ACCOUNT = "switch_account";
|
private static final String NAVIGATION_KEY_SWITCH_ACCOUNT = "switch_account";
|
||||||
|
|
||||||
private SharedPreferences preferences;
|
|
||||||
|
|
||||||
private DrawerLayout drawerLayout;
|
private DrawerLayout drawerLayout;
|
||||||
private Toolbar toolbar;
|
private Toolbar toolbar;
|
||||||
private MaterialCardView homeToolbar;
|
private MaterialCardView homeToolbar;
|
||||||
private SearchView searchView;
|
private SearchView searchView;
|
||||||
private SwipeRefreshLayout swipeRefresh;
|
|
||||||
private RecyclerView recyclerView;
|
|
||||||
private StaggeredGridLayoutManager layoutManager;
|
|
||||||
private FloatingActionButton fab;
|
private FloatingActionButton fab;
|
||||||
|
|
||||||
private GeofavoriteAdapter geofavoriteAdapter;
|
|
||||||
private ItemClickListener rvItemClickListener;
|
|
||||||
private MainActivityViewModel mMainActivityViewModel;
|
|
||||||
|
|
||||||
private boolean isFabOpen = false;
|
private boolean isFabOpen = false;
|
||||||
|
|
||||||
NavigationAdapter navigationCommonAdapter;
|
NavigationAdapter navigationCommonAdapter;
|
||||||
@ -105,75 +93,16 @@ public class MainActivity extends NextcloudMapsStyledActivity implements OnSorti
|
|||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
setContentView(R.layout.activity_main);
|
setContentView(R.layout.activity_main);
|
||||||
|
|
||||||
preferences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
|
boolean showMap = SettingsManager.isGeofavoriteListShownAsMap(this);
|
||||||
|
if (showMap) {
|
||||||
|
// TODO: Map fragment
|
||||||
int sortRule = SettingsManager.getGeofavoriteListSortBy(this);
|
} else {
|
||||||
boolean gridViewEnabled = SettingsManager.isGeofavoriteListShownAsGrid(this);
|
Fragment fragment = new GeofavoriteListFragment();
|
||||||
|
FragmentManager manager = getSupportFragmentManager();
|
||||||
recyclerView = findViewById(R.id.recycler_view);
|
FragmentTransaction transaction = manager.beginTransaction();
|
||||||
layoutManager = new StaggeredGridLayoutManager(gridViewEnabled ? 2 : 1, StaggeredGridLayoutManager.VERTICAL);
|
transaction.replace(R.id.fragment_container, fragment);
|
||||||
recyclerView.setLayoutManager(layoutManager);
|
transaction.commit();
|
||||||
|
}
|
||||||
rvItemClickListener = new ItemClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onItemClick(Geofavorite item) {
|
|
||||||
showGeofavoriteDetailActivity(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onItemShareClick(Geofavorite item) {
|
|
||||||
startActivity(Intent.createChooser(IntentGenerator.newShareIntent(MainActivity.this, item), getString(R.string.share_via)));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onItemNavClick(Geofavorite item) {
|
|
||||||
startActivity(IntentGenerator.newGeoUriIntent(MainActivity.this, item));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onItemDeleteClick(Geofavorite item) {
|
|
||||||
showGeofavoriteDeteleDialog(item);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
geofavoriteAdapter = new GeofavoriteAdapter(this, rvItemClickListener);
|
|
||||||
recyclerView.setAdapter(geofavoriteAdapter);
|
|
||||||
geofavoriteAdapter.setSortRule(sortRule);
|
|
||||||
|
|
||||||
|
|
||||||
mMainActivityViewModel = new ViewModelProvider(this).get(MainActivityViewModel.class);
|
|
||||||
mMainActivityViewModel.init(getApplicationContext());
|
|
||||||
mMainActivityViewModel.getIsUpdating().observe(this, new Observer<Boolean>() {
|
|
||||||
@Override
|
|
||||||
public void onChanged(@Nullable Boolean aBoolean) {
|
|
||||||
if(aBoolean){
|
|
||||||
swipeRefresh.setRefreshing(true);
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
swipeRefresh.setRefreshing(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
mMainActivityViewModel.getOnFinished().observe(this, new Observer<Boolean>() {
|
|
||||||
@Override
|
|
||||||
public void onChanged(@Nullable Boolean success) {
|
|
||||||
if(success == null || !success){
|
|
||||||
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(() ->
|
|
||||||
mMainActivityViewModel.updateGeofavorites());
|
|
||||||
|
|
||||||
fab = findViewById(R.id.open_fab);
|
fab = findViewById(R.id.open_fab);
|
||||||
fab.setOnClickListener(view -> openFab(!this.isFabOpen));
|
fab.setOnClickListener(view -> openFab(!this.isFabOpen));
|
||||||
@ -196,7 +125,12 @@ public class MainActivity extends NextcloudMapsStyledActivity implements OnSorti
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onQueryTextChange(String query) {
|
public boolean onQueryTextChange(String query) {
|
||||||
geofavoriteAdapter.getFilter().filter(query);
|
GeofavoritesFragment gff = (GeofavoritesFragment) getSupportFragmentManager().findFragmentById(R.id.fragment_container);
|
||||||
|
if (gff == null) {
|
||||||
|
Log.e(TAG, "onQueryTextChange: No fragment active!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
gff.onSearch(query);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -214,21 +148,9 @@ public class MainActivity extends NextcloudMapsStyledActivity implements OnSorti
|
|||||||
|
|
||||||
homeToolbar.setOnClickListener(view -> updateToolbars(false));
|
homeToolbar.setOnClickListener(view -> updateToolbars(false));
|
||||||
|
|
||||||
AppCompatImageView sortButton = findViewById(R.id.sort_mode);
|
|
||||||
sortButton.setOnClickListener(view -> openSortingOrderDialogFragment(getSupportFragmentManager(), geofavoriteAdapter.getSortRule()));
|
|
||||||
|
|
||||||
drawerLayout = findViewById(R.id.drawerLayout);
|
drawerLayout = findViewById(R.id.drawerLayout);
|
||||||
AppCompatImageButton menuButton = findViewById(R.id.menu_button);
|
AppCompatImageButton menuButton = findViewById(R.id.menu_button);
|
||||||
menuButton.setOnClickListener(view -> drawerLayout.openDrawer(GravityCompat.START));
|
menuButton.setOnClickListener(view -> drawerLayout.openDrawer(GravityCompat.START));
|
||||||
|
|
||||||
AppCompatImageView viewButton = findViewById(R.id.view_mode);
|
|
||||||
viewButton.setOnClickListener(view -> {
|
|
||||||
boolean gridEnabled = layoutManager.getSpanCount() == 1;
|
|
||||||
onGridIconChosen(gridEnabled);
|
|
||||||
});
|
|
||||||
|
|
||||||
updateSortingIcon(sortRule);
|
|
||||||
updateGridIcon(gridViewEnabled);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -276,13 +198,6 @@ public class MainActivity extends NextcloudMapsStyledActivity implements OnSorti
|
|||||||
searchView.setIconified(disableSearch);
|
searchView.setIconified(disableSearch);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void openSortingOrderDialogFragment(FragmentManager supportFragmentManager, int sortOrder) {
|
|
||||||
FragmentTransaction fragmentTransaction = supportFragmentManager.beginTransaction();
|
|
||||||
fragmentTransaction.addToBackStack(null);
|
|
||||||
|
|
||||||
SortingOrderDialogFragment.newInstance(sortOrder).show(fragmentTransaction, SortingOrderDialogFragment.SORTING_ORDER_FRAGMENT);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addGeofavoriteFromGps() {
|
private void addGeofavoriteFromGps() {
|
||||||
startActivity(
|
startActivity(
|
||||||
new Intent(this, GeofavoriteDetailActivity.class)
|
new Intent(this, GeofavoriteDetailActivity.class)
|
||||||
@ -307,69 +222,6 @@ public class MainActivity extends NextcloudMapsStyledActivity implements OnSorti
|
|||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onSortingOrderChosen(int sortSelection) {
|
|
||||||
geofavoriteAdapter.setSortRule(sortSelection);
|
|
||||||
updateSortingIcon(sortSelection);
|
|
||||||
|
|
||||||
preferences.edit().putInt(getString(R.string.setting_sort_by), sortSelection).apply();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void updateSortingIcon(int sortSelection) {
|
|
||||||
AppCompatImageView sortButton = findViewById(R.id.sort_mode);
|
|
||||||
switch (sortSelection) {
|
|
||||||
case SORT_BY_TITLE:
|
|
||||||
sortButton.setImageResource(R.drawable.ic_alphabetical_asc);
|
|
||||||
break;
|
|
||||||
case SORT_BY_CREATED:
|
|
||||||
sortButton.setImageResource(R.drawable.ic_modification_asc);
|
|
||||||
break;
|
|
||||||
case SORT_BY_CATEGORY:
|
|
||||||
sortButton.setImageResource(R.drawable.ic_category_asc);
|
|
||||||
break;
|
|
||||||
case SORT_BY_DISTANCE:
|
|
||||||
sortButton.setImageResource(R.drawable.ic_distance_asc);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onGridIconChosen(boolean gridEnabled) {
|
|
||||||
layoutManager.setSpanCount(gridEnabled ? 2 : 1);
|
|
||||||
updateGridIcon(gridEnabled);
|
|
||||||
|
|
||||||
preferences.edit().putBoolean(getString(R.string.setting_grid_view_enabled), gridEnabled).apply();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void updateGridIcon(boolean gridEnabled) {
|
|
||||||
AppCompatImageView viewButton = findViewById(R.id.view_mode);
|
|
||||||
viewButton.setImageResource(gridEnabled ? R.drawable.ic_view_list : R.drawable.ic_view_module);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void showGeofavoriteDeteleDialog(Geofavorite item) {
|
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
|
|
||||||
builder.setMessage(getString(R.string.dialog_delete_message).replace("{name}", item.getName() != null ? item.getName() : ""))
|
|
||||||
.setTitle(R.string.dialog_delete_title)
|
|
||||||
.setPositiveButton(R.string.dialog_delete_delete, new DialogInterface.OnClickListener() {
|
|
||||||
public void onClick(DialogInterface dialog, int id) {
|
|
||||||
mMainActivityViewModel.deleteGeofavorite(item);
|
|
||||||
dialog.dismiss();
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.setNegativeButton(R.string.dialog_delete_cancel, new DialogInterface.OnClickListener() {
|
|
||||||
public void onClick(DialogInterface dialog, int id) {
|
|
||||||
dialog.dismiss();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
AlertDialog ad = builder.create();
|
|
||||||
ad.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void showGeofavoriteDetailActivity(Geofavorite item) {
|
|
||||||
Intent i = new Intent(this, GeofavoriteDetailActivity.class);
|
|
||||||
i.putExtra(GeofavoriteDetailActivity.ARG_GEOFAVORITE, item.getId());
|
|
||||||
startActivity(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void openFab(boolean open) {
|
private void openFab(boolean open) {
|
||||||
View fab = findViewById(R.id.open_fab);
|
View fab = findViewById(R.id.open_fab);
|
||||||
View addFromGpsFab = findViewById(R.id.add_from_gps);
|
View addFromGpsFab = findViewById(R.id.add_from_gps);
|
||||||
|
@ -48,6 +48,7 @@ public class SortingOrderDialogFragment extends DialogFragment {
|
|||||||
public static final String SORTING_ORDER_FRAGMENT = "SORTING_ORDER_FRAGMENT";
|
public static final String SORTING_ORDER_FRAGMENT = "SORTING_ORDER_FRAGMENT";
|
||||||
private static final String KEY_SORT_ORDER = "SORT_ORDER";
|
private static final String KEY_SORT_ORDER = "SORT_ORDER";
|
||||||
|
|
||||||
|
private OnSortingOrderListener onSortingOrderListener;
|
||||||
private View mView;
|
private View mView;
|
||||||
private View[] mTaggedViews;
|
private View[] mTaggedViews;
|
||||||
private Button mCancel;
|
private Button mCancel;
|
||||||
@ -90,6 +91,10 @@ public class SortingOrderDialogFragment extends DialogFragment {
|
|||||||
return mView;
|
return mView;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setOnSortingOrderListener(OnSortingOrderListener listener) {
|
||||||
|
this.onSortingOrderListener = listener;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* find all relevant UI elements and set their values.
|
* find all relevant UI elements and set their values.
|
||||||
* TODO: this is REALLY ugly.
|
* TODO: this is REALLY ugly.
|
||||||
@ -171,8 +176,8 @@ public class SortingOrderDialogFragment extends DialogFragment {
|
|||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
dismissAllowingStateLoss();
|
dismissAllowingStateLoss();
|
||||||
((SortingOrderDialogFragment.OnSortingOrderListener) getActivity())
|
if (onSortingOrderListener != null)
|
||||||
.onSortingOrderChosen((int) v.getTag());
|
onSortingOrderListener.onSortingOrderChosen((int) v.getTag());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,160 @@
|
|||||||
|
package it.danieleverducci.nextcloudmaps.fragments;
|
||||||
|
|
||||||
|
import static it.danieleverducci.nextcloudmaps.activity.main.GeofavoriteAdapter.SORT_BY_CATEGORY;
|
||||||
|
import static it.danieleverducci.nextcloudmaps.activity.main.GeofavoriteAdapter.SORT_BY_CREATED;
|
||||||
|
import static it.danieleverducci.nextcloudmaps.activity.main.GeofavoriteAdapter.SORT_BY_DISTANCE;
|
||||||
|
import static it.danieleverducci.nextcloudmaps.activity.main.GeofavoriteAdapter.SORT_BY_TITLE;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.appcompat.widget.AppCompatImageView;
|
||||||
|
import androidx.fragment.app.Fragment;
|
||||||
|
import androidx.fragment.app.FragmentManager;
|
||||||
|
import androidx.fragment.app.FragmentTransaction;
|
||||||
|
import androidx.lifecycle.Observer;
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
import androidx.recyclerview.widget.StaggeredGridLayoutManager;
|
||||||
|
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import it.danieleverducci.nextcloudmaps.R;
|
||||||
|
import it.danieleverducci.nextcloudmaps.activity.main.GeofavoriteAdapter;
|
||||||
|
import it.danieleverducci.nextcloudmaps.activity.main.MainActivity;
|
||||||
|
import it.danieleverducci.nextcloudmaps.activity.main.SortingOrderDialogFragment;
|
||||||
|
import it.danieleverducci.nextcloudmaps.model.Geofavorite;
|
||||||
|
import it.danieleverducci.nextcloudmaps.utils.SettingsManager;
|
||||||
|
|
||||||
|
public class GeofavoriteListFragment extends GeofavoritesFragment implements SortingOrderDialogFragment.OnSortingOrderListener {
|
||||||
|
|
||||||
|
private SwipeRefreshLayout swipeRefresh;
|
||||||
|
private RecyclerView recyclerView;
|
||||||
|
private LinearLayoutManager layoutManager;
|
||||||
|
private GeofavoriteAdapter geofavoriteAdapter;
|
||||||
|
private GeofavoriteAdapter.ItemClickListener rvItemClickListener;
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||||
|
View v = inflater.inflate(R.layout.fragment_geofavorite_list, container, false);
|
||||||
|
|
||||||
|
// Setup list
|
||||||
|
int sortRule = SettingsManager.getGeofavoriteListSortBy(requireContext());
|
||||||
|
|
||||||
|
recyclerView = v.findViewById(R.id.recycler_view);
|
||||||
|
layoutManager = new LinearLayoutManager(requireContext());
|
||||||
|
recyclerView.setLayoutManager(layoutManager);
|
||||||
|
|
||||||
|
rvItemClickListener = new GeofavoriteAdapter.ItemClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onItemClick(Geofavorite item) {
|
||||||
|
openGeofavorite(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onItemShareClick(Geofavorite item) {
|
||||||
|
shareGeofavorite(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onItemNavClick(Geofavorite item) {
|
||||||
|
navigateToGeofavorite(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onItemDeleteClick(Geofavorite item) {
|
||||||
|
deleteGeofavorite(item);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
geofavoriteAdapter = new GeofavoriteAdapter(requireContext(), rvItemClickListener);
|
||||||
|
recyclerView.setAdapter(geofavoriteAdapter);
|
||||||
|
geofavoriteAdapter.setSortRule(sortRule);
|
||||||
|
|
||||||
|
// Register for data source events
|
||||||
|
mGeofavoritesFragmentViewModel.getIsUpdating().observe(this, new Observer<Boolean>() {
|
||||||
|
@Override
|
||||||
|
public void onChanged(@Nullable Boolean changed) {
|
||||||
|
if(Boolean.TRUE.equals(changed)){
|
||||||
|
swipeRefresh.setRefreshing(true);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
swipeRefresh.setRefreshing(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
mGeofavoritesFragmentViewModel.getGeofavorites().observe(this, new Observer<List<Geofavorite>>() {
|
||||||
|
@Override
|
||||||
|
public void onChanged(List<Geofavorite> geofavorites) {
|
||||||
|
geofavoriteAdapter.setGeofavoriteList(geofavorites);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Setup view listeners
|
||||||
|
swipeRefresh = v.findViewById(R.id.swipe_refresh);
|
||||||
|
swipeRefresh.setOnRefreshListener(() ->
|
||||||
|
mGeofavoritesFragmentViewModel.updateGeofavorites());
|
||||||
|
|
||||||
|
AppCompatImageView sortButton = v.findViewById(R.id.sort_mode);
|
||||||
|
sortButton.setOnClickListener(view -> openSortingOrderDialogFragment(geofavoriteAdapter.getSortRule()));
|
||||||
|
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||||
|
super.onViewCreated(view, savedInstanceState);
|
||||||
|
|
||||||
|
// Set icons
|
||||||
|
// Setup list
|
||||||
|
int sortRule = SettingsManager.getGeofavoriteListSortBy(requireContext());
|
||||||
|
updateSortingIcon(sortRule);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onSearch(String query) {
|
||||||
|
geofavoriteAdapter.getFilter().filter(query);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSortingOrderChosen(int sortSelection) {
|
||||||
|
geofavoriteAdapter.setSortRule(sortSelection);
|
||||||
|
updateSortingIcon(sortSelection);
|
||||||
|
|
||||||
|
SettingsManager.setGeofavoriteListSortBy(requireContext(), sortSelection);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void openSortingOrderDialogFragment(int sortOrder) {
|
||||||
|
FragmentTransaction fragmentTransaction = requireActivity().getSupportFragmentManager().beginTransaction();
|
||||||
|
fragmentTransaction.addToBackStack(null);
|
||||||
|
|
||||||
|
SortingOrderDialogFragment sodf = SortingOrderDialogFragment.newInstance(sortOrder);
|
||||||
|
sodf.setOnSortingOrderListener(this);
|
||||||
|
sodf.show(fragmentTransaction, SortingOrderDialogFragment.SORTING_ORDER_FRAGMENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateSortingIcon(int sortSelection) {
|
||||||
|
AppCompatImageView sortButton = requireView().findViewById(R.id.sort_mode);
|
||||||
|
switch (sortSelection) {
|
||||||
|
case SORT_BY_TITLE:
|
||||||
|
sortButton.setImageResource(R.drawable.ic_alphabetical_asc);
|
||||||
|
break;
|
||||||
|
case SORT_BY_CREATED:
|
||||||
|
sortButton.setImageResource(R.drawable.ic_modification_asc);
|
||||||
|
break;
|
||||||
|
case SORT_BY_CATEGORY:
|
||||||
|
sortButton.setImageResource(R.drawable.ic_category_asc);
|
||||||
|
break;
|
||||||
|
case SORT_BY_DISTANCE:
|
||||||
|
sortButton.setImageResource(R.drawable.ic_distance_asc);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,99 @@
|
|||||||
|
package it.danieleverducci.nextcloudmaps.fragments;
|
||||||
|
|
||||||
|
import android.content.DialogInterface;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.appcompat.app.AlertDialog;
|
||||||
|
import androidx.fragment.app.Fragment;
|
||||||
|
import androidx.lifecycle.Observer;
|
||||||
|
import androidx.lifecycle.ViewModelProvider;
|
||||||
|
|
||||||
|
import it.danieleverducci.nextcloudmaps.R;
|
||||||
|
import it.danieleverducci.nextcloudmaps.activity.detail.GeofavoriteDetailActivity;
|
||||||
|
import it.danieleverducci.nextcloudmaps.activity.main.GeofavoritesFragmentViewModel;
|
||||||
|
import it.danieleverducci.nextcloudmaps.model.Geofavorite;
|
||||||
|
import it.danieleverducci.nextcloudmaps.utils.IntentGenerator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Separates the specific list/map implementation details providing a standard interface
|
||||||
|
* to communicate with the activity
|
||||||
|
*/
|
||||||
|
public abstract class GeofavoritesFragment extends Fragment {
|
||||||
|
|
||||||
|
protected GeofavoritesFragmentViewModel mGeofavoritesFragmentViewModel;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
mGeofavoritesFragmentViewModel = new ViewModelProvider(this).get(GeofavoritesFragmentViewModel.class);
|
||||||
|
mGeofavoritesFragmentViewModel.init(requireContext());
|
||||||
|
|
||||||
|
mGeofavoritesFragmentViewModel.getOnFinished().observe(this, new Observer<Boolean>() {
|
||||||
|
@Override
|
||||||
|
public void onChanged(@Nullable Boolean success) {
|
||||||
|
if(success == null || !success){
|
||||||
|
Toast.makeText(requireContext(), R.string.list_geofavorite_connection_error, Toast.LENGTH_LONG).show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStart() {
|
||||||
|
super.onStart();
|
||||||
|
|
||||||
|
mGeofavoritesFragmentViewModel.updateGeofavorites();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
abstract public void onSearch(String query);
|
||||||
|
|
||||||
|
|
||||||
|
protected void openGeofavorite(Geofavorite item) {
|
||||||
|
showGeofavoriteDetailActivity(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void shareGeofavorite(Geofavorite item) {
|
||||||
|
startActivity(Intent.createChooser(IntentGenerator.newShareIntent(requireActivity(), item), getString(R.string.share_via)));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void navigateToGeofavorite(Geofavorite item) {
|
||||||
|
startActivity(IntentGenerator.newGeoUriIntent(requireActivity(), item));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void deleteGeofavorite(Geofavorite item) {
|
||||||
|
showGeofavoriteDeteleDialog(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void showGeofavoriteDetailActivity(Geofavorite item) {
|
||||||
|
Intent i = new Intent(requireContext(), GeofavoriteDetailActivity.class);
|
||||||
|
i.putExtra(GeofavoriteDetailActivity.ARG_GEOFAVORITE, item.getId());
|
||||||
|
startActivity(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showGeofavoriteDeteleDialog(Geofavorite item) {
|
||||||
|
AlertDialog.Builder builder = new AlertDialog.Builder(requireContext());
|
||||||
|
builder.setMessage(getString(R.string.dialog_delete_message).replace("{name}", item.getName() != null ? item.getName() : ""))
|
||||||
|
.setTitle(R.string.dialog_delete_title)
|
||||||
|
.setPositiveButton(R.string.dialog_delete_delete, new DialogInterface.OnClickListener() {
|
||||||
|
public void onClick(DialogInterface dialog, int id) {
|
||||||
|
mGeofavoritesFragmentViewModel.deleteGeofavorite(item);
|
||||||
|
dialog.dismiss();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.setNegativeButton(R.string.dialog_delete_cancel, new DialogInterface.OnClickListener() {
|
||||||
|
public void onClick(DialogInterface dialog, int id) {
|
||||||
|
dialog.dismiss();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
AlertDialog ad = builder.create();
|
||||||
|
ad.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,15 +1,11 @@
|
|||||||
package it.danieleverducci.nextcloudmaps.utils;
|
package it.danieleverducci.nextcloudmaps.utils;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
|
||||||
import androidx.preference.PreferenceManager;
|
import androidx.preference.PreferenceManager;
|
||||||
|
|
||||||
import it.danieleverducci.nextcloudmaps.R;
|
|
||||||
import it.danieleverducci.nextcloudmaps.activity.main.GeofavoriteAdapter;
|
import it.danieleverducci.nextcloudmaps.activity.main.GeofavoriteAdapter;
|
||||||
|
|
||||||
public class SettingsManager {
|
public class SettingsManager {
|
||||||
static private final String SETTING_SORT_BY = "SETTING_SORT_BY";
|
static private final String SETTING_SORT_BY = "SETTING_SORT_BY";
|
||||||
static private final String SETTING_GRID_VIEW_ENABLED = "SETTING_GRID_VIEW_ENABLED";
|
|
||||||
static private final String SETTING_LAST_SELECTED_LIST_VIEW = "SETTING_LAST_SELECTED_LIST_VIEW";
|
static private final String SETTING_LAST_SELECTED_LIST_VIEW = "SETTING_LAST_SELECTED_LIST_VIEW";
|
||||||
|
|
||||||
public static int getGeofavoriteListSortBy(Context context) {
|
public static int getGeofavoriteListSortBy(Context context) {
|
||||||
@ -22,16 +18,6 @@ public class SettingsManager {
|
|||||||
.edit().putInt(SETTING_SORT_BY, value).apply();
|
.edit().putInt(SETTING_SORT_BY, value).apply();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isGeofavoriteListShownAsGrid(Context context) {
|
|
||||||
return PreferenceManager.getDefaultSharedPreferences(context)
|
|
||||||
.getBoolean(SETTING_GRID_VIEW_ENABLED, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void setGeofavoriteListShownAsGrid(Context context, boolean value) {
|
|
||||||
PreferenceManager.getDefaultSharedPreferences(context)
|
|
||||||
.edit().putBoolean(SETTING_GRID_VIEW_ENABLED, value).apply();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isGeofavoriteListShownAsMap(Context context) {
|
public static boolean isGeofavoriteListShownAsMap(Context context) {
|
||||||
return PreferenceManager.getDefaultSharedPreferences(context)
|
return PreferenceManager.getDefaultSharedPreferences(context)
|
||||||
.getBoolean(SETTING_LAST_SELECTED_LIST_VIEW, false);
|
.getBoolean(SETTING_LAST_SELECTED_LIST_VIEW, false);
|
||||||
|
@ -98,35 +98,6 @@
|
|||||||
android:lines="1"
|
android:lines="1"
|
||||||
android:textSize="16sp"
|
android:textSize="16sp"
|
||||||
android:text="@string/search_in_all"/>
|
android:text="@string/search_in_all"/>
|
||||||
<androidx.appcompat.widget.AppCompatImageView
|
|
||||||
android:id="@+id/sort_mode"
|
|
||||||
android:layout_width="?attr/actionBarSize"
|
|
||||||
android:layout_height="?attr/actionBarSize"
|
|
||||||
android:layout_marginRight="@dimen/spacer_1x"
|
|
||||||
android:layout_gravity="center_vertical|end"
|
|
||||||
android:background="?attr/selectableItemBackgroundBorderless"
|
|
||||||
android:contentDescription="@string/list_mode"
|
|
||||||
android:paddingStart="@dimen/spacer_1x"
|
|
||||||
android:paddingTop="@dimen/spacer_2x"
|
|
||||||
android:paddingEnd="@dimen/spacer_1x"
|
|
||||||
android:paddingBottom="@dimen/spacer_2x"
|
|
||||||
android:tint="@color/text_color"
|
|
||||||
android:translationX="@dimen/spacer_1x"
|
|
||||||
android:src="@drawable/ic_alphabetical_asc" />
|
|
||||||
<androidx.appcompat.widget.AppCompatImageView
|
|
||||||
android:id="@+id/view_mode"
|
|
||||||
android:layout_width="?attr/actionBarSize"
|
|
||||||
android:layout_height="?attr/actionBarSize"
|
|
||||||
android:layout_gravity="center_vertical|end"
|
|
||||||
android:background="?attr/selectableItemBackgroundBorderless"
|
|
||||||
android:contentDescription="@string/list_mode"
|
|
||||||
android:paddingStart="@dimen/spacer_1x"
|
|
||||||
android:paddingTop="@dimen/spacer_2x"
|
|
||||||
android:paddingEnd="@dimen/spacer_1x"
|
|
||||||
android:paddingBottom="@dimen/spacer_2x" android:tint="@color/text_color"
|
|
||||||
android:translationX="@dimen/spacer_1x"
|
|
||||||
android:src="@drawable/ic_view_module"
|
|
||||||
android:visibility="gone"/> <!-- TODO: Replace with Map View icon -->
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
</com.google.android.material.card.MaterialCardView>
|
</com.google.android.material.card.MaterialCardView>
|
||||||
@ -135,30 +106,12 @@
|
|||||||
|
|
||||||
</com.google.android.material.appbar.AppBarLayout>
|
</com.google.android.material.appbar.AppBarLayout>
|
||||||
|
|
||||||
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
<androidx.fragment.app.FragmentContainerView
|
||||||
android:id="@+id/swipe_refresh"
|
android:id="@+id/fragment_container"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_margin="@dimen/spacer_1hx"
|
android:name="it.danieleverducci.nextcloudmaps.fragments.GeofavoriteListFragment" />
|
||||||
app:layout_behavior="@string/appbar_scrolling_view_behavior">
|
|
||||||
|
|
||||||
<androidx.core.widget.NestedScrollView
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent">
|
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
|
||||||
android:id="@+id/recycler_view"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
app:layoutManager="androidx.recyclerview.widget.StaggeredGridLayoutManager"
|
|
||||||
app:spanCount="1"
|
|
||||||
tools:itemCount="3"
|
|
||||||
tools:listitem="@layout/item_geofav">
|
|
||||||
</androidx.recyclerview.widget.RecyclerView>
|
|
||||||
|
|
||||||
</androidx.core.widget.NestedScrollView>
|
|
||||||
|
|
||||||
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
|
||||||
|
|
||||||
<!-- Add from map FAB -->
|
<!-- Add from map FAB -->
|
||||||
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||||
|
40
app/src/main/res/layout/fragment_geofavorite_list.xml
Normal file
40
app/src/main/res/layout/fragment_geofavorite_list.xml
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:id="@+id/swipe_refresh"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_margin="@dimen/spacer_1hx"
|
||||||
|
app:layout_behavior="@string/appbar_scrolling_view_behavior">
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.LinearLayoutCompat
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatImageView
|
||||||
|
android:id="@+id/sort_mode"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="@dimen/floating_bar_height"
|
||||||
|
android:background="?attr/selectableItemBackgroundBorderless"
|
||||||
|
android:contentDescription="@string/list_mode"
|
||||||
|
android:paddingStart="@dimen/spacer_2x"
|
||||||
|
android:paddingEnd="@dimen/spacer_2x"
|
||||||
|
android:tint="@color/text_color"
|
||||||
|
android:src="@drawable/ic_alphabetical_asc" />
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/recycler_view"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
app:layoutManager="androidx.recyclerview.widget.StaggeredGridLayoutManager"
|
||||||
|
app:spanCount="1"
|
||||||
|
tools:itemCount="3"
|
||||||
|
tools:listitem="@layout/item_geofav">
|
||||||
|
</androidx.recyclerview.widget.RecyclerView>
|
||||||
|
|
||||||
|
</androidx.appcompat.widget.LinearLayoutCompat>
|
||||||
|
|
||||||
|
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
@ -39,4 +39,7 @@
|
|||||||
<!-- FAB dimensions -->
|
<!-- FAB dimensions -->
|
||||||
<dimen name="fab_vertical_offset">75dp</dimen>
|
<dimen name="fab_vertical_offset">75dp</dimen>
|
||||||
|
|
||||||
|
<!-- Floating bar below search bar -->
|
||||||
|
<dimen name="floating_bar_height">36dp</dimen>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
Loading…
Reference in New Issue
Block a user