diff --git a/drawable-svg/LOGO.svg b/drawable-svg/LOGO.svg
index 151f3f283..dc754f35f 100644
--- a/drawable-svg/LOGO.svg
+++ b/drawable-svg/LOGO.svg
@@ -1,37 +1,119 @@
\ No newline at end of file
+
diff --git a/drawable-svg/LOGO_old_color.svg b/drawable-svg/LOGO_old_color.svg
new file mode 100644
index 000000000..151f3f283
--- /dev/null
+++ b/drawable-svg/LOGO_old_color.svg
@@ -0,0 +1,37 @@
+
+
\ No newline at end of file
diff --git a/drawable-svg/ic_button_done.svg b/drawable-svg/ic_button_done.svg
new file mode 100644
index 000000000..17494b98b
--- /dev/null
+++ b/drawable-svg/ic_button_done.svg
@@ -0,0 +1,67 @@
+
+
diff --git a/drawable-svg/ic_button_resume.svg b/drawable-svg/ic_button_resume.svg
new file mode 100644
index 000000000..ba7116ef3
--- /dev/null
+++ b/drawable-svg/ic_button_resume.svg
@@ -0,0 +1,79 @@
+
+
diff --git a/src/androidTest/java/de/dennisguse/opentracks/EspressoDeleteTrackTest.java b/src/androidTest/java/de/dennisguse/opentracks/EspressoDeleteTrackTest.java
index 68a6177c0..cd9232503 100644
--- a/src/androidTest/java/de/dennisguse/opentracks/EspressoDeleteTrackTest.java
+++ b/src/androidTest/java/de/dennisguse/opentracks/EspressoDeleteTrackTest.java
@@ -78,17 +78,16 @@ public class EspressoDeleteTrackTest {
{
// TrackListActivity: start recording
- ViewInteraction trackControllerRecordButton = onView(withId(R.id.controller_record));
+ ViewInteraction trackControllerRecordButton = onView(withId(R.id.track_list_fab_action));
trackControllerRecordButton.perform(click());
}
{
// TrackRecordingActivity
- ViewInteraction trackControllerRecordButton = onView(withId(R.id.controller_record));
- ViewInteraction trackControllerStopButton = onView(withId(R.id.controller_stop));
+ ViewInteraction trackControllerStopButton = onView(withId(R.id.track_recording_fab_action));
// wait; stay recording
- trackControllerRecordButton.perform(waitFor(5000));
+ trackControllerStopButton.perform(waitFor(5000));
// stop;
trackControllerStopButton.perform(veryLongTouch(1600));
@@ -108,7 +107,7 @@ public class EspressoDeleteTrackTest {
allOf(withContentDescription("More options"),
childAtPosition(
childAtPosition(
- withId(R.id.toolbar),
+ withId(R.id.bottom_app_bar),
2),
2),
isDisplayed()));
diff --git a/src/androidTest/java/de/dennisguse/opentracks/EspressoEditTrackRecordingTest.java b/src/androidTest/java/de/dennisguse/opentracks/EspressoEditTrackRecordingTest.java
index aea53c0f6..2b364e7de 100644
--- a/src/androidTest/java/de/dennisguse/opentracks/EspressoEditTrackRecordingTest.java
+++ b/src/androidTest/java/de/dennisguse/opentracks/EspressoEditTrackRecordingTest.java
@@ -50,16 +50,15 @@ public class EspressoEditTrackRecordingTest {
public void espressoEditTrackRecordingTest() {
{
// TrackListActivity: start recording
- ViewInteraction trackControllerRecordButton = onView(withId(R.id.controller_record));
- trackControllerRecordButton.perform(click());
+ ViewInteraction fabRecordButton = onView(withId(R.id.track_list_fab_action));
+ fabRecordButton.perform(click());
}
{
// TrackRecordingActivity
- ViewInteraction trackControllerRecordButton = onView(withId(R.id.controller_record));
- ViewInteraction trackControllerStopButton = onView(withId(R.id.controller_stop));
+ ViewInteraction trackControllerStopButton = onView(withId(R.id.track_recording_fab_action));
// wait; stay recording
- trackControllerRecordButton.perform(waitFor(15000));
+ trackControllerStopButton.perform(waitFor(15000));
// open menu
openContextualActionModeOverflowMenu();
@@ -88,37 +87,17 @@ public class EspressoEditTrackRecordingTest {
textInputEditText2.perform(closeSoftKeyboard());
// save edition
- ViewInteraction appCompatButton = onView(
- allOf(withId(R.id.track_edit_save),
- childAtPosition(
- childAtPosition(
- withClassName(is("android.widget.LinearLayout")),
- 3),
- 1),
- isDisplayed()));
+ ViewInteraction appCompatButton = onView(withId(R.id.track_edit_save));
appCompatButton.perform(click());
- //pause
- trackControllerRecordButton.perform(veryLongTouch(1600));
-
- // wait; stay paused
- trackControllerRecordButton.perform(waitFor(1000));
-
- // resume
- trackControllerRecordButton.perform(click());
-
- // wait; stay recording
- trackControllerRecordButton.perform(waitFor(1000));
-
// stop;
trackControllerStopButton.perform(veryLongTouch(1600));
- // check track's name is "New Name"
- ViewInteraction textView = onView(
- allOf(withId(R.id.stats_name_value),
- withParent(withParent(IsInstanceOf.instanceOf(android.widget.ScrollView.class))),
- isDisplayed()));
- textView.check(matches(withText("New Name")));
+ // it's on track stopped activity and there are two buttons
+ ViewInteraction resumeButton = onView(withId(R.id.resume_button));
+ resumeButton.check(matches(isDisplayed()));
+ ViewInteraction finishButton = onView(withId(R.id.finish_button));
+ finishButton.check(matches(isDisplayed()));
}
}
diff --git a/src/androidTest/java/de/dennisguse/opentracks/EspressoUITest.java b/src/androidTest/java/de/dennisguse/opentracks/EspressoUITest.java
index 0a93c0226..ecc5484f4 100644
--- a/src/androidTest/java/de/dennisguse/opentracks/EspressoUITest.java
+++ b/src/androidTest/java/de/dennisguse/opentracks/EspressoUITest.java
@@ -42,28 +42,27 @@ public class EspressoUITest {
public void record_pause_resume_stop() {
{
// TrackListActivity: start recording
- ViewInteraction trackControllerRecordButton = onView(withId(R.id.controller_record));
+ ViewInteraction trackControllerRecordButton = onView(withId(R.id.track_list_fab_action));
trackControllerRecordButton.perform(click());
}
{
// TrackRecordingActivity
- ViewInteraction trackControllerRecordButton = onView(withId(R.id.controller_record));
- ViewInteraction trackControllerStopButton = onView(withId(R.id.controller_stop));
+ ViewInteraction trackControllerStopButton = onView(withId(R.id.track_recording_fab_action));
- // wait; stay recording
- trackControllerRecordButton.perform(waitFor(5000));
-
- //pause
- trackControllerRecordButton.perform(veryLongTouch(1600));
-
- // wait; stay paused
- trackControllerRecordButton.perform(waitFor(1000));
-
- // resume
- trackControllerRecordButton.perform(click());
-
- // wait; stay recording
- trackControllerRecordButton.perform(waitFor(1000));
+// // wait; stay recording
+// trackControllerRecordButton.perform(waitFor(5000));
+//
+// //pause
+// trackControllerRecordButton.perform(veryLongTouch(1600));
+//
+// // wait; stay paused
+// trackControllerRecordButton.perform(waitFor(1000));
+//
+// // resume
+// trackControllerRecordButton.perform(click());
+//
+// // wait; stay recording
+// trackControllerRecordButton.perform(waitFor(1000));
// stop;
trackControllerStopButton.perform(veryLongTouch(1600));
@@ -75,13 +74,13 @@ public class EspressoUITest {
public void record_move_through_tabs() {
{
// TrackListActivity: start recording
- ViewInteraction trackControllerRecordButton = onView(withId(R.id.controller_record));
+ ViewInteraction trackControllerRecordButton = onView(withId(R.id.track_list_fab_action));
trackControllerRecordButton.perform(click());
}
{
// TrackRecordingActivity
ViewInteraction tabLayout = onView(withId(R.id.track_detail_activity_tablayout));
- ViewInteraction trackControllerStopButton = onView(withId(R.id.controller_stop));
+ ViewInteraction trackControllerStopButton = onView(withId(R.id.track_recording_fab_action));
tabLayout.perform(selectTabAtIndex(1));
tabLayout.perform(waitFor(1000));
diff --git a/src/androidTest/java/de/dennisguse/opentracks/ui/aggregatedStatistics/EspressoAggregatedFilterTest.java b/src/androidTest/java/de/dennisguse/opentracks/ui/aggregatedStatistics/EspressoAggregatedFilterTest.java
index eaf62f0ad..410cc8c1c 100644
--- a/src/androidTest/java/de/dennisguse/opentracks/ui/aggregatedStatistics/EspressoAggregatedFilterTest.java
+++ b/src/androidTest/java/de/dennisguse/opentracks/ui/aggregatedStatistics/EspressoAggregatedFilterTest.java
@@ -59,13 +59,13 @@ public class EspressoAggregatedFilterTest {
@Test
public void espressoAggregatedFilterTest() {
// open AggregatedStatisticsActivity through toolbar's menu item
- onView(ViewMatchers.withId(R.id.toolbar)).check(matches(isDisplayed()));
- onView(withId(R.id.toolbar)).check(matches(hasDescendant(withId(R.id.track_list_aggregated_stats))));
+ onView(ViewMatchers.withId(R.id.bottom_app_bar)).check(matches(isDisplayed()));
+ onView(withId(R.id.bottom_app_bar)).check(matches(hasDescendant(withId(R.id.track_list_aggregated_stats))));
onView(withId(R.id.track_list_aggregated_stats)).perform(click());
// open FilterDialogFragment through toolbar's menu item
- onView(withId(R.id.toolbar)).check(matches(isDisplayed()));
- onView(withId(R.id.toolbar)).check(matches(hasDescendant(withId(R.id.aggregated_statistics_filter))));
+ onView(withId(R.id.bottom_app_bar)).check(matches(isDisplayed()));
+ onView(withId(R.id.bottom_app_bar)).check(matches(hasDescendant(withId(R.id.aggregated_statistics_filter))));
onView(withId(R.id.aggregated_statistics_filter)).perform(click());
// check there's a checkbox with CATEGORY text
diff --git a/src/androidTest/java/de/dennisguse/opentracks/ui/customRecordingLayout/EspressoCustomLayoutTest.java b/src/androidTest/java/de/dennisguse/opentracks/ui/customRecordingLayout/EspressoCustomLayoutTest.java
index 100fe47a1..162c9867c 100644
--- a/src/androidTest/java/de/dennisguse/opentracks/ui/customRecordingLayout/EspressoCustomLayoutTest.java
+++ b/src/androidTest/java/de/dennisguse/opentracks/ui/customRecordingLayout/EspressoCustomLayoutTest.java
@@ -41,7 +41,7 @@ public class EspressoCustomLayoutTest {
@Test
public void customLayoutTest() {
// TrackListActivity: start recording
- ViewInteraction trackControllerRecordButton = onView(ViewMatchers.withId(R.id.controller_record));
+ ViewInteraction trackControllerRecordButton = onView(ViewMatchers.withId(R.id.track_list_fab_action));
trackControllerRecordButton.perform(click());
// Get custom layout preferences and check all data fields are showed.
@@ -50,7 +50,7 @@ public class EspressoCustomLayoutTest {
onView(withId(R.id.stats_recycler_view)).check(new RecyclerViewItemCountAssertion((int) layout.getFields().stream().filter(DataField::isVisible).count()));
// stop recording
- ViewInteraction trackControllerStopButton = onView(withId(R.id.controller_stop));
+ ViewInteraction trackControllerStopButton = onView(withId(R.id.track_recording_fab_action));
trackControllerStopButton.perform(veryLongTouch(1600));
}
diff --git a/src/main/AndroidManifest.xml b/src/main/AndroidManifest.xml
index d6cd8d275..c87033f84 100644
--- a/src/main/AndroidManifest.xml
+++ b/src/main/AndroidManifest.xml
@@ -324,6 +324,7 @@ limitations under the License.
+
{
- service.getRecordingStatusObservable()
- .observe(ControllerFragment.this, this::onRecordingStatusChanged);
- service.getRecordingDataObservable()
- .observe(ControllerFragment.this, this::onTotalTimeChanged);
- };
-
- @Override
- public void onCreate(@Nullable Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- buttonDelayDuration = getResources().getInteger(R.integer.buttonDelayMillis);
-
- trackRecordingServiceConnection = new TrackRecordingServiceConnection(bindChangedCallback);
- handlerUpdateTotalTime = new Handler();
- recordingStatus = TrackRecordingService.STATUS_DEFAULT;
- }
-
- @Nullable
- @Override
- public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
- viewBinding = ControllerFragmentBinding.inflate(inflater, container, false);
-
- viewBinding.controllerRecord.setOnTouchListener(this);
- viewBinding.controllerRecord.setOnClickListener((view) -> {
- if (buttonDelay != null || recordingStatus.isRecordingAndNotPaused()) {
- return;
- }
-
- Callback callback = (Callback) getContext();
- if (callback != null) {
- callback.recordStart();
- }
- });
-
- viewBinding.controllerStop.setOnTouchListener(this);
- transition = (TransitionDrawable) viewBinding.controllerContainer.getBackground();
-
- onRecordingStatusChanged(recordingStatus);
-
- return viewBinding.getRoot();
- }
-
- @Override
- public void onResume() {
- super.onResume();
- trackRecordingServiceConnection.startConnection(getContext());
- }
-
- @Override
- public void onPause() {
- super.onPause();
- handlerUpdateTotalTime.removeCallbacksAndMessages(null);
- }
-
- @Override
- public void onStop() {
- super.onStop();
- trackRecordingServiceConnection.unbind(getContext());
- }
-
- @Override
- public void onDestroyView() {
- super.onDestroyView();
- viewBinding = null;
- transition = null;
- }
-
- @Override
- public void onDestroy() {
- super.onDestroy();
- trackRecordingServiceConnection = null;
- handlerUpdateTotalTime = null;
- recordingStatus = null;
- }
-
- //TODO Move into a separate object
- @SuppressLint("ClickableViewAccessibility") //We do accessibility manually.
- @Override
- public boolean onTouch(final View view, MotionEvent event) {
- if (!isResumed()) {
- Log.w(TAG, "The UI is already gone, no need to update anything; seen on Android 7.1.2");
- return false;
- }
- if (event.getAction() == MotionEvent.ACTION_MOVE) {
- return false;
- }
-
- if (buttonDelay != null && event.getAction() == MotionEvent.ACTION_UP) {
- handlerUpdateTotalTime.removeCallbacks(buttonDelay);
- buttonDelay = null;
- view.setPressed(false);
-
- transition.resetTransition();
-
- showStatusSetDefaultText();
-
- return false;
- }
-
- //Trigger button pressed animation
- view.setPressed(true);
-
- //To pause a recording
- if (viewBinding.controllerRecord.equals(view)
- && event.getAction() == MotionEvent.ACTION_DOWN
- && recordingStatus.isRecordingAndNotPaused()) {
-
- transition.startTransition(buttonDelayDuration);
-
- ActivityUtils.vibrate(getContext(), 150);
- viewBinding.controllerStatus.setText(R.string.hold_to_pause);
-
- buttonDelay = () -> {
- view.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
- view.performClick();
- Callback callback = (Callback) getContext();
- if (callback != null) {
- callback.recordPause();
- }
-
- transition.resetTransition();
-
- ActivityUtils.vibrate(getContext(), 1000);
- };
- handlerUpdateTotalTime.postDelayed(buttonDelay, buttonDelayDuration);
- return true;
- }
-
- //To stop a recording
- if (viewBinding.controllerStop.equals(view)
- && event.getAction() == MotionEvent.ACTION_DOWN
- && recordingStatus.isRecording()) {
-
-
- transition.startTransition(buttonDelayDuration);
-
- ActivityUtils.vibrate(getContext(), 150);
- viewBinding.controllerStatus.setText(R.string.hold_to_stop);
-
- buttonDelay = () -> {
- view.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
- Context context = getContext();
- Callback callback = (Callback) context;
- if (callback != null) {
- callback.recordStop();
- ActivityUtils.vibrate(context, 1000);
- }
-
- transition.resetTransition();
- };
- handlerUpdateTotalTime.postDelayed(buttonDelay, buttonDelayDuration);
- return true;
- }
-
- return false;
- }
-
- public void hide() {
- viewBinding.controllerContainer.setVisibility(View.GONE);
- }
-
- public void show() {
- viewBinding.controllerContainer.setVisibility(View.VISIBLE);
- }
-
- private void showStatusSetDefaultText() {
- viewBinding.controllerStatus.setText(recordingStatus.isPaused() ? R.string.generic_paused : R.string.generic_recording);
- }
-
- public interface Callback {
- void recordStart();
-
- void recordPause();
-
- void recordStop();
- }
-
- private void onRecordingStatusChanged(RecordingStatus status) {
- recordingStatus = status;
-
- viewBinding.controllerRecord.setImageResource(recordingStatus.isRecordingAndNotPaused() ? R.drawable.ic_button_pause : R.drawable.button_record);
- viewBinding.controllerRecord.setContentDescription(getContext().getString(recordingStatus.isRecordingAndNotPaused() ? R.string.image_pause : R.string.image_record));
-
- viewBinding.controllerStop.setEnabled(recordingStatus.isRecording());
-
- viewBinding.controllerStatus.setVisibility(recordingStatus.isRecording() ? View.VISIBLE : View.INVISIBLE);
- if (recordingStatus.isRecording()) {
- viewBinding.controllerStatus.setTextColor(getContext().getResources().getColor(recordingStatus.isPaused() ? android.R.color.white : R.color.recording_text));
- showStatusSetDefaultText();
- }
-
- viewBinding.controllerTotalTime.setVisibility(recordingStatus.isRecording() ? View.VISIBLE : View.INVISIBLE);
- }
-
- private void onTotalTimeChanged(RecordingData recordingData) {
- this.recordingData = recordingData;
-
- viewBinding.controllerTotalTime.setText(StringUtils.formatElapsedTimeWithHour(this.recordingData.getTrackStatistics().getTotalTime()));
- }
-}
diff --git a/src/main/java/de/dennisguse/opentracks/HelpActivity.java b/src/main/java/de/dennisguse/opentracks/HelpActivity.java
index 5710f7b21..c6be03390 100644
--- a/src/main/java/de/dennisguse/opentracks/HelpActivity.java
+++ b/src/main/java/de/dennisguse/opentracks/HelpActivity.java
@@ -10,14 +10,18 @@ import de.dennisguse.opentracks.ui.util.ViewUtils;
public class HelpActivity extends AbstractActivity {
+ private HelpBinding helpBinding;
+
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+ setSupportActionBar(helpBinding.bottomAppBarLayout.bottomAppBar);
ViewUtils.makeClickableLinks(findViewById(android.R.id.content));
}
@Override
protected View getRootView() {
- return HelpBinding.inflate(getLayoutInflater()).getRoot();
+ helpBinding = HelpBinding.inflate(getLayoutInflater());
+ return helpBinding.getRoot();
}
}
diff --git a/src/main/java/de/dennisguse/opentracks/TrackEditActivity.java b/src/main/java/de/dennisguse/opentracks/TrackEditActivity.java
index 395efe0e8..17fed559d 100644
--- a/src/main/java/de/dennisguse/opentracks/TrackEditActivity.java
+++ b/src/main/java/de/dennisguse/opentracks/TrackEditActivity.java
@@ -71,17 +71,17 @@ public class TrackEditActivity extends AbstractActivity implements ChooseActivit
return;
}
- viewBinding.trackEditName.setText(track.getName());
+ viewBinding.fields.trackEditName.setText(track.getName());
- viewBinding.trackEditActivityType.setText(track.getCategory());
+ viewBinding.fields.trackEditActivityType.setText(track.getCategory());
ArrayAdapter adapter = ArrayAdapter.createFromResource(this, R.array.activity_types, android.R.layout.simple_dropdown_item_1line);
- viewBinding.trackEditActivityType.setAdapter(adapter);
- viewBinding.trackEditActivityType.setOnItemClickListener((parent, view, position, id) -> setActivityTypeIcon(TrackIconUtils.getIconValue(this, (String) viewBinding.trackEditActivityType.getAdapter().getItem(position))));
- viewBinding.trackEditActivityType.setOnFocusChangeListener((v, hasFocus) -> {
+ viewBinding.fields.trackEditActivityType.setAdapter(adapter);
+ viewBinding.fields.trackEditActivityType.setOnItemClickListener((parent, view, position, id) -> setActivityTypeIcon(TrackIconUtils.getIconValue(this, (String) viewBinding.fields.trackEditActivityType.getAdapter().getItem(position))));
+ viewBinding.fields.trackEditActivityType.setOnFocusChangeListener((v, hasFocus) -> {
if (!hasFocus) {
setActivityTypeIcon(TrackIconUtils.getIconValue(
- TrackEditActivity.this, viewBinding.trackEditActivityType.getText().toString()));
+ TrackEditActivity.this, viewBinding.fields.trackEditActivityType.getText().toString()));
}
});
@@ -94,22 +94,23 @@ public class TrackEditActivity extends AbstractActivity implements ChooseActivit
}
setActivityTypeIcon(iconValue);
- viewBinding.trackEditActivityTypeIcon.setOnClickListener(v -> ChooseActivityTypeDialogFragment.showDialog(getSupportFragmentManager(), viewBinding.trackEditActivityType.getText().toString()));
+ viewBinding.fields.trackEditActivityTypeIcon.setOnClickListener(v -> ChooseActivityTypeDialogFragment.showDialog(getSupportFragmentManager(), viewBinding.fields.trackEditActivityType.getText().toString()));
- viewBinding.trackEditDescription.setText(track.getDescription());
+ viewBinding.fields.trackEditDescription.setText(track.getDescription());
viewBinding.trackEditSave.setOnClickListener(v -> {
- TrackUtils.updateTrack(TrackEditActivity.this, track, viewBinding.trackEditName.getText().toString(),
- viewBinding.trackEditActivityType.getText().toString(), viewBinding.trackEditDescription.getText().toString(),
+ TrackUtils.updateTrack(TrackEditActivity.this, track, viewBinding.fields.trackEditName.getText().toString(),
+ viewBinding.fields.trackEditActivityType.getText().toString(), viewBinding.fields.trackEditDescription.getText().toString(),
contentProviderUtils);
finish();
});
- setTitle(R.string.menu_edit);
viewBinding.trackEditCancel.setOnClickListener(v -> finish());
viewBinding.trackEditCancel.setVisibility(View.VISIBLE);
- }
+ viewBinding.bottomAppBarLayout.bottomAppBarTitle.setText(getString(R.string.menu_edit));
+ setSupportActionBar(viewBinding.bottomAppBarLayout.bottomAppBar);
+ }
@Override
protected void onStart() {
@@ -137,12 +138,12 @@ public class TrackEditActivity extends AbstractActivity implements ChooseActivit
private void setActivityTypeIcon(String iconValue) {
this.iconValue = iconValue;
- viewBinding.trackEditActivityTypeIcon.setImageResource(TrackIconUtils.getIconDrawable(iconValue));
+ viewBinding.fields.trackEditActivityTypeIcon.setImageResource(TrackIconUtils.getIconDrawable(iconValue));
}
@Override
public void onChooseActivityTypeDone(String value) {
setActivityTypeIcon(value);
- viewBinding.trackEditActivityType.setText(getString(TrackIconUtils.getIconActivityType(value)));
+ viewBinding.fields.trackEditActivityType.setText(getString(TrackIconUtils.getIconActivityType(value)));
}
}
diff --git a/src/main/java/de/dennisguse/opentracks/TrackListActivity.java b/src/main/java/de/dennisguse/opentracks/TrackListActivity.java
index e898227fa..1e1c4382e 100644
--- a/src/main/java/de/dennisguse/opentracks/TrackListActivity.java
+++ b/src/main/java/de/dennisguse/opentracks/TrackListActivity.java
@@ -22,20 +22,23 @@ import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.database.Cursor;
+import android.graphics.Color;
import android.graphics.drawable.AnimatedVectorDrawable;
import android.location.LocationManager;
import android.os.Bundle;
+import android.os.Vibrator;
import android.provider.Settings;
import android.util.Pair;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
+import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.SearchView;
-import androidx.appcompat.widget.Toolbar;
+import androidx.core.content.ContextCompat;
import androidx.cursoradapter.widget.ResourceCursorAdapter;
import androidx.loader.app.LoaderManager;
import androidx.loader.content.CursorLoader;
@@ -76,7 +79,7 @@ import de.dennisguse.opentracks.util.TrackIconUtils;
*
* @author Leif Hendrik Wilden
*/
-public class TrackListActivity extends AbstractTrackDeleteActivity implements ConfirmDeleteDialogFragment.ConfirmDeleteCaller, ControllerFragment.Callback {
+public class TrackListActivity extends AbstractTrackDeleteActivity implements ConfirmDeleteDialogFragment.ConfirmDeleteCaller {
private static final String TAG = TrackListActivity.class.getSimpleName();
@@ -101,6 +104,9 @@ public class TrackListActivity extends AbstractTrackDeleteActivity implements Co
public void onPrepare(Menu menu, int[] positions, long[] trackIds, boolean showSelectAll) {
boolean isSingleSelection = trackIds.length == 1;
+ viewBinding.bottomAppBar.performHide(true);
+ viewBinding.trackListFabAction.setVisibility(View.INVISIBLE);
+
menu.findItem(R.id.list_context_menu_edit).setVisible(isSingleSelection);
menu.findItem(R.id.list_context_menu_select_all).setVisible(showSelectAll);
}
@@ -109,6 +115,12 @@ public class TrackListActivity extends AbstractTrackDeleteActivity implements Co
public boolean onClick(int itemId, int[] positions, long[] trackIds) {
return handleContextItem(itemId, trackIds);
}
+
+ @Override
+ public void onDestroy() {
+ viewBinding.trackListFabAction.setVisibility(View.VISIBLE);
+ viewBinding.bottomAppBar.performShow(true);
+ }
};
private final OnSharedPreferenceChangeListener sharedPreferenceChangeListener = (sharedPreferences, key) -> {
@@ -201,7 +213,7 @@ public class TrackListActivity extends AbstractTrackDeleteActivity implements Co
String category = icon != null && !icon.equals("") ? null : cursor.getString(categoryIndex);
String description = cursor.getString(descriptionIndex);
- ListItemUtils.setListItem(TrackListActivity.this, view, isRecording, recordingStatus.isPaused(),
+ ListItemUtils.setListItem(TrackListActivity.this, view, isRecording,
iconId, R.string.image_track, name, totalTime, totalDistance, markerCount,
OffsetDateTime.ofInstant(Instant.ofEpochMilli(startTime), ZoneOffset.ofTotalSeconds(startTimeOffset)),
category, description, false);
@@ -210,13 +222,34 @@ public class TrackListActivity extends AbstractTrackDeleteActivity implements Co
viewBinding.trackList.setAdapter(resourceCursorAdapter);
ActivityUtils.configureListViewContextualMenu(viewBinding.trackList, contextualActionModeCallback);
- loadData(getIntent());
- }
+ viewBinding.trackListFabAction.setOnClickListener((view) -> {
+ if (recordingStatus.isRecording()) {
+ Toast.makeText(TrackListActivity.this, getString(R.string.hold_to_stop), Toast.LENGTH_LONG).show();
+ return;
+ }
- @Override
- protected void setupActionBarBack(Toolbar toolbar) {
- setSupportActionBar(toolbar);
- toolbar.setNavigationIcon(R.drawable.ic_logo_color_24dp);
+ // Not Recording -> Recording
+ updateGpsMenuItem(false, true);
+ Intent newIntent = IntentUtils.newIntent(TrackListActivity.this, TrackRecordingActivity.class);
+ startActivity(newIntent);
+ });
+ viewBinding.trackListFabAction.setOnLongClickListener((view) -> {
+ if (!recordingStatus.isRecording()) {
+ return false;
+ }
+
+ // Recording -> Stop
+ ((Vibrator) getSystemService(Context.VIBRATOR_SERVICE)).vibrate(1000);
+ updateGpsMenuItem(false, false);
+ trackRecordingServiceConnection.stopRecording(TrackListActivity.this);
+ viewBinding.trackListFabAction.setImageResource(R.drawable.ic_baseline_record_24);
+ viewBinding.trackListFabAction.setBackgroundTintList(ContextCompat.getColorStateList(this, R.color.red_dark));
+ return true;
+ });
+
+ setSupportActionBar(viewBinding.bottomAppBar);
+
+ loadData(getIntent());
}
@Override
@@ -234,6 +267,9 @@ public class TrackListActivity extends AbstractTrackDeleteActivity implements Co
// Update UI
this.invalidateOptionsMenu();
LoaderManager.getInstance(this).restartLoader(0, null, loaderCallbacks);
+
+ // Float button
+ setFloatButton();
}
@Override
@@ -263,6 +299,13 @@ public class TrackListActivity extends AbstractTrackDeleteActivity implements Co
searchMenuItem = menu.findItem(R.id.track_list_search);
SearchView searchView = ActivityUtils.configureSearchWidget(this, searchMenuItem);
+
+ searchView.findViewById(R.id.search_edit_frame).setPadding(0, 0, 48, 0);
+
+ SearchView.SearchAutoComplete searchAutoComplete = searchView.findViewById(R.id.search_src_text);
+ searchAutoComplete.setHintTextColor(getResources().getColor(android.R.color.white));
+ searchAutoComplete.setTextColor(getResources().getColor(android.R.color.white));
+
searchView.setOnCloseListener(() -> {
searchView.clearFocus();
searchMenuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
@@ -515,38 +558,18 @@ public class TrackListActivity extends AbstractTrackDeleteActivity implements Co
}
}
- @Override
- public void recordStart() {
- if (recordingStatus.getTrackId() == null) {
- // Not recording -> Recording
- updateGpsMenuItem(false, true);
- Intent newIntent = IntentUtils.newIntent(TrackListActivity.this, TrackRecordingActivity.class);
- startActivity(newIntent);
- } else if (recordingStatus.isPaused()) {
- // Paused -> Resume
- updateGpsMenuItem(false, true);
- trackRecordingServiceConnection.resumeTrack();
- }
- }
-
- @Override
- public void recordPause() {
- updateGpsMenuItem(false, true);
- trackRecordingServiceConnection.pauseTrack();
- }
-
- @Override
- public void recordStop() {
- updateGpsMenuItem(false, false);
- trackRecordingServiceConnection.stopRecording(TrackListActivity.this);
- }
-
public void onGpsStatusChanged(GpsStatusValue newStatus) {
gpsStatusValue = newStatus;
updateGpsMenuItem(true, recordingStatus.isRecording());
}
+ private void setFloatButton() {
+ viewBinding.trackListFabAction.setImageResource(recordingStatus.isRecording() ? R.drawable.ic_baseline_stop_24 : R.drawable.ic_baseline_record_24);
+ viewBinding.trackListFabAction.setBackgroundTintList(ContextCompat.getColorStateList(this, recordingStatus.isRecording() ? R.color.opentracks_secondary_color : R.color.red_dark));
+ }
+
private void onRecordingStatusChanged(RecordingStatus status) {
recordingStatus = status;
+ setFloatButton();
}
}
diff --git a/src/main/java/de/dennisguse/opentracks/TrackRecordedActivity.java b/src/main/java/de/dennisguse/opentracks/TrackRecordedActivity.java
index a4c0050a7..c0526bbed 100644
--- a/src/main/java/de/dennisguse/opentracks/TrackRecordedActivity.java
+++ b/src/main/java/de/dennisguse/opentracks/TrackRecordedActivity.java
@@ -102,6 +102,11 @@ public class TrackRecordedActivity extends AbstractTrackDeleteActivity implement
trackRecordingServiceConnection = new TrackRecordingServiceConnection(bindCallback);
+ Track track = contentProviderUtils.getTrack(trackId);
+ viewBinding.bottomAppBarLayout.bottomAppBarTitle.setText(track != null ? track.getName() : "");
+ viewBinding.bottomAppBarLayout.bottomAppBar.replaceMenu(R.menu.track_detail);
+ setSupportActionBar(viewBinding.bottomAppBarLayout.bottomAppBar);
+
postponeEnterTransition();
}
@@ -162,8 +167,6 @@ public class TrackRecordedActivity extends AbstractTrackDeleteActivity implement
public boolean onPrepareOptionsMenu(Menu menu) {
menu.findItem(R.id.track_detail_markers).setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
menu.findItem(R.id.track_detail_resume_track).setVisible(!recordingStatus.isRecording());
- Track track = contentProviderUtils.getTrack(trackId);
- setTitle(track != null ? track.getName() : "");
return super.onPrepareOptionsMenu(menu);
}
@@ -246,7 +249,7 @@ public class TrackRecordedActivity extends AbstractTrackDeleteActivity implement
private void handleIntent(Intent intent) {
trackId = intent.getParcelableExtra(EXTRA_TRACK_ID);
if (trackId == null) {
- Log.e(TAG, "TrackDetailActivity needs EXTRA_TRACK_ID.");
+ Log.e(TAG, TrackRecordedActivity.class.getSimpleName() + " needs EXTRA_TRACK_ID.");
finish();
}
}
diff --git a/src/main/java/de/dennisguse/opentracks/TrackRecordingActivity.java b/src/main/java/de/dennisguse/opentracks/TrackRecordingActivity.java
index dda1691c8..b64bf85be 100644
--- a/src/main/java/de/dennisguse/opentracks/TrackRecordingActivity.java
+++ b/src/main/java/de/dennisguse/opentracks/TrackRecordingActivity.java
@@ -2,10 +2,12 @@ package de.dennisguse.opentracks;
import android.Manifest;
import android.app.AlertDialog;
+import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.os.Build;
import android.os.Bundle;
+import android.os.Vibrator;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
@@ -16,6 +18,7 @@ import android.widget.Toast;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.NonNull;
+import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.viewpager2.adapter.FragmentStateAdapter;
@@ -56,7 +59,7 @@ import de.dennisguse.opentracks.util.TrackUtils;
*/
//NOTE: This activity does NOT react to preference changes of R.string.recording_track_id_key.
//This mode of communication should be removed anyhow.
-public class TrackRecordingActivity extends AbstractActivity implements ChooseActivityTypeDialogFragment.ChooseActivityTypeCaller, TrackDataHubInterface, ControllerFragment.Callback {
+public class TrackRecordingActivity extends AbstractActivity implements ChooseActivityTypeDialogFragment.ChooseActivityTypeCaller, TrackDataHubInterface {
public static final String EXTRA_TRACK_ID = "track_id";
@@ -116,9 +119,6 @@ public class TrackRecordingActivity extends AbstractActivity implements ChooseAc
runOnUiThread(TrackRecordingActivity.this::invalidateOptionsMenu); //TODO Should not be necessary
};
- private MenuItem insertMarkerMenuItem;
- private MenuItem markerListMenuItem;
-
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -148,6 +148,26 @@ public class TrackRecordingActivity extends AbstractActivity implements ChooseAc
}
requestGPSPermissions();
+
+ viewBinding.trackRecordingFabAction.setImageResource(R.drawable.ic_baseline_stop_24);
+ viewBinding.trackRecordingFabAction.setBackgroundTintList(ContextCompat.getColorStateList(this, R.color.opentracks_secondary_color));
+ viewBinding.trackRecordingFabAction.setBackgroundColor(getResources().getColor(R.color.opentracks_secondary_color));
+ viewBinding.trackRecordingFabAction.setOnLongClickListener((view) -> {
+ ((Vibrator) getSystemService(Context.VIBRATOR_SERVICE)).vibrate(1000);
+ trackRecordingServiceConnection.stopRecording(TrackRecordingActivity.this);
+ Intent newIntent = IntentUtils.newIntent(TrackRecordingActivity.this, TrackStoppedActivity.class)
+ .putExtra(TrackStoppedActivity.EXTRA_TRACK_ID, trackId);
+ startActivity(newIntent);
+ overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);
+ finish();
+ return true;
+ });
+ viewBinding.trackRecordingFabAction.setOnClickListener((view) -> {
+ Toast.makeText(TrackRecordingActivity.this, getString(R.string.hold_to_stop), Toast.LENGTH_LONG).show();
+ });
+
+ viewBinding.bottomAppBar.setNavigationIcon(R.drawable.ic_baseline_arrow_back_24);
+ setSupportActionBar(viewBinding.bottomAppBar);
}
@Override
@@ -247,19 +267,9 @@ public class TrackRecordingActivity extends AbstractActivity implements ChooseAc
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.track_record, menu);
-
- insertMarkerMenuItem = menu.findItem(R.id.track_detail_insert_marker);
- markerListMenuItem = menu.findItem(R.id.track_detail_markers);
-
return super.onCreateOptionsMenu(menu);
}
- @Override
- public boolean onPrepareOptionsMenu(Menu menu) {
- updateMenuItems(recordingStatus.isPaused());
- return super.onPrepareOptionsMenu(menu);
- }
-
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.track_detail_menu_show_on_map) {
@@ -315,15 +325,6 @@ public class TrackRecordingActivity extends AbstractActivity implements ChooseAc
return trackDataHub;
}
- /**
- * Updates the menu items.
- */
- private void updateMenuItems(boolean isPaused) {
- insertMarkerMenuItem.setVisible(!isPaused);
- markerListMenuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
- setTitle(getString(isPaused ? R.string.generic_paused : R.string.generic_recording));
- }
-
@Override
public void onChooseActivityTypeDone(String iconValue) {
Track track = contentProviderUtils.getTrack(trackId);
@@ -331,29 +332,6 @@ public class TrackRecordingActivity extends AbstractActivity implements ChooseAc
TrackUtils.updateTrack(this, track, null, category, null, contentProviderUtils);
}
- @Override
- public void recordStart() {
- updateMenuItems(false);
- trackRecordingServiceConnection.resumeTrack();
- }
-
- @Override
- public void recordPause() {
- updateMenuItems(true);
- trackRecordingServiceConnection.pauseTrack();
- }
-
- @Override
- public void recordStop() {
- trackRecordingServiceConnection.stopRecording(TrackRecordingActivity.this);
- Intent newIntent = IntentUtils.newIntent(TrackRecordingActivity.this, TrackRecordedActivity.class)
- .putExtra(TrackRecordedActivity.EXTRA_TRACK_ID, trackId);
- startActivity(newIntent);
- overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);
- updateMenuItems(true);
- finish();
- }
-
private class CustomFragmentPagerAdapter extends FragmentStateAdapter {
public CustomFragmentPagerAdapter(@NonNull FragmentActivity fa) {
diff --git a/src/main/java/de/dennisguse/opentracks/TrackStoppedActivity.java b/src/main/java/de/dennisguse/opentracks/TrackStoppedActivity.java
new file mode 100644
index 000000000..43f376659
--- /dev/null
+++ b/src/main/java/de/dennisguse/opentracks/TrackStoppedActivity.java
@@ -0,0 +1,131 @@
+package de.dennisguse.opentracks;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.util.Log;
+import android.util.Pair;
+import android.view.View;
+import android.widget.ArrayAdapter;
+
+import de.dennisguse.opentracks.data.ContentProviderUtils;
+import de.dennisguse.opentracks.data.models.DistanceFormatter;
+import de.dennisguse.opentracks.data.models.SpeedFormatter;
+import de.dennisguse.opentracks.data.models.Track;
+import de.dennisguse.opentracks.databinding.TrackStoppedBinding;
+import de.dennisguse.opentracks.fragments.ChooseActivityTypeDialogFragment;
+import de.dennisguse.opentracks.settings.PreferencesUtils;
+import de.dennisguse.opentracks.util.ExportUtils;
+import de.dennisguse.opentracks.util.IntentUtils;
+import de.dennisguse.opentracks.util.StringUtils;
+import de.dennisguse.opentracks.util.TrackIconUtils;
+import de.dennisguse.opentracks.util.TrackUtils;
+
+public class TrackStoppedActivity extends AbstractActivity implements ChooseActivityTypeDialogFragment.ChooseActivityTypeCaller {
+
+ private static final String TAG = TrackStoppedActivity.class.getSimpleName();
+
+ public static final String EXTRA_TRACK_ID = "track_id";
+
+ private TrackStoppedBinding viewBinding;
+
+ private Track.Id trackId;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ trackId = getIntent().getParcelableExtra(EXTRA_TRACK_ID);
+ if (trackId == null) {
+ Log.e(TAG, "TrackStoppedActivity needs EXTRA_TRACK_ID.");
+ finish();
+ }
+
+ ContentProviderUtils contentProviderUtils = new ContentProviderUtils(this);
+ Track track = contentProviderUtils.getTrack(trackId);
+
+ viewBinding.fields.trackEditName.setText(track.getName());
+
+ viewBinding.fields.trackEditActivityType.setText(track.getCategory());
+
+ ArrayAdapter adapter = ArrayAdapter.createFromResource(this, R.array.activity_types, android.R.layout.simple_dropdown_item_1line);
+ viewBinding.fields.trackEditActivityType.setAdapter(adapter);
+ viewBinding.fields.trackEditActivityType.setOnItemClickListener((parent, view, position, id) -> setActivityTypeIcon(TrackIconUtils.getIconValue(this, (String) viewBinding.fields.trackEditActivityType.getAdapter().getItem(position))));
+ viewBinding.fields.trackEditActivityType.setOnFocusChangeListener((v, hasFocus) -> {
+ if (!hasFocus) {
+ setActivityTypeIcon(TrackIconUtils.getIconValue(
+ TrackStoppedActivity.this, viewBinding.fields.trackEditActivityType.getText().toString()));
+ }
+ });
+
+ String iconValue = track.getIcon();
+
+ setActivityTypeIcon(iconValue);
+ viewBinding.fields.trackEditActivityTypeIcon.setOnClickListener(v -> ChooseActivityTypeDialogFragment.showDialog(getSupportFragmentManager(), viewBinding.fields.trackEditActivityType.getText().toString()));
+
+ viewBinding.fields.trackEditDescription.setText(track.getDescription());
+
+ viewBinding.time.setText(StringUtils.formatElapsedTime(track.getTrackStatistics().getMovingTime()));
+
+ {
+ Pair parts = SpeedFormatter.Builder()
+ .setUnit(PreferencesUtils.getUnitSystem())
+ .setReportSpeedOrPace(PreferencesUtils.isReportSpeed(track.getCategory()))
+ .build(this)
+ .getSpeedParts(track.getTrackStatistics().getAverageMovingSpeed());
+ viewBinding.speed.setText(parts.first);
+ viewBinding.speedUnit.setText(parts.second);
+ }
+
+ {
+ Pair parts = DistanceFormatter.Builder()
+ .setUnit(PreferencesUtils.getUnitSystem())
+ .build(this)
+ .getDistanceParts(track.getTrackStatistics().getTotalDistance());
+ viewBinding.distance.setText(parts.first);
+ viewBinding.distanceUnit.setText(parts.second);
+ }
+
+ viewBinding.finishButton.setOnClickListener(v -> {
+ TrackUtils.updateTrack(TrackStoppedActivity.this, track, viewBinding.fields.trackEditName.getText().toString(),
+ viewBinding.fields.trackEditActivityType.getText().toString(), viewBinding.fields.trackEditDescription.getText().toString(),
+ contentProviderUtils);
+ ExportUtils.postWorkoutExport(this, trackId);
+ finish();
+ });
+
+ viewBinding.resumeButton.setOnClickListener(v -> {
+ resume();
+ finish();
+ });
+ }
+
+ @Override
+ public void onBackPressed() {
+ super.onBackPressed();
+ resume();
+ finish();
+ }
+
+ @Override
+ protected View getRootView() {
+ viewBinding = TrackStoppedBinding.inflate(getLayoutInflater());
+ return viewBinding.getRoot();
+ }
+
+ private void setActivityTypeIcon(String iconValue) {
+ viewBinding.fields.trackEditActivityTypeIcon.setImageResource(TrackIconUtils.getIconDrawable(iconValue));
+ }
+
+ @Override
+ public void onChooseActivityTypeDone(String iconValue) {
+ setActivityTypeIcon(iconValue);
+ viewBinding.fields.trackEditActivityType.setText(getString(TrackIconUtils.getIconActivityType(iconValue)));
+ }
+
+ private void resume() {
+ Intent newIntent = IntentUtils.newIntent(TrackStoppedActivity.this, TrackRecordingActivity.class)
+ .putExtra(TrackRecordingActivity.EXTRA_TRACK_ID, trackId);
+ startActivity(newIntent);
+ overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/de/dennisguse/opentracks/io/file/exporter/ExportActivity.java b/src/main/java/de/dennisguse/opentracks/io/file/exporter/ExportActivity.java
index 37ec75b44..9760093d0 100644
--- a/src/main/java/de/dennisguse/opentracks/io/file/exporter/ExportActivity.java
+++ b/src/main/java/de/dennisguse/opentracks/io/file/exporter/ExportActivity.java
@@ -37,7 +37,6 @@ import de.dennisguse.opentracks.data.ContentProviderUtils;
import de.dennisguse.opentracks.data.models.Track;
import de.dennisguse.opentracks.data.tables.TracksColumns;
import de.dennisguse.opentracks.databinding.ExportActivityBinding;
-import de.dennisguse.opentracks.databinding.ToolbarBinding;
import de.dennisguse.opentracks.io.file.ErrorListDialog;
import de.dennisguse.opentracks.io.file.TrackFileFormat;
import de.dennisguse.opentracks.util.ExportUtils;
@@ -135,7 +134,6 @@ public class ExportActivity extends FragmentActivity implements ExportServiceRes
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
viewBinding = ExportActivityBinding.inflate(getLayoutInflater());
- ToolbarBinding mergedBinding = ToolbarBinding.bind(viewBinding.getRoot());
setContentView(viewBinding.getRoot());
directoryUri = getIntent().getParcelableExtra(EXTRA_DIRECTORY_URI_KEY);
@@ -146,8 +144,6 @@ public class ExportActivity extends FragmentActivity implements ExportServiceRes
DocumentFile documentFile = DocumentFile.fromTreeUri(this, directoryUri);
String directoryDisplayName = FileUtils.getPath(documentFile);
- mergedBinding.toolbar.setTitle(getString(R.string.export_progress_message, directoryDisplayName));
-
resultReceiver = new ExportServiceResultReceiver(new Handler(), this);
if (savedInstanceState == null) {
@@ -170,6 +166,9 @@ public class ExportActivity extends FragmentActivity implements ExportServiceRes
setProgress();
initExport(getTotalDone());
}
+
+ viewBinding.bottomAppBarLayout.bottomAppBarTitle.setText(getString(R.string.export_progress_message, directoryDisplayName));
+ viewBinding.bottomAppBarLayout.bottomAppBar.setNavigationIcon(R.drawable.ic_logo_color_24dp);
}
@Override
diff --git a/src/main/java/de/dennisguse/opentracks/io/file/importer/ImportActivity.java b/src/main/java/de/dennisguse/opentracks/io/file/importer/ImportActivity.java
index 834e782db..a47b4edc0 100644
--- a/src/main/java/de/dennisguse/opentracks/io/file/importer/ImportActivity.java
+++ b/src/main/java/de/dennisguse/opentracks/io/file/importer/ImportActivity.java
@@ -25,7 +25,6 @@ import android.view.View;
import android.widget.Toast;
import androidx.annotation.NonNull;
-import androidx.appcompat.widget.Toolbar;
import androidx.core.content.ContextCompat;
import androidx.documentfile.provider.DocumentFile;
import androidx.fragment.app.FragmentActivity;
@@ -71,8 +70,6 @@ public class ImportActivity extends FragmentActivity {
viewBinding = ImportActivityBinding.inflate(getLayoutInflater());
setContentView(viewBinding.getRoot());
- Toolbar toolbar = findViewById(R.id.toolbar);
-
final Intent intent = getIntent();
final ClipData intentClipData = intent.getClipData();
@@ -106,9 +103,6 @@ public class ImportActivity extends FragmentActivity {
documentFiles = documentUris.stream().map(it -> DocumentFile.fromSingleUri(this, it)).collect(Collectors.toList());
}
- //Works for a directory, but we might have received multiple files via SEND_MULTIPLE.
- toolbar.setTitle(getString(R.string.import_progress_message, documentFiles.get(0).getName()));
-
initViews();
viewModel = new ViewModelProvider(this).get(ImportViewModel.class);
@@ -116,6 +110,10 @@ public class ImportActivity extends FragmentActivity {
summary = data;
setProgress();
});
+
+ //Works for a directory, but we might have received multiple files via SEND_MULTIPLE.
+ viewBinding.bottomAppBarLayout.bottomAppBarTitle.setText(getString(R.string.import_progress_message, documentFiles.get(0).getName()));
+ viewBinding.bottomAppBarLayout.bottomAppBar.setNavigationIcon(R.drawable.ic_logo_color_24dp);
}
@Override
diff --git a/src/main/java/de/dennisguse/opentracks/services/TrackRecordingService.java b/src/main/java/de/dennisguse/opentracks/services/TrackRecordingService.java
index dc5f15ba7..a3dcfc992 100644
--- a/src/main/java/de/dennisguse/opentracks/services/TrackRecordingService.java
+++ b/src/main/java/de/dennisguse/opentracks/services/TrackRecordingService.java
@@ -39,7 +39,6 @@ import de.dennisguse.opentracks.services.announcement.VoiceAnnouncementManager;
import de.dennisguse.opentracks.services.handlers.EGM2008CorrectionManager;
import de.dennisguse.opentracks.services.handlers.GpsStatusValue;
import de.dennisguse.opentracks.services.handlers.TrackPointCreator;
-import de.dennisguse.opentracks.util.ExportUtils;
import de.dennisguse.opentracks.util.SystemUtils;
public class TrackRecordingService extends Service implements TrackPointCreator.Callback {
@@ -235,8 +234,6 @@ public class TrackRecordingService extends Service implements TrackPointCreator.
endRecording(true);
- ExportUtils.postWorkoutExport(this, trackId);
-
stopSelf();
}
diff --git a/src/main/java/de/dennisguse/opentracks/settings/MainSettingsFragment.java b/src/main/java/de/dennisguse/opentracks/settings/MainSettingsFragment.java
index a2ff31fe9..7913f5548 100644
--- a/src/main/java/de/dennisguse/opentracks/settings/MainSettingsFragment.java
+++ b/src/main/java/de/dennisguse/opentracks/settings/MainSettingsFragment.java
@@ -68,12 +68,6 @@ public class MainSettingsFragment extends PreferenceFragmentCompat {
});
}
- @Override
- public void onStart() {
- super.onStart();
- ((SettingsActivity) getActivity()).getSupportActionBar().setTitle(R.string.menu_settings);
- }
-
@Override
public void onResume() {
super.onResume();
diff --git a/src/main/java/de/dennisguse/opentracks/settings/SettingsActivity.java b/src/main/java/de/dennisguse/opentracks/settings/SettingsActivity.java
index a0ca1bc1e..dbda503e6 100644
--- a/src/main/java/de/dennisguse/opentracks/settings/SettingsActivity.java
+++ b/src/main/java/de/dennisguse/opentracks/settings/SettingsActivity.java
@@ -10,6 +10,8 @@ import androidx.preference.PreferenceFragmentCompat;
import de.dennisguse.opentracks.AbstractActivity;
import de.dennisguse.opentracks.R;
+import de.dennisguse.opentracks.databinding.SettingsBinding;
+import de.dennisguse.opentracks.databinding.TrackRecordedBinding;
import de.dennisguse.opentracks.fragments.ChooseActivityTypeDialogFragment;
public class SettingsActivity extends AbstractActivity implements ChooseActivityTypeDialogFragment.ChooseActivityTypeCaller {
@@ -21,6 +23,8 @@ public class SettingsActivity extends AbstractActivity implements ChooseActivity
private PreferenceFragmentCompat fragment = null;
+ private SettingsBinding viewBinding;
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -37,6 +41,9 @@ public class SettingsActivity extends AbstractActivity implements ChooseActivity
fragment = new MainSettingsFragment();
}
+ viewBinding.bottomAppBarLayout.bottomAppBarTitle.setText(getString(R.string.menu_settings));
+ setSupportActionBar(viewBinding.bottomAppBarLayout.bottomAppBar);
+
getSupportFragmentManager().beginTransaction().replace(R.id.settings_fragment, fragment).commit();
}
@@ -66,7 +73,8 @@ public class SettingsActivity extends AbstractActivity implements ChooseActivity
@Override
protected View getRootView() {
- return getLayoutInflater().inflate(R.layout.settings, null);
+ viewBinding = SettingsBinding.inflate(getLayoutInflater());
+ return viewBinding.getRoot();
}
private PreferenceFragmentCompat getPreferenceScreen(String key) {
diff --git a/src/main/java/de/dennisguse/opentracks/settings/SettingsCustomLayoutEditActivity.java b/src/main/java/de/dennisguse/opentracks/settings/SettingsCustomLayoutEditActivity.java
index b1b7e03de..ffd400181 100644
--- a/src/main/java/de/dennisguse/opentracks/settings/SettingsCustomLayoutEditActivity.java
+++ b/src/main/java/de/dennisguse/opentracks/settings/SettingsCustomLayoutEditActivity.java
@@ -6,7 +6,6 @@ import android.widget.ScrollView;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
-import androidx.appcompat.widget.Toolbar;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.LinearLayoutManager;
@@ -15,12 +14,12 @@ import androidx.recyclerview.widget.RecyclerView;
import java.util.stream.IntStream;
import de.dennisguse.opentracks.AbstractActivity;
-import de.dennisguse.opentracks.ui.util.ArrayAdapterFilterDisabled;
import de.dennisguse.opentracks.R;
import de.dennisguse.opentracks.databinding.ActivitySettingsCustomLayoutBinding;
import de.dennisguse.opentracks.ui.customRecordingLayout.DataField;
import de.dennisguse.opentracks.ui.customRecordingLayout.Layout;
import de.dennisguse.opentracks.ui.customRecordingLayout.SettingsCustomLayoutEditAdapter;
+import de.dennisguse.opentracks.ui.util.ArrayAdapterFilterDisabled;
import de.dennisguse.opentracks.util.StatisticsUtils;
public class SettingsCustomLayoutEditActivity extends AbstractActivity implements SettingsCustomLayoutEditAdapter.SettingsCustomLayoutItemClickListener {
@@ -97,7 +96,8 @@ public class SettingsCustomLayoutEditActivity extends AbstractActivity implement
recyclerViewNotVisible.setLayoutManager(new LinearLayoutManager(this));
recyclerViewNotVisible.setAdapter(adapterFieldsHidden);
- setTitle(profile);
+ viewBinding.bottomAppBarLayout.bottomAppBarTitle.setText(profile);
+ setSupportActionBar(viewBinding.bottomAppBarLayout.bottomAppBar);
}
@Override
@@ -117,12 +117,6 @@ public class SettingsCustomLayoutEditActivity extends AbstractActivity implement
layoutFieldsVisible = null;
}
- @Override
- protected void setupActionBarBack(Toolbar toolbar) {
- super.setupActionBarBack(toolbar);
- toolbar.setTitle(R.string.menu_settings);
- }
-
@Override
protected View getRootView() {
viewBinding = ActivitySettingsCustomLayoutBinding.inflate(getLayoutInflater());
diff --git a/src/main/java/de/dennisguse/opentracks/settings/SettingsCustomLayoutListActivity.java b/src/main/java/de/dennisguse/opentracks/settings/SettingsCustomLayoutListActivity.java
index 905cfe30a..9acf0ef11 100644
--- a/src/main/java/de/dennisguse/opentracks/settings/SettingsCustomLayoutListActivity.java
+++ b/src/main/java/de/dennisguse/opentracks/settings/SettingsCustomLayoutListActivity.java
@@ -40,8 +40,6 @@ public class SettingsCustomLayoutListActivity extends AbstractActivity implement
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- setTitle(getString(R.string.custom_layout_list_title));
-
adapter = new SettingsCustomLayoutListAdapter(this, this);
recyclerView = viewBinding.recyclerView;
recyclerView.setLayoutManager(new LinearLayoutManager(this));
@@ -114,6 +112,9 @@ public class SettingsCustomLayoutListActivity extends AbstractActivity implement
ItemTouchHelper itemTouchhelper = new ItemTouchHelper(recyclerViewSwipeDeleteCallback);
itemTouchhelper.attachToRecyclerView(recyclerView);
+
+ viewBinding.bottomAppBarLayout.bottomAppBarTitle.setText(getString(R.string.custom_layout_list_title));
+ setSupportActionBar(viewBinding.bottomAppBarLayout.bottomAppBar);
}
@Override
diff --git a/src/main/java/de/dennisguse/opentracks/ui/aggregatedStatistics/AggregatedStatisticsActivity.java b/src/main/java/de/dennisguse/opentracks/ui/aggregatedStatistics/AggregatedStatisticsActivity.java
index d4ba978d2..5a6659ee3 100644
--- a/src/main/java/de/dennisguse/opentracks/ui/aggregatedStatistics/AggregatedStatisticsActivity.java
+++ b/src/main/java/de/dennisguse/opentracks/ui/aggregatedStatistics/AggregatedStatisticsActivity.java
@@ -60,6 +60,9 @@ public class AggregatedStatisticsActivity extends AbstractActivity implements Fi
}
adapter.notifyDataSetChanged();
});
+
+ setSupportActionBar(viewBinding.bottomAppBarLayout.bottomAppBar);
+ viewBinding.bottomAppBarLayout.bottomAppBarTitle.setText(getString(R.string.menu_aggregated_statistics));
}
@Override
diff --git a/src/main/java/de/dennisguse/opentracks/ui/markers/MarkerDetailActivity.java b/src/main/java/de/dennisguse/opentracks/ui/markers/MarkerDetailActivity.java
index 71c715779..f13c68919 100644
--- a/src/main/java/de/dennisguse/opentracks/ui/markers/MarkerDetailActivity.java
+++ b/src/main/java/de/dennisguse/opentracks/ui/markers/MarkerDetailActivity.java
@@ -105,7 +105,7 @@ public class MarkerDetailActivity extends AbstractActivity implements DeleteMark
@Override
public void onPageSelected(int position) {
- setTitle(markerAdapter.getPageTitle(position));
+ viewBinding.bottomAppBarLayout.bottomAppBarTitle.setText(markerAdapter.getPageTitle(position));
}
@Override
@@ -113,6 +113,8 @@ public class MarkerDetailActivity extends AbstractActivity implements DeleteMark
}
});
viewBinding.makerDetailActivityViewPager.setCurrentItem(markerIndex == -1 ? 0 : markerIndex);
+
+ setSupportActionBar(viewBinding.bottomAppBarLayout.bottomAppBar);
}
@Override
diff --git a/src/main/java/de/dennisguse/opentracks/ui/markers/MarkerEditActivity.java b/src/main/java/de/dennisguse/opentracks/ui/markers/MarkerEditActivity.java
index faa6d4f45..f4861c6ec 100644
--- a/src/main/java/de/dennisguse/opentracks/ui/markers/MarkerEditActivity.java
+++ b/src/main/java/de/dennisguse/opentracks/ui/markers/MarkerEditActivity.java
@@ -101,7 +101,7 @@ public class MarkerEditActivity extends AbstractActivity {
});
boolean isNewMarker = markerId == null;
- setTitle(isNewMarker ? R.string.menu_insert_marker : R.string.menu_edit);
+ viewBinding.bottomAppBarLayout.bottomAppBarTitle.setText(getString(isNewMarker ? R.string.menu_insert_marker : R.string.menu_edit));
viewBinding.markerEditDone.setText(isNewMarker ? R.string.generic_add : R.string.generic_save);
viewBinding.markerEditDone.setOnClickListener(v -> {
viewModel.onDone(viewBinding.markerEditName.getText().toString(),
@@ -150,6 +150,8 @@ public class MarkerEditActivity extends AbstractActivity {
viewBinding.markerEditDescription.getText().toString());
}
});
+
+ setSupportActionBar(viewBinding.bottomAppBarLayout.bottomAppBar);
}
@Override
diff --git a/src/main/java/de/dennisguse/opentracks/ui/markers/MarkerListActivity.java b/src/main/java/de/dennisguse/opentracks/ui/markers/MarkerListActivity.java
index 9858f8ad9..5bc0c2a85 100644
--- a/src/main/java/de/dennisguse/opentracks/ui/markers/MarkerListActivity.java
+++ b/src/main/java/de/dennisguse/opentracks/ui/markers/MarkerListActivity.java
@@ -80,6 +80,8 @@ public class MarkerListActivity extends AbstractActivity implements DeleteMarker
public void onPrepare(Menu menu, int[] positions, long[] ids, boolean showSelectAll) {
boolean isSingleSelection = ids.length == 1;
+ viewBinding.bottomAppBarLayout.bottomAppBar.performHide(true);
+
menu.findItem(R.id.list_context_menu_show_on_map).setVisible(isSingleSelection);
menu.findItem(R.id.list_context_menu_edit).setVisible(isSingleSelection);
menu.findItem(R.id.list_context_menu_delete).setVisible(true);
@@ -92,6 +94,11 @@ public class MarkerListActivity extends AbstractActivity implements DeleteMarker
public boolean onClick(int itemId, int[] positions, long[] ids) {
return handleContextItem(itemId, ids);
}
+
+ @Override
+ public void onDestroy() {
+ viewBinding.bottomAppBarLayout.bottomAppBar.performShow(true);
+ }
};
private MenuItem insertMarkerMenuItem;
private MenuItem searchMenuItem;
@@ -121,6 +128,8 @@ public class MarkerListActivity extends AbstractActivity implements DeleteMarker
ActivityUtils.configureListViewContextualMenu(viewBinding.markerList, contextualActionModeCallback);
trackRecordingServiceConnection = new TrackRecordingServiceConnection(bindCallback);
+
+ setSupportActionBar(viewBinding.bottomAppBarLayout.bottomAppBar);
}
@Override
@@ -301,9 +310,9 @@ public class MarkerListActivity extends AbstractActivity implements DeleteMarker
this.searchQuery = searchQuery;
restart();
if (searchQuery != null) {
- setTitle(searchQuery);
+ viewBinding.bottomAppBarLayout.bottomAppBarTitle.setText(searchQuery);
} else {
- setTitle(R.string.menu_markers);
+ viewBinding.bottomAppBarLayout.bottomAppBarTitle.setText(getString(R.string.menu_markers));
}
}
diff --git a/src/main/java/de/dennisguse/opentracks/ui/markers/MarkerResourceCursorAdapter.java b/src/main/java/de/dennisguse/opentracks/ui/markers/MarkerResourceCursorAdapter.java
index 05cfe57db..103aa7c10 100644
--- a/src/main/java/de/dennisguse/opentracks/ui/markers/MarkerResourceCursorAdapter.java
+++ b/src/main/java/de/dennisguse/opentracks/ui/markers/MarkerResourceCursorAdapter.java
@@ -105,7 +105,7 @@ public class MarkerResourceCursorAdapter extends ResourceCursorAdapter implement
ContentProviderUtils contentProviderUtils = new ContentProviderUtils(context);
Track track = contentProviderUtils.getTrack(new Track.Id(trackId));
- ListItemUtils.setListItem(activity, view, false, true, iconId, R.string.image_marker, name, null, null, 0,
+ ListItemUtils.setListItem(activity, view, false, iconId, R.string.image_marker, name, null, null, 0,
OffsetDateTime.ofInstant(Instant.ofEpochMilli(time), track.getZoneOffset()), category, description, hasPhoto);
}
diff --git a/src/main/java/de/dennisguse/opentracks/ui/util/ActivityUtils.java b/src/main/java/de/dennisguse/opentracks/ui/util/ActivityUtils.java
index 8a33b49ee..f68451517 100644
--- a/src/main/java/de/dennisguse/opentracks/ui/util/ActivityUtils.java
+++ b/src/main/java/de/dennisguse/opentracks/ui/util/ActivityUtils.java
@@ -45,7 +45,7 @@ public class ActivityUtils {
@Override
public void onDestroyActionMode(ActionMode mode) {
- // Do nothing
+ contextualActionModeCallback.onDestroy();
}
@Override
@@ -127,5 +127,10 @@ public class ActivityUtils {
* @param ids the selected items' ids, if available
*/
boolean onClick(int itemId, int[] positions, long[] ids);
+
+ /**
+ * Invoked when contextual action mode is destroyed.
+ */
+ void onDestroy();
}
}
diff --git a/src/main/java/de/dennisguse/opentracks/ui/util/ListItemUtils.java b/src/main/java/de/dennisguse/opentracks/ui/util/ListItemUtils.java
index 8d229ac1e..32ee8da54 100644
--- a/src/main/java/de/dennisguse/opentracks/ui/util/ListItemUtils.java
+++ b/src/main/java/de/dennisguse/opentracks/ui/util/ListItemUtils.java
@@ -44,7 +44,6 @@ public class ListItemUtils {
* @param context the context
* @param view the list item view
* @param isRecording true if recording
- * @param isPaused true if paused
* @param iconId the icon id
* @param iconContentDescriptionId the icon content description id
* @param name the name value
@@ -56,11 +55,11 @@ public class ListItemUtils {
* @param description the description value
* @param hasPhoto true if this list item has photo
*/
- public static void setListItem(Context context, View view, boolean isRecording, boolean isPaused, int iconId, int iconContentDescriptionId, String name, String totalTime, String totalDistance, int markerCount, OffsetDateTime offsetDateTime, String category, String description, boolean hasPhoto) {
+ public static void setListItem(Context context, View view, boolean isRecording, int iconId, int iconContentDescriptionId, String name, String totalTime, String totalDistance, int markerCount, OffsetDateTime offsetDateTime, String category, String description, boolean hasPhoto) {
// Set icon
if (isRecording) {
- iconId = isPaused ? R.drawable.ic_track_paused : R.drawable.ic_track_recording;
- iconContentDescriptionId = isPaused ? R.string.image_pause : R.string.image_record;
+ iconId = R.drawable.ic_track_recording;
+ iconContentDescriptionId = R.string.image_record;
}
ImageView iconImageView = view.findViewById(R.id.list_item_icon);
@@ -75,7 +74,7 @@ public class ListItemUtils {
TextView timeDistanceTextView = view.findViewById(R.id.list_item_time_distance);
String timeDistanceText;
if (isRecording) {
- timeDistanceText = context.getString(isPaused ? R.string.generic_paused : R.string.generic_recording);
+ timeDistanceText = context.getString(R.string.generic_recording);
} else {
// Match list_item_time_distance in list_item.xml
timeDistanceText = getTimeDistance(totalTime, totalDistance);
diff --git a/src/main/res/drawable/button_record.xml b/src/main/res/drawable/button_record.xml
deleted file mode 100644
index 249596b38..000000000
--- a/src/main/res/drawable/button_record.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-
-
-
-
-
\ No newline at end of file
diff --git a/src/main/res/drawable/button_stop.xml b/src/main/res/drawable/button_stop.xml
deleted file mode 100644
index a6d6ea19e..000000000
--- a/src/main/res/drawable/button_stop.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/main/res/drawable/controller_background.xml b/src/main/res/drawable/controller_background.xml
deleted file mode 100644
index c6074c9ec..000000000
--- a/src/main/res/drawable/controller_background.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/main/res/drawable/ic_baseline_arrow_back_24.xml b/src/main/res/drawable/ic_baseline_arrow_back_24.xml
new file mode 100644
index 000000000..2a31b2ef3
--- /dev/null
+++ b/src/main/res/drawable/ic_baseline_arrow_back_24.xml
@@ -0,0 +1,11 @@
+
+
+
diff --git a/src/main/res/drawable/ic_baseline_record_24.xml b/src/main/res/drawable/ic_baseline_record_24.xml
new file mode 100644
index 000000000..d19183016
--- /dev/null
+++ b/src/main/res/drawable/ic_baseline_record_24.xml
@@ -0,0 +1,10 @@
+
+
+
diff --git a/src/main/res/drawable/ic_baseline_stop_24.xml b/src/main/res/drawable/ic_baseline_stop_24.xml
new file mode 100644
index 000000000..d099f1aa0
--- /dev/null
+++ b/src/main/res/drawable/ic_baseline_stop_24.xml
@@ -0,0 +1,10 @@
+
+
+
diff --git a/src/main/res/drawable/ic_button_done.xml b/src/main/res/drawable/ic_button_done.xml
new file mode 100644
index 000000000..27bc17493
--- /dev/null
+++ b/src/main/res/drawable/ic_button_done.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
diff --git a/src/main/res/drawable/ic_button_resume.xml b/src/main/res/drawable/ic_button_resume.xml
new file mode 100644
index 000000000..c0a8db40b
--- /dev/null
+++ b/src/main/res/drawable/ic_button_resume.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
diff --git a/src/main/res/drawable/ic_logo_color_24dp.xml b/src/main/res/drawable/ic_logo_color_24dp.xml
index 863f22aaf..9a475223b 100644
--- a/src/main/res/drawable/ic_logo_color_24dp.xml
+++ b/src/main/res/drawable/ic_logo_color_24dp.xml
@@ -7,16 +7,16 @@
diff --git a/src/main/res/drawable/ic_track_paused.xml b/src/main/res/drawable/ic_track_paused.xml
deleted file mode 100644
index 27f4fc172..000000000
--- a/src/main/res/drawable/ic_track_paused.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
-
diff --git a/src/main/res/layout-land/controller_fragment.xml b/src/main/res/layout-land/controller_fragment.xml
deleted file mode 100644
index e1d0dc624..000000000
--- a/src/main/res/layout-land/controller_fragment.xml
+++ /dev/null
@@ -1,66 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/main/res/layout-land/track_list.xml b/src/main/res/layout-land/track_list.xml
deleted file mode 100644
index 1db2c980f..000000000
--- a/src/main/res/layout-land/track_list.xml
+++ /dev/null
@@ -1,100 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/main/res/layout-land/track_recording.xml b/src/main/res/layout-land/track_recording.xml
deleted file mode 100644
index 0cbac4ea0..000000000
--- a/src/main/res/layout-land/track_recording.xml
+++ /dev/null
@@ -1,47 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/main/res/layout/about.xml b/src/main/res/layout/about.xml
index 93d24ebc7..6378ce9fb 100644
--- a/src/main/res/layout/about.xml
+++ b/src/main/res/layout/about.xml
@@ -1,117 +1,125 @@
-
+ android:layout_height="match_parent">
-
-
-
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ android:paddingBottom="50dp">
-
+ android:layout_height="wrap_content">
+ android:orientation="vertical"
+ android:padding="20dp">
-
+
+
+
+
+
+
+
+
+ android:padding="6dp" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
diff --git a/src/main/res/layout/activity_settings_custom_layout.xml b/src/main/res/layout/activity_settings_custom_layout.xml
index 957a3b74c..87a2ef216 100644
--- a/src/main/res/layout/activity_settings_custom_layout.xml
+++ b/src/main/res/layout/activity_settings_custom_layout.xml
@@ -1,53 +1,61 @@
-
+ android:layout_height="match_parent">
-
-
-
+ android:layout_height="match_parent"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ android:orientation="vertical"
+ android:paddingBottom="60dp">
-
+ android:hint="@string/settings_recording_customize_layout_select_columns">
-
+
-
+
-
-
+ android:layout_height="wrap_content">
-
+
-
+
-
+
-
\ No newline at end of file
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/res/layout/activity_settings_custom_layout_list.xml b/src/main/res/layout/activity_settings_custom_layout_list.xml
index 42ae4fa97..e29de1d83 100644
--- a/src/main/res/layout/activity_settings_custom_layout_list.xml
+++ b/src/main/res/layout/activity_settings_custom_layout_list.xml
@@ -1,72 +1,80 @@
-
-
+
-
-
-
-
-
-
+ android:paddingBottom="60dp">
+ android:layout_height="wrap_content"
+ android:gravity="center_vertical"
+ android:orientation="vertical"
+ android:layout_marginBottom="50dp"
+ android:visibility="gone"
+ tools:visibility="visible">
-
+ style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
+ app:errorEnabled="true"
+ android:layout_margin="16dp">
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/src/main/res/layout/aggregated_stats.xml b/src/main/res/layout/aggregated_stats.xml
index fc3147ea6..a4aa700a4 100644
--- a/src/main/res/layout/aggregated_stats.xml
+++ b/src/main/res/layout/aggregated_stats.xml
@@ -1,23 +1,31 @@
-
+ android:layout_height="match_parent">
-
-
-
-
-
+ android:orientation="vertical"
+ android:paddingBottom="50dp">
-
\ No newline at end of file
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/res/layout/bottomappbar.xml b/src/main/res/layout/bottomappbar.xml
new file mode 100644
index 000000000..5de2aa724
--- /dev/null
+++ b/src/main/res/layout/bottomappbar.xml
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/res/layout/controller_fragment.xml b/src/main/res/layout/controller_fragment.xml
deleted file mode 100644
index 5381839d4..000000000
--- a/src/main/res/layout/controller_fragment.xml
+++ /dev/null
@@ -1,72 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/main/res/layout/export_activity.xml b/src/main/res/layout/export_activity.xml
index 554c6dd58..b2d3252cf 100644
--- a/src/main/res/layout/export_activity.xml
+++ b/src/main/res/layout/export_activity.xml
@@ -1,305 +1,312 @@
-
+ android:layout_height="match_parent">
-
-
-
+ android:layout_height="match_parent"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:orientation="vertical"
+ android:paddingBottom="50dp">
-
+ android:layout_height="0dp">
-
-
-
-
-
-
-
-
-
+ android:layout_height="match_parent">
-
-
-
+
-
+
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ tools:visibility="visible" />
-
-
-
-
-
-
-
-
+ tools:visibility="visible"/>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
\ No newline at end of file
+
+
+
\ No newline at end of file
diff --git a/src/main/res/layout/help.xml b/src/main/res/layout/help.xml
index f571327fe..95196bbb3 100644
--- a/src/main/res/layout/help.xml
+++ b/src/main/res/layout/help.xml
@@ -1,139 +1,147 @@
-
+ android:layout_height="match_parent">
-
-
-
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ android:paddingBottom="50dp">
-
+ android:layout_height="wrap_content">
-
+ android:orientation="vertical"
+ android:padding="20dp">
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
-
-
+
-
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/res/layout/import_activity.xml b/src/main/res/layout/import_activity.xml
index 166e22e40..1a3f0f6c9 100644
--- a/src/main/res/layout/import_activity.xml
+++ b/src/main/res/layout/import_activity.xml
@@ -1,249 +1,256 @@
-
+ android:layout_height="match_parent">
-
-
-
+ android:layout_height="match_parent"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:orientation="vertical"
+ android:paddingBottom="50dp">
-
+ android:layout_height="0dp">
-
-
-
-
-
-
-
-
-
+ android:layout_height="match_parent">
-
-
-
+
-
+
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ tools:visibility="visible" />
-
-
-
-
-
-
-
-
+ tools:visibility="visible"/>
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
+
+
+
\ No newline at end of file
diff --git a/src/main/res/layout/marker_detail_activity.xml b/src/main/res/layout/marker_detail_activity.xml
index 81644f86a..cee3613d4 100644
--- a/src/main/res/layout/marker_detail_activity.xml
+++ b/src/main/res/layout/marker_detail_activity.xml
@@ -13,15 +13,21 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
-
+ android:layout_height="match_parent">
-
-
-
-
\ No newline at end of file
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/res/layout/marker_edit.xml b/src/main/res/layout/marker_edit.xml
index 6538ced0e..848e6d2c8 100644
--- a/src/main/res/layout/marker_edit.xml
+++ b/src/main/res/layout/marker_edit.xml
@@ -13,124 +13,131 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
-
+ android:layout_height="match_parent">
-
+
-
+
-
-
-
+ android:orientation="vertical"
+ android:padding="8dp">
-
-
-
-
-
-
-
+ android:importantForAutofill="no"
+ android:layout_marginBottom="16dp">
-
+
-
+
-
+ style="?attr/textInputOutlinedExposedDropdownMenuStyle"
+ android:imeOptions="actionNext"
+ android:importantForAutofill="no"
+ android:layout_marginBottom="16dp">
-
+
-
+
-
+
+
+
+
+
+
+ android:layout_marginTop="16dp">
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
+
+
+
+
\ No newline at end of file
diff --git a/src/main/res/layout/marker_list.xml b/src/main/res/layout/marker_list.xml
index 46084f600..5c465cb21 100644
--- a/src/main/res/layout/marker_list.xml
+++ b/src/main/res/layout/marker_list.xml
@@ -13,24 +13,31 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
-
+ android:layout_height="match_parent">
-
-
-
-
-
+ android:orientation="vertical"
+ android:paddingBottom="50dp">
-
\ No newline at end of file
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/res/layout/settings.xml b/src/main/res/layout/settings.xml
index b770cbd04..2ec505182 100644
--- a/src/main/res/layout/settings.xml
+++ b/src/main/res/layout/settings.xml
@@ -1,14 +1,22 @@
-
+ android:layout_height="match_parent">
-
+
-
+
-
\ No newline at end of file
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/res/layout/toolbar.xml b/src/main/res/layout/toolbar.xml
deleted file mode 100644
index bacc60273..000000000
--- a/src/main/res/layout/toolbar.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
-
-
diff --git a/src/main/res/layout/track_edit.xml b/src/main/res/layout/track_edit.xml
index 52a7b6c05..45c1fc7f6 100644
--- a/src/main/res/layout/track_edit.xml
+++ b/src/main/res/layout/track_edit.xml
@@ -13,109 +13,39 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
-
+ android:layout_height="match_parent">
-
+
-
+
-
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
-
-
-
-
-
-
-
-
-
\ No newline at end of file
+
+
+
+
\ No newline at end of file
diff --git a/src/main/res/layout/track_edit_fields.xml b/src/main/res/layout/track_edit_fields.xml
new file mode 100644
index 000000000..05907831d
--- /dev/null
+++ b/src/main/res/layout/track_edit_fields.xml
@@ -0,0 +1,84 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/res/layout/track_list.xml b/src/main/res/layout/track_list.xml
index 170ddfd49..114f4fdfd 100644
--- a/src/main/res/layout/track_list.xml
+++ b/src/main/res/layout/track_list.xml
@@ -13,79 +13,94 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
-
+ xmlns:app="http://schemas.android.com/apk/res-auto">
-
-
-
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ android:paddingBottom="50dp"
+ android:clipToPadding="false">
-
-
-
+ android:layout_height="0dp"
+ android:layout_weight="0.8" />
-
-
-
-
-
-
-
-
+ android:layout_height="0dp"
+ android:layout_weight="1.2">
-
-
-
+ android:layout_alignParentBottom="true"
+ android:paddingTop="16dp"
+ android:paddingBottom="12dp">
-
-
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
\ No newline at end of file
+ android:layout_height="wrap_content"
+ android:layout_gravity="bottom"
+ app:fabAlignmentMode="end"
+ app:logo="@drawable/ic_logo_color_24dp"
+ app:menu="@menu/track_list" />
+
+
+
+
\ No newline at end of file
diff --git a/src/main/res/layout/track_recorded.xml b/src/main/res/layout/track_recorded.xml
index d4f3bb2c5..7b655408a 100644
--- a/src/main/res/layout/track_recorded.xml
+++ b/src/main/res/layout/track_recorded.xml
@@ -13,21 +13,29 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
-
+ android:layout_height="match_parent">
-
-
-
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ android:paddingBottom="70dp">
-
-
\ No newline at end of file
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/res/layout/track_recording.xml b/src/main/res/layout/track_recording.xml
index 972ac2f78..296047931 100644
--- a/src/main/res/layout/track_recording.xml
+++ b/src/main/res/layout/track_recording.xml
@@ -1,35 +1,50 @@
-
+ xmlns:app="http://schemas.android.com/apk/res-auto">
-
-
-
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ android:paddingBottom="90dp">
-
-
-
+ android:layout_height="wrap_content" />
-
+
-
+
+
+
+
+
+
+ android:layout_height="wrap_content"
+ android:layout_gravity="bottom"
+ app:fabAlignmentMode="end"
+ app:navigationIcon="@drawable/ic_logo_color_24dp"
+ app:menu="@menu/track_record" />
-
\ No newline at end of file
+
+
+
\ No newline at end of file
diff --git a/src/main/res/layout/track_stopped.xml b/src/main/res/layout/track_stopped.xml
new file mode 100644
index 000000000..a24fd06fa
--- /dev/null
+++ b/src/main/res/layout/track_stopped.xml
@@ -0,0 +1,116 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/res/values-night/themes_custom.xml b/src/main/res/values-night/themes_custom.xml
index c5cc7c4ce..58dd83cf3 100644
--- a/src/main/res/values-night/themes_custom.xml
+++ b/src/main/res/values-night/themes_custom.xml
@@ -11,8 +11,6 @@
- ?attr/colorPrimaryVariant
- - true
-
- @android:color/black
- @android:color/white
@@ -20,6 +18,26 @@
- @color/opentracks_surface_night_on_background_color
- @drawable/activated_background
+
+ - @style/Widget.OpenTracks.BottomAppBar
+
+ - @style/Widget.OpenTracks.FloatingActionButton
+
+ - true
+
+
+
+
+
+
+
+
diff --git a/src/main/res/values/colors.xml b/src/main/res/values/colors.xml
index d0f4cfb7b..6126a37de 100644
--- a/src/main/res/values/colors.xml
+++ b/src/main/res/values/colors.xml
@@ -18,8 +18,8 @@ limitations under the License.
#344955
#232f34
@android:color/white
- #ff8800
- #55ff8800
+ #FF6D00
+ #55FF6D00
@android:color/white
#f5f5f5
diff --git a/src/main/res/values/styles.xml b/src/main/res/values/styles.xml
index 90b2cef8a..913d89b6b 100644
--- a/src/main/res/values/styles.xml
+++ b/src/main/res/values/styles.xml
@@ -15,12 +15,7 @@ limitations under the License.
-->
-
-
-
-
+
+
+
+
diff --git a/src/main/res/values/type.xml b/src/main/res/values/type.xml
index da8441ebf..ecb916416 100644
--- a/src/main/res/values/type.xml
+++ b/src/main/res/values/type.xml
@@ -52,4 +52,9 @@
- ?attr/colorOnBackground
- true
+
+
\ No newline at end of file