forked from upstream-mirrors/OpenTracks
AggregatedStatisticsActivity: added filter option (by category, start and/or end date).
Fixes #1039.
This commit is contained in:
committed by
Román Martínez
parent
4d333bbafa
commit
b4ce99440a
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user