Implemented filter by category
This commit is contained in:
parent
25f7b05fd0
commit
c5e05e4b8a
@ -0,0 +1,47 @@
|
||||
package it.danieleverducci.nextcloudmaps.activity.detail;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.graphics.drawable.DrawableCompat;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
|
||||
import it.danieleverducci.nextcloudmaps.R;
|
||||
import it.danieleverducci.nextcloudmaps.model.Geofavorite;
|
||||
|
||||
public class CategoriesAdapter extends ArrayAdapter<String> {
|
||||
|
||||
public CategoriesAdapter(@NonNull Context context) {
|
||||
super(context, R.layout.category_listitem, R.id.category_name, new ArrayList<>());
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
|
||||
View v = super.getView(position, convertView, parent);
|
||||
TextView categoryName = v.findViewById(R.id.category_name);
|
||||
Drawable backgroundDrawable = categoryName.getBackground();
|
||||
DrawableCompat.setTint(
|
||||
backgroundDrawable,
|
||||
Geofavorite.categoryColorFromName(categoryName.getText().toString()) == 0
|
||||
? v.getContext().getColor(R.color.defaultBrand)
|
||||
: Geofavorite.categoryColorFromName(categoryName.getText().toString())
|
||||
);
|
||||
return v;
|
||||
}
|
||||
|
||||
public void setCategoriesList(HashSet<String> categories) {
|
||||
clear();
|
||||
addAll(categories);
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
package it.danieleverducci.nextcloudmaps.activity.detail;
|
||||
|
||||
import android.content.Context;
|
||||
import android.widget.ArrayAdapter;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import java.util.HashSet;
|
||||
|
||||
public class CategoriesSpinnerAdapter extends ArrayAdapter<String> {
|
||||
|
||||
public CategoriesSpinnerAdapter(@NonNull Context context) {
|
||||
super(context, android.R.layout.simple_dropdown_item_1line);
|
||||
}
|
||||
|
||||
// TODO: implement colors
|
||||
|
||||
public void setCategoriesList(HashSet<String> categories) {
|
||||
clear();
|
||||
addAll(categories);
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
}
|
@ -21,11 +21,9 @@ import android.Manifest;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.Color;
|
||||
import android.location.Location;
|
||||
import android.location.LocationListener;
|
||||
import android.location.LocationManager;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
@ -34,7 +32,6 @@ import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.appcompat.content.res.AppCompatResources;
|
||||
import androidx.core.app.ActivityCompat;
|
||||
import androidx.lifecycle.Observer;
|
||||
@ -43,7 +40,6 @@ import androidx.preference.PreferenceManager;
|
||||
|
||||
import org.osmdroid.api.IMapController;
|
||||
import org.osmdroid.config.Configuration;
|
||||
import org.osmdroid.config.IConfigurationProvider;
|
||||
import org.osmdroid.util.GeoPoint;
|
||||
import org.osmdroid.views.CustomZoomButtonsController;
|
||||
import org.osmdroid.views.overlay.Marker;
|
||||
@ -52,10 +48,8 @@ import org.threeten.bp.format.FormatStyle;
|
||||
|
||||
import java.util.HashSet;
|
||||
|
||||
import it.danieleverducci.nextcloudmaps.BuildConfig;
|
||||
import it.danieleverducci.nextcloudmaps.R;
|
||||
import it.danieleverducci.nextcloudmaps.activity.NextcloudMapsStyledActivity;
|
||||
import it.danieleverducci.nextcloudmaps.activity.mappicker.MapPickerActivity;
|
||||
import it.danieleverducci.nextcloudmaps.databinding.ActivityGeofavoriteDetailBinding;
|
||||
import it.danieleverducci.nextcloudmaps.model.Geofavorite;
|
||||
import it.danieleverducci.nextcloudmaps.utils.GeoUriParser;
|
||||
@ -313,7 +307,7 @@ public class GeofavoriteDetailActivity extends NextcloudMapsStyledActivity imple
|
||||
this.binding.actionIconNav.setOnClickListener(this);
|
||||
|
||||
// Set categories adapter
|
||||
CategoriesSpinnerAdapter categoriesAdapter = new CategoriesSpinnerAdapter(binding.root.getContext());
|
||||
CategoriesAdapter categoriesAdapter = new CategoriesAdapter(binding.root.getContext());
|
||||
this.binding.categoryAt.setAdapter(categoriesAdapter);
|
||||
this.binding.categoryAt.setText(Geofavorite.DEFAULT_CATEGORY);
|
||||
|
||||
@ -378,7 +372,7 @@ public class GeofavoriteDetailActivity extends NextcloudMapsStyledActivity imple
|
||||
}
|
||||
|
||||
public void setCategories(HashSet<String> categories) {
|
||||
((CategoriesSpinnerAdapter)binding.categoryAt.getAdapter()).setCategoriesList(categories);
|
||||
((CategoriesAdapter)binding.categoryAt.getAdapter()).setCategoriesList(categories);
|
||||
}
|
||||
|
||||
public void hideAccuracy() {
|
||||
|
@ -5,6 +5,7 @@ import static android.view.View.VISIBLE;
|
||||
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.text.TextUtils;
|
||||
@ -19,25 +20,20 @@ import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.appcompat.widget.AppCompatImageButton;
|
||||
import androidx.appcompat.widget.AppCompatImageView;
|
||||
import androidx.appcompat.widget.SearchView;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.core.graphics.drawable.DrawableCompat;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.lifecycle.Observer;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
|
||||
import com.google.android.material.card.MaterialCardView;
|
||||
import com.nextcloud.android.sso.exceptions.NextcloudFilesAppAccountNotFoundException;
|
||||
import com.nextcloud.android.sso.exceptions.NoCurrentAccountSelectedException;
|
||||
import com.nextcloud.android.sso.helper.SingleAccountHelper;
|
||||
import com.nextcloud.android.sso.model.SingleSignOnAccount;
|
||||
import com.squareup.picasso.Picasso;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import it.danieleverducci.nextcloudmaps.R;
|
||||
import it.danieleverducci.nextcloudmaps.activity.detail.CategoriesAdapter;
|
||||
import it.danieleverducci.nextcloudmaps.activity.detail.GeofavoriteDetailActivity;
|
||||
import it.danieleverducci.nextcloudmaps.activity.main.GeofavoritesFragmentViewModel;
|
||||
import it.danieleverducci.nextcloudmaps.activity.main.MainActivity;
|
||||
@ -154,6 +150,8 @@ public abstract class GeofavoritesFragment extends Fragment {
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
|
||||
// Reset filter and update data
|
||||
filterButton.setImageResource(R.drawable.ic_filter_off);
|
||||
mGeofavoritesFragmentViewModel.updateGeofavorites();
|
||||
}
|
||||
|
||||
@ -226,14 +224,30 @@ public abstract class GeofavoritesFragment extends Fragment {
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(requireContext());
|
||||
builder.setTitle(R.string.filtering_dialog_title);
|
||||
String[] categoryNames = categories.toArray(new String[categories.size()]);
|
||||
builder.setItems(categoryNames, new DialogInterface.OnClickListener() {
|
||||
CategoriesAdapter ca = new CategoriesAdapter(requireContext());
|
||||
ca.setCategoriesList(categories);
|
||||
builder.setAdapter(ca, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
String category = categoryNames[which];
|
||||
Log.d(TAG, "Selected category " + category);
|
||||
// Set filter button enabled icon and color
|
||||
String categoryName = ca.getItem(which);
|
||||
filterButton.setImageResource(R.drawable.ic_filter);
|
||||
Drawable d = filterButton.getDrawable();
|
||||
DrawableCompat.setTint(
|
||||
d,
|
||||
Geofavorite.categoryColorFromName(categoryName) == 0
|
||||
? requireContext().getColor(R.color.defaultBrand)
|
||||
: Geofavorite.categoryColorFromName(categoryName)
|
||||
);
|
||||
filterByCategory(categoryName);
|
||||
}
|
||||
});
|
||||
|
||||
builder.setPositiveButton(R.string.filtering_dialog_cancel, (dialog, id) -> {
|
||||
dialog.dismiss();
|
||||
filterButton.setImageResource(R.drawable.ic_filter_off);
|
||||
filterByCategory(null);
|
||||
});
|
||||
AlertDialog dialog = builder.create();
|
||||
dialog.show();
|
||||
}
|
||||
@ -247,4 +261,10 @@ public abstract class GeofavoritesFragment extends Fragment {
|
||||
searchView.setIconified(disableSearch);
|
||||
}
|
||||
|
||||
private void filterByCategory(String category) {
|
||||
onDatasetChange(
|
||||
(new GeofavoritesFilter(geofavorites)).byCategory(category)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -204,17 +204,7 @@ public class Geofavorite implements Serializable {
|
||||
* @return the generated color or null for the default category
|
||||
*/
|
||||
public int categoryColor() {
|
||||
// If category is default, return null: will be used Nextcloud's accent
|
||||
if (this.category == null || this.category.equals(DEFAULT_CATEGORY) || this.category.length() == 0)
|
||||
return 0;
|
||||
|
||||
float letter1Index = this.category.toLowerCase().charAt(0);
|
||||
float letter2Index = this.category.toLowerCase().charAt(1);
|
||||
float letterCoef = ((letter1Index * letter2Index) % 100) / 100;
|
||||
float h = letterCoef * 360;
|
||||
float s = 75 + letterCoef * 10;
|
||||
float l = 50 + letterCoef * 10;
|
||||
return Color.HSVToColor( new float[]{ Math.round(h), Math.round(s), Math.round(l) });
|
||||
return categoryColorFromName(this.category);
|
||||
}
|
||||
|
||||
public String categoryLetter() {
|
||||
@ -229,4 +219,27 @@ public class Geofavorite implements Serializable {
|
||||
return "[" + getName() + " (" + getLat() + "," + getLng() + ")]";
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Based on Nextcloud Maps's getLetterColor util.
|
||||
* Assigns a color to a category based on its two first letters.
|
||||
*
|
||||
* @see "https://github.com/nextcloud/maps/blob/master/src/utils.js"
|
||||
* @return the generated color or null for the default category
|
||||
*/
|
||||
public static int categoryColorFromName(String category) {
|
||||
// If category is default, return null: will be used Nextcloud's accent
|
||||
if (category == null || category.equals(DEFAULT_CATEGORY) || category.length() == 0)
|
||||
return 0;
|
||||
|
||||
float letter1Index = category.toLowerCase().charAt(0);
|
||||
float letter2Index = category.toLowerCase().charAt(1);
|
||||
float letterCoef = ((letter1Index * letter2Index) % 100) / 100;
|
||||
float h = letterCoef * 360;
|
||||
float s = 75 + letterCoef * 10;
|
||||
float l = 50 + letterCoef * 10;
|
||||
return Color.HSVToColor( new float[]{ Math.round(h), Math.round(s), Math.round(l) });
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ public class GeofavoritesFilter {
|
||||
public List<Geofavorite> byCategory(String category) {
|
||||
List<Geofavorite> filteredGeofavorites = new ArrayList<>();
|
||||
|
||||
if (category.isEmpty()) {
|
||||
if (category == null) {
|
||||
return items;
|
||||
} else {
|
||||
for (Geofavorite geofavorite : items) {
|
||||
|
27
app/src/main/res/layout/category_listitem.xml
Normal file
27
app/src/main/res/layout/category_listitem.xml
Normal file
@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingLeft="20dp"
|
||||
android:paddingRight="20dp"
|
||||
android:paddingTop="10dp"
|
||||
android:paddingBottom="10dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/category_name"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="30dp"
|
||||
android:gravity="center_vertical"
|
||||
android:lines="1"
|
||||
android:ellipsize="end"
|
||||
android:text="Lorem ipsum"
|
||||
app:drawableLeftCompat="@drawable/ic_category_asc"
|
||||
android:drawablePadding="8sp"
|
||||
android:drawableTint="@color/white"
|
||||
android:textColor="@color/white"
|
||||
android:textStyle="bold"
|
||||
android:background="@drawable/rounded_label_background"/>
|
||||
|
||||
</FrameLayout>
|
@ -45,6 +45,7 @@
|
||||
<string name="list_geofavorite_connection_error">Impossibile ottenere la lista dei geosegnalibri</string>
|
||||
<string name="filtering_unavailable">Il filtro per categoria non è disponibile al momento</string>
|
||||
<string name="filtering_dialog_title">Filtra per categoria</string>
|
||||
<string name="filtering_dialog_cancel">Mostra tutti</string>
|
||||
|
||||
<!-- Sort dialog -->
|
||||
<string name="sort_by">Ordina per</string>
|
||||
|
@ -44,6 +44,7 @@
|
||||
<string name="list_geofavorite_connection_error">Unable to obtain geofavorites list</string>
|
||||
<string name="filtering_unavailable">Category filtering is unavailable at the moment</string>
|
||||
<string name="filtering_dialog_title">Filter by category</string>
|
||||
<string name="filtering_dialog_cancel">Show all</string>
|
||||
|
||||
<!-- Sort dialog -->
|
||||
<string name="sort_by">Sort by</string>
|
||||
|
Loading…
Reference in New Issue
Block a user