Skip to content

Commit e52a24f

Browse files
committed
Feature: add button to restore default values for logging interval and logging distance (Closes #345)
1 parent 721fb64 commit e52a24f

File tree

3 files changed

+102
-3
lines changed

3 files changed

+102
-3
lines changed

app/src/androidTest/java/net/osmtracker/activity/PreferencesTest.java

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,39 @@ public void testNumericInputLogic() {
122122
suffix))))));
123123
}
124124

125+
/**
126+
* Test that the Reset button in numeric preferences restores the default value.
127+
*/
128+
@Test
129+
public void testResetButtonResetsValue() {
130+
String title = context.getString(R.string.prefs_gps_logging_interval);
131+
String suffix = context.getString(R.string.prefs_gps_logging_interval_seconds);
132+
String defaultValue = OSMTracker.Preferences.VAL_GPS_LOGGING_INTERVAL;
133+
134+
scrollToAndClick(title);
135+
136+
// Set a custom value "50"
137+
onView(withId(android.R.id.edit)).perform(clearText(), typeText("50"));
138+
onView(withText(android.R.string.ok)).perform(click());
139+
140+
// Verify custom value is set
141+
onView(ViewMatchers.isAssignableFrom(RecyclerView.class))
142+
.check(matches(hasDescendant(withText(stringContainsInOrder(Arrays.asList("50",
143+
suffix))))));
144+
145+
// Reopen dialog
146+
scrollToAndClick(title);
147+
148+
// Click the Reset button (Neutral button)
149+
onView(withText(R.string.prefs_reset_default_value)).perform(click());
150+
151+
// Verify value is back to default "0"
152+
onView(ViewMatchers.isAssignableFrom(RecyclerView.class))
153+
.check(matches(hasDescendant(withText(stringContainsInOrder(Arrays.asList(
154+
defaultValue,
155+
suffix))))));
156+
}
157+
125158
/**
126159
* Test ListPreference custom summary logic (Screen Orientation)
127160
* Should show "Selected Value. \n ..." (don't check for the 2nd line of the summary)

app/src/main/java/net/osmtracker/activity/Preferences.java

Lines changed: 68 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,15 @@
44
import android.content.SharedPreferences;
55
import android.os.Bundle;
66
import android.text.TextUtils;
7+
import android.widget.Button;
78
import android.widget.Toast;
89

910
import androidx.appcompat.app.ActionBar;
11+
import androidx.appcompat.app.AlertDialog;
1012
import androidx.appcompat.app.AppCompatActivity;
13+
import androidx.fragment.app.FragmentManager;
1114
import androidx.preference.EditTextPreference;
15+
import androidx.preference.EditTextPreferenceDialogFragmentCompat;
1216
import androidx.preference.ListPreference;
1317
import androidx.preference.Preference;
1418
import androidx.preference.PreferenceFragmentCompat;
@@ -42,6 +46,9 @@ protected void onCreate(Bundle savedInstanceState) {
4246
}
4347

4448
public static class SettingsFragment extends PreferenceFragmentCompat {
49+
50+
private static final String EXTRA_DEFAULT_VALUE = "DEFAULT_VALUE";
51+
4552
@Override
4653
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
4754
setPreferencesFromResource(R.xml.preferences, rootKey);
@@ -62,14 +69,16 @@ public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
6269
OSMTracker.Preferences.KEY_GPS_LOGGING_INTERVAL,
6370
getString(R.string.prefs_gps_logging_interval_seconds),
6471
getString(R.string.prefs_gps_logging_interval_summary),
65-
getString(R.string.prefs_gps_logging_interval_empty)
72+
getString(R.string.prefs_gps_logging_interval_empty),
73+
OSMTracker.Preferences.VAL_GPS_LOGGING_INTERVAL
6674
);
6775
//GPS Logging Min Distance
6876
setupEditTextNum(
6977
OSMTracker.Preferences.KEY_GPS_LOGGING_MIN_DISTANCE,
7078
getString(R.string.prefs_gps_logging_min_distance_meters),
7179
getString(R.string.prefs_gps_logging_min_distance_summary),
72-
getString(R.string.prefs_gps_logging_min_distance_empty)
80+
getString(R.string.prefs_gps_logging_min_distance_empty),
81+
OSMTracker.Preferences.VAL_GPS_LOGGING_MIN_DISTANCE
7382
);
7483

7584

@@ -231,12 +240,16 @@ private void setupPreferenceNavigation(String preferenceKey, Intent intent) {
231240
* @param valueSuffix appended to the end of the value, shown in the summary
232241
* @param summary static summary to be appended to the end of the summary
233242
* @param validationError in case of empty value
243+
* @param defaultValue value to be used for the reset button
234244
*/
235245
private void setupEditTextNum(String preferenceKey, String valueSuffix, String summary,
236-
String validationError) {
246+
String validationError, String defaultValue) {
237247
EditTextPreference numInputPref = findPreference(preferenceKey);
238248
if (numInputPref == null) return;
239249

250+
// Store default value in Extras so it can be retrieved by the Reset Dialog
251+
numInputPref.getExtras().putString(EXTRA_DEFAULT_VALUE, defaultValue);
252+
240253
// Set input type to number and move cursor to the end
241254
numInputPref.setOnBindEditTextListener(editText -> {
242255
editText.setInputType(android.text.InputType.TYPE_CLASS_NUMBER);
@@ -259,6 +272,58 @@ private void setupEditTextNum(String preferenceKey, String valueSuffix, String s
259272
});
260273
}
261274

275+
@SuppressWarnings("deprecation") // Required to link the dialog to the fragment
276+
@Override
277+
public void onDisplayPreferenceDialog(Preference preference) {
278+
279+
// Retrieve the default value defined in extras.
280+
// If null, it means this preference doesn't support the reset feature.
281+
// Fallback to the default dialog behavior.
282+
String defaultValue = preference.getExtras().getString(EXTRA_DEFAULT_VALUE);
283+
if (defaultValue == null) {
284+
super.onDisplayPreferenceDialog(preference);
285+
return;
286+
}
287+
288+
// Create the standard dialog fragment
289+
final EditTextPreferenceDialogFragmentCompat dialogFragment =
290+
EditTextPreferenceDialogFragmentCompat.newInstance(preference.getKey());
291+
dialogFragment.setTargetFragment(this, 0);
292+
dialogFragment.show(
293+
getParentFragmentManager(),
294+
"androidx.preference.PreferenceFragment.DIALOG");
295+
296+
// Inject the button after the dialog is shown
297+
getParentFragmentManager().registerFragmentLifecycleCallbacks(
298+
new FragmentManager.FragmentLifecycleCallbacks() {
299+
@Override
300+
public void onFragmentStarted(
301+
@androidx.annotation.NonNull FragmentManager fm,
302+
@androidx.annotation.NonNull androidx.fragment.app.Fragment f) {
303+
if (f == dialogFragment) {
304+
android.app.Dialog dialog = dialogFragment.getDialog();
305+
if (dialog instanceof androidx.appcompat.app.AlertDialog alertDialog) {
306+
307+
// Configure the Neutral Button for reset default value
308+
Button btnReset = alertDialog.getButton(AlertDialog.BUTTON_NEUTRAL);
309+
btnReset.setText(R.string.prefs_reset_default_value);
310+
btnReset.setVisibility(android.view.View.VISIBLE);
311+
312+
btnReset.setOnClickListener(v -> {
313+
if (preference instanceof EditTextPreference) {
314+
((EditTextPreference) preference).setText(defaultValue);
315+
alertDialog.dismiss();
316+
}
317+
});
318+
}
319+
// Cleanup
320+
getParentFragmentManager().unregisterFragmentLifecycleCallbacks(this);
321+
}
322+
}
323+
}, false);
324+
}
325+
326+
262327
/**
263328
* Setup a ListPreference with a custom two lines summary, displays the selected entry
264329
* on the first line, and the static summary on the second line.

app/src/main/res/values/strings-preferences.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,4 +124,5 @@
124124
<string name="prefs_compass_heading">Export compass heading</string>
125125
<string name="prefs_compass_heading_summary">Defines if and how the compass data should be exported to the GPX file</string>
126126

127+
<string name="prefs_reset_default_value">Reset default value</string>
127128
</resources>

0 commit comments

Comments
 (0)