From ffedc047773aba8ea89d971d701eb0bda7df9e87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rom=C3=A1n?= Date: Sat, 12 Sep 2020 14:53:00 +0200 Subject: [PATCH] Intervals refactoring: avoid duplication code: IntervalsRecordingFragment is a version of IntervalsFragment. --- .../opentracks/TrackRecordedActivity.java | 4 +- .../opentracks/TrackRecordingActivity.java | 7 +- .../adapters/IntervalStatisticsAdapter.java | 3 +- ...ngFragment.java => IntervalsFragment.java} | 112 +++++++++----- .../fragments/IntervalsRecordedFragment.java | 137 ------------------ .../viewmodels/IntervalStatisticsModel.java | 1 - 6 files changed, 80 insertions(+), 184 deletions(-) rename src/main/java/de/dennisguse/opentracks/fragments/{IntervalsRecordingFragment.java => IntervalsFragment.java} (68%) delete mode 100644 src/main/java/de/dennisguse/opentracks/fragments/IntervalsRecordedFragment.java diff --git a/src/main/java/de/dennisguse/opentracks/TrackRecordedActivity.java b/src/main/java/de/dennisguse/opentracks/TrackRecordedActivity.java index eafd09ee2..f75b570bd 100644 --- a/src/main/java/de/dennisguse/opentracks/TrackRecordedActivity.java +++ b/src/main/java/de/dennisguse/opentracks/TrackRecordedActivity.java @@ -37,7 +37,7 @@ import de.dennisguse.opentracks.content.provider.ContentProviderUtils; import de.dennisguse.opentracks.fragments.ChartFragment; import de.dennisguse.opentracks.fragments.ChooseActivityTypeDialogFragment; import de.dennisguse.opentracks.fragments.ConfirmDeleteDialogFragment; -import de.dennisguse.opentracks.fragments.IntervalsRecordedFragment; +import de.dennisguse.opentracks.fragments.IntervalsFragment; import de.dennisguse.opentracks.fragments.StatisticsRecordedFragment; import de.dennisguse.opentracks.services.TrackRecordingServiceConnection; import de.dennisguse.opentracks.settings.SettingsActivity; @@ -253,7 +253,7 @@ public class TrackRecordedActivity extends AbstractListActivity implements Choos case 0: return StatisticsRecordedFragment.newInstance(track.getId()); case 1: - return IntervalsRecordedFragment.newInstance(track.getId()); + return IntervalsFragment.newInstance(track.getId()); case 2: return ChartFragment.newInstance(false); case 3: diff --git a/src/main/java/de/dennisguse/opentracks/TrackRecordingActivity.java b/src/main/java/de/dennisguse/opentracks/TrackRecordingActivity.java index e32af7d93..1eae187cc 100644 --- a/src/main/java/de/dennisguse/opentracks/TrackRecordingActivity.java +++ b/src/main/java/de/dennisguse/opentracks/TrackRecordingActivity.java @@ -25,7 +25,7 @@ import de.dennisguse.opentracks.content.data.Track; import de.dennisguse.opentracks.content.provider.ContentProviderUtils; import de.dennisguse.opentracks.fragments.ChartFragment; import de.dennisguse.opentracks.fragments.ChooseActivityTypeDialogFragment; -import de.dennisguse.opentracks.fragments.IntervalsRecordingFragment; +import de.dennisguse.opentracks.fragments.IntervalsFragment; import de.dennisguse.opentracks.fragments.StatisticsRecordingFragment; import de.dennisguse.opentracks.services.TrackRecordingServiceConnection; import de.dennisguse.opentracks.services.TrackRecordingServiceInterface; @@ -390,7 +390,7 @@ public class TrackRecordingActivity extends AbstractActivity implements ChooseAc case 0: return StatisticsRecordingFragment.newInstance(); case 1: - return IntervalsRecordingFragment.newInstance(trackId); + return IntervalsFragment.IntervalsRecordingFragment.newInstance(trackId); case 2: return ChartFragment.newInstance(false); case 3: @@ -423,5 +423,8 @@ public class TrackRecordingActivity extends AbstractActivity implements ChooseAc public void setTrackIdListener(OnTrackIdListener listener) { this.intervalsListener = listener; + if (trackId != null) { + listener.onTrackId(trackId); + } } } \ No newline at end of file diff --git a/src/main/java/de/dennisguse/opentracks/adapters/IntervalStatisticsAdapter.java b/src/main/java/de/dennisguse/opentracks/adapters/IntervalStatisticsAdapter.java index 596dbe959..8ca29b1a1 100644 --- a/src/main/java/de/dennisguse/opentracks/adapters/IntervalStatisticsAdapter.java +++ b/src/main/java/de/dennisguse/opentracks/adapters/IntervalStatisticsAdapter.java @@ -1,7 +1,6 @@ package de.dennisguse.opentracks.adapters; import android.content.Context; -import android.util.Log; import android.util.Pair; import android.view.LayoutInflater; import android.view.View; @@ -49,7 +48,7 @@ public class IntervalStatisticsAdapter extends ArrayAdapter 0 ? (position * getItem(position - 1).getDistance_m()) + interval.getDistance_m() : (position + 1) * interval.getDistance_m(); viewHolder.distance.setText(StringUtils.formatDistance(getContext(), sumDistance_m, metricUnits)); Pair speedParts = StringUtils.getSpeedParts(getContext(), interval.getSpeed_ms(), metricUnits, true); diff --git a/src/main/java/de/dennisguse/opentracks/fragments/IntervalsRecordingFragment.java b/src/main/java/de/dennisguse/opentracks/fragments/IntervalsFragment.java similarity index 68% rename from src/main/java/de/dennisguse/opentracks/fragments/IntervalsRecordingFragment.java rename to src/main/java/de/dennisguse/opentracks/fragments/IntervalsFragment.java index e32c89e50..5d86d3938 100644 --- a/src/main/java/de/dennisguse/opentracks/fragments/IntervalsRecordingFragment.java +++ b/src/main/java/de/dennisguse/opentracks/fragments/IntervalsFragment.java @@ -30,17 +30,14 @@ import de.dennisguse.opentracks.viewmodels.IntervalStatistics; import de.dennisguse.opentracks.viewmodels.IntervalStatisticsModel; /** - * A fragment to display the intervals from recording track. + * A fragment to display the intervals from recorded track. */ -public class IntervalsRecordingFragment extends Fragment implements TrackRecordingActivity.OnTrackIdListener { +public class IntervalsFragment extends Fragment { - private static final String TAG = IntervalsRecordingFragment.class.getSimpleName(); + private static final String TAG = IntervalsFragment.class.getSimpleName(); private static final String TRACK_ID_KEY = "trackId"; - // Refreshing intervals stats it's not so demanding so 5 seconds is enough to balance performance and user experience. - private static final long UI_UPDATE_INTERVAL = 5 * UnitConversions.ONE_SECOND_MS; - private IntervalStatisticsModel viewModel; private ListView intervalListView; private IntervalStatisticsModel.IntervalOption selectedInterval; @@ -64,23 +61,11 @@ public class IntervalsRecordingFragment extends Fragment implements TrackRecordi Bundle bundle = new Bundle(); bundle.putParcelable(TRACK_ID_KEY, trackId); - Fragment fragment = new IntervalsRecordingFragment(); + Fragment fragment = new IntervalsFragment(); fragment.setArguments(bundle); return fragment; } - private final Runnable intervalRunner = new Runnable() { - @Override - public void run() { - if (isResumed()) { - updateIntervals(); - intervalHandler.postDelayed(intervalRunner, UI_UPDATE_INTERVAL); - } - } - }; - - private Handler intervalHandler; - @Override public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.interval_list_view, container, false); @@ -92,10 +77,11 @@ public class IntervalsRecordingFragment extends Fragment implements TrackRecordi PreferencesUtils.register(getContext(), sharedPreferenceChangeListener); - trackId = getArguments().getParcelable(TRACK_ID_KEY); - ((TrackRecordingActivity) getActivity()).setTrackIdListener(this); - - intervalHandler = new Handler(); + if (savedInstanceState != null) { + trackId = savedInstanceState.getParcelable(TRACK_ID_KEY); + } else { + trackId = getArguments().getParcelable(TRACK_ID_KEY); + } intervalListView = view.findViewById(R.id.interval_list); intervalListView.setEmptyView(view.findViewById(R.id.interval_list_empty_view)); @@ -122,18 +108,8 @@ public class IntervalsRecordingFragment extends Fragment implements TrackRecordi } }); - } - @Override - public void onResume() { - super.onResume(); - intervalHandler.post(intervalRunner); - } - - @Override - public void onPause() { - super.onPause(); - intervalHandler.removeCallbacks(intervalRunner); + intervalChanged(); } @Override @@ -149,6 +125,12 @@ public class IntervalsRecordingFragment extends Fragment implements TrackRecordi viewModel = null; } + @Override + public void onSaveInstanceState(@NonNull Bundle outState) { + super.onSaveInstanceState(outState); + outState.putParcelable(TRACK_ID_KEY, trackId); + } + /** * Update intervals through {@link IntervalStatisticsModel} view model. */ @@ -166,12 +148,62 @@ public class IntervalsRecordingFragment extends Fragment implements TrackRecordi }); } - private void updateIntervals() { - intervalChanged(); - } - - @Override - public void onTrackId(Track.Id trackId) { + public void setTrackId(Track.Id trackId) { this.trackId = trackId; } + + public static class IntervalsRecordingFragment extends IntervalsFragment implements TrackRecordingActivity.OnTrackIdListener { + // Refreshing intervals stats it's not so demanding so 5 seconds is enough to balance performance and user experience. + private static final long UI_UPDATE_INTERVAL = 5 * UnitConversions.ONE_SECOND_MS; + + private Handler intervalHandler; + + private final Runnable intervalRunner = new Runnable() { + @Override + public void run() { + if (isResumed()) { + updateIntervals(); + intervalHandler.postDelayed(intervalRunner, UI_UPDATE_INTERVAL); + } + } + }; + + public static Fragment newInstance(Track.Id trackId) { + Bundle bundle = new Bundle(); + bundle.putParcelable(TRACK_ID_KEY, trackId); + + Fragment fragment = new IntervalsRecordingFragment(); + fragment.setArguments(bundle); + return fragment; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + ((TrackRecordingActivity) getActivity()).setTrackIdListener(this); + intervalHandler = new Handler(); + + super.onViewCreated(view, savedInstanceState); + } + + @Override + public void onResume() { + super.onResume(); + intervalHandler.post(intervalRunner); + } + + @Override + public void onPause() { + super.onPause(); + intervalHandler.removeCallbacks(intervalRunner); + } + + private void updateIntervals() { + intervalChanged(); + } + + @Override + public void onTrackId(Track.Id trackId) { + setTrackId(trackId); + } + } } \ No newline at end of file diff --git a/src/main/java/de/dennisguse/opentracks/fragments/IntervalsRecordedFragment.java b/src/main/java/de/dennisguse/opentracks/fragments/IntervalsRecordedFragment.java deleted file mode 100644 index cec53df34..000000000 --- a/src/main/java/de/dennisguse/opentracks/fragments/IntervalsRecordedFragment.java +++ /dev/null @@ -1,137 +0,0 @@ -package de.dennisguse.opentracks.fragments; - -import android.content.SharedPreferences; -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.AdapterView; -import android.widget.ArrayAdapter; -import android.widget.ListView; -import android.widget.Spinner; -import android.widget.TextView; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.fragment.app.Fragment; -import androidx.lifecycle.LiveData; -import androidx.lifecycle.ViewModelProvider; - -import java.util.Arrays; - -import de.dennisguse.opentracks.R; -import de.dennisguse.opentracks.adapters.IntervalStatisticsAdapter; -import de.dennisguse.opentracks.content.data.Track; -import de.dennisguse.opentracks.util.PreferencesUtils; -import de.dennisguse.opentracks.viewmodels.IntervalStatistics; -import de.dennisguse.opentracks.viewmodels.IntervalStatisticsModel; - -/** - * A fragment to display the intervals from recorded track. - */ -public class IntervalsRecordedFragment extends Fragment { - - private static final String TAG = IntervalsRecordedFragment.class.getSimpleName(); - - private static final String TRACK_ID_KEY = "trackId"; - - private IntervalStatisticsModel viewModel; - private ListView intervalListView; - private IntervalStatisticsModel.IntervalOption selectedInterval; - private IntervalStatisticsAdapter adapter; - - protected Spinner spinnerIntervals; - protected TextView spinnerIntervalsUnit; - - private Track.Id trackId; - - protected final SharedPreferences.OnSharedPreferenceChangeListener sharedPreferenceChangeListener = (preferences, key) -> { - if (PreferencesUtils.isKey(getContext(), R.string.stats_units_key, key) || PreferencesUtils.isKey(getContext(), R.string.stats_rate_key, key)) { - if (spinnerIntervalsUnit != null) { - spinnerIntervalsUnit.setText(PreferencesUtils.isMetricUnits(getContext()) ? getContext().getString(R.string.unit_kilometer) : getContext().getString(R.string.unit_mile)); - intervalChanged(); - } - } - }; - - public static Fragment newInstance(Track.Id trackId) { - Bundle bundle = new Bundle(); - bundle.putParcelable(TRACK_ID_KEY, trackId); - - Fragment fragment = new IntervalsRecordedFragment(); - fragment.setArguments(bundle); - return fragment; - } - - @Override - public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - return inflater.inflate(R.layout.interval_list_view, container, false); - } - - @Override - public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { - super.onViewCreated(view, savedInstanceState); - - PreferencesUtils.register(getContext(), sharedPreferenceChangeListener); - - trackId = getArguments().getParcelable(TRACK_ID_KEY); - - intervalListView = view.findViewById(R.id.interval_list); - intervalListView.setEmptyView(view.findViewById(R.id.interval_list_empty_view)); - - viewModel = new ViewModelProvider(this).get(IntervalStatisticsModel.class); - - spinnerIntervals = view.findViewById(R.id.spinner_intervals); - - int[] intValues = Arrays.stream(IntervalStatisticsModel.IntervalOption.values()).mapToInt(i -> i.getValue()).toArray(); - - spinnerIntervals.setAdapter(new ArrayAdapter<>(getContext(), android.R.layout.simple_spinner_dropdown_item, Arrays.stream(intValues).mapToObj(String::valueOf).toArray(String[]::new))); - spinnerIntervalsUnit = view.findViewById(R.id.spinner_intervals_unit); - spinnerIntervalsUnit.setText(PreferencesUtils.isMetricUnits(getContext()) ? getContext().getString(R.string.unit_kilometer) : getContext().getString(R.string.unit_mile)); - - spinnerIntervals.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { - @Override - public void onItemSelected(AdapterView adapterView, View view, int i, long l) { - selectedInterval = IntervalStatisticsModel.IntervalOption.values()[i]; - intervalChanged(); - } - - @Override - public void onNothingSelected(AdapterView adapterView) { - - } - }); - - intervalChanged(); - } - - @Override - public void onDestroy() { - super.onDestroy(); - - PreferencesUtils.unregister(getContext(), sharedPreferenceChangeListener); - - intervalListView = null; - adapter = null; - spinnerIntervals = null; - spinnerIntervalsUnit = null; - viewModel = null; - } - - /** - * Update intervals through {@link IntervalStatisticsModel} view model. - */ - public void intervalChanged() { - if (viewModel == null || intervalListView == null) { - return; - } - - LiveData liveData = viewModel.getIntervalStats(trackId, selectedInterval); - liveData.observe(getActivity(), intervalStatistics -> { - if (intervalStatistics != null) { - adapter = new IntervalStatisticsAdapter(getContext(), intervalStatistics.getIntervalList()); - intervalListView.setAdapter(adapter); - } - }); - } -} \ No newline at end of file diff --git a/src/main/java/de/dennisguse/opentracks/viewmodels/IntervalStatisticsModel.java b/src/main/java/de/dennisguse/opentracks/viewmodels/IntervalStatisticsModel.java index ef698986a..212f64746 100644 --- a/src/main/java/de/dennisguse/opentracks/viewmodels/IntervalStatisticsModel.java +++ b/src/main/java/de/dennisguse/opentracks/viewmodels/IntervalStatisticsModel.java @@ -24,7 +24,6 @@ import de.dennisguse.opentracks.util.UnitConversions; public class IntervalStatisticsModel extends AndroidViewModel { private MutableLiveData intervalStats = new MutableLiveData<>(); - private IntervalOption interval = IntervalOption.OPTION_1; public IntervalStatisticsModel(@NonNull Application application) { super(application);