From 41bf5e3abfde0453eefe99fc17f577612949ec22 Mon Sep 17 00:00:00 2001 From: PavelRatushny Date: Thu, 21 Sep 2017 17:28:59 +0300 Subject: [PATCH] Add swipes with snackbar in groups --- OsmAnd/res/values/strings.xml | 1 + .../src/net/osmand/plus/MapMarkersHelper.java | 121 ++++++++----- .../mapmarkers/MapMarkersGroupsFragment.java | 160 +++++++++++++++++- .../mapmarkers/MapMarkersHistoryFragment.java | 4 +- 4 files changed, 239 insertions(+), 47 deletions(-) diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index d5888fba2e..c6c8e60c41 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -9,6 +9,7 @@ 3. All your modified/created strings are in the top of the file (to make easier find what\'s translated). PLEASE: Have a look at http://code.google.com/p/osmand/wiki/UIConsistency, it may really improve your and our work :-) Thx - Hardy --> + Move to history Group will be removed after restart Show guide line Show arrows on the map diff --git a/OsmAnd/src/net/osmand/plus/MapMarkersHelper.java b/OsmAnd/src/net/osmand/plus/MapMarkersHelper.java index 76bdf038d6..7a461137f5 100644 --- a/OsmAnd/src/net/osmand/plus/MapMarkersHelper.java +++ b/OsmAnd/src/net/osmand/plus/MapMarkersHelper.java @@ -507,12 +507,17 @@ public class MapMarkersHelper { } } - public void removeMarkerFromHistory(MapMarker marker) { + public void removeMarker(MapMarker marker) { if (marker != null) { - markersDbHelper.removeMarker(marker, true); - mapMarkersHistory.remove(marker); - refresh(); + boolean history = marker.history; + markersDbHelper.removeMarker(marker, history); + if (history) { + mapMarkersHistory.remove(marker); + } else { + mapMarkers.remove(marker); + } removeMarkerFromGroup(marker); + refresh(); } } @@ -840,15 +845,21 @@ public class MapMarkersHelper { } } markersGroup.setMarkers(activeMarkers); - updateShowHideHistoryButtonInGroup(markersGroup); + updateGroup(markersGroup); } } - private void updateShowHideHistoryButtonInGroup(MapMarkersGroup mapMarkersGroup) { + public void updateGroup(MapMarkersGroup mapMarkersGroup) { + if (mapMarkersGroup.getMarkers().size() == 0) { + mapMarkersGroups.remove(mapMarkersGroup); + return; + } int historyMarkersCount = mapMarkersGroup.getHistoryMarkers().size(); ShowHideHistoryButton showHideHistoryButton = mapMarkersGroup.getShowHideHistoryButton(); - if (showHideHistoryButton != null && historyMarkersCount == 0) { - mapMarkersGroup.setShowHideHistoryButton(null); + if (showHideHistoryButton != null) { + if (historyMarkersCount == 0) { + mapMarkersGroup.setShowHideHistoryButton(null); + } } else if (historyMarkersCount > 0) { showHideHistoryButton = new ShowHideHistoryButton(); showHideHistoryButton.setShowHistory(false); @@ -862,7 +873,7 @@ public class MapMarkersHelper { MapMarkersGroup mapMarkersGroup = getMapMarkerGroupByName(marker.groupName); if (mapMarkersGroup != null) { mapMarkersGroup.getMarkers().add(marker); - updateShowHideHistoryButtonInGroup(mapMarkersGroup); + updateGroup(mapMarkersGroup); if (mapMarkersGroup.getName() == null) { sortMarkers(mapMarkersGroup.getMarkers(), false, OsmandSettings.MapMarkersOrderByMode.DATE_ADDED_DESC); } @@ -876,27 +887,32 @@ public class MapMarkersHelper { private MapMarkersGroup createMapMarkerGroup(MapMarker marker) { MapMarkersGroup group = new MapMarkersGroup(); - group.setName(marker.groupName); - group.setGroupKey(marker.groupKey); - MapMarkersHelper.MarkersSyncGroup syncGroup = getGroup(marker.groupKey); - if (syncGroup != null) { - group.setType(syncGroup.getType()); + if (marker.groupName != null) { + group.setName(marker.groupName); + group.setGroupKey(marker.groupKey); + MapMarkersHelper.MarkersSyncGroup syncGroup = getGroup(marker.groupKey); + if (syncGroup != null) { + group.setType(syncGroup.getType()); + } + group.setColor(MapMarker.getColorId(marker.colorIndex)); } - group.setColor(MapMarker.getColorId(marker.colorIndex)); group.setCreationDate(marker.creationDate); mapMarkersGroups.add(group); + sortGroups(); return group; } private void createHeaderAndHistoryButtonInGroup(MapMarkersGroup group) { - GroupHeader header = new GroupHeader(); - int type = group.getType(); - if (type != -1) { - header.setIconRes(type == MapMarkersHelper.MarkersSyncGroup.FAVORITES_TYPE ? R.drawable.ic_action_fav_dark : R.drawable.ic_action_track_16); + if (group.getName() != null) { + GroupHeader header = new GroupHeader(); + int type = group.getType(); + if (type != -1) { + header.setIconRes(type == MapMarkersHelper.MarkersSyncGroup.FAVORITES_TYPE ? R.drawable.ic_action_fav_dark : R.drawable.ic_action_track_16); + } + header.setGroup(group); + group.setGroupHeader(header); + updateGroup(group); } - header.setGroup(group); - group.setGroupHeader(header); - updateShowHideHistoryButtonInGroup(group); } private void removeMarkerFromGroup(MapMarker marker) { @@ -904,7 +920,7 @@ public class MapMarkersHelper { MapMarkersGroup mapMarkersGroup = getMapMarkerGroupByName(marker.groupName); if (mapMarkersGroup != null) { mapMarkersGroup.getMarkers().remove(marker); - updateShowHideHistoryButtonInGroup(mapMarkersGroup); + updateGroup(mapMarkersGroup); } } } @@ -931,7 +947,15 @@ public class MapMarkersHelper { } else { MapMarkersGroup group = groupsMap.get(groupName); if (group == null) { - group = createMapMarkerGroup(marker); + group = new MapMarkersGroup(); + group.setName(marker.groupName); + group.setGroupKey(marker.groupKey); + MapMarkersHelper.MarkersSyncGroup syncGroup = getGroup(marker.groupKey); + if (syncGroup != null) { + group.setType(syncGroup.getType()); + } + group.setColor(MapMarker.getColorId(marker.colorIndex)); + group.setCreationDate(marker.creationDate); groupsMap.put(groupName, group); } else { long markerCreationDate = marker.creationDate; @@ -943,33 +967,44 @@ public class MapMarkersHelper { } } mapMarkersGroups = new ArrayList<>(groupsMap.values()); - sortGroups(mapMarkersGroups); + if (noGroup != null) { + mapMarkersGroups.add(noGroup); + } + sortGroups(); for (MapMarkersGroup group : mapMarkersGroups) { createHeaderAndHistoryButtonInGroup(group); } - - if (noGroup != null) { - sortMarkers(noGroup.getMarkers(), false, OsmandSettings.MapMarkersOrderByMode.DATE_ADDED_DESC); - mapMarkersGroups.add(0, noGroup); - } } - private void sortGroups(List groups) { - Collections.sort(groups, new Comparator() { - @Override - public int compare(MapMarkersGroup group1, MapMarkersGroup group2) { - long t1 = group1.getCreationDate(); - long t2 = group2.getCreationDate(); - if (t1 > t2) { - return -1; - } else if (t1 == t2) { - return 0; - } else { - return 1; + private void sortGroups() { + if (mapMarkersGroups.size() > 0) { + MapMarkersGroup noGroup = null; + for (int i = 0; i < mapMarkersGroups.size(); i++) { + MapMarkersGroup group = mapMarkersGroups.get(i); + if (group.getName() == null) { + sortMarkers(group.getMarkers(), false, OsmandSettings.MapMarkersOrderByMode.DATE_ADDED_DESC); + noGroup = mapMarkersGroups.remove(i); } } - }); + Collections.sort(mapMarkersGroups, new Comparator() { + @Override + public int compare(MapMarkersGroup group1, MapMarkersGroup group2) { + long t1 = group1.getCreationDate(); + long t2 = group2.getCreationDate(); + if (t1 > t2) { + return -1; + } else if (t1 == t2) { + return 0; + } else { + return 1; + } + } + }); + if (noGroup != null) { + mapMarkersGroups.add(0, noGroup); + } + } } public MapMarkersGroup getMapMarkerGroupByName(String name) { diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersGroupsFragment.java b/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersGroupsFragment.java index 5dfdc43dd6..e280fd5f7d 100644 --- a/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersGroupsFragment.java +++ b/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersGroupsFragment.java @@ -1,22 +1,37 @@ package net.osmand.plus.mapmarkers; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.PorterDuff; +import android.graphics.PorterDuffColorFilter; +import android.graphics.Rect; import android.os.Bundle; import android.support.annotation.Nullable; +import android.support.design.widget.Snackbar; import android.support.v4.app.Fragment; +import android.support.v4.content.ContextCompat; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; +import android.support.v7.widget.helper.ItemTouchHelper; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.TextView; import net.osmand.Location; import net.osmand.data.LatLon; +import net.osmand.plus.MapMarkersHelper; +import net.osmand.plus.MapMarkersHelper.MapMarker; import net.osmand.plus.OsmAndLocationProvider.OsmAndCompassListener; import net.osmand.plus.OsmAndLocationProvider.OsmAndLocationListener; import net.osmand.plus.OsmandApplication; +import net.osmand.plus.R; import net.osmand.plus.activities.MapActivity; import net.osmand.plus.base.MapViewTrackingUtilities; import net.osmand.plus.dashboard.DashLocationFragment; +import net.osmand.plus.mapmarkers.adapters.MapMarkerItemViewHolder; import net.osmand.plus.mapmarkers.adapters.MapMarkersGroupsAdapter; import net.osmand.util.MapUtils; @@ -28,13 +43,151 @@ public class MapMarkersGroupsFragment extends Fragment implements OsmAndCompassL private Float heading; private Location location; private boolean locationUpdateStarted; + private Paint backgroundPaint = new Paint(); + private Paint iconPaint = new Paint(); + private Paint textPaint = new Paint(); + private Snackbar snackbar; @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { - final RecyclerView recyclerView = new RecyclerView(getContext()); - recyclerView.setLayoutManager(new LinearLayoutManager(getContext())); final MapActivity mapActivity = (MapActivity) getActivity(); + final boolean night = !mapActivity.getMyApplication().getSettings().isLightContent(); + final RecyclerView recyclerView = new RecyclerView(getContext()); + + backgroundPaint.setColor(ContextCompat.getColor(getActivity(), night ? R.color.dashboard_divider_dark : R.color.dashboard_divider_light)); + backgroundPaint.setStyle(Paint.Style.FILL_AND_STROKE); + backgroundPaint.setAntiAlias(true); + iconPaint.setAntiAlias(true); + iconPaint.setFilterBitmap(true); + iconPaint.setDither(true); + textPaint.setTextSize(getResources().getDimension(R.dimen.default_desc_text_size)); + textPaint.setFakeBoldText(true); + textPaint.setAntiAlias(true); + + final String delStr = getString(R.string.shared_string_delete).toUpperCase(); + final String moveToHistoryStr = getString(R.string.move_to_history).toUpperCase(); + final Rect bounds = new Rect(); + + textPaint.getTextBounds(moveToHistoryStr, 0, moveToHistoryStr.length(), bounds); + final int moveToHistoryStrWidth = bounds.width(); + final int textHeight = bounds.height(); + + recyclerView.setLayoutManager(new LinearLayoutManager(getContext())); + ItemTouchHelper.SimpleCallback simpleItemTouchCallback = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) { + private float marginSides = getResources().getDimension(R.dimen.list_content_padding); + private Bitmap deleteBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_action_delete_dark); + private Bitmap resetBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_action_reset_to_default_dark); + private boolean iconHidden; + + @Override + public int getSwipeDirs(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) { + boolean markerViewHolder = viewHolder instanceof MapMarkerItemViewHolder; + if (markerViewHolder) { + MapMarker marker = (MapMarker) adapter.getItem(viewHolder.getAdapterPosition()); + if (marker.history) { + return ItemTouchHelper.RIGHT; + } else { + return super.getSwipeDirs(recyclerView, viewHolder); + } + } else { + return 0; + } + } + + @Override + public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) { + return false; + } + + @Override + public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) { + if (actionState == ItemTouchHelper.ACTION_STATE_SWIPE && viewHolder instanceof MapMarkerItemViewHolder) { + if (!iconHidden && isCurrentlyActive) { + ((MapMarkerItemViewHolder) viewHolder).optionsBtn.setVisibility(View.GONE); + iconHidden = true; + } + View itemView = viewHolder.itemView; + int colorIcon; + int colorText; + if (Math.abs(dX) > itemView.getWidth() / 2) { + colorIcon = R.color.map_widget_blue; + colorText = R.color.map_widget_blue; + } else { + colorIcon = night ? 0 : R.color.icon_color; + colorText = R.color.dashboard_subheader_text_light; + } + if (colorIcon != 0) { + iconPaint.setColorFilter(new PorterDuffColorFilter(ContextCompat.getColor(getActivity(), colorIcon), PorterDuff.Mode.SRC_IN)); + } + textPaint.setColor(ContextCompat.getColor(getActivity(), colorText)); + float textMarginTop = ((float) itemView.getHeight() - (float) textHeight) / 2; + if (dX > 0) { + c.drawRect(itemView.getLeft(), itemView.getTop(), dX, itemView.getBottom(), backgroundPaint); + float iconMarginTop = ((float) itemView.getHeight() - (float) deleteBitmap.getHeight()) / 2; + c.drawBitmap(deleteBitmap, itemView.getLeft() + marginSides, itemView.getTop() + iconMarginTop, iconPaint); + c.drawText(delStr, itemView.getLeft() + 2 * marginSides + deleteBitmap.getWidth(), + itemView.getTop() + textMarginTop + textHeight, textPaint); + } else { + c.drawRect(itemView.getRight() + dX, itemView.getTop(), itemView.getRight(), itemView.getBottom(), backgroundPaint); + float iconMarginTop = ((float) itemView.getHeight() - (float) resetBitmap.getHeight()) / 2; + c.drawBitmap(resetBitmap, itemView.getRight() - resetBitmap.getWidth() - marginSides, itemView.getTop() + iconMarginTop, iconPaint); + c.drawText(moveToHistoryStr, itemView.getRight() - resetBitmap.getWidth() - 2 * marginSides - moveToHistoryStrWidth, + itemView.getTop() + textMarginTop + textHeight, textPaint); + } + } + super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive); + } + + @Override + public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) { + if (viewHolder instanceof MapMarkerItemViewHolder) { + ((MapMarkerItemViewHolder) viewHolder).optionsBtn.setVisibility(View.VISIBLE); + iconHidden = false; + } + super.clearView(recyclerView, viewHolder); + } + + @Override + public void onSwiped(RecyclerView.ViewHolder viewHolder, final int direction) { + final int pos = viewHolder.getAdapterPosition(); + Object item = adapter.getItem(pos); + if (item instanceof MapMarker) { + final MapMarker marker = (MapMarker) item; + int snackbarStringRes; + if (direction == ItemTouchHelper.LEFT) { + mapActivity.getMyApplication().getMapMarkersHelper().moveMapMarkerToHistory((MapMarker) item); + MapMarkersHelper.MapMarkersGroup group = mapActivity.getMyApplication().getMapMarkersHelper().getMapMarkerGroupByName(marker.groupName); + if (group != null) { + mapActivity.getMyApplication().getMapMarkersHelper().updateGroup(group); + } + snackbarStringRes = R.string.marker_moved_to_history; + } else { + mapActivity.getMyApplication().getMapMarkersHelper().removeMarker((MapMarker) item); + snackbarStringRes = R.string.item_removed; + } + updateAdapter(); + snackbar = Snackbar.make(viewHolder.itemView, snackbarStringRes, Snackbar.LENGTH_LONG) + .setAction(R.string.shared_string_undo, new View.OnClickListener() { + @Override + public void onClick(View view) { + if (direction == ItemTouchHelper.LEFT) { + mapActivity.getMyApplication().getMapMarkersHelper().restoreMarkerFromHistory(marker, 0); + } else { + mapActivity.getMyApplication().getMapMarkersHelper().addMarker(marker); + } + updateAdapter(); + } + }); + View snackBarView = snackbar.getView(); + TextView tv = (TextView) snackBarView.findViewById(android.support.design.R.id.snackbar_action); + tv.setTextColor(ContextCompat.getColor(mapActivity, R.color.color_dialog_buttons_dark)); + snackbar.show(); + } + } + }; + ItemTouchHelper itemTouchHelper = new ItemTouchHelper(simpleItemTouchCallback); + itemTouchHelper.attachToRecyclerView(recyclerView); adapter = new MapMarkersGroupsAdapter(mapActivity); recyclerView.setAdapter(adapter); @@ -87,6 +240,9 @@ public class MapMarkersGroupsFragment extends Fragment implements OsmAndCompassL if (adapter != null) { adapter.hideSnackbar(); } + if (snackbar != null && snackbar.isShown()) { + snackbar.dismiss(); + } } @Override diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersHistoryFragment.java b/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersHistoryFragment.java index 37aaa9d326..df92b9e9b4 100644 --- a/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersHistoryFragment.java +++ b/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersHistoryFragment.java @@ -152,7 +152,7 @@ public class MapMarkersHistoryFragment extends Fragment implements MapMarkersHel app.getMapMarkersHelper().restoreMarkerFromHistory((MapMarker) item, 0); snackbarStringRes = R.string.marker_moved_to_active; } else { - app.getMapMarkersHelper().removeMarkerFromHistory((MapMarker) item); + app.getMapMarkersHelper().removeMarker((MapMarker) item); snackbarStringRes = R.string.item_removed; } adapter.notifyItemRemoved(pos); @@ -225,7 +225,7 @@ public class MapMarkersHistoryFragment extends Fragment implements MapMarkersHel public void onDeleteMarker(int pos) { Object item = adapter.getItem(pos); if (item instanceof MapMarker) { - app.getMapMarkersHelper().removeMarkerFromHistory((MapMarker) item); + app.getMapMarkersHelper().removeMarker((MapMarker) item); adapter.notifyItemRemoved(pos); } }