AggregatedStatisticsActivity: added filter option (by category, start and/or end date).

Fixes #1039.
This commit is contained in:
Román Ginés
2021-12-15 23:22:13 +01:00
committed by Román Martínez
parent 4d333bbafa
commit b4ce99440a
20 changed files with 940 additions and 18 deletions
@@ -0,0 +1,188 @@
package de.dennisguse.opentracks.fragments;
import android.app.Dialog;
import android.content.Context;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.CheckBox;
import android.widget.DatePicker;
import android.widget.GridLayout;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.FragmentManager;
import com.google.android.material.textfield.TextInputEditText;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.temporal.WeekFields;
import java.util.ArrayList;
import java.util.Locale;
import de.dennisguse.opentracks.R;
import de.dennisguse.opentracks.util.StringUtils;
public class FilterDialogFragment extends DialogFragment {
private static final String TAG = FilterDialogFragment.class.getSimpleName();
public static final String KEY_FILTER_ITEMS = "filterItems";
private FilterDialogListener filterDialogListener;
private ArrayList<FilterItem> filterItems = new ArrayList<>();
public static void showDialog(FragmentManager fragmentManager) {
FilterDialogFragment filterDialogFragment = new FilterDialogFragment();
filterDialogFragment.show(fragmentManager, TAG);
}
public static void showDialog(FragmentManager fragmentManager, ArrayList<FilterItem> items) {
Bundle bundle = new Bundle();
bundle.putParcelableArrayList(KEY_FILTER_ITEMS, items);
FilterDialogFragment filterDialogFragment = new FilterDialogFragment();
filterDialogFragment.setArguments(bundle);
filterDialogFragment.show(fragmentManager, TAG);
}
@NonNull
@Override
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
filterItems = getArguments().getParcelableArrayList(KEY_FILTER_ITEMS);
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle(getString(R.string.generic_filter));
LayoutInflater inflater = LayoutInflater.from(getActivity());
View layout = inflater.inflate(R.layout.fragment_filter_dialog, null, false);
GridLayout itemsLayout = layout.findViewById(R.id.filter_items);
builder.setView(layout);
for (FilterItem item : filterItems) {
View view = inflater.inflate(R.layout.fragment_filter_dialog_item, null);
CheckBox checkBox = view.findViewById(R.id.filter_dialog_check_button);
checkBox.setText(item.value);
checkBox.setChecked(item.isChecked);
checkBox.setTag(item.id);
checkBox.setOnClickListener(v -> item.isChecked = !item.isChecked);
itemsLayout.addView(view);
}
DatePicker datePickerFrom = layout.findViewById(R.id.filter_date_picker_from);
DatePicker datePickerTo = layout.findViewById(R.id.filter_date_picker_to);
TextInputEditText dateFrom = layout.findViewById(R.id.filter_date_edit_text_from);
TextInputEditText dateTo = layout.findViewById(R.id.filter_date_edit_text_to);
LocalDateTime firstDayThisWeek = LocalDate.now().with(WeekFields.of(Locale.getDefault()).getFirstDayOfWeek()).atStartOfDay();
dateFrom.setText(StringUtils.formatDate(getActivity(), firstDayThisWeek));
datePickerFrom.init(firstDayThisWeek.getYear(), firstDayThisWeek.getMonthValue() - 1, firstDayThisWeek.getDayOfMonth(), (view, year, monthOfYear, dayOfMonth) -> {
LocalDateTime localDateTime = LocalDateTime.of(year, monthOfYear + 1, dayOfMonth, 0, 0, 0);
dateFrom.setText(StringUtils.formatDate(getActivity(), localDateTime));
datePickerFrom.setVisibility(View.GONE);
datePickerTo.setMinDate(localDateTime.toInstant(ZoneOffset.ofTotalSeconds(0)).toEpochMilli());
if (localDateTime.isAfter(LocalDateTime.of(datePickerTo.getYear(), datePickerTo.getMonth() + 1, datePickerTo.getDayOfMonth(), 23, 59, 59))) {
datePickerTo.updateDate(year, monthOfYear, dayOfMonth);
}
});
LocalDateTime lastDayThisWeek = firstDayThisWeek.plusDays(6).withHour(23).withMinute(59).withSecond(59);
dateTo.setText(StringUtils.formatDate(getActivity(), lastDayThisWeek));
datePickerTo.init(lastDayThisWeek.getYear(), lastDayThisWeek.getMonthValue() - 1, lastDayThisWeek.getDayOfMonth(), (view, year, monthOfYear, dayOfMonth) -> {
LocalDateTime localDateTime = LocalDateTime.of(year, monthOfYear + 1, dayOfMonth, 23, 59, 59);
dateTo.setText(StringUtils.formatDate(getActivity(), localDateTime));
datePickerTo.setVisibility(View.GONE);
});
dateFrom.setOnClickListener(v -> {
datePickerFrom.setVisibility(View.VISIBLE);
datePickerTo.setVisibility(View.GONE);
});
dateTo.setOnClickListener(v -> {
datePickerFrom.setVisibility(View.GONE);
datePickerTo.setVisibility(View.VISIBLE);
});
builder.setPositiveButton(android.R.string.ok, (dialog, which) -> {
filterDialogListener.onFilterDone(
filterItems,
LocalDateTime.of(datePickerFrom.getYear(), datePickerFrom.getMonth() + 1, datePickerFrom.getDayOfMonth(), 0, 0, 0),
LocalDateTime.of(datePickerTo.getYear(), datePickerTo.getMonth() + 1, datePickerTo.getDayOfMonth(), 23, 59, 59)
);
});
builder.setNegativeButton(android.R.string.cancel, null);
return builder.create();
}
@Override
public void onAttach(@NonNull Context context) {
super.onAttach(context);
try {
filterDialogListener = (FilterDialogListener) context;
} catch (ClassCastException e) {
throw new ClassCastException(context + " must implement " + FilterDialogListener.class.getSimpleName());
}
}
public interface FilterDialogListener {
void onFilterDone(ArrayList<FilterItem> filters, LocalDateTime from, LocalDateTime to);
}
public static class FilterItem implements Parcelable {
public final String id;
public final String value;
public boolean isChecked;
public FilterItem(String id, String value) {
this.id = id;
this.value = value;
this.isChecked = true;
}
public FilterItem(String id, String value, boolean isChecked) {
this.id = id;
this.value = value;
this.isChecked = isChecked;
}
protected FilterItem(Parcel in) {
id = in.readString();
value = in.readString();
isChecked = in.readByte() != 0;
}
public static final Creator<FilterItem> CREATOR = new Creator<FilterItem>() {
@Override
public FilterItem createFromParcel(Parcel in) {
return new FilterItem(in);
}
@Override
public FilterItem[] newArray(int size) {
return new FilterItem[size];
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(id);
dest.writeString(value);
dest.writeByte((byte) (isChecked ? 1 : 0));
}
}
}