diff --git a/OsmAnd/res/layout/fragment_measurement_tool.xml b/OsmAnd/res/layout/fragment_measurement_tool.xml
index d4b7f7ea57..2fe4dc1416 100644
--- a/OsmAnd/res/layout/fragment_measurement_tool.xml
+++ b/OsmAnd/res/layout/fragment_measurement_tool.xml
@@ -130,33 +130,25 @@
tools:text="@string/add_point_after"/>
-
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:visibility="gone" >
-
+
-
+ android:layout_height="@dimen/content_padding_small" />
-
-
-
-
+ android:layout_height="wrap_content" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/OsmAnd/res/layout/fragment_measurement_tool_points_list.xml b/OsmAnd/res/layout/fragment_measurement_tool_points_list.xml
new file mode 100644
index 0000000000..a0684707ea
--- /dev/null
+++ b/OsmAnd/res/layout/fragment_measurement_tool_points_list.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/OsmAnd/res/values/sizes.xml b/OsmAnd/res/values/sizes.xml
index f4eb13a389..69f711b6fb 100644
--- a/OsmAnd/res/values/sizes.xml
+++ b/OsmAnd/res/values/sizes.xml
@@ -324,6 +324,7 @@
8dp
18dp
71dp
+ 120dp
40dp
48dp
18dp
diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml
index 22b7b37b2f..5f63c1dc0b 100644
--- a/OsmAnd/res/values/strings.xml
+++ b/OsmAnd/res/values/strings.xml
@@ -11,6 +11,9 @@
Thx - Hardy
-->
+ Wait for the route recalculation.\nGraph will be available after recalculation.
+ %1$s data available only on the roads, you need to calculate a route using “Route between points” to get it.
+ Graph
Use 2-phase A* routing algorithm
File is already imported in OsmAnd
Logout successful
diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/PointEditorFragmentNew.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/PointEditorFragmentNew.java
index 7500a17d77..0bc215c366 100644
--- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/PointEditorFragmentNew.java
+++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/PointEditorFragmentNew.java
@@ -618,12 +618,12 @@ public abstract class PointEditorFragmentNew extends BaseOsmAndFragment {
}
}
HorizontalSelectionAdapter horizontalSelectionAdapter = new HorizontalSelectionAdapter(app, nightMode);
- horizontalSelectionAdapter.setItems(new ArrayList<>(iconCategories.keySet()));
- horizontalSelectionAdapter.setSelectedItem(selectedIconCategory);
+ horizontalSelectionAdapter.setTitledItems(new ArrayList<>(iconCategories.keySet()));
+ horizontalSelectionAdapter.setSelectedItemByTitle(selectedIconCategory);
horizontalSelectionAdapter.setListener(new HorizontalSelectionAdapter.HorizontalSelectionAdapterListener() {
@Override
- public void onItemSelected(String item) {
- selectedIconCategory = item;
+ public void onItemSelected(HorizontalSelectionAdapter.HorizontalSelectionItem item) {
+ selectedIconCategory = item.getTitle();
createIconForCategory();
updateIconSelector(selectedIcon, PointEditorFragmentNew.this.view);
}
diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/other/HorizontalSelectionAdapter.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/other/HorizontalSelectionAdapter.java
index bf7844a0f4..0eb3c3b21e 100644
--- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/other/HorizontalSelectionAdapter.java
+++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/other/HorizontalSelectionAdapter.java
@@ -17,6 +17,7 @@ import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R;
import net.osmand.plus.UiUtilities;
+import java.util.ArrayList;
import java.util.List;
import static net.osmand.util.Algorithms.capitalizeFirstLetter;
@@ -24,19 +25,28 @@ import static net.osmand.util.Algorithms.capitalizeFirstLetter;
public class HorizontalSelectionAdapter extends RecyclerView.Adapter {
- private List items;
+ public static int INVALID_ID = -1;
+
+ private List items;
private OsmandApplication app;
private boolean nightMode;
private HorizontalSelectionAdapterListener listener;
-
- private String selectedItem = "";
+ private HorizontalSelectionItem selectedItem = null;
public HorizontalSelectionAdapter(OsmandApplication app, boolean nightMode) {
this.app = app;
this.nightMode = nightMode;
}
- public void setItems(List items) {
+ public void setTitledItems(List titles) {
+ List items = new ArrayList<>();
+ for (String title : titles) {
+ items.add(new HorizontalSelectionItem(title));
+ }
+ setItems(items);
+ }
+
+ public void setItems(List items) {
this.items = items;
}
@@ -44,23 +54,30 @@ public class HorizontalSelectionAdapter extends RecyclerView.Adapter graphTypes = new ArrayList<>();
+
+ private View commonGraphContainer;
+ private View customGraphContainer;
+ private View messageContainer;
+ private LineChart commonGraphChart;
+ private HorizontalBarChart customGraphChart;
+ private RecyclerView graphTypesMenu;
+
+ private enum CommonGraphType {
+ OVERVIEW(R.string.shared_string_overview, false),
+ ALTITUDE(R.string.altitude, true),
+ SLOPE(R.string.shared_string_slope, true),
+ SPEED(R.string.map_widget_speed, false);
+
+ CommonGraphType(int titleId, boolean canBeCalculated) {
+ this.titleId = titleId;
+ this.canBeCalculated = canBeCalculated;
+ }
+
+ final int titleId;
+ final boolean canBeCalculated;
+ }
+
+ public GraphsCard(@NonNull MapActivity mapActivity, MeasurementToolFragment fragment) {
+ super(mapActivity);
+ this.fragment = fragment;
+ }
+
+ @Override
+ protected void updateContent() {
+ if (mapActivity == null || fragment == null) return;
+ editingCtx = fragment.getEditingCtx();
+
+ commonGraphContainer = view.findViewById(R.id.common_graphs_container);
+ customGraphContainer = view.findViewById(R.id.custom_graphs_container);
+ messageContainer = view.findViewById(R.id.message_container);
+ commonGraphChart = (LineChart) view.findViewById(R.id.line_chart);
+ customGraphChart = (HorizontalBarChart) view.findViewById(R.id.horizontal_chart);
+ updateGraphData();
+
+ graphTypesMenu = view.findViewById(R.id.graph_types_recycler_view);
+ graphTypesMenu.setLayoutManager(
+ new LinearLayoutManager(mapActivity, RecyclerView.HORIZONTAL, false));
+
+ refreshGraphTypesSelectionMenu();
+ updateDataView();
+ }
+
+ @Override
+ public int getCardLayoutId() {
+ return R.layout.fragment_measurement_tool_graph;
+ }
+
+ @Override
+ public void onUpdateAdditionalInfo() {
+ if (!isRouteCalculating()) {
+ updateGraphData();
+ refreshGraphTypesSelectionMenu();
+ }
+ updateDataView();
+ }
+
+ private void refreshGraphTypesSelectionMenu() {
+ graphTypesMenu.removeAllViews();
+ OsmandApplication app = getMyApplication();
+ int activeColorId = nightMode ? R.color.active_color_primary_dark : R.color.active_color_primary_light;
+ final HorizontalSelectionAdapter adapter = new HorizontalSelectionAdapter(app, nightMode);
+ final ArrayList items = new ArrayList<>();
+ for (GraphType type : graphTypes) {
+ HorizontalSelectionItem item = new HorizontalSelectionItem(type.getTitle(), type);
+ if (type.isCustom()) {
+ item.setTitleColorId(activeColorId);
+ }
+ if (type.isAvailable()) {
+ items.add(item);
+ }
+ }
+ adapter.setItems(items);
+ String selectedItemKey = visibleGraphType.getTitle();
+ adapter.setSelectedItemByTitle(selectedItemKey);
+ adapter.setListener(new HorizontalSelectionAdapter.HorizontalSelectionAdapterListener() {
+ @Override
+ public void onItemSelected(HorizontalSelectionAdapter.HorizontalSelectionItem item) {
+ adapter.setItems(items);
+ adapter.setSelectedItem(item);
+ GraphType chosenGraphType = (GraphType) item.getObject();
+ if (!isCurrentVisibleType(chosenGraphType)) {
+ setupVisibleGraphType(chosenGraphType);
+ }
+ }
+ });
+ graphTypesMenu.setAdapter(adapter);
+ adapter.notifyDataSetChanged();
+ }
+
+ private void setupVisibleGraphType(GraphType type) {
+ visibleGraphType = type;
+ updateDataView();
+ }
+
+ private boolean isCurrentVisibleType(GraphType type) {
+ if (visibleGraphType != null && type != null) {
+ return Algorithms.objectEquals(visibleGraphType.getTitle(), type.getTitle());
+ }
+ return false;
+ }
+
+ private GraphType getFirstAvailableGraphType() {
+ for (GraphType type : graphTypes) {
+ if (type.isAvailable()) {
+ return type;
+ }
+ }
+ return null;
+ }
+
+ private void updateDataView() {
+ if (isRouteCalculating()) {
+ showProgressMessage();
+ } else if (visibleGraphType.hasData()) {
+ showGraph();
+ } else if (visibleGraphType.canBeCalculated()) {
+ showMessage();
+ }
+ }
+
+ private void showProgressMessage() {
+ commonGraphContainer.setVisibility(View.GONE);
+ customGraphContainer.setVisibility(View.GONE);
+ messageContainer.setVisibility(View.VISIBLE);
+ TextView tvMessage = messageContainer.findViewById(R.id.message_text);
+ ImageView icon = messageContainer.findViewById(R.id.message_icon);
+ ProgressBar pb = messageContainer.findViewById(R.id.progress_bar);
+ pb.setVisibility(View.VISIBLE);
+ icon.setVisibility(View.GONE);
+ tvMessage.setText(R.string.message_graph_will_be_available_after_recalculation);
+ }
+
+ private void showGraph() {
+ if (visibleGraphType.isCustom()) {
+ customGraphChart.clear();
+ commonGraphContainer.setVisibility(View.GONE);
+ customGraphContainer.setVisibility(View.VISIBLE);
+ messageContainer.setVisibility(View.GONE);
+ prepareCustomGraphView((BarData) visibleGraphType.getGraphData());
+ } else {
+ commonGraphChart.clear();
+ commonGraphContainer.setVisibility(View.VISIBLE);
+ customGraphContainer.setVisibility(View.GONE);
+ messageContainer.setVisibility(View.GONE);
+ prepareCommonGraphView((LineData) visibleGraphType.getGraphData());
+ }
+ }
+
+ private void showMessage() {
+ commonGraphContainer.setVisibility(View.GONE);
+ customGraphContainer.setVisibility(View.GONE);
+ messageContainer.setVisibility(View.VISIBLE);
+ TextView tvMessage = messageContainer.findViewById(R.id.message_text);
+ ImageView icon = messageContainer.findViewById(R.id.message_icon);
+ ProgressBar pb = messageContainer.findViewById(R.id.progress_bar);
+ pb.setVisibility(View.GONE);
+ icon.setVisibility(View.VISIBLE);
+ tvMessage.setText(app.getString(
+ R.string.message_need_calculate_route_before_show_graph,
+ visibleGraphType.getTitle()));
+ icon.setImageResource(R.drawable.ic_action_altitude_average);
+ }
+
+ private void prepareCommonGraphView(LineData data) {
+ GpxUiHelper.setupGPXChart(commonGraphChart, 4, 24f, 16f, !nightMode, true);
+ commonGraphChart.setData(data);
+ }
+
+ private void prepareCustomGraphView(BarData data) {
+ OsmandApplication app = getMyApplication();
+ if (app == null) return;
+
+ GpxUiHelper.setupHorizontalGPXChart(app, customGraphChart, 5, 9, 24, true, nightMode);
+ customGraphChart.setExtraRightOffset(16);
+ customGraphChart.setExtraLeftOffset(16);
+ customGraphChart.setData(data);
+ }
+
+ private void updateGraphData() {
+ graphTypes.clear();
+ OsmandApplication app = getMyApplication();
+ GPXTrackAnalysis analysis = createGpxTrackAnalysis();
+
+ // update common graph data
+ for (CommonGraphType commonType : CommonGraphType.values()) {
+ List dataSets = getDataSets(commonType, commonGraphChart, analysis);
+ LineData data = null;
+ if (!Algorithms.isEmpty(dataSets)) {
+ data = new LineData(dataSets);
+ }
+ String title = app.getString(commonType.titleId);
+ graphTypes.add(new GraphType(title, false, commonType.canBeCalculated, data));
+ }
+
+ // update custom graph data
+ List routeSegments = editingCtx.getAllRouteSegments();
+ List routeStatistics = calculateRouteStatistics(routeSegments);
+ if (analysis != null && routeStatistics != null) {
+ for (RouteStatistics statistics : routeStatistics) {
+ String title = SettingsBaseActivity.getStringRouteInfoPropertyValue(app, statistics.name);
+ BarData data = null;
+ if (!Algorithms.isEmpty(statistics.elements)) {
+ data = GpxUiHelper.buildStatisticChart(
+ app, customGraphChart, statistics, analysis, true, nightMode);
+ }
+ graphTypes.add(new GraphType(title, true, false, data));
+ }
+ }
+
+ // update current visible graph type
+ if (visibleGraphType == null) {
+ visibleGraphType = getFirstAvailableGraphType();
+ } else {
+ for (GraphType type : graphTypes) {
+ if (isCurrentVisibleType(type)) {
+ visibleGraphType = type.isAvailable() ? type : getFirstAvailableGraphType();
+ break;
+ }
+ }
+ }
+ }
+
+ private List getDataSets(CommonGraphType type, LineChart chart, GPXTrackAnalysis analysis) {
+ List dataSets = new ArrayList<>();
+ if (chart != null && analysis != null) {
+ OsmandApplication app = getMyApplication();
+ switch (type) {
+ case OVERVIEW: {
+ List dataList = new ArrayList<>();
+ if (analysis.hasSpeedData) {
+ OrderedLineDataSet speedDataSet = GpxUiHelper.createGPXSpeedDataSet(app, chart,
+ analysis, GPXDataSetAxisType.DISTANCE, true, true, false);
+ dataList.add(speedDataSet);
+ }
+ if (analysis.hasElevationData) {
+ OrderedLineDataSet elevationDataSet = GpxUiHelper.createGPXElevationDataSet(app, chart,
+ analysis, GPXDataSetAxisType.DISTANCE, false, true, false);
+ dataList.add(elevationDataSet);
+ OrderedLineDataSet slopeDataSet = GpxUiHelper.createGPXSlopeDataSet(app, chart,
+ analysis, GPXDataSetAxisType.DISTANCE, null, true, true, false);
+ dataList.add(slopeDataSet);
+ }
+ if (dataList.size() > 0) {
+ Collections.sort(dataList, new Comparator() {
+ @Override
+ public int compare(OrderedLineDataSet o1, OrderedLineDataSet o2) {
+ return Float.compare(o1.getPriority(), o2.getPriority());
+ }
+ });
+ }
+ dataSets.addAll(dataList);
+ break;
+ }
+ case ALTITUDE: {
+ if (analysis.hasElevationData) {
+ OrderedLineDataSet elevationDataSet = GpxUiHelper.createGPXElevationDataSet(app, chart,
+ analysis, GPXDataSetAxisType.DISTANCE, false, true, false);//calcWithoutGaps);
+ dataSets.add(elevationDataSet);
+ }
+ break;
+ }
+ case SLOPE:
+ if (analysis.hasElevationData) {
+ OrderedLineDataSet slopeDataSet = GpxUiHelper.createGPXSlopeDataSet(app, chart,
+ analysis, GPXDataSetAxisType.DISTANCE, null, true, true, false);
+ dataSets.add(slopeDataSet);
+ }
+ break;
+ case SPEED: {
+ if (analysis.hasSpeedData) {
+ OrderedLineDataSet speedDataSet = GpxUiHelper.createGPXSpeedDataSet(app, chart,
+ analysis, GPXDataSetAxisType.DISTANCE, false, true, false);//calcWithoutGaps);
+ dataSets.add(speedDataSet);
+ }
+ break;
+ }
+ }
+ }
+ return dataSets;
+ }
+
+ private GPXTrackAnalysis createGpxTrackAnalysis() {
+ GPXFile gpx;
+ if (editingCtx.getGpxData() != null) {
+ gpx = editingCtx.getGpxData().getGpxFile();
+ } else {
+ gpx = editingCtx.exportRouteAsGpx(GRAPH_DATA_GPX_FILE_NAME);
+ }
+ return gpx != null ? gpx.getAnalysis(0) : null;
+ }
+
+ private List calculateRouteStatistics(List route) {
+ OsmandApplication app = getMyApplication();
+ if (route == null || app == null) return null;
+ return RouteDetailsFragment.calculateRouteStatistics(app, route, nightMode);
+ }
+
+ private boolean isRouteCalculating() {
+ return fragment.isProgressBarVisible();
+ }
+
+ private static class GraphType {
+ private String title;
+ private boolean isCustom;
+ private boolean canBeCalculated;
+ private ChartData graphData;
+
+ public GraphType(String title, boolean isCustom, boolean canBeCalculated, ChartData graphData) {
+ this.title = title;
+ this.isCustom = isCustom;
+ this.canBeCalculated = canBeCalculated;
+ this.graphData = graphData;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public boolean isCustom() {
+ return isCustom;
+ }
+
+ public boolean isAvailable() {
+ return hasData() || canBeCalculated();
+ }
+
+ public boolean canBeCalculated() {
+ return canBeCalculated;
+ }
+
+ public boolean hasData() {
+ return getGraphData() != null;
+ }
+
+ public ChartData getGraphData() {
+ return graphData;
+ }
+ }
+}
diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementEditingContext.java b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementEditingContext.java
index c8e0ff043b..66ced9ebd1 100644
--- a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementEditingContext.java
+++ b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementEditingContext.java
@@ -313,6 +313,74 @@ public class MeasurementEditingContext {
return before.points.size();
}
+ public List getAllRouteSegments() {
+ // prepare data for sorting
+ List fullList = new ArrayList<>();
+ for (Map.Entry, RoadSegmentData> entry : roadSegmentData.entrySet()) {
+ fullList.add(new TmpRouteSegmentData(
+ entry.getKey().first,
+ entry.getKey().second,
+ entry.getValue().getSegments()));
+ }
+ // sorting data by connecting together
+ while (fullList.size() > 1) {
+ TmpRouteSegmentData firstInList = fullList.get(0);
+ for (int i = 1; i < fullList.size(); i++) {
+ TmpRouteSegmentData other = fullList.get(i);
+ boolean isMatched = false;
+
+ if (firstInList.isAfterOf(other)) {
+ isMatched = true;
+ firstInList.joinBefore(other);
+ } else if (firstInList.isBeforeOf(other)) {
+ isMatched = true;
+ firstInList.joinAfter(other);
+ }
+
+ if (isMatched) {
+ fullList.remove(other);
+ break;
+ }
+ }
+ }
+ return fullList.size() > 0 ? fullList.get(0).getRouteSegments() : null;
+ }
+
+ private static class TmpRouteSegmentData {
+ private WptPt start;
+ private WptPt end;
+ private List routeSegments;
+
+ public TmpRouteSegmentData(WptPt start, WptPt end,
+ List routeSegments) {
+ this.start = start;
+ this.end = end;
+ this.routeSegments = new ArrayList<>(routeSegments);
+ }
+
+ boolean isAfterOf(TmpRouteSegmentData other) {
+ return Algorithms.objectEquals(this.start, other.end);
+ }
+
+ boolean isBeforeOf(TmpRouteSegmentData other) {
+ return Algorithms.objectEquals(this.end, other.start);
+ }
+
+ void joinAfter(TmpRouteSegmentData other) {
+ end = other.end;
+ routeSegments.addAll(other.routeSegments);
+ }
+
+ void joinBefore(TmpRouteSegmentData other) {
+ start = other.start;
+ routeSegments.addAll(0, other.routeSegments);
+ }
+
+ public List getRouteSegments() {
+ return routeSegments;
+ }
+ }
+
void splitSegments(int position) {
List points = new ArrayList<>();
points.addAll(before.points);
diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java
index b2b9b509b4..c40e7b70ca 100644
--- a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java
+++ b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java
@@ -5,7 +5,6 @@ import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
-import android.os.Build;
import android.os.Bundle;
import android.util.TypedValue;
import android.view.LayoutInflater;
@@ -14,6 +13,7 @@ import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.ImageButton;
import android.widget.ImageView;
+import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
@@ -24,10 +24,8 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import androidx.core.widget.TextViewCompat;
-import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.recyclerview.widget.ItemTouchHelper;
-import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.snackbar.Snackbar;
@@ -62,7 +60,6 @@ import net.osmand.plus.measurementtool.RouteBetweenPointsBottomSheetDialogFragme
import net.osmand.plus.measurementtool.RouteBetweenPointsBottomSheetDialogFragment.RouteBetweenPointsFragmentListener;
import net.osmand.plus.measurementtool.SaveGpxRouteAsyncTask.SaveGpxRouteListener;
import net.osmand.plus.measurementtool.SelectedPointBottomSheetDialogFragment.SelectedPointFragmentListener;
-import net.osmand.plus.measurementtool.adapter.MeasurementToolAdapter;
import net.osmand.plus.measurementtool.adapter.MeasurementToolAdapter.MeasurementAdapterListener;
import net.osmand.plus.measurementtool.command.AddPointCommand;
import net.osmand.plus.measurementtool.command.ApplyGpxApproximationCommand;
@@ -73,9 +70,9 @@ import net.osmand.plus.measurementtool.command.MovePointCommand;
import net.osmand.plus.measurementtool.command.RemovePointCommand;
import net.osmand.plus.measurementtool.command.ReorderPointCommand;
import net.osmand.plus.measurementtool.command.ReversePointsCommand;
+import net.osmand.plus.routepreparationmenu.cards.BaseCard;
import net.osmand.plus.settings.backend.ApplicationMode;
import net.osmand.plus.settings.backend.OsmandSettings;
-import net.osmand.plus.views.controls.ReorderItemTouchHelperCallback;
import net.osmand.plus.views.layers.MapControlsLayer;
import net.osmand.plus.views.mapwidgets.MapInfoWidgetsFactory.TopToolbarController;
import net.osmand.plus.views.mapwidgets.MapInfoWidgetsFactory.TopToolbarControllerType;
@@ -93,6 +90,8 @@ import java.util.Locale;
import static net.osmand.IndexConstants.GPX_FILE_EXT;
import static net.osmand.IndexConstants.GPX_INDEX_DIR;
+import static net.osmand.plus.UiUtilities.CustomRadioButtonType.END;
+import static net.osmand.plus.UiUtilities.CustomRadioButtonType.START;
import static net.osmand.plus.measurementtool.MeasurementEditingContext.CalculationMode;
import static net.osmand.plus.measurementtool.MeasurementEditingContext.SnapToRoadProgressListener;
import static net.osmand.plus.measurementtool.SaveAsNewTrackBottomSheetDialogFragment.SaveAsNewTrackFragmentListener;
@@ -110,18 +109,16 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
public static final String TAG = MeasurementToolFragment.class.getSimpleName();
public static final String TAPS_DISABLED_KEY = "taps_disabled_key";
- private RecyclerView pointsRv;
private String previousToolBarTitle = "";
private MeasurementToolBarController toolBarController;
- private MeasurementToolAdapter adapter;
private TextView distanceTv;
private TextView pointsTv;
private TextView distanceToCenterTv;
private String pointsSt;
- private Drawable upIcon;
- private Drawable downIcon;
- private View pointsListContainer;
- private View upDownRow;
+ private View additionalInfoContainer;
+ private ViewGroup additionalInfoCardsContainer;
+ private BaseCard visibleAdditionalInfoCard;
+ private LinearLayout customRadioButton;
private View mainView;
private ImageView upDownBtn;
private ImageView undoBtn;
@@ -130,9 +127,11 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
private Snackbar snackbar;
private String fileName;
+ private AdditionalInfoType currentAdditionalInfoType;
+
private boolean wasCollapseButtonVisible;
private boolean progressBarVisible;
- private boolean pointsListOpened;
+ private boolean additionalInfoExpanded;
private static final int PLAN_ROUTE_MODE = 0x1;
private static final int DIRECTION_MODE = 0x2;
@@ -160,8 +159,9 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
SHOW_IS_SAVED_FRAGMENT
}
- protected MeasurementEditingContext getEditingCtx() {
- return editingCtx;
+ private enum AdditionalInfoType {
+ POINTS,
+ GRAPH
}
private void setEditingCtx(MeasurementEditingContext editingCtx) {
@@ -223,6 +223,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
@Override
public void showProgressBar() {
MeasurementToolFragment.this.showProgressBar();
+ updateAdditionalInfoView();
}
@Override
@@ -234,6 +235,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
public void hideProgressBar() {
((ProgressBar) mainView.findViewById(R.id.snap_to_road_progress_bar)).setVisibility(View.GONE);
progressBarVisible = false;
+ updateAdditionalInfoView();
}
@Override
@@ -245,17 +247,9 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
measurementLayer.setEditingCtx(editingCtx);
- // If rotate the screen from landscape to portrait when the list of points is displayed then
- // the RecyclerViewFragment will exist without view. This is necessary to remove it.
- if (!portrait) {
- hidePointsListFragment();
- }
-
nightMode = mapActivity.getMyApplication().getDaynightHelper().isNightModeForMapControls();
portrait = AndroidUiHelper.isOrientationPortrait(mapActivity);
- upIcon = getContentIcon(R.drawable.ic_action_arrow_up);
- downIcon = getContentIcon(R.drawable.ic_action_arrow_down);
pointsSt = getString(R.string.shared_string_gpx_points).toLowerCase();
View view = UiUtilities.getInflater(getContext(), nightMode)
@@ -263,12 +257,30 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
mainView = view.findViewById(R.id.main_view);
AndroidUtils.setBackground(mapActivity, mainView, nightMode, R.drawable.bg_bottom_menu_light, R.drawable.bg_bottom_menu_dark);
- pointsListContainer = view.findViewById(R.id.points_list_container);
- if (portrait && pointsListContainer != null) {
- final int backgroundColor = ContextCompat.getColor(mapActivity, nightMode
- ? R.color.activity_background_color_dark
- : R.color.activity_background_color_light);
- pointsListContainer.setBackgroundColor(backgroundColor);
+ additionalInfoContainer = mainView.findViewById(R.id.additional_info_container);
+ additionalInfoCardsContainer = mainView.findViewById(R.id.cards_container);
+ if (portrait) {
+ customRadioButton = mainView.findViewById(R.id.custom_radio_buttons);
+
+ View pointListBtn = customRadioButton.findViewById(R.id.left_button_container);
+ TextView tvPointListBtn = customRadioButton.findViewById(R.id.left_button);
+ tvPointListBtn.setText(R.string.shared_string_gpx_points);
+ pointListBtn.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ changeAdditionalInfoType(AdditionalInfoType.POINTS);
+ }
+ });
+
+ View graphBtn = customRadioButton.findViewById(R.id.right_button_container);
+ TextView tvGraphBtn = customRadioButton.findViewById(R.id.right_button);
+ tvGraphBtn.setText(R.string.shared_string_graph);
+ graphBtn.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ changeAdditionalInfoType(AdditionalInfoType.GRAPH);
+ }
+ });
}
if (progressBarVisible) {
@@ -281,7 +293,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
mainIcon = (ImageView) mainView.findViewById(R.id.main_icon);
upDownBtn = (ImageView) mainView.findViewById(R.id.up_down_button);
- upDownBtn.setImageDrawable(upIcon);
+ updateUpDownBtn();
mainView.findViewById(R.id.cancel_move_point_button).setOnClickListener(new OnClickListener() {
@Override
@@ -297,14 +309,14 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
}
});
- upDownRow = mainView.findViewById(R.id.up_down_row);
+ View upDownRow = mainView.findViewById(R.id.up_down_row);
upDownRow.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
- if (!pointsListOpened && editingCtx.getPointsCount() > 0 && editingCtx.getSelectedPointPosition() == -1) {
- showPointsList();
+ if (!additionalInfoExpanded && editingCtx.getPointsCount() > 0 && editingCtx.getSelectedPointPosition() == -1) {
+ expandAdditionalInfoView();
} else {
- hidePointsList();
+ collapseAdditionalInfoView();
}
}
});
@@ -397,8 +409,8 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
@Override
public void onSelectPoint(int selectedPointPos) {
- if (pointsListOpened) {
- hidePointsList();
+ if (additionalInfoExpanded) {
+ collapseAdditionalInfoView();
}
if (selectedPointPos != -1) {
openSelectedPointMenu(mapActivity);
@@ -421,8 +433,8 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
measurementLayer.setOnEnterMovePointModeListener(new MeasurementToolLayer.OnEnterMovePointModeListener() {
@Override
public void onEnterMovePointMode() {
- if (pointsListOpened) {
- hidePointsList();
+ if (additionalInfoExpanded) {
+ collapseAdditionalInfoView();
}
switchMovePointMode(true);
}
@@ -475,18 +487,6 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
updateToolbar();
final GpxData gpxData = editingCtx.getGpxData();
- adapter = new MeasurementToolAdapter(getMapActivity(), editingCtx.getPoints(),
- gpxData != null ? gpxData.getActionType() : null);
- if (portrait) {
- pointsRv = mainView.findViewById(R.id.measure_points_recycler_view);
- } else {
- pointsRv = new RecyclerView(getActivity());
- }
- ItemTouchHelper touchHelper = new ItemTouchHelper(new ReorderItemTouchHelperCallback(adapter));
- touchHelper.attachToRecyclerView(pointsRv);
- adapter.setAdapterListener(createMeasurementAdapterListener(touchHelper));
- pointsRv.setLayoutManager(new LinearLayoutManager(getContext()));
- pointsRv.setAdapter(adapter);
ImageButton snapToRoadBtn = (ImageButton) mapActivity.findViewById(R.id.snap_to_road_image_button);
snapToRoadBtn.setBackgroundResource(nightMode ? R.drawable.btn_circle_night : R.drawable.btn_circle);
@@ -513,6 +513,36 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
return view;
}
+ private void changeAdditionalInfoType(@NonNull AdditionalInfoType type) {
+ if (!additionalInfoExpanded || !isCurrentAdditionalInfoType(type)) {
+ MapActivity ma = getMapActivity();
+ if (ma == null) return;
+ currentAdditionalInfoType = type;
+ updateUpDownBtn();
+ OsmandApplication app = ma.getMyApplication();
+ BaseCard additionalInfoCard = null;
+ if (AdditionalInfoType.POINTS == type) {
+ additionalInfoCard = new PointsCard(ma, this);
+ UiUtilities.updateCustomRadioButtons(app, customRadioButton, nightMode, START);
+ } else if (AdditionalInfoType.GRAPH == type) {
+ additionalInfoCard = new GraphsCard(ma, this);
+ UiUtilities.updateCustomRadioButtons(app, customRadioButton, nightMode, END);
+ }
+ if (additionalInfoCard != null) {
+ visibleAdditionalInfoCard = additionalInfoCard;
+ additionalInfoCardsContainer.removeAllViews();
+ additionalInfoCardsContainer.addView(additionalInfoCard.build(ma));
+ additionalInfoExpanded = true;
+ }
+ }
+ }
+
+ private void updateAdditionalInfoView() {
+ if (visibleAdditionalInfoCard instanceof OnUpdateAdditionalInfoListener) {
+ ((OnUpdateAdditionalInfoListener) visibleAdditionalInfoCard).onUpdateAdditionalInfo();
+ }
+ }
+
public boolean isInEditMode() {
return !isPlanRouteMode() && !editingCtx.isNewData() && !isDirectionMode() && !isFollowTrackMode();
}
@@ -521,12 +551,16 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
this.fileName = fileName;
}
+ public MeasurementEditingContext getEditingCtx() {
+ return editingCtx;
+ }
+
private void updateUndoRedoCommonStuff() {
- hidePointsListIfNoPoints();
+ collapseAdditionalInfoIfNoPointsEnough();
if (editingCtx.getPointsCount() > 0) {
enable(upDownBtn);
}
- adapter.notifyDataSetChanged();
+ updateAdditionalInfoView();
updateDistancePointsText();
updateSnapToRoadControls();
}
@@ -586,9 +620,8 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
super.onDestroyView();
cancelModes();
exitMeasurementMode();
- adapter.setAdapterListener(null);
- if (pointsListOpened) {
- hidePointsList();
+ if (additionalInfoExpanded) {
+ collapseAdditionalInfoView();
}
MeasurementToolLayer layer = getMeasurementLayer();
if (layer != null) {
@@ -636,6 +669,10 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
progressBarVisible = true;
}
+ public boolean isProgressBarVisible() {
+ return progressBarVisible;
+ }
+
private void updateMainIcon() {
GpxData gpxData = editingCtx.getGpxData();
if (gpxData != null) {
@@ -839,8 +876,8 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
MeasurementToolLayer measurementLayer = getMeasurementLayer();
editingCtx.getCommandManager().execute(new ClearPointsCommand(measurementLayer, ALL));
editingCtx.cancelSnapToRoad();
- if (pointsListOpened) {
- hidePointsList();
+ if (additionalInfoExpanded) {
+ collapseAdditionalInfoView();
}
updateUndoRedoButton(false, redoBtn);
disable(upDownBtn);
@@ -855,8 +892,8 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
if (points.size() > 1) {
MeasurementToolLayer measurementLayer = getMeasurementLayer();
editingCtx.getCommandManager().execute(new ReversePointsCommand(measurementLayer));
- if (pointsListOpened) {
- hidePointsList();
+ if (additionalInfoExpanded) {
+ collapseAdditionalInfoView();
}
updateUndoRedoButton(false, redoBtn);
updateUndoRedoButton(true, undoBtn);
@@ -924,8 +961,8 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
private void trimRoute(ClearCommandMode before) {
MeasurementToolLayer measurementLayer = getMeasurementLayer();
editingCtx.getCommandManager().execute(new ClearPointsCommand(measurementLayer, before));
- if (pointsListOpened) {
- hidePointsList();
+ if (additionalInfoExpanded) {
+ collapseAdditionalInfoView();
}
editingCtx.setSelectedPointPosition(-1);
editingCtx.splitSegments(editingCtx.getBeforePoints().size() + editingCtx.getAfterPoints().size());
@@ -1082,11 +1119,11 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
private void removePoint(MeasurementToolLayer measurementLayer, int position) {
if (measurementLayer != null) {
editingCtx.getCommandManager().execute(new RemovePointCommand(measurementLayer, position));
- adapter.notifyDataSetChanged();
+ updateAdditionalInfoView();
updateUndoRedoButton(true, undoBtn);
updateUndoRedoButton(false, redoBtn);
updateDistancePointsText();
- hidePointsListIfNoPoints();
+ collapseAdditionalInfoIfNoPointsEnough();
}
}
@@ -1109,7 +1146,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
}
}
- private MeasurementAdapterListener createMeasurementAdapterListener(final ItemTouchHelper touchHelper) {
+ MeasurementAdapterListener createMeasurementAdapterListener(final ItemTouchHelper touchHelper) {
return new MeasurementAdapterListener() {
final MapActivity mapActivity = getMapActivity();
@@ -1125,8 +1162,8 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
@Override
public void onItemClick(int position) {
if (mapActivity != null && measurementLayer != null) {
- if (pointsListOpened) {
- hidePointsList();
+ if (additionalInfoExpanded) {
+ collapseAdditionalInfoView();
}
if (portrait) {
setMapPosition(OsmandSettings.MIDDLE_TOP_CONSTANT);
@@ -1148,7 +1185,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
toPosition = holder.getAdapterPosition();
if (toPosition >= 0 && fromPosition >= 0 && toPosition != fromPosition) {
editingCtx.getCommandManager().execute(new ReorderPointCommand(measurementLayer, fromPosition, toPosition));
- adapter.notifyDataSetChanged();
+ updateAdditionalInfoView();
updateUndoRedoButton(false, redoBtn);
updateDistancePointsText();
mapActivity.refreshMap();
@@ -1214,7 +1251,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
if (!isUndoMode()) {
editingCtx.addPoints(points);
}
- adapter.notifyDataSetChanged();
+ updateAdditionalInfoView();
updateDistancePointsText();
}
}
@@ -1226,7 +1263,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
if (!isUndoMode()) {
editingCtx.addPoints();
}
- adapter.notifyDataSetChanged();
+ updateAdditionalInfoView();
updateDistancePointsText();
}
}
@@ -1422,80 +1459,48 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
updateUndoRedoButton(true, undoBtn);
updateUndoRedoButton(false, redoBtn);
updateDistancePointsText();
- adapter.notifyDataSetChanged();
+ updateAdditionalInfoView();
}
- private void showPointsList() {
- pointsListOpened = true;
- upDownBtn.setImageDrawable(downIcon);
- MapActivity mapActivity = getMapActivity();
- if (mapActivity != null) {
- if (portrait && pointsListContainer != null) {
- pointsListContainer.setVisibility(View.VISIBLE);
- } else {
- showPointsListFragment();
+ private void expandAdditionalInfoView() {
+ if (portrait) {
+ MapActivity mapActivity = getMapActivity();
+ if (mapActivity != null) {
+ additionalInfoContainer.setVisibility(View.VISIBLE);
+ AdditionalInfoType typeToShow = currentAdditionalInfoType == null
+ ? AdditionalInfoType.POINTS : currentAdditionalInfoType;
+ changeAdditionalInfoType(typeToShow);
+ setMapPosition(portrait
+ ? OsmandSettings.MIDDLE_TOP_CONSTANT
+ : OsmandSettings.LANDSCAPE_MIDDLE_RIGHT_CONSTANT);
}
- setMapPosition(portrait
- ? OsmandSettings.MIDDLE_TOP_CONSTANT
- : OsmandSettings.LANDSCAPE_MIDDLE_RIGHT_CONSTANT);
}
}
- private void hidePointsList() {
- pointsListOpened = false;
- upDownBtn.setImageDrawable(upIcon);
- if (portrait && pointsListContainer != null) {
- pointsListContainer.setVisibility(View.GONE);
- } else {
- hidePointsListFragment();
+ private void collapseAdditionalInfoView() {
+ if (portrait) {
+ additionalInfoExpanded = false;
+ updateUpDownBtn();
+ additionalInfoContainer.setVisibility(View.GONE);
+ setDefaultMapPosition();
}
- setDefaultMapPosition();
}
- private void hidePointsListIfNoPoints() {
+ private void collapseAdditionalInfoIfNoPointsEnough() {
MeasurementToolLayer measurementLayer = getMeasurementLayer();
if (measurementLayer != null) {
- if (editingCtx.getPointsCount() < 1) {
+ int pointsCount = editingCtx.getPointsCount();
+ if (isCurrentAdditionalInfoType(AdditionalInfoType.GRAPH) && pointsCount < 2) {
+ collapseAdditionalInfoView();
+ } else if (pointsCount < 1) {
disable(upDownBtn);
- if (pointsListOpened) {
- hidePointsList();
+ if (additionalInfoExpanded) {
+ collapseAdditionalInfoView();
}
}
}
}
- private void showPointsListFragment() {
- MapActivity mapActivity = getMapActivity();
- if (mapActivity != null) {
- boolean transparentStatusBar = Build.VERSION.SDK_INT >= 21;
- int statusBarHeight = transparentStatusBar ? 0 : AndroidUtils.getStatusBarHeight(mapActivity);
- int screenHeight = AndroidUtils.getScreenHeight(mapActivity) - statusBarHeight;
- RecyclerViewFragment fragment = new RecyclerViewFragment();
- fragment.setRecyclerView(pointsRv);
- fragment.setWidth(upDownRow.getWidth());
- fragment.setHeight(screenHeight - upDownRow.getHeight());
- fragment.setTransparentStatusBar(transparentStatusBar);
- mapActivity.getSupportFragmentManager().beginTransaction()
- .add(R.id.fragmentContainer, fragment, RecyclerViewFragment.TAG)
- .commitAllowingStateLoss();
- }
- }
-
- private void hidePointsListFragment() {
- MapActivity mapActivity = getMapActivity();
- if (mapActivity != null) {
- try {
- FragmentManager manager = mapActivity.getSupportFragmentManager();
- Fragment fragment = manager.findFragmentByTag(RecyclerViewFragment.TAG);
- if (fragment != null) {
- manager.beginTransaction().remove(fragment).commitAllowingStateLoss();
- }
- } catch (Exception e) {
- // ignore
- }
- }
- }
-
private void setDefaultMapPosition() {
setMapPosition(OsmandSettings.CENTER_CONSTANT);
}
@@ -1520,6 +1525,16 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
}
}
+ private void updateUpDownBtn() {
+ Drawable icon = getContentIcon(additionalInfoExpanded
+ ? R.drawable.ic_action_arrow_down : R.drawable.ic_action_arrow_up);
+ upDownBtn.setImageDrawable(icon);
+ }
+
+ private boolean isCurrentAdditionalInfoType(@NonNull AdditionalInfoType type) {
+ return type.equals(currentAdditionalInfoType);
+ }
+
private String getSuggestedFileName() {
GpxData gpxData = editingCtx.getGpxData();
String displayedName = null;
@@ -1803,8 +1818,8 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
final MapActivity mapActivity = getMapActivity();
MeasurementToolLayer measurementLayer = getMeasurementLayer();
if (mapActivity != null && measurementLayer != null) {
- if (pointsListOpened && hidePointsListFirst) {
- hidePointsList();
+ if (additionalInfoExpanded && hidePointsListFirst) {
+ collapseAdditionalInfoView();
return;
}
if (!editingCtx.hasChanges()) {
@@ -1824,8 +1839,8 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
if (clearContext) {
editingCtx.clearSegments();
}
- if (pointsListOpened) {
- hidePointsList();
+ if (additionalInfoExpanded) {
+ collapseAdditionalInfoView();
}
resetAppMode();
hideSnapToRoadIcon();
@@ -1962,8 +1977,8 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
if (!editingCtx.getCommandManager().update(command)) {
editingCtx.getCommandManager().execute(command);
}
- if (pointsListOpened) {
- hidePointsList();
+ if (additionalInfoExpanded) {
+ collapseAdditionalInfoView();
}
updateSnapToRoadControls();
}
@@ -2037,4 +2052,8 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
public boolean isNightModeForMapControls() {
return nightMode;
}
+
+ public interface OnUpdateAdditionalInfoListener {
+ void onUpdateAdditionalInfo();
+ }
}
\ No newline at end of file
diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/PointsCard.java b/OsmAnd/src/net/osmand/plus/measurementtool/PointsCard.java
new file mode 100644
index 0000000000..4b0117bd42
--- /dev/null
+++ b/OsmAnd/src/net/osmand/plus/measurementtool/PointsCard.java
@@ -0,0 +1,48 @@
+package net.osmand.plus.measurementtool;
+
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.ItemTouchHelper;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+
+import net.osmand.plus.R;
+import net.osmand.plus.activities.MapActivity;
+import net.osmand.plus.measurementtool.MeasurementToolFragment.OnUpdateAdditionalInfoListener;
+import net.osmand.plus.measurementtool.adapter.MeasurementToolAdapter;
+import net.osmand.plus.routepreparationmenu.cards.BaseCard;
+import net.osmand.plus.views.controls.ReorderItemTouchHelperCallback;
+
+public class PointsCard extends BaseCard implements OnUpdateAdditionalInfoListener {
+
+ private MeasurementToolAdapter adapter;
+ private MeasurementToolFragment fragment;
+
+ public PointsCard(@NonNull MapActivity mapActivity, MeasurementToolFragment fragment) {
+ super(mapActivity);
+ this.fragment = fragment;
+ }
+
+ @Override
+ public void onUpdateAdditionalInfo() {
+ adapter.notifyDataSetChanged();
+ }
+
+ @Override
+ public int getCardLayoutId() {
+ return R.layout.fragment_measurement_tool_points_list;
+ }
+
+ @Override
+ protected void updateContent() {
+ MeasurementEditingContext editingCtx = fragment.getEditingCtx();
+ final GpxData gpxData = editingCtx.getGpxData();
+ adapter = new MeasurementToolAdapter(mapActivity, editingCtx.getPoints(),
+ gpxData != null ? gpxData.getActionType() : null);
+ RecyclerView pointsRv = view.findViewById(R.id.measure_points_recycler_view);
+ ItemTouchHelper touchHelper = new ItemTouchHelper(new ReorderItemTouchHelperCallback(adapter));
+ touchHelper.attachToRecyclerView(pointsRv);
+ adapter.setAdapterListener(fragment.createMeasurementAdapterListener(touchHelper));
+ pointsRv.setLayoutManager(new LinearLayoutManager(app));
+ pointsRv.setAdapter(adapter);
+ }
+}
diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/SelectFileBottomSheet.java b/OsmAnd/src/net/osmand/plus/measurementtool/SelectFileBottomSheet.java
index c155ec493c..b89cbda954 100644
--- a/OsmAnd/src/net/osmand/plus/measurementtool/SelectFileBottomSheet.java
+++ b/OsmAnd/src/net/osmand/plus/measurementtool/SelectFileBottomSheet.java
@@ -28,6 +28,7 @@ import net.osmand.plus.helpers.GpxUiHelper.GPXInfo;
import net.osmand.plus.helpers.enums.TracksSortByMode;
import net.osmand.plus.mapcontextmenu.other.HorizontalSelectionAdapter;
import net.osmand.plus.mapcontextmenu.other.HorizontalSelectionAdapter.HorizontalSelectionAdapterListener;
+import net.osmand.plus.mapcontextmenu.other.HorizontalSelectionAdapter.HorizontalSelectionItem;
import java.io.File;
import java.util.ArrayList;
@@ -128,7 +129,7 @@ public class SelectFileBottomSheet extends BottomSheetBehaviourDialogFragment {
sortButton.setImageResource(mode.getIconId());
updateDescription(descriptionView);
sortFolderList();
- folderAdapter.setItems(getFolderNames());
+ folderAdapter.setTitledItems(getFolderNames());
folderAdapter.notifyDataSetChanged();
sortFileList();
adapter.notifyDataSetChanged();
@@ -191,13 +192,13 @@ public class SelectFileBottomSheet extends BottomSheetBehaviourDialogFragment {
folders = new ArrayList<>();
collectDirs(gpxDir, folders);
sortFolderList();
- folderAdapter.setItems(getFolderNames());
- folderAdapter.setSelectedItem(selectedFolder);
+ folderAdapter.setTitledItems(getFolderNames());
+ folderAdapter.setSelectedItemByTitle(selectedFolder);
foldersRecyclerView.setAdapter(folderAdapter);
folderAdapter.setListener(new HorizontalSelectionAdapterListener() {
@Override
- public void onItemSelected(String item) {
- selectedFolder = item;
+ public void onItemSelected(HorizontalSelectionItem item) {
+ selectedFolder = item.getTitle();
updateFileList(folderAdapter);
}
});
diff --git a/OsmAnd/src/net/osmand/plus/routepreparationmenu/RouteDetailsFragment.java b/OsmAnd/src/net/osmand/plus/routepreparationmenu/RouteDetailsFragment.java
index fcab4d6578..1f29dfd1b7 100644
--- a/OsmAnd/src/net/osmand/plus/routepreparationmenu/RouteDetailsFragment.java
+++ b/OsmAnd/src/net/osmand/plus/routepreparationmenu/RouteDetailsFragment.java
@@ -345,18 +345,9 @@ public class RouteDetailsFragment extends ContextMenuFragment implements PublicT
List route = app.getRoutingHelper().getRoute().getOriginalRoute();
if (route != null) {
- RenderingRulesStorage currentRenderer = app.getRendererRegistry().getCurrentSelectedRenderer();
- RenderingRulesStorage defaultRender = app.getRendererRegistry().defaultRender();
-
- MapRenderRepositories maps = app.getResourceManager().getRenderer();
- RenderingRuleSearchRequest currentSearchRequest = maps.getSearchRequestWithAppliedCustomRules(currentRenderer, isNightMode());
- RenderingRuleSearchRequest defaultSearchRequest = maps.getSearchRequestWithAppliedCustomRules(defaultRender, isNightMode());
-
- List routeStatistics = RouteStatisticsHelper.calculateRouteStatistic(route,
- currentRenderer, defaultRender, currentSearchRequest, defaultSearchRequest);
+ List routeStatistics = calculateRouteStatistics(app, route, isNightMode());
GPXTrackAnalysis analysis = gpx.getAnalysis(0);
-
for (RouteStatistics statistic : routeStatistics) {
RouteInfoCard routeClassCard = new RouteInfoCard(mapActivity, statistic, analysis);
addRouteCard(cardsContainer, routeClassCard);
@@ -375,6 +366,20 @@ public class RouteDetailsFragment extends ContextMenuFragment implements PublicT
}
}
+ public static List calculateRouteStatistics(OsmandApplication app,
+ List route,
+ boolean nightMode) {
+ RenderingRulesStorage currentRenderer = app.getRendererRegistry().getCurrentSelectedRenderer();
+ RenderingRulesStorage defaultRender = app.getRendererRegistry().defaultRender();
+ MapRenderRepositories maps = app.getResourceManager().getRenderer();
+ RenderingRuleSearchRequest currentSearchRequest =
+ maps.getSearchRequestWithAppliedCustomRules(currentRenderer, nightMode);
+ RenderingRuleSearchRequest defaultSearchRequest =
+ maps.getSearchRequestWithAppliedCustomRules(defaultRender, nightMode);
+ return RouteStatisticsHelper.calculateRouteStatistic(route, currentRenderer,
+ defaultRender, currentSearchRequest, defaultSearchRequest);
+ }
+
@Override
protected void calculateLayout(View view, boolean initLayout) {
super.calculateLayout(view, initLayout);
diff --git a/OsmAnd/src/net/osmand/plus/routepreparationmenu/cards/TracksToFollowCard.java b/OsmAnd/src/net/osmand/plus/routepreparationmenu/cards/TracksToFollowCard.java
index 94770e0135..c21b508116 100644
--- a/OsmAnd/src/net/osmand/plus/routepreparationmenu/cards/TracksToFollowCard.java
+++ b/OsmAnd/src/net/osmand/plus/routepreparationmenu/cards/TracksToFollowCard.java
@@ -85,13 +85,13 @@ public class TracksToFollowCard extends BaseCard {
private void setupCategoriesRow() {
final HorizontalSelectionAdapter selectionAdapter = new HorizontalSelectionAdapter(app, nightMode);
- selectionAdapter.setItems(new ArrayList<>(gpxInfoCategories.keySet()));
- selectionAdapter.setSelectedItem(selectedCategory);
+ selectionAdapter.setTitledItems(new ArrayList<>(gpxInfoCategories.keySet()));
+ selectionAdapter.setSelectedItemByTitle(selectedCategory);
selectionAdapter.setListener(new HorizontalSelectionAdapter.HorizontalSelectionAdapterListener() {
@Override
- public void onItemSelected(String item) {
- selectedCategory = item;
- List items = gpxInfoCategories.get(item);
+ public void onItemSelected(HorizontalSelectionAdapter.HorizontalSelectionItem item) {
+ selectedCategory = item.getTitle();
+ List items = gpxInfoCategories.get(selectedCategory);
tracksAdapter.setShowFolderName(showFoldersName());
tracksAdapter.setGpxInfoList(items != null ? items : new ArrayList());
tracksAdapter.notifyDataSetChanged();
diff --git a/OsmAnd/src/net/osmand/plus/settings/bottomsheets/VehicleParametersBottomSheet.java b/OsmAnd/src/net/osmand/plus/settings/bottomsheets/VehicleParametersBottomSheet.java
index 5ac7aea8e8..9d3275e8fd 100644
--- a/OsmAnd/src/net/osmand/plus/settings/bottomsheets/VehicleParametersBottomSheet.java
+++ b/OsmAnd/src/net/osmand/plus/settings/bottomsheets/VehicleParametersBottomSheet.java
@@ -121,7 +121,7 @@ public class VehicleParametersBottomSheet extends BasePreferenceBottomSheet {
currentValue = 0.0f;
}
selectedItem = preference.getEntryFromValue(String.valueOf(currentValue));
- adapter.setSelectedItem(selectedItem);
+ adapter.setSelectedItemByTitle(selectedItem);
int itemPosition = adapter.getItemPosition(selectedItem);
if (itemPosition >= 0) {
recyclerView.smoothScrollToPosition(itemPosition);
@@ -129,11 +129,11 @@ public class VehicleParametersBottomSheet extends BasePreferenceBottomSheet {
}
});
- adapter.setItems(Arrays.asList(preference.getEntries()));
+ adapter.setTitledItems(Arrays.asList(preference.getEntries()));
adapter.setListener(new HorizontalSelectionAdapter.HorizontalSelectionAdapterListener() {
@Override
- public void onItemSelected(String item) {
- selectedItem = item;
+ public void onItemSelected(HorizontalSelectionAdapter.HorizontalSelectionItem item) {
+ selectedItem = item.getTitle();
currentValue = preference.getValueFromEntries(selectedItem);
String currentValueStr = currentValue == 0.0f
? "" : df.format(currentValue + 0.01f);
@@ -145,7 +145,7 @@ public class VehicleParametersBottomSheet extends BasePreferenceBottomSheet {
}
});
recyclerView.setAdapter(adapter);
- adapter.setSelectedItem(selectedItem);
+ adapter.setSelectedItemByTitle(selectedItem);
return new BaseBottomSheetItem.Builder()
.setCustomView(mainView)
.create();