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();