forked from upstream-mirrors/OpenTracks
Aggregated stats: start of the week uses regional preferences (Android14+).
Implemented using Material3's DatePicker. Fixes #1681.
This commit is contained in:
+43
-34
@@ -10,15 +10,18 @@ import android.view.View;
|
|||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.appcompat.app.AlertDialog;
|
import androidx.appcompat.app.AlertDialog;
|
||||||
|
import androidx.core.util.Pair;
|
||||||
import androidx.fragment.app.DialogFragment;
|
import androidx.fragment.app.DialogFragment;
|
||||||
import androidx.fragment.app.FragmentManager;
|
import androidx.fragment.app.FragmentManager;
|
||||||
|
|
||||||
|
import com.google.android.material.datepicker.MaterialDatePicker;
|
||||||
|
|
||||||
|
import java.time.Instant;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.ZoneOffset;
|
import java.time.ZoneOffset;
|
||||||
import java.time.temporal.WeekFields;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Locale;
|
import java.util.TimeZone;
|
||||||
|
|
||||||
import de.dennisguse.opentracks.R;
|
import de.dennisguse.opentracks.R;
|
||||||
import de.dennisguse.opentracks.databinding.FragmentFilterDialogBinding;
|
import de.dennisguse.opentracks.databinding.FragmentFilterDialogBinding;
|
||||||
@@ -65,49 +68,55 @@ public class FilterDialogFragment extends DialogFragment {
|
|||||||
layout.filterItems.addView(view.getRoot());
|
layout.filterItems.addView(view.getRoot());
|
||||||
}
|
}
|
||||||
|
|
||||||
LocalDateTime firstDayThisWeek = LocalDate.now().with(WeekFields.of(Locale.getDefault()).getFirstDayOfWeek()).atStartOfDay();
|
|
||||||
layout.filterDateEditTextFrom.setText(StringUtils.formatLocalDateTime(firstDayThisWeek));
|
// Interval is last 7 days.
|
||||||
layout.filterDatePickerFrom.init(firstDayThisWeek.getYear(), firstDayThisWeek.getMonthValue() - 1, firstDayThisWeek.getDayOfMonth(), (view, year, monthOfYear, dayOfMonth) -> {
|
LocalDateTime initialToDate = LocalDate.now().atStartOfDay();
|
||||||
LocalDateTime localDateTime = LocalDateTime.of(year, monthOfYear + 1, dayOfMonth, 0, 0, 0);
|
LocalDateTime initialFromDate = initialToDate.minusDays(6);
|
||||||
layout.filterDateEditTextFrom.setText(StringUtils.formatLocalDateTime(localDateTime));
|
|
||||||
layout.filterDatePickerFrom.setVisibility(View.GONE);
|
MaterialDatePicker<Pair<Long, Long>> dateRangePicker = MaterialDatePicker.Builder
|
||||||
layout.filterDatePickerTo.setMinDate(localDateTime.toInstant(ZoneOffset.ofTotalSeconds(0)).toEpochMilli());
|
.dateRangePicker()
|
||||||
if (localDateTime.isAfter(LocalDateTime.of(layout.filterDatePickerTo.getYear(), layout.filterDatePickerTo.getMonth() + 1, layout.filterDatePickerTo.getDayOfMonth(), 23, 59, 59))) {
|
.setSelection(new Pair<>(
|
||||||
layout.filterDatePickerTo.updateDate(year, monthOfYear, dayOfMonth);
|
initialFromDate.toInstant(ZoneOffset.UTC).toEpochMilli(),
|
||||||
}
|
initialToDate.toInstant(ZoneOffset.UTC).toEpochMilli())
|
||||||
|
|
||||||
|
)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
layout.filterDateEditTextFrom.setText(StringUtils.formatLocalDateTime(initialFromDate));
|
||||||
|
layout.filterDateEditTextTo.setText(StringUtils.formatLocalDateTime(initialToDate));
|
||||||
|
|
||||||
|
dateRangePicker.addOnPositiveButtonClickListener(selection -> {
|
||||||
|
Pair<LocalDateTime, LocalDateTime> javaxSelection = to(dateRangePicker);
|
||||||
|
|
||||||
|
layout.filterDateEditTextFrom.setText(StringUtils.formatLocalDateTime(javaxSelection.first));
|
||||||
|
layout.filterDateEditTextTo.setText(StringUtils.formatLocalDateTime(javaxSelection.second));
|
||||||
});
|
});
|
||||||
|
|
||||||
LocalDateTime lastDayThisWeek = firstDayThisWeek.plusDays(6).withHour(23).withMinute(59).withSecond(59);
|
View.OnClickListener openDatePicker = v -> dateRangePicker.show(getChildFragmentManager(), "DATE_PICKER");
|
||||||
layout.filterDateEditTextTo.setText(StringUtils.formatLocalDateTime(lastDayThisWeek));
|
layout.filterDateEditTextFrom.setOnClickListener(openDatePicker);
|
||||||
layout.filterDatePickerTo.init(lastDayThisWeek.getYear(), lastDayThisWeek.getMonthValue() - 1, lastDayThisWeek.getDayOfMonth(), (view, year, monthOfYear, dayOfMonth) -> {
|
layout.filterDateEditTextTo.setOnClickListener(openDatePicker);
|
||||||
LocalDateTime localDateTime = LocalDateTime.of(year, monthOfYear + 1, dayOfMonth, 23, 59, 59);
|
|
||||||
layout.filterDateEditTextTo.setText(StringUtils.formatLocalDateTime(localDateTime));
|
|
||||||
layout.filterDatePickerTo.setVisibility(View.GONE);
|
|
||||||
});
|
|
||||||
|
|
||||||
layout.filterDateEditTextFrom.setOnClickListener(v -> {
|
|
||||||
layout.filterDatePickerFrom.setVisibility(View.VISIBLE);
|
|
||||||
layout.filterDatePickerTo.setVisibility(View.GONE);
|
|
||||||
});
|
|
||||||
|
|
||||||
layout.filterDateEditTextTo.setOnClickListener(v -> {
|
|
||||||
layout.filterDatePickerFrom.setVisibility(View.GONE);
|
|
||||||
layout.filterDatePickerTo.setVisibility(View.VISIBLE);
|
|
||||||
});
|
|
||||||
|
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
||||||
builder.setTitle(getString(R.string.generic_filter));
|
builder.setTitle(getString(R.string.generic_filter));
|
||||||
builder.setView(layout.getRoot());
|
builder.setView(layout.getRoot());
|
||||||
builder.setPositiveButton(android.R.string.ok, (dialog, which) -> filterDialogListener.onFilterDone(
|
builder.setPositiveButton(android.R.string.ok, (dialog, which) -> {
|
||||||
filterItems,
|
Pair<LocalDateTime, LocalDateTime> a = to(dateRangePicker);
|
||||||
LocalDateTime.of(layout.filterDatePickerFrom.getYear(), layout.filterDatePickerFrom.getMonth() + 1, layout.filterDatePickerFrom.getDayOfMonth(), 0, 0, 0),
|
filterDialogListener.onFilterDone(filterItems, a.first, a.second);
|
||||||
LocalDateTime.of(layout.filterDatePickerTo.getYear(), layout.filterDatePickerTo.getMonth() + 1, layout.filterDatePickerTo.getDayOfMonth(), 23, 59, 59)
|
});
|
||||||
));
|
|
||||||
builder.setNegativeButton(android.R.string.cancel, null);
|
builder.setNegativeButton(android.R.string.cancel, null);
|
||||||
|
|
||||||
return builder.create();
|
return builder.create();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Pair<LocalDateTime, LocalDateTime> to(MaterialDatePicker<Pair<Long, Long>> dateRangePicker) {
|
||||||
|
Pair<Long, Long> selection = dateRangePicker.getSelection();
|
||||||
|
|
||||||
|
return new Pair<>(
|
||||||
|
LocalDateTime.ofInstant(Instant.ofEpochMilli(selection.first), TimeZone.getDefault().toZoneId()),
|
||||||
|
LocalDateTime.ofInstant(Instant.ofEpochMilli(selection.second), TimeZone.getDefault().toZoneId())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onAttach(@NonNull Context context) {
|
public void onAttach(@NonNull Context context) {
|
||||||
super.onAttach(context);
|
super.onAttach(context);
|
||||||
|
|||||||
@@ -3,12 +3,12 @@
|
|||||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||||
xmlns:tools="http://schemas.android.com/tools">
|
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
android:padding="8dp">
|
android:padding="8dp">
|
||||||
|
|
||||||
<com.google.android.material.button.MaterialButtonToggleGroup
|
<com.google.android.material.button.MaterialButtonToggleGroup
|
||||||
@@ -17,11 +17,7 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:padding="8dp"
|
android:padding="8dp"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
app:singleSelection="false"
|
app:singleSelection="false" />
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintBottom_toTopOf="@id/filter_date_from" />
|
|
||||||
|
|
||||||
<com.google.android.material.textfield.TextInputLayout
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
android:id="@+id/filter_date_from"
|
android:id="@+id/filter_date_from"
|
||||||
@@ -30,11 +26,7 @@
|
|||||||
android:hint="@string/generic_from"
|
android:hint="@string/generic_from"
|
||||||
android:imeOptions="actionNext"
|
android:imeOptions="actionNext"
|
||||||
android:importantForAutofill="no"
|
android:importantForAutofill="no"
|
||||||
android:padding="8dp"
|
android:padding="8dp">
|
||||||
app:layout_constraintTop_toBottomOf="@id/filter_items"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintBottom_toTopOf="@id/filter_date_picker_from">
|
|
||||||
|
|
||||||
<com.google.android.material.textfield.TextInputEditText
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
android:id="@+id/filter_date_edit_text_from"
|
android:id="@+id/filter_date_edit_text_from"
|
||||||
@@ -49,19 +41,6 @@
|
|||||||
|
|
||||||
</com.google.android.material.textfield.TextInputLayout>
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
<DatePicker
|
|
||||||
android:id="@+id/filter_date_picker_from"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:visibility="gone"
|
|
||||||
tools:visibility="visible"
|
|
||||||
android:paddingLeft="8dp"
|
|
||||||
android:paddingRight="8dp"
|
|
||||||
app:layout_constraintTop_toBottomOf="@id/filter_date_from"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintBottom_toTopOf="@id/filter_date_to" />
|
|
||||||
|
|
||||||
<com.google.android.material.textfield.TextInputLayout
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
android:id="@+id/filter_date_to"
|
android:id="@+id/filter_date_to"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
@@ -69,11 +48,7 @@
|
|||||||
android:hint="@string/generic_to"
|
android:hint="@string/generic_to"
|
||||||
android:imeOptions="actionNext"
|
android:imeOptions="actionNext"
|
||||||
android:importantForAutofill="no"
|
android:importantForAutofill="no"
|
||||||
android:padding="8dp"
|
android:padding="8dp">
|
||||||
app:layout_constraintTop_toBottomOf="@id/filter_date_picker_from"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintBottom_toTopOf="@id/filter_date_picker_to">
|
|
||||||
|
|
||||||
<com.google.android.material.textfield.TextInputEditText
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
android:id="@+id/filter_date_edit_text_to"
|
android:id="@+id/filter_date_edit_text_to"
|
||||||
@@ -87,20 +62,5 @@
|
|||||||
android:selectAllOnFocus="true" />
|
android:selectAllOnFocus="true" />
|
||||||
|
|
||||||
</com.google.android.material.textfield.TextInputLayout>
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
</LinearLayout>
|
||||||
<DatePicker
|
|
||||||
android:id="@+id/filter_date_picker_to"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:visibility="gone"
|
|
||||||
tools:visibility="visible"
|
|
||||||
android:paddingLeft="8dp"
|
|
||||||
android:paddingRight="8dp"
|
|
||||||
app:layout_constraintTop_toBottomOf="@id/filter_date_to"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent" />
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
||||||
|
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
Reference in New Issue
Block a user