Added map markers rearranging feature

This commit is contained in:
Alexey Kulish 2016-02-19 17:56:01 +03:00
parent 069fa5fad8
commit 936c4ed3ca
5 changed files with 100 additions and 33 deletions

View file

@ -114,7 +114,6 @@
android:layout_width="48dp" android:layout_width="48dp"
android:layout_height="48dp" android:layout_height="48dp"
android:layout_gravity="center_vertical" android:layout_gravity="center_vertical"
android:layout_marginRight="2dp"
android:focusable="false" android:focusable="false"
android:clickable="false" android:clickable="false"
android:scaleType="center" android:scaleType="center"

View file

@ -1706,7 +1706,9 @@ public class OsmandSettings {
int index = ps.indexOf(new LatLon(latitude, longitude)); int index = ps.indexOf(new LatLon(latitude, longitude));
ds.set(index, PointDescription.serializeToString(historyDescription)); ds.set(index, PointDescription.serializeToString(historyDescription));
cs.set(index, colorIndex); cs.set(index, colorIndex);
if (ns.size() > index) {
ns.set(index, pos); ns.set(index, pos);
}
if (historyDescription != null && !historyDescription.isSearchingAddress(ctx)) { if (historyDescription != null && !historyDescription.isSearchingAddress(ctx)) {
SearchHistoryHelper.getInstance(ctx).addNewItemToHistory(latitude, longitude, historyDescription); SearchHistoryHelper.getInstance(ctx).addNewItemToHistory(latitude, longitude, historyDescription);
} }

View file

@ -41,7 +41,6 @@ import net.osmand.plus.ContextMenuAdapter;
import net.osmand.plus.ContextMenuAdapter.OnContextMenuClick; import net.osmand.plus.ContextMenuAdapter.OnContextMenuClick;
import net.osmand.plus.ContextMenuAdapter.OnRowItemClick; import net.osmand.plus.ContextMenuAdapter.OnRowItemClick;
import net.osmand.plus.IconsCache; import net.osmand.plus.IconsCache;
import net.osmand.plus.MapMarkersHelper;
import net.osmand.plus.MapMarkersHelper.MapMarker; import net.osmand.plus.MapMarkersHelper.MapMarker;
import net.osmand.plus.MapMarkersHelper.MapMarkerChangedListener; import net.osmand.plus.MapMarkersHelper.MapMarkerChangedListener;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
@ -58,6 +57,7 @@ import net.osmand.plus.dialogs.RasterMapMenu;
import net.osmand.plus.download.DownloadActivity; import net.osmand.plus.download.DownloadActivity;
import net.osmand.plus.helpers.AndroidUiHelper; import net.osmand.plus.helpers.AndroidUiHelper;
import net.osmand.plus.helpers.MapMarkerDialogHelper; import net.osmand.plus.helpers.MapMarkerDialogHelper;
import net.osmand.plus.helpers.MapMarkerDialogHelper.MapMarkersDialogHelperCallbacks;
import net.osmand.plus.helpers.WaypointDialogHelper; import net.osmand.plus.helpers.WaypointDialogHelper;
import net.osmand.plus.helpers.WaypointDialogHelper.WaypointDialogHelperCallbacks; import net.osmand.plus.helpers.WaypointDialogHelper.WaypointDialogHelperCallbacks;
import net.osmand.plus.helpers.WaypointHelper.LocationPointWrapper; import net.osmand.plus.helpers.WaypointHelper.LocationPointWrapper;
@ -88,7 +88,8 @@ import static android.util.TypedValue.COMPLEX_UNIT_DIP;
/** /**
*/ */
public class DashboardOnMap implements ObservableScrollViewCallbacks, DynamicListViewCallbacks, public class DashboardOnMap implements ObservableScrollViewCallbacks, DynamicListViewCallbacks,
IRouteInformationListener, WaypointDialogHelperCallbacks, MapMarkerChangedListener { IRouteInformationListener, WaypointDialogHelperCallbacks, MapMarkersDialogHelperCallbacks,
MapMarkerChangedListener {
private static final org.apache.commons.logging.Log LOG = private static final org.apache.commons.logging.Log LOG =
PlatformUtil.getLog(DashboardOnMap.class); PlatformUtil.getLog(DashboardOnMap.class);
private static final String TAG = "DashboardOnMap"; private static final String TAG = "DashboardOnMap";
@ -190,8 +191,9 @@ public class DashboardOnMap implements ObservableScrollViewCallbacks, DynamicLis
public void createDashboardView() { public void createDashboardView() {
baseColor = mapActivity.getResources().getColor(R.color.osmand_orange) & 0x00ffffff; baseColor = mapActivity.getResources().getColor(R.color.osmand_orange) & 0x00ffffff;
waypointDialogHelper = new WaypointDialogHelper(mapActivity); waypointDialogHelper = new WaypointDialogHelper(mapActivity);
waypointDialogHelper.setWaypointDialogHelperCallbacks(this); waypointDialogHelper.setHelperCallbacks(this);
mapMarkerDialogHelper = new MapMarkerDialogHelper(mapActivity); mapMarkerDialogHelper = new MapMarkerDialogHelper(mapActivity);
mapMarkerDialogHelper.setHelperCallbacks(this);
landscape = !AndroidUiHelper.isOrientationPortrait(mapActivity); landscape = !AndroidUiHelper.isOrientationPortrait(mapActivity);
dashboardView = (FrameLayout) mapActivity.findViewById(R.id.dashboard); dashboardView = (FrameLayout) mapActivity.findViewById(R.id.dashboard);
final View.OnClickListener listener = new View.OnClickListener() { final View.OnClickListener listener = new View.OnClickListener() {
@ -220,9 +222,14 @@ public class DashboardOnMap implements ObservableScrollViewCallbacks, DynamicLis
public boolean canDismiss(int position) { public boolean canDismiss(int position) {
boolean res = false; boolean res = false;
if (listAdapter instanceof StableArrayAdapter) { if (listAdapter instanceof StableArrayAdapter) {
if (visibleType == DashboardType.WAYPOINTS || visibleType == DashboardType.WAYPOINTS_FLAT) {
List<Object> activeObjects = ((StableArrayAdapter) listAdapter).getActiveObjects(); List<Object> activeObjects = ((StableArrayAdapter) listAdapter).getActiveObjects();
Object obj = listAdapter.getItem(position); Object obj = listAdapter.getItem(position);
res = activeObjects.contains(obj); res = activeObjects.contains(obj);
} else if (visibleType == DashboardType.MAP_MARKERS) {
Object obj = listAdapter.getItem(position);
res = obj instanceof MapMarker;
}
} }
return res; return res;
} }
@ -785,10 +792,7 @@ public class DashboardOnMap implements ObservableScrollViewCallbacks, DynamicLis
OnItemClickListener listener = waypointDialogHelper.getDrawerItemClickListener(mapActivity, running, OnItemClickListener listener = waypointDialogHelper.getDrawerItemClickListener(mapActivity, running,
listAdapter); listAdapter);
DynamicListView dynamicListView = (DynamicListView) listView; setDynamicListItems((DynamicListView) listView, listAdapter);
dynamicListView.setItemsList(listAdapter.getObjects());
dynamicListView.setActiveItemsList(listAdapter.getActiveObjects());
updateListAdapter(listAdapter, listener); updateListAdapter(listAdapter, listener);
} else if (DashboardType.MAP_MARKERS == visibleType) { } else if (DashboardType.MAP_MARKERS == visibleType) {
@ -797,10 +801,7 @@ public class DashboardOnMap implements ObservableScrollViewCallbacks, DynamicLis
StableArrayAdapter listAdapter = mapMarkerDialogHelper.getMapMarkersListAdapter(); StableArrayAdapter listAdapter = mapMarkerDialogHelper.getMapMarkersListAdapter();
OnItemClickListener listener = mapMarkerDialogHelper.getItemClickListener(listAdapter); OnItemClickListener listener = mapMarkerDialogHelper.getItemClickListener(listAdapter);
DynamicListView dynamicListView = (DynamicListView) listView; setDynamicListItems((DynamicListView) listView, listAdapter);
dynamicListView.setItemsList(listAdapter.getObjects());
dynamicListView.setActiveItemsList(listAdapter.getActiveObjects());
updateListAdapter(listAdapter, listener); updateListAdapter(listAdapter, listener);
} else { } else {
@ -852,6 +853,21 @@ public class DashboardOnMap implements ObservableScrollViewCallbacks, DynamicLis
} }
} }
private void setDynamicListItems(DynamicListView listView, StableArrayAdapter listAdapter) {
listView.setItemsList(listAdapter.getObjects());
if (DashboardType.WAYPOINTS == visibleType || DashboardType.WAYPOINTS_FLAT == visibleType) {
listView.setActiveItemsList(listAdapter.getActiveObjects());
} else if (DashboardType.MAP_MARKERS == visibleType) {
List<Object> activeMarkers = new ArrayList<>();
for (Object obj : listAdapter.getActiveObjects()) {
if (obj instanceof MapMarker && !((MapMarker) obj).history) {
activeMarkers.add(obj);
}
}
listView.setActiveItemsList(activeMarkers);
}
}
private OnItemClickListener getOptionsMenuOnClickListener(final ContextMenuAdapter cm, private OnItemClickListener getOptionsMenuOnClickListener(final ContextMenuAdapter cm,
final ArrayAdapter<?> listAdapter) { final ArrayAdapter<?> listAdapter) {
@ -1288,6 +1304,7 @@ public class DashboardOnMap implements ObservableScrollViewCallbacks, DynamicLis
} }
} }
@SuppressWarnings("unchecked")
@Override @Override
public void onItemsSwapped(final List<Object> items) { public void onItemsSwapped(final List<Object> items) {
getMyApplication().runInUIThread(new Runnable() { getMyApplication().runInUIThread(new Runnable() {
@ -1316,11 +1333,15 @@ public class DashboardOnMap implements ObservableScrollViewCallbacks, DynamicLis
newRouteIsCalculated(false, new ValueHolder<Boolean>()); newRouteIsCalculated(false, new ValueHolder<Boolean>());
getMyApplication().getTargetPointsHelper().updateRouteAndRefresh(true); getMyApplication().getTargetPointsHelper().updateRouteAndRefresh(true);
} else if (visibleType == DashboardType.MAP_MARKERS) {
List<MapMarker> markers = (List<MapMarker>)(Object)items;
getMyApplication().getMapMarkersHelper().saveMapMarkers(markers, null);
}
if (swipeDismissListener != null) { if (swipeDismissListener != null) {
swipeDismissListener.setEnabled(true); swipeDismissListener.setEnabled(true);
} }
} }
}
}, 50); }, 50);
} }
@ -1355,17 +1376,24 @@ public class DashboardOnMap implements ObservableScrollViewCallbacks, DynamicLis
mapMarkerDialogHelper.reloadListAdapter(stableAdapter); mapMarkerDialogHelper.reloadListAdapter(stableAdapter);
} }
if (listView instanceof DynamicListView) { if (listView instanceof DynamicListView) {
DynamicListView dynamicListView = (DynamicListView) listView; setDynamicListItems((DynamicListView) listView, stableAdapter);
dynamicListView.setItemsList(stableAdapter.getObjects());
dynamicListView.setActiveItemsList(stableAdapter.getActiveObjects());
} }
} }
} }
private void deleteSwipeItem(int position) {
if (swipeDismissListener != null) {
swipeDismissListener.delete(position);
}
}
@Override @Override
public void deleteWaypoint(int position) { public void deleteWaypoint(int position) {
if (swipeDismissListener != null) { deleteSwipeItem(position);
swipeDismissListener.delete(position);
} }
@Override
public void deleteMapMarker(int position) {
deleteSwipeItem(position);
} }
} }

View file

@ -33,11 +33,11 @@ import net.osmand.plus.OsmAndFormatter;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity; import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.audionotes.AudioVideoNotesPlugin;
import net.osmand.plus.dashboard.DashLocationFragment; import net.osmand.plus.dashboard.DashLocationFragment;
import net.osmand.plus.dashboard.DashboardOnMap; import net.osmand.plus.dashboard.DashboardOnMap;
import net.osmand.plus.dialogs.DirectionsDialogs; import net.osmand.plus.dialogs.DirectionsDialogs;
import net.osmand.plus.views.DirectionDrawable; import net.osmand.plus.views.DirectionDrawable;
import net.osmand.plus.views.controls.DynamicListView;
import net.osmand.plus.views.controls.ListDividerShape; import net.osmand.plus.views.controls.ListDividerShape;
import net.osmand.plus.views.controls.StableArrayAdapter; import net.osmand.plus.views.controls.StableArrayAdapter;
import net.osmand.util.Algorithms; import net.osmand.util.Algorithms;
@ -59,6 +59,7 @@ public class MapMarkerDialogHelper {
private MapActivity mapActivity; private MapActivity mapActivity;
private OsmandApplication app; private OsmandApplication app;
private MapMarkersHelper markersHelper; private MapMarkersHelper markersHelper;
private MapMarkersDialogHelperCallbacks helperCallbacks;
private boolean sorted; private boolean sorted;
private boolean nightMode; private boolean nightMode;
@ -69,12 +70,21 @@ public class MapMarkerDialogHelper {
private boolean reloading; private boolean reloading;
private long lastUpdateTime; private long lastUpdateTime;
public interface MapMarkersDialogHelperCallbacks {
void reloadAdapter();
void deleteMapMarker(int position);
}
public MapMarkerDialogHelper(MapActivity mapActivity) { public MapMarkerDialogHelper(MapActivity mapActivity) {
this.mapActivity = mapActivity; this.mapActivity = mapActivity;
app = mapActivity.getMyApplication(); app = mapActivity.getMyApplication();
markersHelper = app.getMapMarkersHelper(); markersHelper = app.getMapMarkersHelper();
} }
public void setHelperCallbacks(MapMarkersDialogHelperCallbacks helperCallbacks) {
this.helperCallbacks = helperCallbacks;
}
public boolean isNightMode() { public boolean isNightMode() {
return nightMode; return nightMode;
} }
@ -116,7 +126,7 @@ public class MapMarkerDialogHelper {
final List<Object> objects = getListObjects(); final List<Object> objects = getListObjects();
List<Object> activeObjects = getActiveObjects(objects); List<Object> activeObjects = getActiveObjects(objects);
final StableArrayAdapter listAdapter = new StableArrayAdapter(mapActivity, return new StableArrayAdapter(mapActivity,
R.layout.map_marker_item, R.id.title, objects, activeObjects) { R.layout.map_marker_item, R.id.title, objects, activeObjects) {
@Override @Override
@ -147,14 +157,12 @@ public class MapMarkerDialogHelper {
v = mapActivity.getLayoutInflater().inflate(R.layout.card_bottom_divider, null); v = mapActivity.getLayoutInflater().inflate(R.layout.card_bottom_divider, null);
} else if (obj instanceof MapMarker) { } else if (obj instanceof MapMarker) {
MapMarker marker = (MapMarker) obj; MapMarker marker = (MapMarker) obj;
v = updateMapMarkerItemView(v, marker); v = updateMapMarkerItemView(this, v, marker);
AndroidUtils.setListItemBackground(mapActivity, v, nightMode); AndroidUtils.setListItemBackground(mapActivity, v, nightMode);
} }
return v; return v;
} }
}; };
return listAdapter;
} }
private List<Drawable> getCustomDividers(List<Object> points) { private List<Drawable> getCustomDividers(List<Object> points) {
@ -308,7 +316,7 @@ public class MapMarkerDialogHelper {
return v; return v;
} }
protected View updateMapMarkerItemView(View v, final MapMarker marker) { protected View updateMapMarkerItemView(final StableArrayAdapter adapter, View v, final MapMarker marker) {
if (v == null || v.findViewById(R.id.info_close) == null) { if (v == null || v.findViewById(R.id.info_close) == null) {
v = mapActivity.getLayoutInflater().inflate(R.layout.map_marker_item, null); v = mapActivity.getLayoutInflater().inflate(R.layout.map_marker_item, null);
} }
@ -317,8 +325,38 @@ public class MapMarkerDialogHelper {
final View move = v.findViewById(R.id.info_move); final View move = v.findViewById(R.id.info_move);
final View remove = v.findViewById(R.id.info_close); final View remove = v.findViewById(R.id.info_close);
remove.setVisibility(View.GONE); remove.setVisibility(View.GONE);
move.setVisibility(View.GONE);
more.setVisibility(View.GONE); more.setVisibility(View.GONE);
if (!marker.history) {
move.setVisibility(View.VISIBLE);
((ImageView) move).setImageDrawable(app.getIconsCache().getContentIcon(
R.drawable.ic_action_reorder, !nightMode));
move.setTag(new DynamicListView.DragIcon() {
@Override
public void onClick() {
final PopupMenu optionsMenu = new PopupMenu(mapActivity, move);
DirectionsDialogs.setupPopUpMenuIcon(optionsMenu);
MenuItem item;
item = optionsMenu.getMenu().add(
R.string.shared_string_remove).setIcon(app.getIconsCache().
getContentIcon(R.drawable.ic_action_remove_dark));
item.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
if (helperCallbacks != null) {
int pos = adapter.getPosition(marker);
if (pos != -1) {
helperCallbacks.deleteMapMarker(pos);
}
}
return true;
}
});
optionsMenu.show();
}
});
} else {
move.setVisibility(View.GONE);
}
return v; return v;
} }

View file

@ -73,7 +73,7 @@ public class WaypointDialogHelper {
} }
} }
public void setWaypointDialogHelperCallbacks(WaypointDialogHelperCallbacks callbacks) { public void setHelperCallbacks(WaypointDialogHelperCallbacks callbacks) {
this.helperCallbacks = callbacks; this.helperCallbacks = callbacks;
} }