From f3909ec3a54decb7afd4f9b71baba56fc4ad6267 Mon Sep 17 00:00:00 2001 From: y20k Date: Mon, 12 Dec 2016 18:52:01 +0100 Subject: [PATCH] saving the last track: implemented a floating action button sub menu instead of a user dialog (#2) --- app/build.gradle | 1 + .../java/org/y20k/trackbook/MainActivity.java | 208 +++++++++++++----- .../trackbook/MainActivityMapFragment.java | 26 ++- .../helpers/DialogClearFragment.java | 83 ------- .../trackbook/helpers/NotificationHelper.java | 4 - .../y20k/trackbook/helpers/TrackbookKeys.java | 4 + .../layout/DodgeAbleLayoutBehavior.java | 68 ++++++ .../main/res/drawable/ic_clear_white_24dp.xml | 9 + .../ic_fiber_manual_record_white_24dp.xml | 2 +- .../main/res/drawable/ic_save_white_24dp.xml | 9 + .../drawable/ic_track_calendar_white_24dp.xml | 9 + app/src/main/res/layout/activity_main.xml | 40 ++-- ...ty_main_test.xml => activity_main_old.xml} | 40 ++-- .../res/layout/floating_action_button.xml | 129 +++++++++++ app/src/main/res/layout/fragment_main_map.xml | 2 +- .../main/res/layout/fragment_main_track.xml | 2 - app/src/main/res/values-de/strings.xml | 10 +- app/src/main/res/values/strings.xml | 11 +- build.gradle | 2 +- 19 files changed, 451 insertions(+), 208 deletions(-) delete mode 100644 app/src/main/java/org/y20k/trackbook/helpers/DialogClearFragment.java create mode 100644 app/src/main/java/org/y20k/trackbook/layout/DodgeAbleLayoutBehavior.java create mode 100644 app/src/main/res/drawable/ic_clear_white_24dp.xml create mode 100644 app/src/main/res/drawable/ic_save_white_24dp.xml create mode 100644 app/src/main/res/drawable/ic_track_calendar_white_24dp.xml rename app/src/main/res/layout/{activity_main_test.xml => activity_main_old.xml} (58%) create mode 100644 app/src/main/res/layout/floating_action_button.xml diff --git a/app/build.gradle b/app/build.gradle index 63376ab..69bcf37 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -25,6 +25,7 @@ dependencies { testCompile 'junit:junit:4.12' compile 'com.android.support:appcompat-v7:25.0.1' compile 'com.android.support:design:25.0.1' + compile 'com.android.support:cardview-v7:25.0.1' compile 'org.osmdroid:osmdroid-android:5.5:release@aar' compile 'com.google.code.gson:gson:2.8.0' } diff --git a/app/src/main/java/org/y20k/trackbook/MainActivity.java b/app/src/main/java/org/y20k/trackbook/MainActivity.java index f6830bb..84b24f0 100644 --- a/app/src/main/java/org/y20k/trackbook/MainActivity.java +++ b/app/src/main/java/org/y20k/trackbook/MainActivity.java @@ -23,10 +23,12 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.location.Location; import android.os.Build; import android.os.Bundle; +import android.preference.PreferenceManager; import android.support.annotation.NonNull; import android.support.design.widget.FloatingActionButton; import android.support.design.widget.Snackbar; @@ -44,9 +46,9 @@ import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.Button; +import android.widget.LinearLayout; import android.widget.Toast; -import org.y20k.trackbook.helpers.DialogClearFragment; import org.y20k.trackbook.helpers.LogHelper; import org.y20k.trackbook.helpers.NotificationHelper; import org.y20k.trackbook.helpers.TrackbookKeys; @@ -60,7 +62,7 @@ import java.util.Map; /** * MainActivity class */ -public class MainActivity extends AppCompatActivity implements TrackbookKeys, DialogClearFragment.DialogClearListener { +public class MainActivity extends AppCompatActivity implements TrackbookKeys { /* Define log tag */ private static final String LOG_TAG = MainActivity.class.getSimpleName(); @@ -68,9 +70,14 @@ public class MainActivity extends AppCompatActivity implements TrackbookKeys, Di /* Main class variables */ private boolean mTrackerServiceRunning; + private boolean mCurrentTrackVisible; private boolean mPermissionsGranted; + private boolean mFloatingActionButtonSubMenuVisible; private List mMissingPermissions; + private LinearLayout mFloatingActionButtonLayout; private FloatingActionButton mFloatingActionButton; + private LinearLayout mFloatingActionButtonSubMenu1; + private LinearLayout mFloatingActionButtonSubMenu2; private MainActivityMapFragment mMainActivityMapFragment; private MainActivityTrackFragment mMainActivityTrackFragment; private BroadcastReceiver mTrackingStoppedReceiver; @@ -81,12 +88,8 @@ public class MainActivity extends AppCompatActivity implements TrackbookKeys, Di protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - // get state of tracking and get selected tab - mTrackerServiceRunning = false; - if (savedInstanceState != null) { - mTrackerServiceRunning = savedInstanceState.getBoolean(INSTANCE_TRACKING_STATE, false); - mSelectedTab = savedInstanceState.getInt(INSTANCE_SELECTED_TAB, 0); - } + // load saved state of app + loadAppState(this); // check permissions on Android 6 and higher mPermissionsGranted = false; @@ -104,7 +107,6 @@ public class MainActivity extends AppCompatActivity implements TrackbookKeys, Di // set up main layout setupLayout(); - } @@ -112,27 +114,28 @@ public class MainActivity extends AppCompatActivity implements TrackbookKeys, Di protected void onStart() { super.onStart(); - // add listeners to button + // add listeners to button and submenu if (mFloatingActionButton != null) { mFloatingActionButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { - // onClick: start / stop tracking handleFloatingActionButtonClick(view); } }); - mFloatingActionButton.setOnLongClickListener(new View.OnLongClickListener() { + } + if (mFloatingActionButtonSubMenu1 != null) { + mFloatingActionButtonSubMenu1.setOnClickListener(new View.OnClickListener() { @Override - public boolean onLongClick(View view) { - // onLongClick: clear map - if (mTrackerServiceRunning || mMainActivityMapFragment == null) { - return false; - } else { - // show clear dialog - DialogFragment dialog = new DialogClearFragment(); - dialog.show(getFragmentManager(), "DialogClearFragment"); - return true; - } + public void onClick(View view) { + handleButtonSaveAndClearClick(); + } + }); + } + if (mFloatingActionButtonSubMenu2 != null) { + mFloatingActionButtonSubMenu2.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + handleButtonClearClick(); } }); } @@ -177,14 +180,6 @@ public class MainActivity extends AppCompatActivity implements TrackbookKeys, Di } - @Override - protected void onSaveInstanceState(Bundle outState) { - outState.putBoolean(INSTANCE_TRACKING_STATE, mTrackerServiceRunning); - outState.putInt(INSTANCE_SELECTED_TAB, mSelectedTab); - super.onSaveInstanceState(outState); - } - - @Override protected void onResume() { super.onResume(); @@ -243,25 +238,48 @@ public class MainActivity extends AppCompatActivity implements TrackbookKeys, Di @Override - public void onDialogClearPositiveClick(DialogFragment dialog) { - // DialogClear: User chose CLEAR. - LogHelper.v(LOG_TAG, "User chose CLEAR"); - - // clear the map - mMainActivityMapFragment.clearMap(); - - // reset current track - mMainActivityTrackFragment.refreshTrackView(); - - // dismiss notification - NotificationHelper.stop(); + protected void onSaveInstanceState(Bundle outState) { + LogHelper.v(LOG_TAG, "onSaveInstanceState called."); + outState.putBoolean(INSTANCE_TRACKING_STATE, mTrackerServiceRunning); + outState.putBoolean(INSTANCE_TRACK_VISIBLE, mCurrentTrackVisible); + outState.putBoolean(INSTANCE_FAB_SUB_MENU_VISIBLE, mFloatingActionButtonSubMenuVisible); + outState.putInt(INSTANCE_SELECTED_TAB, mSelectedTab); + super.onSaveInstanceState(outState); } @Override - public void onDialogClearNegativeClick(DialogFragment dialog) { - // DialogClear: User chose CANCEL. - LogHelper.v(LOG_TAG, "User chose CANCEL."); + public void onRestoreInstanceState(Bundle savedInstanceState) { + super.onRestoreInstanceState(savedInstanceState); + LogHelper.v(LOG_TAG, "onRestoreInstanceState called."); + mTrackerServiceRunning = savedInstanceState.getBoolean(INSTANCE_TRACKING_STATE, false); + mCurrentTrackVisible = savedInstanceState.getBoolean(INSTANCE_TRACK_VISIBLE, false); + mFloatingActionButtonSubMenuVisible = savedInstanceState.getBoolean(INSTANCE_FAB_SUB_MENU_VISIBLE, false); + mSelectedTab = savedInstanceState.getInt(INSTANCE_SELECTED_TAB, 0); + } + + + /* Saves app state to SharedPreferences */ + private void saveAppState(Context context) { + SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(context); + SharedPreferences.Editor editor = settings.edit(); + editor.putBoolean(INSTANCE_TRACKING_STATE, mTrackerServiceRunning); + editor.putBoolean(INSTANCE_TRACK_VISIBLE, mCurrentTrackVisible); + editor.putBoolean(INSTANCE_FAB_SUB_MENU_VISIBLE, mFloatingActionButtonSubMenuVisible); + editor.putInt(INSTANCE_SELECTED_TAB, mSelectedTab); + editor.apply(); + LogHelper.v(LOG_TAG, "Saving state."); + } + + + /* Loads app state from preferences */ + private void loadAppState(Context context) { + SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(context); + mTrackerServiceRunning = settings.getBoolean(INSTANCE_TRACKING_STATE, false); + mCurrentTrackVisible = settings.getBoolean(INSTANCE_TRACK_VISIBLE, false); + mFloatingActionButtonSubMenuVisible = settings.getBoolean(INSTANCE_FAB_SUB_MENU_VISIBLE, false); + mSelectedTab = settings.getInt(INSTANCE_SELECTED_TAB, 0); + LogHelper.v(LOG_TAG, "Loading state."); } @@ -269,7 +287,7 @@ public class MainActivity extends AppCompatActivity implements TrackbookKeys, Di private void setupLayout() { if (mPermissionsGranted) { // point to the main map layout - setContentView(R.layout.activity_main_test); + setContentView(R.layout.activity_main); // show action bar Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); @@ -312,8 +330,16 @@ public class MainActivity extends AppCompatActivity implements TrackbookKeys, Di } }); - // show the record button and attach listener - mFloatingActionButton = (FloatingActionButton) findViewById(R.id.fab); + // get references to the record button and show/hide its sub menu + mFloatingActionButtonLayout = (LinearLayout) findViewById(R.id.fabFrameLayout); + mFloatingActionButton = (FloatingActionButton) findViewById(R.id.fabMainButton); + mFloatingActionButtonSubMenu1 = (LinearLayout) findViewById(R.id.fabSubMenu1); + mFloatingActionButtonSubMenu2 = (LinearLayout) findViewById(R.id.fabSubMenu2); + if (mFloatingActionButtonSubMenuVisible) { + showFloatingActionButtonMenu(true); + } else { + showFloatingActionButtonMenu(false); + } } else { // point to the on main onboarding layout @@ -338,6 +364,15 @@ public class MainActivity extends AppCompatActivity implements TrackbookKeys, Di } + @Override + protected void onPause() { + super.onPause(); + + // save current state + saveAppState(this); + } + + /* Handles tap on the record button */ private void handleFloatingActionButtonClick(View view) { if (mTrackerServiceRunning) { @@ -352,14 +387,21 @@ public class MainActivity extends AppCompatActivity implements TrackbookKeys, Di intent.setAction(ACTION_STOP); startService(intent); + } else if (mCurrentTrackVisible) { + // toggle floating action button sub menu + if (!mFloatingActionButtonSubMenuVisible) { + showFloatingActionButtonMenu(true); + } else { + showFloatingActionButtonMenu(false); + } + } else { - // TODO ask if user wants to save the last track before starting a new recording - // TODO alternatively only ask if last track was very short // show snackbar Snackbar.make(view, R.string.snackbar_message_tracking_started, Snackbar.LENGTH_SHORT).setAction("Action", null).show(); // change state mTrackerServiceRunning = true; + mCurrentTrackVisible = true; setFloatingActionButtonState(); // get last location from MainActivity Fragment @@ -385,16 +427,76 @@ public class MainActivity extends AppCompatActivity implements TrackbookKeys, Di } + /* Handles tap on the save and clear button */ + public void handleButtonSaveAndClearClick() { + LogHelper.v(LOG_TAG, "User chose SAVE and CLEAR"); + + // clear map and save track + mMainActivityMapFragment.clearMap(true); // TODO change to true + mCurrentTrackVisible = false; + +// // reset current track // TODO ist this still necessary +// mMainActivityTrackFragment.refreshTrackView(); + + // TODO change to track tab + + // dismiss notification + NotificationHelper.stop(); + + // hide Floating Action Button sub menu + showFloatingActionButtonMenu(false); + + // update Floating Action Button icon + setFloatingActionButtonState(); + } + + + /* Handles tap on the clear button */ + public void handleButtonClearClick() { + LogHelper.v(LOG_TAG, "User chose CLEAR"); + + // clear map, do not save track + mMainActivityMapFragment.clearMap(false); + mCurrentTrackVisible = false; + + // dismiss notification + NotificationHelper.stop(); + + // hide Floating Action Button sub menu + showFloatingActionButtonMenu(false); + + // update Floating Action Button icon + setFloatingActionButtonState(); + } + + /* Set state of FloatingActionButton */ private void setFloatingActionButtonState() { if (mTrackerServiceRunning) { mFloatingActionButton.setImageResource(R.drawable.ic_fiber_manual_record_red_24dp); + } else if (mCurrentTrackVisible) { + mFloatingActionButton.setImageResource(R.drawable.ic_save_white_24dp); } else { mFloatingActionButton.setImageResource(R.drawable.ic_fiber_manual_record_white_24dp); } } + /* Shows (and hides) the sub menu of the floating action button */ + private void showFloatingActionButtonMenu(boolean visible) { + if (visible) { + mFloatingActionButtonSubMenu1.setVisibility(View.VISIBLE); + mFloatingActionButtonSubMenu2.setVisibility(View.VISIBLE); + mFloatingActionButtonSubMenuVisible = true; + } else { + mFloatingActionButtonSubMenu1.setVisibility(View.INVISIBLE); + mFloatingActionButtonSubMenu2.setVisibility(View.INVISIBLE); + mFloatingActionButtonSubMenuVisible = false; + } + + } + + /* Handles new incoming intents */ private void handleIncomingIntent() { Intent intent = getIntent(); @@ -407,12 +509,6 @@ public class MainActivity extends AppCompatActivity implements TrackbookKeys, Di mMainActivityMapFragment.setTrackingState(mTrackerServiceRunning); // prevent multiple reactions to intent intent.setAction(ACTION_DEFAULT); - } else if (intent.hasExtra(EXTRA_CLEAR_MAP) && mMainActivityMapFragment != null) { - // show clear dialog - DialogFragment dialog = new DialogClearFragment(); - dialog.show(getFragmentManager(), "DialogClearFragment"); - // prevent multiple reactions to intent - intent.setAction(ACTION_DEFAULT); } break; diff --git a/app/src/main/java/org/y20k/trackbook/MainActivityMapFragment.java b/app/src/main/java/org/y20k/trackbook/MainActivityMapFragment.java index f34f64e..01d7621 100644 --- a/app/src/main/java/org/y20k/trackbook/MainActivityMapFragment.java +++ b/app/src/main/java/org/y20k/trackbook/MainActivityMapFragment.java @@ -108,7 +108,7 @@ public class MainActivityMapFragment extends Fragment implements TrackbookKeys { mFirstStart = savedInstanceState.getBoolean(INSTANCE_FIRST_START, true); } - // restore tracking state + // restore tracking and map state mTrackerServiceRunning = false; if (savedInstanceState != null) { mTrackerServiceRunning = savedInstanceState.getBoolean(INSTANCE_TRACKING_STATE, false); @@ -235,7 +235,7 @@ public class MainActivityMapFragment extends Fragment implements TrackbookKeys { // show/hide the location off notification bar toggleLocationOffBar(); - // start preliminary tracking - if no TrackerService is running + // start preliminary tracking - if no TrackerService is running // TODO check if this still works in tabbed ui if (!mTrackerServiceRunning && mFragmentVisible) { startPreliminaryTracking(); } @@ -388,20 +388,26 @@ public class MainActivityMapFragment extends Fragment implements TrackbookKeys { /* Removes track crumbs from map */ - public void clearMap() { - - LogHelper.v(LOG_TAG, "!!! Ding clear."); + public void clearMap(boolean saveTrack) { // clear map if (mTrackOverlay != null) { - Toast.makeText(mActivity, mActivity.getString(R.string.toast_message_clear_map), Toast.LENGTH_LONG).show(); mMapView.getOverlays().remove(mTrackOverlay); } - // save track object - SaveTrackAsyncHelper saveTrackAsyncHelper = new SaveTrackAsyncHelper(); - saveTrackAsyncHelper.execute(); - // TODO add toast indicating track save + // save track object if requested + if (saveTrack) { + SaveTrackAsyncHelper saveTrackAsyncHelper = new SaveTrackAsyncHelper(); + saveTrackAsyncHelper.execute(); + Toast.makeText(mActivity, mActivity.getString(R.string.toast_message_save_track), Toast.LENGTH_LONG).show(); + } + + } + + + /* Getter for length of current track */ + public String getCurrentTrackLength() { + return mTrack.getTrackDistance(); } diff --git a/app/src/main/java/org/y20k/trackbook/helpers/DialogClearFragment.java b/app/src/main/java/org/y20k/trackbook/helpers/DialogClearFragment.java deleted file mode 100644 index 9c589c1..0000000 --- a/app/src/main/java/org/y20k/trackbook/helpers/DialogClearFragment.java +++ /dev/null @@ -1,83 +0,0 @@ -/** - * DialogClearFragment.java - * Implements the DialogClearFragment class - * A DialogClearFragment appears when the user wants to clear the map - * - * This file is part of - * TRACKBOOK - Movement Recorder for Android - * - * Copyright (c) 2016 - Y20K.org - * Licensed under the MIT-License - * http://opensource.org/licenses/MIT - * - * Trackbook uses osmdroid - OpenStreetMap-Tools for Android - * https://github.com/osmdroid/osmdroid - */ - -package org.y20k.trackbook.helpers; - -import android.app.AlertDialog; -import android.app.Dialog; -import android.app.DialogFragment; -import android.content.Context; -import android.content.DialogInterface; -import android.os.Bundle; - -import org.y20k.trackbook.R; - - -/** - * DialogClearFragment class - */ -public class DialogClearFragment extends DialogFragment { - - /* Define log tag */ - private static final String LOG_TAG = DialogClearFragment.class.getSimpleName(); - - - /* Interface that the context that creates an instance of this fragment must implement */ - public interface DialogClearListener { - public void onDialogClearPositiveClick(DialogFragment dialog); - public void onDialogClearNegativeClick(DialogFragment dialog); - } - - - /* Main class variables */ - private DialogClearListener mListener; - - - @Override - public void onAttach(Context context) { - super.onAttach(context); - // verify that the host context implements the callback interface - try { - // instantiate the NoticeDialogListener so we can send events to the host - mListener = (DialogClearListener) context; - } catch (ClassCastException e) { - LogHelper.e(LOG_TAG, "Context does not implement the DialogClearListener interface."); - } - } - - - @Override - public Dialog onCreateDialog(Bundle savedInstanceState) { - // construct dialog - AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); - builder.setTitle(R.string.dialog_clear_map_title) - .setMessage(R.string.dialog_clear_map_message) - .setPositiveButton(R.string.dialog_clear_map_okay, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int id) { - // user clicked CLEAR - inform initiating fragment / context - mListener.onDialogClearPositiveClick(DialogClearFragment.this); - } - }) - .setNegativeButton(R.string.dialog_clear_map_cancel, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int id) { - // user clicked CANCEL - inform initiating fragment / context - mListener.onDialogClearNegativeClick(DialogClearFragment.this); - } - }); - // create the AlertDialog object and return it - return builder.create(); - } -} diff --git a/app/src/main/java/org/y20k/trackbook/helpers/NotificationHelper.java b/app/src/main/java/org/y20k/trackbook/helpers/NotificationHelper.java index 782f602..03606b0 100644 --- a/app/src/main/java/org/y20k/trackbook/helpers/NotificationHelper.java +++ b/app/src/main/java/org/y20k/trackbook/helpers/NotificationHelper.java @@ -114,8 +114,6 @@ public class NotificationHelper implements TrackbookKeys { TaskStackBuilder swipeActionIntentBuilder = TaskStackBuilder.create(mService); swipeActionIntentBuilder.addParentStack(MainActivity.class); swipeActionIntentBuilder.addNextIntent(swipeActionIntent); - // pending intent wrapper for notification tap - PendingIntent swipeActionPendingIntent = swipeActionIntentBuilder.getPendingIntent(11, PendingIntent.FLAG_UPDATE_CURRENT); // ACTION: NOTIFICATION BUTTON STOP Intent stopActionIntent = new Intent(mService, TrackerService.class); @@ -136,10 +134,8 @@ public class NotificationHelper implements TrackbookKeys { builder.setContentTitle(mService.getString(R.string.notification_title_trackbook_running)); builder.setContentText(contentText); } else { - builder.setDeleteIntent(swipeActionPendingIntent); builder.setContentTitle(mService.getString(R.string.notification_title_trackbook_not_running)); builder.setContentText(contentText); - builder.setSubText(mService.getString(R.string.notification_swipe_to_clear_map)); } return builder; diff --git a/app/src/main/java/org/y20k/trackbook/helpers/TrackbookKeys.java b/app/src/main/java/org/y20k/trackbook/helpers/TrackbookKeys.java index 6e0e46a..0c029be 100644 --- a/app/src/main/java/org/y20k/trackbook/helpers/TrackbookKeys.java +++ b/app/src/main/java/org/y20k/trackbook/helpers/TrackbookKeys.java @@ -42,6 +42,8 @@ public interface TrackbookKeys { String ARG_PERMISSIONS_GRANTED = "ArgPermissionsGranted"; String ARG_TRACKING_STATE = "ArgTrackingState"; String ARG_TRACK = "ArgTrack"; + String ARG_TRACK_VISIBLE = "ArgTrackVisible"; + String ARG_TRACK_DISTANCE = "ArgTrackDistance"; /* TAGS */ String TAG_MAIN_ACTIVITY_FRAGMENT = "TagMainActivityFragment"; @@ -58,7 +60,9 @@ public interface TrackbookKeys { /* INSTANCE STATE */ String INSTANCE_FIRST_START = "firstStart"; String INSTANCE_TRACKING_STATE = "trackingState"; + String INSTANCE_TRACK_VISIBLE = "trackVisible"; String INSTANCE_SELECTED_TAB = "selectedTab"; + String INSTANCE_FAB_SUB_MENU_VISIBLE = "fabSubMenuVisible"; String INSTANCE_TRACK_MAIN_MAP = "trackMainMap"; String INSTANCE_LATITUDE_MAIN_MAP = "latitudeMainMap"; String INSTANCE_LONGITUDE_MAIN_MAP = "longitudeMainMap"; diff --git a/app/src/main/java/org/y20k/trackbook/layout/DodgeAbleLayoutBehavior.java b/app/src/main/java/org/y20k/trackbook/layout/DodgeAbleLayoutBehavior.java new file mode 100644 index 0000000..984edf4 --- /dev/null +++ b/app/src/main/java/org/y20k/trackbook/layout/DodgeAbleLayoutBehavior.java @@ -0,0 +1,68 @@ +/** + * DodgeAbleLayoutBehavior.java + * Implements the DodgeAbleLayoutBehavior class + * A DodgeAbleLayoutBehavior enables any element to be dodged up by a snackbar + * + * This file is part of + * TRACKBOOK - Movement Recorder for Android + * + * Copyright (c) 2016 - Y20K.org + * Licensed under the MIT-License + * http://opensource.org/licenses/MIT + * + * Trackbook uses osmdroid - OpenStreetMap-Tools for Android + * https://github.com/osmdroid/osmdroid + */ + + +package org.y20k.trackbook.layout; + +import android.content.Context; +import android.os.Build; +import android.support.design.widget.CoordinatorLayout; +import android.support.design.widget.Snackbar; +import android.util.AttributeSet; +import android.view.View; + + +/** + * DodgeAbleLayoutBehavior class + * adapted from: http://stackoverflow.com/a/35904421 + */ +public class DodgeAbleLayoutBehavior extends CoordinatorLayout.Behavior { + + /* Main class variables */ + private static final boolean SNACKBAR_BEHAVIOR_ENABLED; + + + /* Constructor (default) */ + public DodgeAbleLayoutBehavior() { + super(); + } + + + /* Constructor for context and attributes */ + public DodgeAbleLayoutBehavior(Context context, AttributeSet attrs) { + super(context, attrs); + } + + + @Override + public boolean layoutDependsOn(CoordinatorLayout parent, View child, View dependency) { + return SNACKBAR_BEHAVIOR_ENABLED && dependency instanceof Snackbar.SnackbarLayout; + } + + + @Override + public boolean onDependentViewChanged(CoordinatorLayout parent, View child, View dependency) { + float translationY = Math.min(0, dependency.getTranslationY() - dependency.getHeight()); + child.setTranslationY(translationY); + return true; + } + + + static { + SNACKBAR_BEHAVIOR_ENABLED = Build.VERSION.SDK_INT >= 11; + } + +} \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_clear_white_24dp.xml b/app/src/main/res/drawable/ic_clear_white_24dp.xml new file mode 100644 index 0000000..27ca255 --- /dev/null +++ b/app/src/main/res/drawable/ic_clear_white_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_fiber_manual_record_white_24dp.xml b/app/src/main/res/drawable/ic_fiber_manual_record_white_24dp.xml index 164176e..d734aef 100644 --- a/app/src/main/res/drawable/ic_fiber_manual_record_white_24dp.xml +++ b/app/src/main/res/drawable/ic_fiber_manual_record_white_24dp.xml @@ -5,5 +5,5 @@ android:viewportHeight="24.0"> + android:fillColor="@color/trackbook_white" /> diff --git a/app/src/main/res/drawable/ic_save_white_24dp.xml b/app/src/main/res/drawable/ic_save_white_24dp.xml new file mode 100644 index 0000000..1f1ec00 --- /dev/null +++ b/app/src/main/res/drawable/ic_save_white_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_track_calendar_white_24dp.xml b/app/src/main/res/drawable/ic_track_calendar_white_24dp.xml new file mode 100644 index 0000000..0cc338b --- /dev/null +++ b/app/src/main/res/drawable/ic_track_calendar_white_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 3da2216..1c6cadd 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -1,15 +1,19 @@ - + app:layout_scrollFlags="scroll|enterAlways" + app:popupTheme="@style/TrackbookAppTheme.PopupOverlay"> + + + + - - + app:layout_behavior="@string/appbar_scrolling_view_behavior" /> + - + + - + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main_test.xml b/app/src/main/res/layout/activity_main_old.xml similarity index 58% rename from app/src/main/res/layout/activity_main_test.xml rename to app/src/main/res/layout/activity_main_old.xml index 81b97ea..f00794e 100644 --- a/app/src/main/res/layout/activity_main_test.xml +++ b/app/src/main/res/layout/activity_main_old.xml @@ -1,19 +1,15 @@ - - - - - + app:popupTheme="@style/TrackbookAppTheme.PopupOverlay" /> - + - + app:layout_behavior="@string/appbar_scrolling_view_behavior" + tools:layout="@layout/fragment_main_map" /> - + + - \ No newline at end of file + diff --git a/app/src/main/res/layout/floating_action_button.xml b/app/src/main/res/layout/floating_action_button.xml new file mode 100644 index 0000000..dc1e291 --- /dev/null +++ b/app/src/main/res/layout/floating_action_button.xml @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_main_map.xml b/app/src/main/res/layout/fragment_main_map.xml index 3bd12eb..53c17cb 100644 --- a/app/src/main/res/layout/fragment_main_map.xml +++ b/app/src/main/res/layout/fragment_main_map.xml @@ -7,7 +7,7 @@ android:layout_width="fill_parent" android:layout_height="fill_parent" tools:context=".MainActivityMapFragment" - tools:showIn="@layout/activity_main"> + tools:showIn="@layout/activity_main_old"> - - Tracking aktiviert Standortdienste sind deaktiviert. Trackbook kann nicht aufzeichnen. - - Zurücksetzen - Möchten Sie die Karte zurücksetzen? - Zurücksetzen - Abbrechen + + Zurücksetzen + Speichern und Zurücksetzen Berechtigungen erteilt. @@ -42,7 +40,7 @@ Suche aktuellen Standort. Standortdienste noch nicht bereit. Bitte erneut versuchen. Letzte Position: - Kartenansicht wird zurückgesetzt + Aufzeichnung wird gespeichert. über eine Stunde diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 7b3b59d..b281e9b 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -28,11 +28,10 @@ Tracking started Location is turned off. Trackbook will not work. - - Clear - Do you want to clear the map? - Clear - Cancel + + Clear + Save and Clear + Permissions granted. @@ -42,7 +41,7 @@ Acquiring current location. Location services not ready. Please retry. Last location: - Clearing map. + Saving current track. over one hour diff --git a/build.gradle b/build.gradle index c20bca1..74b2ab0 100644 --- a/build.gradle +++ b/build.gradle @@ -5,7 +5,7 @@ buildscript { jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:2.2.2' + classpath 'com.android.tools.build:gradle:2.2.3' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files