commit
b5f10aaae0
15 changed files with 618 additions and 69 deletions
72
OsmAnd/res/layout/bottom_sheet_select_segment.xml
Normal file
72
OsmAnd/res/layout/bottom_sheet_select_segment.xml
Normal file
|
@ -0,0 +1,72 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:osmand="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:paddingStart="@dimen/content_padding"
|
||||
android:paddingLeft="@dimen/content_padding"
|
||||
android:paddingTop="@dimen/measurement_tool_menu_title_padding_top"
|
||||
android:paddingEnd="@dimen/content_padding"
|
||||
android:paddingRight="@dimen/content_padding"
|
||||
android:paddingBottom="@dimen/measurement_tool_button_padding_top">
|
||||
|
||||
<net.osmand.plus.widgets.TextViewEx
|
||||
android:id="@+id/title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="@dimen/widget_turn_lane_margin"
|
||||
android:ellipsize="end"
|
||||
android:gravity="center_vertical"
|
||||
android:letterSpacing="@dimen/text_button_letter_spacing"
|
||||
android:lineSpacingExtra="@dimen/titleLineSpacingExtra"
|
||||
android:maxLines="1"
|
||||
android:text="@string/select_segments"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:textSize="@dimen/default_list_text_size"
|
||||
osmand:typeface="@string/font_roboto_medium" />
|
||||
|
||||
<net.osmand.plus.widgets.TextViewEx
|
||||
android:id="@+id/description"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="@dimen/list_header_settings_top_margin"
|
||||
android:letterSpacing="@dimen/description_letter_spacing"
|
||||
android:lineSpacingMultiplier="@dimen/bottom_sheet_text_spacing_multiplier"
|
||||
android:lineSpacingExtra="@dimen/descriptionLineSpacingExtra"
|
||||
android:text="@string/select_segments_description"
|
||||
android:textColor="?android:textColorSecondary"
|
||||
android:textSize="@dimen/default_desc_text_size"
|
||||
osmand:typeface="@string/font_roboto_regular" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<include
|
||||
android:id="@+id/gpx_track_container"
|
||||
layout="@layout/gpx_track_item"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="@dimen/dashPluginMargin" />
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:background="?attr/dashboard_divider" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/gpx_segment_list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1"
|
||||
tools:itemCount="1"
|
||||
tools:listitem="@layout/gpx_segment_list_item">
|
||||
|
||||
</androidx.recyclerview.widget.RecyclerView>
|
||||
|
||||
</LinearLayout>
|
98
OsmAnd/res/layout/gpx_segment_list_item.xml
Normal file
98
OsmAnd/res/layout/gpx_segment_list_item.xml
Normal file
|
@ -0,0 +1,98 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:osmand="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:minHeight="@dimen/favorites_list_item_height"
|
||||
android:paddingTop="@dimen/list_header_settings_top_margin"
|
||||
android:paddingBottom="@dimen/list_header_settings_top_margin"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/icon"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginStart="@dimen/list_content_padding"
|
||||
android:layout_marginLeft="@dimen/list_content_padding"
|
||||
android:layout_marginEnd="@dimen/list_content_padding"
|
||||
android:layout_marginRight="@dimen/list_content_padding"
|
||||
android:contentDescription="@string/shared_string_icon"
|
||||
android:visibility="visible"
|
||||
osmand:srcCompat="@drawable/ic_action_split_interval" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginStart="@dimen/list_content_padding"
|
||||
android:layout_marginLeft="@dimen/list_content_padding"
|
||||
android:layout_marginEnd="@dimen/list_content_padding"
|
||||
android:layout_marginRight="@dimen/list_content_padding"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/name"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="start"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:textSize="@dimen/default_list_text_size"
|
||||
tools:text="Segment" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/read_section"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:paddingTop="@dimen/subHeaderPadding"
|
||||
android:paddingBottom="@dimen/subHeaderPadding"
|
||||
android:visibility="visible">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/distance_icon"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="@dimen/content_padding_half"
|
||||
android:layout_marginRight="@dimen/content_padding_half"
|
||||
android:contentDescription="@string/distance"
|
||||
osmand:srcCompat="@drawable/ic_action_distance_16" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/distance"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="@dimen/content_padding"
|
||||
android:layout_marginRight="@dimen/content_padding"
|
||||
android:textColor="?android:textColorSecondary"
|
||||
android:textSize="@dimen/default_desc_text_size"
|
||||
tools:text="0" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/time_icon"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="@dimen/content_padding_half"
|
||||
android:layout_marginRight="@dimen/content_padding_half"
|
||||
android:contentDescription="@string/track_points"
|
||||
osmand:srcCompat="@drawable/ic_action_time_moving_16" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/time_interval"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="@dimen/content_padding"
|
||||
android:layout_marginRight="@dimen/content_padding"
|
||||
android:textColor="?android:textColorSecondary"
|
||||
android:textSize="@dimen/default_desc_text_size"
|
||||
tools:text="0" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
|
@ -51,6 +51,7 @@
|
|||
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/name_and_read_section_container"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="@dimen/gpx_text_top_margin"
|
||||
|
|
|
@ -413,4 +413,7 @@
|
|||
|
||||
<dimen name="radioButtonSize">32dp</dimen>
|
||||
<dimen name="checkBoxSize">24dp</dimen>
|
||||
|
||||
<dimen name="titleLineSpacingExtra">5sp</dimen>
|
||||
<dimen name="descriptionLineSpacingExtra">3sp</dimen>
|
||||
</resources>
|
|
@ -39,6 +39,9 @@
|
|||
<string name="hillshade_slope_contour_lines">Hillshade / Slope / Contour lines</string>
|
||||
<string name="toast_select_edits_for_upload">Select edits for upload</string>
|
||||
<string name="uploaded_count">Uploaded %1$d of %2$d</string>
|
||||
<string name="segments_count">Segment %1$d</string>
|
||||
<string name="select_segments_description">%1$s contains more than one segment, you need to select the needed part for the navigation.</string>
|
||||
<string name="select_segments">Select segments</string>
|
||||
<string name="uploading_count">Uploading %1$d of %2$d</string>
|
||||
<string name="upload_photo_completed">Upload completed</string>
|
||||
<string name="upload_photo">Uploading</string>
|
||||
|
|
|
@ -522,6 +522,7 @@ public class MapActivityActions implements DialogProvider {
|
|||
GPXRouteParamsBuilder params = new GPXRouteParamsBuilder(result, settings);
|
||||
params.setCalculateOsmAndRouteParts(settings.GPX_ROUTE_CALC_OSMAND_PARTS.get());
|
||||
params.setCalculateOsmAndRoute(settings.GPX_ROUTE_CALC.get());
|
||||
params.setSelectedSegment(settings.GPX_ROUTE_SEGMENT.get());
|
||||
List<Location> ps = params.getPoints(settings.getContext());
|
||||
mapActivity.getRoutingHelper().setGpxParams(params);
|
||||
settings.FOLLOW_THE_GPX_ROUTE.set(result.path);
|
||||
|
|
|
@ -134,6 +134,9 @@ public class FailSafeFuntions {
|
|||
if(settings.GPX_ROUTE_CALC.get()) {
|
||||
gpxRoute.setCalculateOsmAndRoute(true);
|
||||
}
|
||||
if (settings.GPX_ROUTE_SEGMENT.get() != -1) {
|
||||
gpxRoute.setSelectedSegment(settings.GPX_ROUTE_SEGMENT.get());
|
||||
}
|
||||
} else {
|
||||
gpxRoute = null;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,134 @@
|
|||
package net.osmand.plus.helpers;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import net.osmand.GPXUtilities.TrkSegment;
|
||||
import net.osmand.GPXUtilities.WptPt;
|
||||
import net.osmand.plus.OsmAndFormatter;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.UiUtilities;
|
||||
import net.osmand.plus.helpers.TrackSelectSegmentAdapter.TrackViewHolder;
|
||||
import net.osmand.util.MapUtils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class TrackSelectSegmentAdapter extends RecyclerView.Adapter<TrackViewHolder> {
|
||||
|
||||
private final OsmandApplication app;
|
||||
private final LayoutInflater themedInflater;
|
||||
private final UiUtilities iconsCache;
|
||||
private final List<TrkSegment> segments;
|
||||
private OnItemClickListener onItemClickListener;
|
||||
|
||||
public TrackSelectSegmentAdapter(Context ctx, List<TrkSegment> segments) {
|
||||
app = (OsmandApplication) ctx.getApplicationContext();
|
||||
themedInflater = UiUtilities.getInflater(ctx, app.getDaynightHelper().isNightModeForMapControls());
|
||||
iconsCache = app.getUIUtilities();
|
||||
this.segments = segments;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public TrackViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
View view = themedInflater.inflate(R.layout.gpx_segment_list_item, parent, false);
|
||||
ImageView distanceIcon = view.findViewById(R.id.distance_icon);
|
||||
distanceIcon.setImageDrawable(iconsCache.getThemedIcon(R.drawable.ic_action_split_interval));
|
||||
ImageView timeIcon = view.findViewById(R.id.time_icon);
|
||||
timeIcon.setImageDrawable(iconsCache.getThemedIcon(R.drawable.ic_action_time_moving_16));
|
||||
return new TrackViewHolder(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull final TrackViewHolder holder, int position) {
|
||||
holder.icon.setImageDrawable(iconsCache.getThemedIcon(R.drawable.ic_action_split_interval));
|
||||
|
||||
TrkSegment segment = segments.get(position);
|
||||
|
||||
String segmentTitle = app.getResources().getString(R.string.segments_count, position + 1);
|
||||
holder.name.setText(segmentTitle);
|
||||
|
||||
double distance = getDistance(segment);
|
||||
long time = getSegmentTime(segment);
|
||||
if (time != 1) {
|
||||
holder.time.setText(OsmAndFormatter.getFormattedDurationShort((int) (time / 1000)));
|
||||
} else {
|
||||
holder.time.setText("");
|
||||
}
|
||||
holder.distance.setText(OsmAndFormatter.getFormattedDistance((float) distance, app));
|
||||
holder.itemView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (onItemClickListener != null) {
|
||||
onItemClickListener.onItemClick(holder.getAdapterPosition());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return segments.size();
|
||||
}
|
||||
|
||||
private long getSegmentTime(TrkSegment segment) {
|
||||
long startTime = Long.MAX_VALUE;
|
||||
long endTime = Long.MIN_VALUE;
|
||||
for (int i = 0; i < segment.points.size(); i++) {
|
||||
WptPt point = segment.points.get(i);
|
||||
long time = point.time;
|
||||
if (time != 0) {
|
||||
startTime = Math.min(startTime, time);
|
||||
endTime = Math.max(endTime, time);
|
||||
}
|
||||
}
|
||||
return endTime - startTime;
|
||||
}
|
||||
|
||||
private double getDistance(TrkSegment segment) {
|
||||
double distance = 0;
|
||||
WptPt prevPoint = null;
|
||||
for (int i = 0; i < segment.points.size(); i++) {
|
||||
WptPt point = segment.points.get(i);
|
||||
if (prevPoint != null) {
|
||||
distance += MapUtils.getDistance(prevPoint.getLatitude(), prevPoint.getLongitude(), point.getLatitude(), point.getLongitude());
|
||||
}
|
||||
prevPoint = point;
|
||||
}
|
||||
return distance;
|
||||
}
|
||||
|
||||
public void setAdapterListener(OnItemClickListener onItemClickListener) {
|
||||
this.onItemClickListener = onItemClickListener;
|
||||
}
|
||||
|
||||
public interface OnItemClickListener {
|
||||
|
||||
void onItemClick(int position);
|
||||
|
||||
}
|
||||
|
||||
static class TrackViewHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
ImageView icon;
|
||||
TextView name;
|
||||
TextView distance;
|
||||
TextView time;
|
||||
|
||||
TrackViewHolder(View itemView) {
|
||||
super(itemView);
|
||||
icon = itemView.findViewById(R.id.icon);
|
||||
name = itemView.findViewById(R.id.name);
|
||||
distance = itemView.findViewById(R.id.distance);
|
||||
time = itemView.findViewById(R.id.time_interval);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -62,10 +62,11 @@ import net.osmand.plus.routing.RouteProvider;
|
|||
import net.osmand.plus.routing.RouteProvider.GPXRouteParamsBuilder;
|
||||
import net.osmand.plus.routing.RoutingHelper;
|
||||
import net.osmand.plus.settings.backend.ApplicationMode;
|
||||
import net.osmand.plus.views.layers.MapControlsLayer;
|
||||
import net.osmand.plus.track.TrackSelectSegmentBottomSheet;
|
||||
import net.osmand.plus.track.TrackSelectSegmentBottomSheet.OnSegmentSelectedListener;
|
||||
import net.osmand.plus.views.layers.MapControlsLayer.MapControlsThemeInfoProvider;
|
||||
import net.osmand.plus.widgets.popup.PopUpMenuHelper;
|
||||
import net.osmand.plus.widgets.popup.PopUpMenuItem;
|
||||
import net.osmand.util.Algorithms;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
|
||||
|
@ -75,7 +76,7 @@ import java.util.List;
|
|||
|
||||
|
||||
public class FollowTrackFragment extends ContextMenuScrollFragment implements CardListener,
|
||||
IRouteInformationListener, MapControlsLayer.MapControlsThemeInfoProvider {
|
||||
IRouteInformationListener, MapControlsThemeInfoProvider, OnSegmentSelectedListener {
|
||||
|
||||
public static final String TAG = FollowTrackFragment.class.getName();
|
||||
|
||||
|
@ -210,20 +211,8 @@ public class FollowTrackFragment extends ContextMenuScrollFragment implements Ca
|
|||
if (gpxFile == null || selectingTrack) {
|
||||
setupTracksCard();
|
||||
} else {
|
||||
String fileName = null;
|
||||
File file = null;
|
||||
if (!Algorithms.isEmpty(gpxFile.path)) {
|
||||
file = new File(gpxFile.path);
|
||||
fileName = file.getName();
|
||||
} else if (!Algorithms.isEmpty(gpxFile.tracks)) {
|
||||
fileName = gpxFile.tracks.get(0).name;
|
||||
}
|
||||
if (Algorithms.isEmpty(fileName)) {
|
||||
fileName = app.getString(R.string.shared_string_gpx_track);
|
||||
}
|
||||
sortButton.setVisibility(View.GONE);
|
||||
GPXInfo gpxInfo = new GPXInfo(fileName, file != null ? file.lastModified() : 0, file != null ? file.length() : 0);
|
||||
TrackEditCard importTrackCard = new TrackEditCard(mapActivity, gpxInfo);
|
||||
TrackEditCard importTrackCard = new TrackEditCard(mapActivity, gpxFile);
|
||||
importTrackCard.setListener(this);
|
||||
cardsContainer.addView(importTrackCard.build(mapActivity));
|
||||
|
||||
|
@ -490,14 +479,26 @@ public class FollowTrackFragment extends ContextMenuScrollFragment implements Ca
|
|||
String fileName = gpxInfo.getFileName();
|
||||
SelectedGpxFile selectedGpxFile = app.getSelectedGpxHelper().getSelectedFileByName(fileName);
|
||||
if (selectedGpxFile != null) {
|
||||
selectTrackToFollow(selectedGpxFile.getGpxFile());
|
||||
updateSelectionMode(false);
|
||||
GPXFile gpxFile = selectedGpxFile.getGpxFile();
|
||||
if (gpxFile.getNonEmptySegmentsCount() > 1) {
|
||||
TrackSelectSegmentBottomSheet.showInstance(mapActivity.getSupportFragmentManager(), gpxFile, this);
|
||||
} else {
|
||||
selectTrackToFollow(gpxFile);
|
||||
updateSelectionMode(false);
|
||||
}
|
||||
} else {
|
||||
CallbackWithObject<GPXFile[]> callback = new CallbackWithObject<GPXFile[]>() {
|
||||
@Override
|
||||
public boolean processResult(GPXFile[] result) {
|
||||
selectTrackToFollow(result[0]);
|
||||
updateSelectionMode(false);
|
||||
MapActivity mapActivity = getMapActivity();
|
||||
if (mapActivity != null) {
|
||||
if (result[0].getNonEmptySegmentsCount() > 1) {
|
||||
TrackSelectSegmentBottomSheet.showInstance(mapActivity.getSupportFragmentManager(), result[0], FollowTrackFragment.this);
|
||||
} else {
|
||||
selectTrackToFollow(result[0]);
|
||||
updateSelectionMode(false);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
@ -716,4 +717,16 @@ public class FollowTrackFragment extends ContextMenuScrollFragment implements Ca
|
|||
protected String getThemeInfoProviderTag() {
|
||||
return TAG;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSegmentSelect(GPXFile gpxFile, int selectedSegment) {
|
||||
selectTrackToFollow(gpxFile);
|
||||
GPXRouteParamsBuilder paramsBuilder = app.getRoutingHelper().getCurrentGPXRoute();
|
||||
if (paramsBuilder != null) {
|
||||
paramsBuilder.setSelectedSegment(selectedSegment);
|
||||
app.getSettings().GPX_ROUTE_SEGMENT.set(selectedSegment);
|
||||
app.getRoutingHelper().onSettingsChanged(true);
|
||||
}
|
||||
updateSelectionMode(false);
|
||||
}
|
||||
}
|
|
@ -1675,6 +1675,13 @@ public class MapRouteInfoMenu implements IRouteInformationListener, CardListener
|
|||
if (Algorithms.isEmpty(fileName)) {
|
||||
fileName = app.getString(R.string.shared_string_gpx_track);
|
||||
}
|
||||
GPXRouteParamsBuilder routeParams = app.getRoutingHelper().getCurrentGPXRoute();
|
||||
|
||||
if (gpxFile.getNonEmptySegmentsCount() > 1 && routeParams != null && routeParams.getSelectedSegment() != -1) {
|
||||
int selectedSegmentCount = routeParams.getSelectedSegment() + 1;
|
||||
int totalSegmentCount = routeParams.getFile().getNonEmptyTrkSegments(false).size();
|
||||
fileName = app.getResources().getString(R.string.of, selectedSegmentCount, totalSegmentCount) + ", " + fileName;
|
||||
}
|
||||
title.setText(GpxUiHelper.getGpxTitle(fileName));
|
||||
description.setText(R.string.follow_track);
|
||||
buttonDescription.setText(R.string.shared_string_add);
|
||||
|
|
|
@ -6,6 +6,7 @@ import android.widget.ImageButton;
|
|||
import android.widget.LinearLayout;
|
||||
|
||||
import net.osmand.AndroidUtils;
|
||||
import net.osmand.GPXUtilities.GPXFile;
|
||||
import net.osmand.plus.GPXDatabase.GpxDataItem;
|
||||
import net.osmand.plus.GpxDbHelper.GpxDataItemCallback;
|
||||
import net.osmand.plus.R;
|
||||
|
@ -13,17 +14,18 @@ import net.osmand.plus.UiUtilities;
|
|||
import net.osmand.plus.activities.MapActivity;
|
||||
import net.osmand.plus.helpers.GpxUiHelper;
|
||||
import net.osmand.plus.helpers.GpxUiHelper.GPXInfo;
|
||||
import net.osmand.plus.routing.RouteProvider.GPXRouteParamsBuilder;
|
||||
import net.osmand.util.Algorithms;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class TrackEditCard extends BaseCard {
|
||||
|
||||
private GPXInfo gpxInfo;
|
||||
private final GPXFile gpxFile;
|
||||
|
||||
public TrackEditCard(MapActivity mapActivity, GPXInfo gpxInfo) {
|
||||
public TrackEditCard(MapActivity mapActivity, GPXFile gpxFile) {
|
||||
super(mapActivity);
|
||||
this.gpxInfo = gpxInfo;
|
||||
this.gpxFile = gpxFile;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -50,9 +52,27 @@ public class TrackEditCard extends BaseCard {
|
|||
|
||||
@Override
|
||||
protected void updateContent() {
|
||||
String fileName = Algorithms.getFileWithoutDirs(gpxInfo.getFileName());
|
||||
String title = GpxUiHelper.getGpxTitle(fileName);
|
||||
String fileName = null;
|
||||
File file = null;
|
||||
if (!Algorithms.isEmpty(gpxFile.path)) {
|
||||
file = new File(gpxFile.path);
|
||||
fileName = gpxFile.path;
|
||||
} else if (!Algorithms.isEmpty(gpxFile.tracks)) {
|
||||
fileName = gpxFile.tracks.get(0).name;
|
||||
}
|
||||
if (Algorithms.isEmpty(fileName)) {
|
||||
fileName = app.getString(R.string.shared_string_gpx_track);
|
||||
}
|
||||
|
||||
GPXInfo gpxInfo = new GPXInfo(gpxFile.path, file != null ? file.lastModified() : 0, file != null ? file.length() : 0);
|
||||
GpxDataItem dataItem = getDataItem(gpxInfo);
|
||||
String title = GpxUiHelper.getGpxTitle(Algorithms.getFileWithoutDirs(fileName));
|
||||
GPXRouteParamsBuilder routeParams = app.getRoutingHelper().getCurrentGPXRoute();
|
||||
if (gpxFile.getNonEmptySegmentsCount() > 1 && routeParams != null && routeParams.getSelectedSegment() != -1) {
|
||||
int selectedSegmentCount = routeParams.getSelectedSegment() + 1;
|
||||
int totalSegmentCount = routeParams.getFile().getNonEmptyTrkSegments(false).size();
|
||||
title = app.getResources().getString(R.string.of, selectedSegmentCount, totalSegmentCount) + ", " + title;
|
||||
}
|
||||
GpxUiHelper.updateGpxInfoView(view, title, gpxInfo, dataItem, false, app);
|
||||
|
||||
ImageButton editButton = view.findViewById(R.id.show_on_map);
|
||||
|
|
|
@ -8,7 +8,6 @@ import android.util.Base64;
|
|||
import net.osmand.GPXUtilities;
|
||||
import net.osmand.GPXUtilities.GPXFile;
|
||||
import net.osmand.GPXUtilities.Route;
|
||||
import net.osmand.GPXUtilities.Track;
|
||||
import net.osmand.GPXUtilities.TrkSegment;
|
||||
import net.osmand.GPXUtilities.WptPt;
|
||||
import net.osmand.Location;
|
||||
|
@ -20,15 +19,15 @@ import net.osmand.data.LatLon;
|
|||
import net.osmand.data.LocationPoint;
|
||||
import net.osmand.data.WptLocationPoint;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.onlinerouting.OnlineRoutingHelper;
|
||||
import net.osmand.plus.onlinerouting.engine.OnlineRoutingEngine.OnlineRoutingResponse;
|
||||
import net.osmand.plus.settings.backend.OsmandSettings;
|
||||
import net.osmand.plus.settings.backend.CommonPreference;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.TargetPointsHelper;
|
||||
import net.osmand.plus.TargetPointsHelper.TargetPoint;
|
||||
import net.osmand.plus.onlinerouting.OnlineRoutingHelper;
|
||||
import net.osmand.plus.onlinerouting.engine.OnlineRoutingEngine.OnlineRoutingResponse;
|
||||
import net.osmand.plus.render.NativeOsmandLibrary;
|
||||
import net.osmand.plus.settings.backend.ApplicationMode;
|
||||
import net.osmand.plus.settings.backend.CommonPreference;
|
||||
import net.osmand.plus.settings.backend.OsmandSettings;
|
||||
import net.osmand.router.GeneralRouter;
|
||||
import net.osmand.router.GeneralRouter.RoutingParameter;
|
||||
import net.osmand.router.GeneralRouter.RoutingParameterType;
|
||||
|
@ -161,6 +160,7 @@ public class RouteProvider {
|
|||
private boolean leftSide;
|
||||
private boolean passWholeRoute;
|
||||
private boolean calculateOsmAndRouteParts;
|
||||
private int selectedSegment = -1;
|
||||
|
||||
public GPXRouteParamsBuilder(GPXFile file, OsmandSettings settings) {
|
||||
leftSide = settings.DRIVING_REGION.get().leftHandDriving;
|
||||
|
@ -191,6 +191,14 @@ public class RouteProvider {
|
|||
this.calculateOsmAndRoute = calculateOsmAndRoute;
|
||||
}
|
||||
|
||||
public int getSelectedSegment() {
|
||||
return selectedSegment;
|
||||
}
|
||||
|
||||
public void setSelectedSegment(int selectedSegment) {
|
||||
this.selectedSegment = selectedSegment;
|
||||
}
|
||||
|
||||
public void setPassWholeRoute(boolean passWholeRoute) {
|
||||
this.passWholeRoute = passWholeRoute;
|
||||
}
|
||||
|
@ -278,8 +286,9 @@ public class RouteProvider {
|
|||
wpt.add(new WptLocationPoint(w));
|
||||
}
|
||||
}
|
||||
int selectedSegment = builder.getSelectedSegment();
|
||||
if (OSMAND_ROUTER_V2.equals(file.author)) {
|
||||
route = parseOsmAndGPXRoute(points, file);
|
||||
route = parseOsmAndGPXRoute(points, file, selectedSegment);
|
||||
routePoints = file.getRoutePoints();
|
||||
if (reverse) {
|
||||
Collections.reverse(points);
|
||||
|
@ -287,7 +296,7 @@ public class RouteProvider {
|
|||
}
|
||||
addMissingTurns = route != null && route.isEmpty();
|
||||
} else if (file.isCloudmadeRouteFile() || OSMAND_ROUTER.equals(file.author)) {
|
||||
directions = parseOsmAndGPXRoute(points, file, OSMAND_ROUTER.equals(file.author), builder.leftSide, 10);
|
||||
directions = parseOsmAndGPXRoute(points, file, OSMAND_ROUTER.equals(file.author), builder.leftSide, 10, selectedSegment);
|
||||
if (OSMAND_ROUTER.equals(file.author) && file.hasRtePt()) {
|
||||
// For files generated by OSMAND_ROUTER use directions contained unaltered
|
||||
addMissingTurns = false;
|
||||
|
@ -301,12 +310,16 @@ public class RouteProvider {
|
|||
} else {
|
||||
// first of all check tracks
|
||||
if (!useIntermediatePointsRTE) {
|
||||
for (Track tr : file.tracks) {
|
||||
if (!tr.generalTrack) {
|
||||
for (TrkSegment tkSeg : tr.segments) {
|
||||
for (WptPt pt : tkSeg.points) {
|
||||
points.add(createLocation(pt));
|
||||
}
|
||||
List<TrkSegment> segments = file.getNonEmptyTrkSegments(false);
|
||||
if (selectedSegment != -1 && segments.size() > selectedSegment) {
|
||||
TrkSegment segment = segments.get(selectedSegment);
|
||||
for (WptPt p : segment.points) {
|
||||
points.add(createLocation(p));
|
||||
}
|
||||
} else {
|
||||
for (TrkSegment tkSeg : segments) {
|
||||
for (WptPt p : tkSeg.points) {
|
||||
points.add(createLocation(p));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -998,35 +1011,49 @@ public class RouteProvider {
|
|||
return new RouteCalculationResult("Empty result");
|
||||
}
|
||||
|
||||
private static List<RouteSegmentResult> parseOsmAndGPXRoute(List<Location> points, GPXFile gpxFile) {
|
||||
for (Track tr : gpxFile.tracks) {
|
||||
for (TrkSegment ts : tr.segments) {
|
||||
private static List<RouteSegmentResult> parseOsmAndGPXRoute(List<Location> points, GPXFile gpxFile, int selectedSegment) {
|
||||
List<TrkSegment> segments = gpxFile.getNonEmptyTrkSegments(false);
|
||||
if (selectedSegment != -1 && segments.size() > selectedSegment) {
|
||||
TrkSegment segment = segments.get(selectedSegment);
|
||||
for (WptPt p : segment.points) {
|
||||
points.add(createLocation(p));
|
||||
}
|
||||
RouteImporter routeImporter = new RouteImporter(segment);
|
||||
return routeImporter.importRoute();
|
||||
} else {
|
||||
for (TrkSegment ts : segments) {
|
||||
for (WptPt p : ts.points) {
|
||||
points.add(createLocation(p));
|
||||
}
|
||||
}
|
||||
RouteImporter routeImporter = new RouteImporter(gpxFile);
|
||||
return routeImporter.importRoute();
|
||||
}
|
||||
RouteImporter routeImporter = new RouteImporter(gpxFile);
|
||||
return routeImporter.importRoute();
|
||||
}
|
||||
|
||||
private static List<RouteDirectionInfo> parseOsmAndGPXRoute(List<Location> points, GPXFile gpxFile, boolean osmandRouter,
|
||||
boolean leftSide, float defSpeed) {
|
||||
boolean leftSide, float defSpeed, int selectedSegment) {
|
||||
List<RouteDirectionInfo> directions = null;
|
||||
if (!osmandRouter) {
|
||||
for (WptPt pt : gpxFile.getPoints()) {
|
||||
points.add(createLocation(pt));
|
||||
}
|
||||
} else {
|
||||
for (Track tr : gpxFile.tracks) {
|
||||
for (TrkSegment ts : tr.segments) {
|
||||
List<TrkSegment> segments = gpxFile.getNonEmptyTrkSegments(false);
|
||||
if (selectedSegment != -1 && segments.size() > selectedSegment) {
|
||||
TrkSegment segment = segments.get(selectedSegment);
|
||||
for (WptPt p : segment.points) {
|
||||
points.add(createLocation(p));
|
||||
}
|
||||
} else {
|
||||
for (TrkSegment ts : segments) {
|
||||
for (WptPt p : ts.points) {
|
||||
points.add(createLocation(p));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
float[] distanceToEnd = new float[points.size()];
|
||||
float[] distanceToEnd = new float[points.size()];
|
||||
for (int i = points.size() - 2; i >= 0; i--) {
|
||||
distanceToEnd[i] = distanceToEnd[i + 1] + points.get(i).distanceTo(points.get(i + 1));
|
||||
}
|
||||
|
@ -1307,7 +1334,7 @@ public class RouteProvider {
|
|||
|
||||
GPXFile gpxFile = GPXUtilities.loadGPXFile(gpxStream);
|
||||
|
||||
dir = parseOsmAndGPXRoute(res, gpxFile, true, params.leftSide, params.mode.getDefaultSpeed());
|
||||
dir = parseOsmAndGPXRoute(res, gpxFile, true, params.leftSide, params.mode.getDefaultSpeed(), -1);
|
||||
|
||||
if (dir != null) {
|
||||
addMissingTurns = false;
|
||||
|
|
|
@ -45,10 +45,8 @@ import net.osmand.plus.helpers.enums.DrivingRegion;
|
|||
import net.osmand.plus.helpers.enums.MetricsConstants;
|
||||
import net.osmand.plus.helpers.enums.SpeedConstants;
|
||||
import net.osmand.plus.helpers.enums.TracksSortByMode;
|
||||
import net.osmand.plus.mapillary.MapillaryPlugin;
|
||||
import net.osmand.plus.mapmarkers.CoordinateInputFormats.Format;
|
||||
import net.osmand.plus.mapmarkers.MapMarkersMode;
|
||||
import net.osmand.plus.openplacereviews.OpenPlaceReviewsPlugin;
|
||||
import net.osmand.plus.profiles.LocationIcon;
|
||||
import net.osmand.plus.profiles.NavigationIcon;
|
||||
import net.osmand.plus.profiles.ProfileIconColors;
|
||||
|
@ -1389,6 +1387,7 @@ public class OsmandSettings {
|
|||
public final OsmandPreference<Boolean> GPX_ROUTE_CALC_OSMAND_PARTS = new BooleanPreference(this, "gpx_routing_calculate_osmand_route", true).makeGlobal().makeShared().cache();
|
||||
public final OsmandPreference<Boolean> GPX_CALCULATE_RTEPT = new BooleanPreference(this, "gpx_routing_calculate_rtept", true).makeGlobal().makeShared().cache();
|
||||
public final OsmandPreference<Boolean> GPX_ROUTE_CALC = new BooleanPreference(this, "calc_gpx_route", false).makeGlobal().makeShared().cache();
|
||||
public final OsmandPreference<Integer> GPX_ROUTE_SEGMENT = new IntPreference(this, "gpx_route_segment", -1).makeGlobal().makeShared().cache();
|
||||
public final OsmandPreference<Boolean> SHOW_START_FINISH_ICONS = new BooleanPreference(this, "show_start_finish_icons", true).makeGlobal().makeShared().cache();
|
||||
|
||||
public final OsmandPreference<Boolean> AVOID_TOLL_ROADS = new BooleanPreference(this, "avoid_toll_roads", false).makeProfile().cache();
|
||||
|
@ -2594,7 +2593,7 @@ public class OsmandSettings {
|
|||
|
||||
public static final String VOICE_PROVIDER_NOT_USE = "VOICE_PROVIDER_NOT_USE";
|
||||
|
||||
public static final String[] TTS_AVAILABLE_VOICES = new String[]{
|
||||
public static final String[] TTS_AVAILABLE_VOICES = new String[] {
|
||||
"de", "en", "es", "fr", "it", "ja", "nl", "pl", "pt", "ru", "zh"
|
||||
};
|
||||
// this value string is synchronized with settings_pref.xml preference name
|
||||
|
|
|
@ -81,6 +81,7 @@ import net.osmand.plus.myplaces.TrackActivityFragmentAdapter;
|
|||
import net.osmand.plus.osmedit.OsmEditingPlugin;
|
||||
import net.osmand.plus.routepreparationmenu.cards.BaseCard;
|
||||
import net.osmand.plus.routepreparationmenu.cards.BaseCard.CardListener;
|
||||
import net.osmand.plus.routing.RouteProvider;
|
||||
import net.osmand.plus.track.SaveGpxAsyncTask.SaveGpxListener;
|
||||
import net.osmand.plus.views.AddGpxPointBottomSheetHelper.NewGpxPoint;
|
||||
import net.osmand.plus.widgets.IconPopupMenu;
|
||||
|
@ -114,7 +115,7 @@ import static net.osmand.plus.track.TrackPointsCard.OPEN_WAYPOINT_INDEX;
|
|||
|
||||
public class TrackMenuFragment extends ContextMenuScrollFragment implements CardListener,
|
||||
SegmentActionsListener, RenameCallback, OnTrackFileMoveListener, OnPointsDeleteListener,
|
||||
OsmAndLocationListener, OsmAndCompassListener {
|
||||
OsmAndLocationListener, OsmAndCompassListener, TrackSelectSegmentBottomSheet.OnSegmentSelectedListener {
|
||||
|
||||
public static final String OPEN_TRACK_MENU = "open_track_menu";
|
||||
public static final String RETURN_SCREEN_NAME = "return_screen_name";
|
||||
|
@ -160,6 +161,7 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
|
|||
private int toolbarHeightPx;
|
||||
private boolean mapPositionAdjusted;
|
||||
|
||||
|
||||
public enum TrackMenuType {
|
||||
OVERVIEW(R.id.action_overview, R.string.shared_string_overview),
|
||||
TRACK(R.id.action_track, R.string.shared_string_gpx_tracks),
|
||||
|
@ -175,6 +177,7 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
|
|||
public final int titleId;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getMainLayoutId() {
|
||||
return R.layout.track_menu;
|
||||
|
@ -591,8 +594,8 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
|
|||
MapActivity mapActivity = getMapActivity();
|
||||
View view = overviewCard.getView();
|
||||
if (mapActivity != null && view != null) {
|
||||
TextView distanceText = (TextView) view.findViewById(R.id.distance);
|
||||
ImageView direction = (ImageView) view.findViewById(R.id.direction);
|
||||
TextView distanceText = view.findViewById(R.id.distance);
|
||||
ImageView direction = view.findViewById(R.id.direction);
|
||||
app.getUIUtilities().updateLocationView(updateLocationViewCache, direction, distanceText, latLon);
|
||||
}
|
||||
}
|
||||
|
@ -723,23 +726,12 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
|
|||
TrackAppearanceFragment.showInstance(mapActivity, selectedGpxFile, this);
|
||||
} else if (buttonIndex == DIRECTIONS_BUTTON_INDEX) {
|
||||
MapActivityActions mapActions = mapActivity.getMapActions();
|
||||
if (app.getRoutingHelper().isFollowingMode()) {
|
||||
mapActions.stopNavigationActionConfirm(null, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
MapActivity mapActivity = getMapActivity();
|
||||
if (mapActivity != null) {
|
||||
mapActivity.getMapActions().enterRoutePlanningModeGivenGpx(gpxFile, null,
|
||||
null, null, true, true, MenuState.HEADER_ONLY);
|
||||
}
|
||||
}
|
||||
});
|
||||
if (gpxFile.getNonEmptySegmentsCount() > 1) {
|
||||
TrackSelectSegmentBottomSheet.showInstance(mapActivity.getSupportFragmentManager(), gpxFile, this);
|
||||
} else {
|
||||
mapActions.stopNavigationWithoutConfirm();
|
||||
mapActions.enterRoutePlanningModeGivenGpx(gpxFile, null, null,
|
||||
null, true, true, MenuState.HEADER_ONLY);
|
||||
startNavigationForGPX(gpxFile, mapActions);
|
||||
dismiss();
|
||||
}
|
||||
dismiss();
|
||||
}
|
||||
if (buttonIndex == JOIN_GAPS_BUTTON_INDEX) {
|
||||
displayHelper.setJoinSegments(!displayHelper.isJoinSegments());
|
||||
|
@ -830,6 +822,25 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
|
|||
}
|
||||
}
|
||||
|
||||
private void startNavigationForGPX(final GPXFile gpxFile, MapActivityActions mapActions) {
|
||||
if (app.getRoutingHelper().isFollowingMode()) {
|
||||
mapActions.stopNavigationActionConfirm(null, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
MapActivity mapActivity = getMapActivity();
|
||||
if (mapActivity != null) {
|
||||
mapActivity.getMapActions().enterRoutePlanningModeGivenGpx(gpxFile, null,
|
||||
null, null, true, true, MenuState.HEADER_ONLY);
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
mapActions.stopNavigationWithoutConfirm();
|
||||
mapActions.enterRoutePlanningModeGivenGpx(gpxFile, null, null,
|
||||
null, true, true, MenuState.HEADER_ONLY);
|
||||
}
|
||||
}
|
||||
|
||||
public void updateToolbar(int y, boolean animated) {
|
||||
final MapActivity mapActivity = getMapActivity();
|
||||
if (mapActivity != null) {
|
||||
|
@ -1066,6 +1077,21 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSegmentSelect(GPXFile gpxFile, int selectedSegment) {
|
||||
MapActivity mapActivity = getMapActivity();
|
||||
if (mapActivity != null) {
|
||||
startNavigationForGPX(gpxFile, mapActivity.getMapActions());
|
||||
app.getSettings().GPX_ROUTE_SEGMENT.set(selectedSegment);
|
||||
RouteProvider.GPXRouteParamsBuilder paramsBuilder = app.getRoutingHelper().getCurrentGPXRoute();
|
||||
if (paramsBuilder != null) {
|
||||
paramsBuilder.setSelectedSegment(selectedSegment);
|
||||
app.getRoutingHelper().onSettingsChanged(true);
|
||||
}
|
||||
dismiss();
|
||||
}
|
||||
}
|
||||
|
||||
private void editSegment(TrkSegment segment) {
|
||||
GPXFile gpxFile = getGpx();
|
||||
openPlanRoute(new GpxData(gpxFile));
|
||||
|
|
|
@ -0,0 +1,142 @@
|
|||
package net.osmand.plus.track;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Typeface;
|
||||
import android.os.Bundle;
|
||||
import android.text.Spannable;
|
||||
import android.text.SpannableString;
|
||||
import android.text.style.ForegroundColorSpan;
|
||||
import android.util.TypedValue;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import net.osmand.AndroidUtils;
|
||||
import net.osmand.GPXUtilities;
|
||||
import net.osmand.GPXUtilities.GPXFile;
|
||||
import net.osmand.GPXUtilities.TrkSegment;
|
||||
import net.osmand.plus.OsmAndFormatter;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.UiUtilities;
|
||||
import net.osmand.plus.base.MenuBottomSheetDialogFragment;
|
||||
import net.osmand.plus.base.bottomsheetmenu.BaseBottomSheetItem;
|
||||
import net.osmand.plus.helpers.FontCache;
|
||||
import net.osmand.plus.helpers.TrackSelectSegmentAdapter;
|
||||
import net.osmand.plus.helpers.TrackSelectSegmentAdapter.OnItemClickListener;
|
||||
import net.osmand.plus.widgets.style.CustomTypefaceSpan;
|
||||
import net.osmand.util.Algorithms;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class TrackSelectSegmentBottomSheet extends MenuBottomSheetDialogFragment {
|
||||
|
||||
public static final String TAG = TrackSelectSegmentBottomSheet.class.getSimpleName();
|
||||
|
||||
private OsmandApplication app;
|
||||
private GPXFile gpxFile;
|
||||
|
||||
@Override
|
||||
public void createMenuItems(Bundle savedInstanceState) {
|
||||
app = requiredMyApplication();
|
||||
Context context = requireContext();
|
||||
|
||||
LayoutInflater inflater = UiUtilities.getInflater(context, nightMode);
|
||||
View itemView = inflater.inflate(R.layout.bottom_sheet_select_segment, null, false);
|
||||
|
||||
String titleGpxTrack = Algorithms.getFileWithoutDirs(gpxFile.path);
|
||||
Typeface typeface = FontCache.getRobotoMedium(app);
|
||||
String selectSegmentDescription = getString(R.string.select_segments_description, titleGpxTrack);
|
||||
SpannableString gpxTrackName = new SpannableString(selectSegmentDescription);
|
||||
int startIndex = selectSegmentDescription.indexOf(titleGpxTrack);
|
||||
int descriptionColor = getResolvedColor(nightMode ? R.color.text_color_secondary_dark : R.color.text_color_secondary_light);
|
||||
int endIndex = startIndex + titleGpxTrack.length();
|
||||
gpxTrackName.setSpan(new CustomTypefaceSpan(typeface), startIndex, endIndex, 0);
|
||||
gpxTrackName.setSpan(new ForegroundColorSpan(descriptionColor), startIndex, endIndex, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
|
||||
items.add(new BaseBottomSheetItem.Builder()
|
||||
.setCustomView(itemView)
|
||||
.create());
|
||||
|
||||
LinearLayout gpxTrackContainer = itemView.findViewById(R.id.gpx_track_container);
|
||||
GPXUtilities.GPXTrackAnalysis analysis = gpxFile.getAnalysis(0);
|
||||
|
||||
ImageView icon = gpxTrackContainer.findViewById(R.id.icon);
|
||||
int sidePadding = AndroidUtils.dpToPx(context, 16f);
|
||||
int bottomTopPadding = AndroidUtils.dpToPx(context, 2f);
|
||||
|
||||
LinearLayout readContainer = gpxTrackContainer.findViewById(R.id.read_section);
|
||||
readContainer.setPadding(0, bottomTopPadding, 0, bottomTopPadding);
|
||||
TextView name = gpxTrackContainer.findViewById(R.id.name);
|
||||
TextView description = itemView.findViewById(R.id.description);
|
||||
TextView distance = gpxTrackContainer.findViewById(R.id.distance);
|
||||
TextView pointsCount = gpxTrackContainer.findViewById(R.id.points_count);
|
||||
TextView time = gpxTrackContainer.findViewById(R.id.time);
|
||||
LinearLayout container = gpxTrackContainer.findViewById(R.id.container);
|
||||
LinearLayout containerNameAndReadSection = gpxTrackContainer.findViewById(R.id.name_and_read_section_container);
|
||||
container.setPadding(sidePadding, 0, 0, 0);
|
||||
containerNameAndReadSection.setPadding(sidePadding, 0, 0, 0);
|
||||
icon.setImageDrawable(app.getUIUtilities().getThemedIcon(R.drawable.ic_action_polygom_dark));
|
||||
name.setText(titleGpxTrack);
|
||||
description.setText(gpxTrackName);
|
||||
distance.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14);
|
||||
distance.setText(OsmAndFormatter.getFormattedDistance(analysis.totalDistance, app));
|
||||
pointsCount.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14);
|
||||
pointsCount.setText(String.valueOf(analysis.wptPoints));
|
||||
time.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14);
|
||||
time.setText(analysis.isTimeSpecified() ? Algorithms.formatDuration((int) (analysis.timeSpan / 1000), app.accessibilityEnabled()) : "");
|
||||
|
||||
RecyclerView recyclerView = itemView.findViewById(R.id.gpx_segment_list);
|
||||
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
|
||||
recyclerView.setNestedScrollingEnabled(false);
|
||||
|
||||
List<TrkSegment> segments = gpxFile.getNonEmptyTrkSegments(false);
|
||||
TrackSelectSegmentAdapter adapterSegments = new TrackSelectSegmentAdapter(context, segments);
|
||||
adapterSegments.setAdapterListener(new OnItemClickListener() {
|
||||
@Override
|
||||
public void onItemClick(int position) {
|
||||
Fragment fragment = getTargetFragment();
|
||||
if (fragment instanceof OnSegmentSelectedListener) {
|
||||
((OnSegmentSelectedListener) fragment).onSegmentSelect(gpxFile, position);
|
||||
}
|
||||
dismiss();
|
||||
}
|
||||
});
|
||||
recyclerView.setAdapter(adapterSegments);
|
||||
|
||||
gpxTrackContainer.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
Fragment fragment = getTargetFragment();
|
||||
if (fragment instanceof OnSegmentSelectedListener) {
|
||||
((OnSegmentSelectedListener) fragment).onSegmentSelect(gpxFile, -1);
|
||||
}
|
||||
dismiss();
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public interface OnSegmentSelectedListener {
|
||||
void onSegmentSelect(GPXFile gpxFile, int selectedSegment);
|
||||
}
|
||||
|
||||
public static void showInstance(@NonNull FragmentManager fragmentManager, @NonNull GPXFile gpxFile, @Nullable Fragment target) {
|
||||
if (!fragmentManager.isStateSaved()) {
|
||||
TrackSelectSegmentBottomSheet fragment = new TrackSelectSegmentBottomSheet();
|
||||
fragment.setRetainInstance(true);
|
||||
fragment.setTargetFragment(target, 0);
|
||||
fragment.gpxFile = gpxFile;
|
||||
fragment.show(fragmentManager, TAG);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue