Merge pull request #11220 from osmandapp/trip_recording_graphs
Redesign trip recording base dialog (added graphs)
This commit is contained in:
commit
334d7a11e1
13 changed files with 512 additions and 202 deletions
|
@ -52,7 +52,7 @@
|
|||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/average_range"
|
||||
android:id="@+id/top_line_blocks"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
|
@ -171,7 +171,7 @@
|
|||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/ascent_descent"
|
||||
android:id="@+id/bottom_line_blocks"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
|
@ -273,6 +273,7 @@
|
|||
</LinearLayout>
|
||||
|
||||
<View
|
||||
android:id="@+id/details_divider"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:background="?attr/dashboard_divider" />
|
||||
|
|
|
@ -52,7 +52,7 @@
|
|||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/distance_time_span"
|
||||
android:id="@+id/top_line_blocks"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
|
@ -171,7 +171,7 @@
|
|||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/start_end_time"
|
||||
android:id="@+id/bottom_line_blocks"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
|
@ -291,6 +291,7 @@
|
|||
</LinearLayout>
|
||||
|
||||
<View
|
||||
android:id="@+id/details_divider"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:background="?attr/dashboard_divider" />
|
||||
|
|
|
@ -52,7 +52,7 @@
|
|||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/average_max"
|
||||
android:id="@+id/top_line_blocks"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
|
@ -172,7 +172,7 @@
|
|||
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/time_distance"
|
||||
android:id="@+id/bottom_line_blocks"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
|
@ -275,6 +275,7 @@
|
|||
</LinearLayout>
|
||||
|
||||
<View
|
||||
android:id="@+id/details_divider"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:background="?attr/dashboard_divider" />
|
||||
|
|
|
@ -4,7 +4,9 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<include layout="@layout/list_item_divider" />
|
||||
<include
|
||||
android:id="@+id/list_item_divider"
|
||||
layout="@layout/list_item_divider" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
|
|
|
@ -72,7 +72,13 @@
|
|||
android:layout_marginLeft="@dimen/content_padding"
|
||||
android:layout_marginEnd="@dimen/content_padding"
|
||||
android:layout_marginRight="@dimen/content_padding"
|
||||
android:layout_marginBottom="@dimen/dialog_content_margin" />
|
||||
android:layout_marginBottom="@dimen/context_menu_padding_margin_small" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/segments_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/block_statistics"
|
||||
|
|
|
@ -40,7 +40,6 @@ import java.util.LinkedHashMap;
|
|||
import static net.osmand.plus.activities.PluginInfoFragment.PLUGIN_INFO;
|
||||
import static net.osmand.plus.monitoring.OsmandMonitoringPlugin.MINUTES;
|
||||
import static net.osmand.plus.monitoring.OsmandMonitoringPlugin.SECONDS;
|
||||
import static net.osmand.plus.monitoring.TripRecordingStartingBottomFragment.UPDATE_LOGGING_INTERVAL;
|
||||
import static net.osmand.plus.myplaces.FavoritesActivity.TAB_ID;
|
||||
import static net.osmand.plus.settings.backend.OsmandSettings.MONTHLY_DIRECTORY;
|
||||
import static net.osmand.plus.settings.backend.OsmandSettings.REC_DIRECTORY;
|
||||
|
|
|
@ -9,6 +9,7 @@ import android.os.Bundle;
|
|||
import android.os.Handler;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.LinearLayout;
|
||||
|
@ -31,7 +32,10 @@ import androidx.recyclerview.widget.RecyclerView;
|
|||
|
||||
import net.osmand.AndroidUtils;
|
||||
import net.osmand.GPXUtilities.GPXFile;
|
||||
import net.osmand.GPXUtilities.TrkSegment;
|
||||
import net.osmand.PlatformUtil;
|
||||
import net.osmand.data.LatLon;
|
||||
import net.osmand.plus.GpxSelectionHelper.GpxDisplayItem;
|
||||
import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.OsmandPlugin;
|
||||
|
@ -42,27 +46,41 @@ import net.osmand.plus.activities.SavingTrackHelper;
|
|||
import net.osmand.plus.base.MenuBottomSheetDialogFragment;
|
||||
import net.osmand.plus.base.bottomsheetmenu.BaseBottomSheetItem;
|
||||
import net.osmand.plus.helpers.AndroidUiHelper;
|
||||
import net.osmand.plus.helpers.GpxUiHelper;
|
||||
import net.osmand.plus.mapcontextmenu.other.TrackChartPoints;
|
||||
import net.osmand.plus.myplaces.GPXItemPagerAdapter;
|
||||
import net.osmand.plus.myplaces.SegmentActionsListener;
|
||||
import net.osmand.plus.myplaces.SegmentGPXAdapter;
|
||||
import net.osmand.plus.settings.backend.OsmandSettings;
|
||||
import net.osmand.plus.track.GpxBlockStatisticsBuilder;
|
||||
import net.osmand.plus.track.TrackAppearanceFragment;
|
||||
import net.osmand.plus.track.TrackDisplayHelper;
|
||||
import net.osmand.plus.views.controls.PagerSlidingTabStrip;
|
||||
import net.osmand.plus.views.controls.WrapContentHeightViewPager;
|
||||
import net.osmand.plus.widgets.TextViewEx;
|
||||
import net.osmand.util.Algorithms;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import static net.osmand.AndroidUtils.getSecondaryTextColorId;
|
||||
import static net.osmand.AndroidUtils.setPadding;
|
||||
import static net.osmand.plus.UiUtilities.CompoundButtonType.GLOBAL;
|
||||
import static net.osmand.plus.track.GpxBlockStatisticsBuilder.INIT_BLOCKS_ALTITUDE;
|
||||
import static net.osmand.plus.track.GpxBlockStatisticsBuilder.INIT_BLOCKS_GENERAL;
|
||||
import static net.osmand.plus.track.GpxBlockStatisticsBuilder.INIT_BLOCKS_SPEED;
|
||||
|
||||
public class TripRecordingBottomFragment extends MenuBottomSheetDialogFragment {
|
||||
public class TripRecordingBottomFragment extends MenuBottomSheetDialogFragment implements SegmentActionsListener {
|
||||
|
||||
public static final String TAG = TripRecordingBottomFragment.class.getSimpleName();
|
||||
private static final Log LOG = PlatformUtil.getLog(TripRecordingBottomFragment.class);
|
||||
public static final String UPDATE_TRACK_ICON = "update_track_icon";
|
||||
private static final int GPS_UPDATE_INTERVAL = 1000;
|
||||
private static final String[] INIT_BLOCKS_KEYS =
|
||||
new String[]{INIT_BLOCKS_GENERAL, INIT_BLOCKS_ALTITUDE, INIT_BLOCKS_SPEED};
|
||||
|
||||
private OsmandApplication app;
|
||||
private OsmandSettings settings;
|
||||
|
@ -71,8 +89,13 @@ public class TripRecordingBottomFragment extends MenuBottomSheetDialogFragment {
|
|||
|
||||
private View statusContainer;
|
||||
private AppCompatImageView trackAppearanceIcon;
|
||||
private GpxBlockStatisticsBuilder blockStatisticsBuilder;
|
||||
private LinearLayout segmentsContainer;
|
||||
|
||||
private TrackDisplayHelper displayHelper;
|
||||
private TrackChartPoints trackChartPoints;
|
||||
private GPXItemPagerAdapter graphsAdapter;
|
||||
|
||||
private GpxBlockStatisticsBuilder blockStatisticsBuilder;
|
||||
private SelectedGpxFile selectedGpxFile;
|
||||
private final Handler handler = new Handler();
|
||||
private Runnable updatingGPS;
|
||||
|
@ -123,12 +146,6 @@ public class TripRecordingBottomFragment extends MenuBottomSheetDialogFragment {
|
|||
statusContainer = itemView.findViewById(R.id.status_container);
|
||||
updateStatus();
|
||||
|
||||
RecyclerView statBlocks = itemView.findViewById(R.id.block_statistics);
|
||||
blockStatisticsBuilder = new GpxBlockStatisticsBuilder(app, selectedGpxFile);
|
||||
blockStatisticsBuilder.setBlocksView(statBlocks);
|
||||
blockStatisticsBuilder.setBlocksClickable(false);
|
||||
blockStatisticsBuilder.initStatBlocks(null, ContextCompat.getColor(app, getActiveTextColorId(nightMode)), nightMode);
|
||||
|
||||
LinearLayout showTrackContainer = itemView.findViewById(R.id.show_track_on_map);
|
||||
trackAppearanceIcon = showTrackContainer.findViewById(R.id.additional_button_icon);
|
||||
createShowTrackItem(showTrackContainer, trackAppearanceIcon, ItemType.SHOW_TRACK.getTitleId(),
|
||||
|
@ -139,6 +156,17 @@ public class TripRecordingBottomFragment extends MenuBottomSheetDialogFragment {
|
|||
}
|
||||
});
|
||||
|
||||
segmentsContainer = itemView.findViewById(R.id.segments_container);
|
||||
createSegmentsTabs(segmentsContainer);
|
||||
|
||||
RecyclerView statBlocks = itemView.findViewById(R.id.block_statistics);
|
||||
blockStatisticsBuilder = new GpxBlockStatisticsBuilder(app, selectedGpxFile, nightMode);
|
||||
blockStatisticsBuilder.setBlocksView(statBlocks);
|
||||
blockStatisticsBuilder.setBlocksClickable(false);
|
||||
blockStatisticsBuilder.setInitBlocksKey(INIT_BLOCKS_GENERAL);
|
||||
blockStatisticsBuilder.initStatBlocks(null,
|
||||
ContextCompat.getColor(app, getActiveTextColorId(nightMode)));
|
||||
|
||||
CardView cardLeft = itemView.findViewById(R.id.button_left);
|
||||
createItem(cardLeft, ItemType.CANCEL);
|
||||
cardLeft.setOnClickListener(new View.OnClickListener() {
|
||||
|
@ -197,6 +225,10 @@ public class TripRecordingBottomFragment extends MenuBottomSheetDialogFragment {
|
|||
super.onResume();
|
||||
blockStatisticsBuilder.runUpdatingStatBlocksIfNeeded();
|
||||
runUpdatingGPS();
|
||||
MapActivity mapActivity = getMapActivity();
|
||||
if (mapActivity != null) {
|
||||
mapActivity.getMapLayers().getGpxLayer().setTrackChartPoints(trackChartPoints);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -204,6 +236,10 @@ public class TripRecordingBottomFragment extends MenuBottomSheetDialogFragment {
|
|||
super.onPause();
|
||||
blockStatisticsBuilder.stopUpdatingStatBlocks();
|
||||
stopUpdatingGPS();
|
||||
MapActivity mapActivity = getMapActivity();
|
||||
if (mapActivity != null) {
|
||||
mapActivity.getMapLayers().getGpxLayer().setTrackChartPoints(null);
|
||||
}
|
||||
}
|
||||
|
||||
public void show() {
|
||||
|
@ -245,6 +281,51 @@ public class TripRecordingBottomFragment extends MenuBottomSheetDialogFragment {
|
|||
handler.post(updatingGPS);
|
||||
}
|
||||
|
||||
private void recreateStatBlocks(String initBlocksKey) {
|
||||
blockStatisticsBuilder.stopUpdatingStatBlocks();
|
||||
blockStatisticsBuilder.setInitBlocksKey(initBlocksKey);
|
||||
blockStatisticsBuilder.runUpdatingStatBlocksIfNeeded();
|
||||
}
|
||||
|
||||
private void setupDisplayHelper() {
|
||||
displayHelper = new TrackDisplayHelper(app);
|
||||
if (!selectedGpxFile.isShowCurrentTrack()) {
|
||||
File file = new File(getGPXFile().path);
|
||||
displayHelper.setFile(file);
|
||||
displayHelper.setGpxDataItem(app.getGpxDbHelper().getItem(file));
|
||||
}
|
||||
displayHelper.setGpx(getGPXFile());
|
||||
}
|
||||
|
||||
private void createSegmentsTabs(ViewGroup viewGroup) {
|
||||
viewGroup.removeAllViews();
|
||||
setupDisplayHelper();
|
||||
|
||||
View segmentView = SegmentGPXAdapter.createGpxTabsView(displayHelper, viewGroup, this, nightMode);
|
||||
AndroidUiHelper.setVisibility(View.GONE, segmentView.findViewById(R.id.list_item_divider));
|
||||
WrapContentHeightViewPager pager = segmentView.findViewById(R.id.pager);
|
||||
PagerSlidingTabStrip tabLayout = segmentView.findViewById(R.id.sliding_tabs);
|
||||
tabLayout.setOnTabReselectedListener(new PagerSlidingTabStrip.OnTabReselectedListener() {
|
||||
@Override
|
||||
public void onTabSelected(int position) {
|
||||
recreateStatBlocks(INIT_BLOCKS_KEYS[position]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTabReselected(int position) {
|
||||
recreateStatBlocks(INIT_BLOCKS_KEYS[position]);
|
||||
}
|
||||
});
|
||||
|
||||
graphsAdapter = new GPXItemPagerAdapter(app, GpxUiHelper.makeGpxDisplayItem(app,
|
||||
displayHelper.getGpx()), displayHelper, nightMode, this, true);
|
||||
|
||||
pager.setAdapter(graphsAdapter);
|
||||
tabLayout.setViewPager(pager);
|
||||
|
||||
viewGroup.addView(segmentView);
|
||||
}
|
||||
|
||||
private void updateStatus() {
|
||||
TextView statusTitle = statusContainer.findViewById(R.id.text_status);
|
||||
AppCompatImageView statusIcon = statusContainer.findViewById(R.id.icon_status);
|
||||
|
@ -474,6 +555,46 @@ public class TripRecordingBottomFragment extends MenuBottomSheetDialogFragment {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPointSelected(TrkSegment segment, double lat, double lon) {
|
||||
if (trackChartPoints == null) {
|
||||
trackChartPoints = new TrackChartPoints();
|
||||
trackChartPoints.setGpx(displayHelper.getGpx());
|
||||
}
|
||||
MapActivity mapActivity = getMapActivity();
|
||||
if (mapActivity != null) {
|
||||
int segmentColor = segment != null ? segment.getColor(0) : 0;
|
||||
trackChartPoints.setSegmentColor(segmentColor);
|
||||
trackChartPoints.setHighlightedPoint(new LatLon(lat, lon));
|
||||
mapActivity.getMapLayers().getGpxLayer().setTrackChartPoints(trackChartPoints);
|
||||
mapActivity.refreshMap();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateContent() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChartTouch() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void scrollBy(int px) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void openSplitInterval(GpxDisplayItem gpxItem, TrkSegment trkSegment) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showOptionsPopupMenu(View view, TrkSegment segment, boolean confirmDeletion, GpxDisplayItem gpxItem) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void openAnalyzeOnMap(GpxDisplayItem gpxItem) {
|
||||
}
|
||||
|
||||
public interface DismissTargetFragment {
|
||||
void dismissTarget();
|
||||
}
|
||||
|
|
|
@ -61,6 +61,8 @@ import java.util.Map;
|
|||
import static net.osmand.plus.helpers.GpxUiHelper.LineGraphType.ALTITUDE;
|
||||
import static net.osmand.plus.helpers.GpxUiHelper.LineGraphType.SLOPE;
|
||||
import static net.osmand.plus.helpers.GpxUiHelper.LineGraphType.SPEED;
|
||||
import static net.osmand.plus.myplaces.GPXTabItemType.GPX_TAB_ITEM_ALTITUDE;
|
||||
import static net.osmand.plus.myplaces.GPXTabItemType.GPX_TAB_ITEM_SPEED;
|
||||
|
||||
public class GPXItemPagerAdapter extends PagerAdapter implements CustomTabProvider, ViewAtPositionInterface {
|
||||
|
||||
|
@ -79,18 +81,21 @@ public class GPXItemPagerAdapter extends PagerAdapter implements CustomTabProvid
|
|||
|
||||
private boolean chartClicked;
|
||||
private boolean nightMode;
|
||||
|
||||
private boolean onlyGraphs;
|
||||
|
||||
public GPXItemPagerAdapter(@NonNull OsmandApplication app,
|
||||
@NonNull GpxDisplayItem gpxItem,
|
||||
@NonNull TrackDisplayHelper displayHelper,
|
||||
boolean nightMode, @NonNull SegmentActionsListener actionsListener) {
|
||||
boolean nightMode,
|
||||
@NonNull SegmentActionsListener actionsListener,
|
||||
boolean onlyGraphs) {
|
||||
super();
|
||||
this.app = app;
|
||||
this.gpxItem = gpxItem;
|
||||
this.nightMode = nightMode;
|
||||
this.displayHelper = displayHelper;
|
||||
this.actionsListener = actionsListener;
|
||||
this.onlyGraphs = onlyGraphs;
|
||||
iconsCache = app.getUIUtilities();
|
||||
fetchTabTypes();
|
||||
}
|
||||
|
@ -100,10 +105,10 @@ public class GPXItemPagerAdapter extends PagerAdapter implements CustomTabProvid
|
|||
tabTypeList.add(GPXTabItemType.GPX_TAB_ITEM_GENERAL);
|
||||
if (gpxItem != null && gpxItem.analysis != null) {
|
||||
if (gpxItem.analysis.hasElevationData) {
|
||||
tabTypeList.add(GPXTabItemType.GPX_TAB_ITEM_ALTITUDE);
|
||||
tabTypeList.add(GPX_TAB_ITEM_ALTITUDE);
|
||||
}
|
||||
if (gpxItem.analysis.isSpeedSpecified()) {
|
||||
tabTypeList.add(GPXTabItemType.GPX_TAB_ITEM_SPEED);
|
||||
tabTypeList.add(GPX_TAB_ITEM_SPEED);
|
||||
}
|
||||
}
|
||||
tabTypes = tabTypeList.toArray(new GPXTabItemType[0]);
|
||||
|
@ -217,72 +222,87 @@ public class GPXItemPagerAdapter extends PagerAdapter implements CustomTabProvid
|
|||
|
||||
private View getViewForTab(@NonNull ViewGroup container, @NonNull GPXTabItemType tabType) {
|
||||
LayoutInflater inflater = LayoutInflater.from(container.getContext());
|
||||
switch (tabType) {
|
||||
case GPX_TAB_ITEM_ALTITUDE:
|
||||
return inflater.inflate(R.layout.gpx_item_altitude, container, false);
|
||||
case GPX_TAB_ITEM_SPEED:
|
||||
return inflater.inflate(R.layout.gpx_item_speed, container, false);
|
||||
case GPX_TAB_ITEM_GENERAL:
|
||||
default:
|
||||
return inflater.inflate(R.layout.gpx_item_general, container, false);
|
||||
int layoutResId;
|
||||
if (tabType == GPX_TAB_ITEM_ALTITUDE) {
|
||||
layoutResId = R.layout.gpx_item_altitude;
|
||||
} else if (tabType == GPX_TAB_ITEM_SPEED) {
|
||||
layoutResId = R.layout.gpx_item_speed;
|
||||
} else {
|
||||
layoutResId = R.layout.gpx_item_general;
|
||||
}
|
||||
View view = inflater.inflate(layoutResId, container, false);
|
||||
if (onlyGraphs) {
|
||||
AndroidUiHelper.setVisibility(View.GONE,
|
||||
view.findViewById(R.id.gpx_join_gaps_container),
|
||||
view.findViewById(R.id.top_line_blocks),
|
||||
view.findViewById(R.id.list_divider),
|
||||
view.findViewById(R.id.bottom_line_blocks),
|
||||
view.findViewById(R.id.details_divider),
|
||||
view.findViewById(R.id.details_view)
|
||||
);
|
||||
}
|
||||
return view;
|
||||
}
|
||||
|
||||
private void setupSpeedTab(View view, LineChart chart, GPXTrackAnalysis analysis, GPXFile gpxFile, int position) {
|
||||
if (analysis != null && analysis.isSpeedSpecified()) {
|
||||
if (analysis.hasSpeedData) {
|
||||
GpxUiHelper.setupGPXChart(app, chart, 4);
|
||||
chart.setData(new LineData(getDataSets(chart, GPXTabItemType.GPX_TAB_ITEM_SPEED, SPEED, null)));
|
||||
chart.setData(new LineData(getDataSets(chart, GPX_TAB_ITEM_SPEED, SPEED, null)));
|
||||
updateChart(chart);
|
||||
chart.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
chart.setVisibility(View.GONE);
|
||||
}
|
||||
((ImageView) view.findViewById(R.id.average_icon))
|
||||
.setImageDrawable(iconsCache.getThemedIcon(R.drawable.ic_action_speed));
|
||||
((ImageView) view.findViewById(R.id.max_icon))
|
||||
.setImageDrawable(iconsCache.getThemedIcon(R.drawable.ic_action_max_speed));
|
||||
((ImageView) view.findViewById(R.id.time_moving_icon))
|
||||
.setImageDrawable(iconsCache.getThemedIcon(R.drawable.ic_action_time_span));
|
||||
((ImageView) view.findViewById(R.id.distance_icon))
|
||||
.setImageDrawable(iconsCache.getThemedIcon(R.drawable.ic_action_polygom_dark));
|
||||
if (!onlyGraphs) {
|
||||
((ImageView) view.findViewById(R.id.average_icon))
|
||||
.setImageDrawable(iconsCache.getThemedIcon(R.drawable.ic_action_speed));
|
||||
((ImageView) view.findViewById(R.id.max_icon))
|
||||
.setImageDrawable(iconsCache.getThemedIcon(R.drawable.ic_action_max_speed));
|
||||
((ImageView) view.findViewById(R.id.time_moving_icon))
|
||||
.setImageDrawable(iconsCache.getThemedIcon(R.drawable.ic_action_time_span));
|
||||
((ImageView) view.findViewById(R.id.distance_icon))
|
||||
.setImageDrawable(iconsCache.getThemedIcon(R.drawable.ic_action_polygom_dark));
|
||||
|
||||
String avg = OsmAndFormatter.getFormattedSpeed(analysis.avgSpeed, app);
|
||||
String max = OsmAndFormatter.getFormattedSpeed(analysis.maxSpeed, app);
|
||||
String avg = OsmAndFormatter.getFormattedSpeed(analysis.avgSpeed, app);
|
||||
String max = OsmAndFormatter.getFormattedSpeed(analysis.maxSpeed, app);
|
||||
|
||||
((TextView) view.findViewById(R.id.average_text)).setText(avg);
|
||||
((TextView) view.findViewById(R.id.max_text)).setText(max);
|
||||
((TextView) view.findViewById(R.id.average_text)).setText(avg);
|
||||
((TextView) view.findViewById(R.id.max_text)).setText(max);
|
||||
|
||||
view.findViewById(R.id.gpx_join_gaps_container).setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (displayHelper.setJoinSegments(!displayHelper.isJoinSegments())) {
|
||||
actionsListener.updateContent();
|
||||
for (int i = 0; i < getCount(); i++) {
|
||||
View view = getViewAtPosition(i);
|
||||
updateJoinGapsInfo(view, i);
|
||||
view.findViewById(R.id.gpx_join_gaps_container).setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (displayHelper.setJoinSegments(!displayHelper.isJoinSegments())) {
|
||||
actionsListener.updateContent();
|
||||
for (int i = 0; i < getCount(); i++) {
|
||||
View view = getViewAtPosition(i);
|
||||
updateJoinGapsInfo(view, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
} else {
|
||||
chart.setVisibility(View.GONE);
|
||||
view.findViewById(R.id.average_max).setVisibility(View.GONE);
|
||||
view.findViewById(R.id.top_line_blocks).setVisibility(View.GONE);
|
||||
view.findViewById(R.id.list_divider).setVisibility(View.GONE);
|
||||
view.findViewById(R.id.time_distance).setVisibility(View.GONE);
|
||||
view.findViewById(R.id.bottom_line_blocks).setVisibility(View.GONE);
|
||||
}
|
||||
updateJoinGapsInfo(view, position);
|
||||
view.findViewById(R.id.analyze_on_map).setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
openAnalyzeOnMap(GPXTabItemType.GPX_TAB_ITEM_SPEED);
|
||||
if (!onlyGraphs) {
|
||||
updateJoinGapsInfo(view, position);
|
||||
view.findViewById(R.id.analyze_on_map).setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
openAnalyzeOnMap(GPX_TAB_ITEM_SPEED);
|
||||
}
|
||||
});
|
||||
TextView overflowMenu = view.findViewById(R.id.overflow_menu);
|
||||
if (!gpxItem.group.getTrack().generalTrack) {
|
||||
setupOptionsPopupMenu(overflowMenu, false);
|
||||
} else {
|
||||
overflowMenu.setVisibility(View.GONE);
|
||||
}
|
||||
});
|
||||
TextView overflowMenu = view.findViewById(R.id.overflow_menu);
|
||||
if (!gpxItem.group.getTrack().generalTrack) {
|
||||
setupOptionsPopupMenu(overflowMenu, false);
|
||||
} else {
|
||||
overflowMenu.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -300,62 +320,66 @@ public class GPXItemPagerAdapter extends PagerAdapter implements CustomTabProvid
|
|||
if (analysis != null) {
|
||||
if (analysis.hasElevationData) {
|
||||
GpxUiHelper.setupGPXChart(app, chart, 4);
|
||||
chart.setData(new LineData(getDataSets(chart, GPXTabItemType.GPX_TAB_ITEM_ALTITUDE, ALTITUDE, SLOPE)));
|
||||
chart.setData(new LineData(getDataSets(chart, GPX_TAB_ITEM_ALTITUDE, ALTITUDE, SLOPE)));
|
||||
updateChart(chart);
|
||||
chart.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
chart.setVisibility(View.GONE);
|
||||
}
|
||||
((ImageView) view.findViewById(R.id.average_icon))
|
||||
.setImageDrawable(iconsCache.getThemedIcon(R.drawable.ic_action_altitude_average));
|
||||
((ImageView) view.findViewById(R.id.range_icon))
|
||||
.setImageDrawable(iconsCache.getThemedIcon(R.drawable.ic_action_altitude_average));
|
||||
((ImageView) view.findViewById(R.id.ascent_icon))
|
||||
.setImageDrawable(iconsCache.getThemedIcon(R.drawable.ic_action_altitude_ascent));
|
||||
((ImageView) view.findViewById(R.id.descent_icon))
|
||||
.setImageDrawable(iconsCache.getThemedIcon(R.drawable.ic_action_altitude_descent));
|
||||
if (!onlyGraphs) {
|
||||
((ImageView) view.findViewById(R.id.average_icon))
|
||||
.setImageDrawable(iconsCache.getThemedIcon(R.drawable.ic_action_altitude_average));
|
||||
((ImageView) view.findViewById(R.id.range_icon))
|
||||
.setImageDrawable(iconsCache.getThemedIcon(R.drawable.ic_action_altitude_average));
|
||||
((ImageView) view.findViewById(R.id.ascent_icon))
|
||||
.setImageDrawable(iconsCache.getThemedIcon(R.drawable.ic_action_altitude_ascent));
|
||||
((ImageView) view.findViewById(R.id.descent_icon))
|
||||
.setImageDrawable(iconsCache.getThemedIcon(R.drawable.ic_action_altitude_descent));
|
||||
|
||||
String min = OsmAndFormatter.getFormattedAlt(analysis.minElevation, app);
|
||||
String max = OsmAndFormatter.getFormattedAlt(analysis.maxElevation, app);
|
||||
String asc = OsmAndFormatter.getFormattedAlt(analysis.diffElevationUp, app);
|
||||
String desc = OsmAndFormatter.getFormattedAlt(analysis.diffElevationDown, app);
|
||||
String min = OsmAndFormatter.getFormattedAlt(analysis.minElevation, app);
|
||||
String max = OsmAndFormatter.getFormattedAlt(analysis.maxElevation, app);
|
||||
String asc = OsmAndFormatter.getFormattedAlt(analysis.diffElevationUp, app);
|
||||
String desc = OsmAndFormatter.getFormattedAlt(analysis.diffElevationDown, app);
|
||||
|
||||
((TextView) view.findViewById(R.id.average_text))
|
||||
.setText(OsmAndFormatter.getFormattedAlt(analysis.avgElevation, app));
|
||||
((TextView) view.findViewById(R.id.range_text)).setText(String.format("%s - %s", min, max));
|
||||
((TextView) view.findViewById(R.id.ascent_text)).setText(asc);
|
||||
((TextView) view.findViewById(R.id.descent_text)).setText(desc);
|
||||
((TextView) view.findViewById(R.id.average_text))
|
||||
.setText(OsmAndFormatter.getFormattedAlt(analysis.avgElevation, app));
|
||||
((TextView) view.findViewById(R.id.range_text)).setText(String.format("%s - %s", min, max));
|
||||
((TextView) view.findViewById(R.id.ascent_text)).setText(asc);
|
||||
((TextView) view.findViewById(R.id.descent_text)).setText(desc);
|
||||
|
||||
view.findViewById(R.id.gpx_join_gaps_container).setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (displayHelper.setJoinSegments(!displayHelper.isJoinSegments())) {
|
||||
actionsListener.updateContent();
|
||||
for (int i = 0; i < getCount(); i++) {
|
||||
View view = getViewAtPosition(i);
|
||||
updateJoinGapsInfo(view, i);
|
||||
view.findViewById(R.id.gpx_join_gaps_container).setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (displayHelper.setJoinSegments(!displayHelper.isJoinSegments())) {
|
||||
actionsListener.updateContent();
|
||||
for (int i = 0; i < getCount(); i++) {
|
||||
View view = getViewAtPosition(i);
|
||||
updateJoinGapsInfo(view, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
} else {
|
||||
chart.setVisibility(View.GONE);
|
||||
view.findViewById(R.id.average_range).setVisibility(View.GONE);
|
||||
view.findViewById(R.id.top_line_blocks).setVisibility(View.GONE);
|
||||
view.findViewById(R.id.list_divider).setVisibility(View.GONE);
|
||||
view.findViewById(R.id.ascent_descent).setVisibility(View.GONE);
|
||||
view.findViewById(R.id.bottom_line_blocks).setVisibility(View.GONE);
|
||||
}
|
||||
updateJoinGapsInfo(view, position);
|
||||
view.findViewById(R.id.analyze_on_map).setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
openAnalyzeOnMap(GPXTabItemType.GPX_TAB_ITEM_ALTITUDE);
|
||||
if (!onlyGraphs) {
|
||||
updateJoinGapsInfo(view, position);
|
||||
view.findViewById(R.id.analyze_on_map).setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
openAnalyzeOnMap(GPX_TAB_ITEM_ALTITUDE);
|
||||
}
|
||||
});
|
||||
TextView overflowMenu = view.findViewById(R.id.overflow_menu);
|
||||
if (!gpxItem.group.getTrack().generalTrack) {
|
||||
setupOptionsPopupMenu(overflowMenu, false);
|
||||
} else {
|
||||
overflowMenu.setVisibility(View.GONE);
|
||||
}
|
||||
});
|
||||
TextView overflowMenu = view.findViewById(R.id.overflow_menu);
|
||||
if (!gpxItem.group.getTrack().generalTrack) {
|
||||
setupOptionsPopupMenu(overflowMenu, false);
|
||||
} else {
|
||||
overflowMenu.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -369,60 +393,63 @@ public class GPXItemPagerAdapter extends PagerAdapter implements CustomTabProvid
|
|||
} else {
|
||||
chart.setVisibility(View.GONE);
|
||||
}
|
||||
if (!onlyGraphs) {
|
||||
((ImageView) view.findViewById(R.id.distance_icon))
|
||||
.setImageDrawable(iconsCache.getThemedIcon(R.drawable.ic_action_polygom_dark));
|
||||
((ImageView) view.findViewById(R.id.duration_icon))
|
||||
.setImageDrawable(iconsCache.getThemedIcon(R.drawable.ic_action_time_span));
|
||||
((ImageView) view.findViewById(R.id.start_time_icon))
|
||||
.setImageDrawable(iconsCache.getThemedIcon(R.drawable.ic_action_time_start));
|
||||
((ImageView) view.findViewById(R.id.end_time_icon))
|
||||
.setImageDrawable(iconsCache.getThemedIcon(R.drawable.ic_action_time_end));
|
||||
|
||||
((ImageView) view.findViewById(R.id.distance_icon))
|
||||
.setImageDrawable(iconsCache.getThemedIcon(R.drawable.ic_action_polygom_dark));
|
||||
((ImageView) view.findViewById(R.id.duration_icon))
|
||||
.setImageDrawable(iconsCache.getThemedIcon(R.drawable.ic_action_time_span));
|
||||
((ImageView) view.findViewById(R.id.start_time_icon))
|
||||
.setImageDrawable(iconsCache.getThemedIcon(R.drawable.ic_action_time_start));
|
||||
((ImageView) view.findViewById(R.id.end_time_icon))
|
||||
.setImageDrawable(iconsCache.getThemedIcon(R.drawable.ic_action_time_end));
|
||||
|
||||
view.findViewById(R.id.gpx_join_gaps_container).setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (displayHelper.setJoinSegments(!displayHelper.isJoinSegments())) {
|
||||
actionsListener.updateContent();
|
||||
for (int i = 0; i < getCount(); i++) {
|
||||
View view = getViewAtPosition(i);
|
||||
updateJoinGapsInfo(view, i);
|
||||
view.findViewById(R.id.gpx_join_gaps_container).setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (displayHelper.setJoinSegments(!displayHelper.isJoinSegments())) {
|
||||
actionsListener.updateContent();
|
||||
for (int i = 0; i < getCount(); i++) {
|
||||
View view = getViewAtPosition(i);
|
||||
updateJoinGapsInfo(view, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
if (analysis.timeSpan > 0) {
|
||||
DateFormat tf = SimpleDateFormat.getTimeInstance(DateFormat.SHORT);
|
||||
DateFormat df = SimpleDateFormat.getDateInstance(DateFormat.MEDIUM);
|
||||
});
|
||||
if (analysis.timeSpan > 0) {
|
||||
DateFormat tf = SimpleDateFormat.getTimeInstance(DateFormat.SHORT);
|
||||
DateFormat df = SimpleDateFormat.getDateInstance(DateFormat.MEDIUM);
|
||||
|
||||
Date start = new Date(analysis.startTime);
|
||||
((TextView) view.findViewById(R.id.start_time_text)).setText(tf.format(start));
|
||||
((TextView) view.findViewById(R.id.start_date_text)).setText(df.format(start));
|
||||
Date end = new Date(analysis.endTime);
|
||||
((TextView) view.findViewById(R.id.end_time_text)).setText(tf.format(end));
|
||||
((TextView) view.findViewById(R.id.end_date_text)).setText(df.format(end));
|
||||
} else {
|
||||
view.findViewById(R.id.list_divider).setVisibility(View.GONE);
|
||||
view.findViewById(R.id.start_end_time).setVisibility(View.GONE);
|
||||
Date start = new Date(analysis.startTime);
|
||||
((TextView) view.findViewById(R.id.start_time_text)).setText(tf.format(start));
|
||||
((TextView) view.findViewById(R.id.start_date_text)).setText(df.format(start));
|
||||
Date end = new Date(analysis.endTime);
|
||||
((TextView) view.findViewById(R.id.end_time_text)).setText(tf.format(end));
|
||||
((TextView) view.findViewById(R.id.end_date_text)).setText(df.format(end));
|
||||
} else {
|
||||
view.findViewById(R.id.list_divider).setVisibility(View.GONE);
|
||||
view.findViewById(R.id.bottom_line_blocks).setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
chart.setVisibility(View.GONE);
|
||||
view.findViewById(R.id.distance_time_span).setVisibility(View.GONE);
|
||||
view.findViewById(R.id.top_line_blocks).setVisibility(View.GONE);
|
||||
view.findViewById(R.id.list_divider).setVisibility(View.GONE);
|
||||
view.findViewById(R.id.start_end_time).setVisibility(View.GONE);
|
||||
view.findViewById(R.id.bottom_line_blocks).setVisibility(View.GONE);
|
||||
}
|
||||
updateJoinGapsInfo(view, position);
|
||||
view.findViewById(R.id.analyze_on_map).setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
openAnalyzeOnMap(GPXTabItemType.GPX_TAB_ITEM_GENERAL);
|
||||
if (!onlyGraphs) {
|
||||
view.findViewById(R.id.analyze_on_map).setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
openAnalyzeOnMap(GPXTabItemType.GPX_TAB_ITEM_GENERAL);
|
||||
}
|
||||
});
|
||||
TextView overflowMenu = view.findViewById(R.id.overflow_menu);
|
||||
if (!gpxItem.group.getTrack().generalTrack) {
|
||||
setupOptionsPopupMenu(overflowMenu, true);
|
||||
} else {
|
||||
overflowMenu.setVisibility(View.GONE);
|
||||
}
|
||||
});
|
||||
TextView overflowMenu = view.findViewById(R.id.overflow_menu);
|
||||
if (!gpxItem.group.getTrack().generalTrack) {
|
||||
setupOptionsPopupMenu(overflowMenu, true);
|
||||
} else {
|
||||
overflowMenu.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -598,7 +625,7 @@ public class GPXItemPagerAdapter extends PagerAdapter implements CustomTabProvid
|
|||
@Override
|
||||
public void tabStylesUpdated(View tabsContainer, int currentPosition) {
|
||||
ViewGroup.MarginLayoutParams params = (MarginLayoutParams) tabsContainer.getLayoutParams();
|
||||
params.height = app.getResources().getDimensionPixelSize(R.dimen.dialog_button_height);
|
||||
params.height = app.getResources().getDimensionPixelSize(!onlyGraphs ? R.dimen.dialog_button_height : R.dimen.context_menu_buttons_bottom_height);
|
||||
tabsContainer.setLayoutParams(params);
|
||||
UiUtilities.updateCustomRadioButtons(app, tabsContainer, nightMode, getCustomRadioButtonType(currentPosition));
|
||||
}
|
||||
|
@ -645,7 +672,7 @@ public class GPXItemPagerAdapter extends PagerAdapter implements CustomTabProvid
|
|||
|
||||
((TextView) view.findViewById(R.id.distance_text)).setText(OsmAndFormatter.getFormattedDistance(totalDistance, app));
|
||||
((TextView) view.findViewById(R.id.duration_text)).setText(Algorithms.formatDuration((int) (timeSpan / 1000), app.accessibilityEnabled()));
|
||||
} else if (tabType.equals(GPXTabItemType.GPX_TAB_ITEM_SPEED)) {
|
||||
} else if (tabType.equals(GPX_TAB_ITEM_SPEED)) {
|
||||
long timeMoving = !joinSegments && gpxItem.isGeneralTrack() ? analysis.timeMovingWithoutGaps : analysis.timeMoving;
|
||||
float totalDistanceMoving = !joinSegments && gpxItem.isGeneralTrack() ? analysis.totalDistanceMovingWithoutGaps : analysis.totalDistanceMoving;
|
||||
|
||||
|
|
|
@ -55,7 +55,7 @@ public class SegmentGPXAdapter extends ArrayAdapter<GpxDisplayItem> {
|
|||
WrapContentHeightViewPager pager = row.findViewById(R.id.pager);
|
||||
PagerSlidingTabStrip tabLayout = row.findViewById(R.id.sliding_tabs);
|
||||
|
||||
pager.setAdapter(new GPXItemPagerAdapter(app, item, displayHelper, nightMode, listener));
|
||||
pager.setAdapter(new GPXItemPagerAdapter(app, item, displayHelper, nightMode, listener, false));
|
||||
if (create) {
|
||||
tabLayout.setViewPager(pager);
|
||||
} else {
|
||||
|
|
|
@ -8,6 +8,16 @@ import android.view.View;
|
|||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.ColorInt;
|
||||
import androidx.annotation.ColorRes;
|
||||
import androidx.annotation.DrawableRes;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.widget.AppCompatImageView;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import net.osmand.AndroidUtils;
|
||||
import net.osmand.GPXUtilities.GPXFile;
|
||||
import net.osmand.GPXUtilities.GPXTrackAnalysis;
|
||||
|
@ -26,39 +36,44 @@ import net.osmand.util.Algorithms;
|
|||
|
||||
import org.apache.commons.logging.Log;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import androidx.annotation.ColorInt;
|
||||
import androidx.annotation.ColorRes;
|
||||
import androidx.annotation.DrawableRes;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.widget.AppCompatImageView;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import static net.osmand.plus.liveupdates.LiveUpdatesFragmentNew.getDefaultIconColorId;
|
||||
|
||||
public class GpxBlockStatisticsBuilder {
|
||||
|
||||
private static final Log log = PlatformUtil.getLog(GpxBlockStatisticsBuilder.class);
|
||||
private static final int GENERAL_UPDATE_INTERVAL = 1000;
|
||||
private static final Log LOG = PlatformUtil.getLog(GpxBlockStatisticsBuilder.class);
|
||||
private static final int BLOCKS_UPDATE_INTERVAL = 1000;
|
||||
public static final String INIT_BLOCKS_BASE = "init_blocks_base";
|
||||
public static final String INIT_BLOCKS_GENERAL = "init_blocks_general";
|
||||
public static final String INIT_BLOCKS_ALTITUDE = "init_blocks_altitude";
|
||||
public static final String INIT_BLOCKS_SPEED = "init_blocks_speed";
|
||||
|
||||
private final OsmandApplication app;
|
||||
private final boolean nightMode;
|
||||
|
||||
private RecyclerView blocksView;
|
||||
private final SelectedGpxFile selectedGpxFile;
|
||||
private GPXTrackAnalysis analysis;
|
||||
|
||||
private BlockStatisticsAdapter adapter;
|
||||
private final List<StatBlock> items = new ArrayList<>();
|
||||
private boolean blocksClickable = true;
|
||||
private String initBlocksKey = INIT_BLOCKS_BASE;
|
||||
|
||||
private final Handler handler = new Handler();
|
||||
private Runnable updatingItems;
|
||||
private boolean updateRunning = false;
|
||||
|
||||
public GpxBlockStatisticsBuilder(OsmandApplication app, SelectedGpxFile selectedGpxFile) {
|
||||
public GpxBlockStatisticsBuilder(OsmandApplication app, SelectedGpxFile selectedGpxFile, boolean nightMode) {
|
||||
this.app = app;
|
||||
this.selectedGpxFile = selectedGpxFile;
|
||||
this.nightMode = nightMode;
|
||||
}
|
||||
|
||||
public boolean isUpdateRunning() {
|
||||
|
@ -73,6 +88,10 @@ public class GpxBlockStatisticsBuilder {
|
|||
this.blocksView = blocksView;
|
||||
}
|
||||
|
||||
public void setInitBlocksKey(String initBlocksKey) {
|
||||
this.initBlocksKey = initBlocksKey;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public GpxDisplayItem getDisplayItem(GPXFile gpxFile) {
|
||||
return gpxFile.tracks.size() > 0 ? GpxUiHelper.makeGpxDisplayItem(app, gpxFile) : null;
|
||||
|
@ -82,9 +101,9 @@ public class GpxBlockStatisticsBuilder {
|
|||
return selectedGpxFile.getGpxFile();
|
||||
}
|
||||
|
||||
public void initStatBlocks(@Nullable SegmentActionsListener actionsListener, @ColorInt int activeColor, boolean nightMode) {
|
||||
public void initStatBlocks(@Nullable SegmentActionsListener actionsListener, @ColorInt int activeColor) {
|
||||
initItems();
|
||||
adapter = new BlockStatisticsAdapter(getDisplayItem(getGPXFile()), actionsListener, activeColor, nightMode);
|
||||
adapter = new BlockStatisticsAdapter(getDisplayItem(getGPXFile()), actionsListener, activeColor);
|
||||
adapter.setItems(items);
|
||||
blocksView.setLayoutManager(new LinearLayoutManager(app, LinearLayoutManager.HORIZONTAL, false));
|
||||
blocksView.setAdapter(adapter);
|
||||
|
@ -107,7 +126,7 @@ public class GpxBlockStatisticsBuilder {
|
|||
}
|
||||
AndroidUiHelper.updateVisibility(blocksView, !Algorithms.isEmpty(items));
|
||||
int interval = app.getSettings().SAVE_GLOBAL_TRACK_INTERVAL.get();
|
||||
updateRunning = handler.postDelayed(this, Math.max(GENERAL_UPDATE_INTERVAL, interval));
|
||||
updateRunning = handler.postDelayed(this, Math.max(BLOCKS_UPDATE_INTERVAL, interval));
|
||||
}
|
||||
};
|
||||
updateRunning = handler.post(updatingItems);
|
||||
|
@ -119,7 +138,7 @@ public class GpxBlockStatisticsBuilder {
|
|||
if (app == null || gpxFile == null) {
|
||||
return;
|
||||
}
|
||||
GPXTrackAnalysis analysis = null;
|
||||
analysis = null;
|
||||
boolean withoutGaps = true;
|
||||
if (gpxFile.equals(app.getSavingTrackHelper().getCurrentGpx())) {
|
||||
GPXFile currentGpx = app.getSavingTrackHelper().getCurrentTrack().getGpxFile();
|
||||
|
@ -133,34 +152,140 @@ public class GpxBlockStatisticsBuilder {
|
|||
withoutGaps = !selectedGpxFile.isJoinSegments() && gpxDisplayItem.isGeneralTrack();
|
||||
}
|
||||
}
|
||||
items.clear();
|
||||
if (analysis != null) {
|
||||
float totalDistance = withoutGaps ? analysis.totalDistanceWithoutGaps : analysis.totalDistance;
|
||||
float timeSpan = withoutGaps ? analysis.timeSpanWithoutGaps : analysis.timeSpan;
|
||||
String asc = OsmAndFormatter.getFormattedAlt(analysis.diffElevationUp, app);
|
||||
String desc = OsmAndFormatter.getFormattedAlt(analysis.diffElevationDown, app);
|
||||
String avg = OsmAndFormatter.getFormattedSpeed(analysis.avgSpeed, app);
|
||||
String max = OsmAndFormatter.getFormattedSpeed(analysis.maxSpeed, app);
|
||||
|
||||
items.clear();
|
||||
prepareData(analysis, app.getString(R.string.distance), OsmAndFormatter.getFormattedDistance(totalDistance, app),
|
||||
R.drawable.ic_action_track_16, R.color.icon_color_default_light, GPXDataSetType.ALTITUDE, GPXDataSetType.SPEED, ItemType.ITEM_DISTANCE);
|
||||
prepareData(analysis, app.getString(R.string.altitude_ascent), asc,
|
||||
R.drawable.ic_action_arrow_up_16, R.color.gpx_chart_red, GPXDataSetType.SLOPE, null, ItemType.ITEM_ALTITUDE);
|
||||
prepareData(analysis, app.getString(R.string.altitude_descent), desc,
|
||||
R.drawable.ic_action_arrow_down_16, R.color.gpx_pale_green, GPXDataSetType.ALTITUDE, GPXDataSetType.SLOPE, ItemType.ITEM_ALTITUDE);
|
||||
prepareData(analysis, app.getString(R.string.average_speed), avg,
|
||||
R.drawable.ic_action_speed_16, R.color.icon_color_default_light, GPXDataSetType.SPEED, null, ItemType.ITEM_SPEED);
|
||||
prepareData(analysis, app.getString(R.string.max_speed), max,
|
||||
R.drawable.ic_action_max_speed_16, R.color.icon_color_default_light, GPXDataSetType.SPEED, null, ItemType.ITEM_SPEED);
|
||||
prepareData(analysis, app.getString(R.string.shared_string_time_span),
|
||||
Algorithms.formatDuration((int) (timeSpan / 1000), app.accessibilityEnabled()),
|
||||
R.drawable.ic_action_time_span_16, R.color.icon_color_default_light, GPXDataSetType.SPEED, null, ItemType.ITEM_TIME);
|
||||
switch (initBlocksKey) {
|
||||
case INIT_BLOCKS_GENERAL: {
|
||||
float totalDistance = withoutGaps ? analysis.totalDistanceWithoutGaps : analysis.totalDistance;
|
||||
float timeSpan = withoutGaps ? analysis.timeSpanWithoutGaps : analysis.timeSpan;
|
||||
Date start = new Date(analysis.startTime);
|
||||
Date end = new Date(analysis.endTime);
|
||||
prepareDataDistance(totalDistance);
|
||||
prepareDataTimeSpan(timeSpan);
|
||||
prepareDataStartTime(start);
|
||||
prepareDataEndTime(end);
|
||||
break;
|
||||
}
|
||||
case INIT_BLOCKS_ALTITUDE: {
|
||||
String min = OsmAndFormatter.getFormattedAlt(analysis.minElevation, app);
|
||||
String max = OsmAndFormatter.getFormattedAlt(analysis.maxElevation, app);
|
||||
String asc = OsmAndFormatter.getFormattedAlt(analysis.diffElevationUp, app);
|
||||
String desc = OsmAndFormatter.getFormattedAlt(analysis.diffElevationDown, app);
|
||||
prepareDataAverageAltitude();
|
||||
prepareDataAltitudeRange(min, max);
|
||||
prepareDataAscent(asc);
|
||||
prepareDataDescent(desc);
|
||||
break;
|
||||
}
|
||||
case INIT_BLOCKS_SPEED: {
|
||||
String avg = OsmAndFormatter.getFormattedSpeed(analysis.avgSpeed, app);
|
||||
String max = OsmAndFormatter.getFormattedSpeed(analysis.maxSpeed, app);
|
||||
long timeMoving = withoutGaps ? analysis.timeMovingWithoutGaps : analysis.timeMoving;
|
||||
float totalDistanceMoving = withoutGaps ? analysis.totalDistanceMovingWithoutGaps : analysis.totalDistanceMoving;
|
||||
prepareDataAverageSpeed(avg);
|
||||
prepareDataMaximumSpeed(max);
|
||||
prepareDataTimeMoving(timeMoving);
|
||||
prepareDataDistanceCorrected(totalDistanceMoving);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
case INIT_BLOCKS_BASE: {
|
||||
float totalDistance = withoutGaps ? analysis.totalDistanceWithoutGaps : analysis.totalDistance;
|
||||
String asc = OsmAndFormatter.getFormattedAlt(analysis.diffElevationUp, app);
|
||||
String desc = OsmAndFormatter.getFormattedAlt(analysis.diffElevationDown, app);
|
||||
String avg = OsmAndFormatter.getFormattedSpeed(analysis.avgSpeed, app);
|
||||
String max = OsmAndFormatter.getFormattedSpeed(analysis.maxSpeed, app);
|
||||
float timeSpan = withoutGaps ? analysis.timeSpanWithoutGaps : analysis.timeSpan;
|
||||
prepareDataDistance(totalDistance);
|
||||
prepareDataAscent(asc);
|
||||
prepareDataDescent(desc);
|
||||
prepareDataAverageSpeed(avg);
|
||||
prepareDataMaximumSpeed(max);
|
||||
prepareDataTimeSpan(timeSpan);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void prepareData(GPXTrackAnalysis analysis, String title, String value,
|
||||
@DrawableRes int imageResId, @ColorRes int imageColorId,
|
||||
public void prepareDataDistance(float totalDistance) {
|
||||
prepareData(app.getString(R.string.distance), OsmAndFormatter.getFormattedDistance(totalDistance, app),
|
||||
R.drawable.ic_action_track_16, GPXDataSetType.ALTITUDE, GPXDataSetType.SPEED, ItemType.ITEM_DISTANCE);
|
||||
}
|
||||
|
||||
public void prepareDataAverageAltitude() {
|
||||
prepareData(app.getString(R.string.average_altitude), OsmAndFormatter.getFormattedAlt(analysis.avgElevation, app),
|
||||
R.drawable.ic_action_altitude_average_16, GPXDataSetType.ALTITUDE, null, ItemType.ITEM_ALTITUDE);
|
||||
}
|
||||
|
||||
public void prepareDataAltitudeRange(String min, String max) {
|
||||
String pattern = app.getString(R.string.ltr_or_rtl_combine_via_dash);
|
||||
prepareData(app.getString(R.string.altitude_range), String.format(pattern, min, max),
|
||||
R.drawable.ic_action_altitude_range_16, GPXDataSetType.ALTITUDE, null, ItemType.ITEM_ALTITUDE);
|
||||
}
|
||||
|
||||
public void prepareDataAscent(String asc) {
|
||||
prepareData(app.getString(R.string.altitude_ascent), asc,
|
||||
R.drawable.ic_action_arrow_up_16, R.color.gpx_chart_red,
|
||||
GPXDataSetType.SLOPE, null, ItemType.ITEM_ALTITUDE);
|
||||
}
|
||||
|
||||
public void prepareDataDescent(String desc) {
|
||||
prepareData(app.getString(R.string.altitude_descent), desc,
|
||||
R.drawable.ic_action_arrow_down_16, R.color.gpx_pale_green,
|
||||
GPXDataSetType.ALTITUDE, GPXDataSetType.SLOPE, ItemType.ITEM_ALTITUDE);
|
||||
}
|
||||
|
||||
public void prepareDataAverageSpeed(String avg) {
|
||||
prepareData(app.getString(R.string.average_speed), avg,
|
||||
R.drawable.ic_action_speed_16, GPXDataSetType.SPEED, null, ItemType.ITEM_SPEED);
|
||||
}
|
||||
|
||||
public void prepareDataMaximumSpeed(String max) {
|
||||
prepareData(app.getString(R.string.max_speed), max,
|
||||
R.drawable.ic_action_max_speed_16, GPXDataSetType.SPEED, null, ItemType.ITEM_SPEED);
|
||||
}
|
||||
|
||||
public void prepareDataTimeMoving(long timeMoving) {
|
||||
prepareData(app.getString(R.string.shared_string_time_moving),
|
||||
Algorithms.formatDuration((int) (timeMoving / 1000), app.accessibilityEnabled()),
|
||||
R.drawable.ic_action_time_span_16, GPXDataSetType.SPEED, null, ItemType.ITEM_TIME_MOVING);
|
||||
}
|
||||
|
||||
public void prepareDataDistanceCorrected(float totalDistanceMoving) {
|
||||
prepareData(app.getString(R.string.distance_moving),
|
||||
OsmAndFormatter.getFormattedDistance(totalDistanceMoving, app),
|
||||
R.drawable.ic_action_polygom_dark, GPXDataSetType.SPEED, null, ItemType.ITEM_DISTANCE_MOVING);
|
||||
}
|
||||
|
||||
public void prepareDataTimeSpan(float timeSpan) {
|
||||
prepareData(app.getString(R.string.shared_string_time_span),
|
||||
Algorithms.formatDuration((int) (timeSpan / 1000), app.accessibilityEnabled()),
|
||||
R.drawable.ic_action_time_span_16, GPXDataSetType.SPEED, null, ItemType.ITEM_TIME_SPAN);
|
||||
}
|
||||
|
||||
public void prepareDataStartTime(Date start) {
|
||||
DateFormat dtf = SimpleDateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT);
|
||||
prepareData(app.getString(R.string.shared_string_start_time), dtf.format(start),
|
||||
R.drawable.ic_action_time_start_16, GPXDataSetType.SPEED, null, ItemType.ITEM_TIME);
|
||||
}
|
||||
|
||||
public void prepareDataEndTime(Date end) {
|
||||
DateFormat dtf = SimpleDateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT);
|
||||
prepareData(app.getString(R.string.shared_string_end_time), dtf.format(end),
|
||||
R.drawable.ic_action_time_end_16, GPXDataSetType.SPEED, null, ItemType.ITEM_TIME);
|
||||
}
|
||||
|
||||
public void prepareData(String title, String value, @DrawableRes int imageResId,
|
||||
GPXDataSetType firstType, GPXDataSetType secondType, ItemType itemType) {
|
||||
prepareData(title, value, imageResId, getDefaultIconColorId(nightMode), firstType, secondType, itemType);
|
||||
}
|
||||
|
||||
public void prepareData(String title, String value, @DrawableRes int imageResId, @ColorRes int imageColorId,
|
||||
GPXDataSetType firstType, GPXDataSetType secondType, ItemType itemType) {
|
||||
if (analysis == null) {
|
||||
return;
|
||||
}
|
||||
StatBlock statBlock = new StatBlock(title, value, imageResId, imageColorId, firstType, secondType, itemType);
|
||||
switch (statBlock.itemType) {
|
||||
case ITEM_DISTANCE: {
|
||||
|
@ -169,6 +294,12 @@ public class GpxBlockStatisticsBuilder {
|
|||
}
|
||||
break;
|
||||
}
|
||||
case ITEM_DISTANCE_MOVING: {
|
||||
if (analysis.totalDistanceMoving != 0f) {
|
||||
items.add(statBlock);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ITEM_ALTITUDE: {
|
||||
if (analysis.hasElevationData) {
|
||||
items.add(statBlock);
|
||||
|
@ -182,11 +313,23 @@ public class GpxBlockStatisticsBuilder {
|
|||
break;
|
||||
}
|
||||
case ITEM_TIME: {
|
||||
if (analysis.timeSpan > 0) {
|
||||
items.add(statBlock);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ITEM_TIME_SPAN: {
|
||||
if (analysis.hasSpeedData) {
|
||||
items.add(statBlock);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ITEM_TIME_MOVING: {
|
||||
if (analysis.isTimeMoving()) {
|
||||
items.add(statBlock);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -213,9 +356,12 @@ public class GpxBlockStatisticsBuilder {
|
|||
|
||||
public enum ItemType {
|
||||
ITEM_DISTANCE,
|
||||
ITEM_DISTANCE_MOVING,
|
||||
ITEM_ALTITUDE,
|
||||
ITEM_SPEED,
|
||||
ITEM_TIME;
|
||||
ITEM_TIME,
|
||||
ITEM_TIME_SPAN,
|
||||
ITEM_TIME_MOVING;
|
||||
}
|
||||
|
||||
private class BlockStatisticsAdapter extends RecyclerView.Adapter<BlockStatisticsViewHolder> {
|
||||
|
@ -225,17 +371,15 @@ public class GpxBlockStatisticsBuilder {
|
|||
private final SegmentActionsListener actionsListener;
|
||||
@ColorInt
|
||||
private final int activeColor;
|
||||
private final boolean nightMode;
|
||||
private final int minWidthPx;
|
||||
private final int maxWidthPx;
|
||||
private final int textSize;
|
||||
|
||||
public BlockStatisticsAdapter(GpxDisplayItem displayItem, SegmentActionsListener actionsListener,
|
||||
@ColorInt int activeColor, boolean nightMode) {
|
||||
@ColorInt int activeColor) {
|
||||
this.displayItem = displayItem;
|
||||
this.actionsListener = actionsListener;
|
||||
this.activeColor = activeColor;
|
||||
this.nightMode = nightMode;
|
||||
minWidthPx = AndroidUtils.dpToPx(app, 60f);
|
||||
maxWidthPx = AndroidUtils.dpToPx(app, 120f);
|
||||
textSize = app.getResources().getDimensionPixelSize(R.dimen.default_desc_text_size);
|
||||
|
@ -260,7 +404,7 @@ public class GpxBlockStatisticsBuilder {
|
|||
holder.valueText.setText(item.value);
|
||||
holder.valueText.setTextColor(activeColor);
|
||||
holder.titleText.setText(item.title);
|
||||
holder.titleText.setTextColor(app.getResources().getColor(R.color.text_color_secondary_light));
|
||||
holder.titleText.setTextColor(ContextCompat.getColor(app, R.color.text_color_secondary_light));
|
||||
float letterSpacing = 0.00f;
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
letterSpacing = Math.max(holder.valueText.getLetterSpacing(), holder.titleText.getLetterSpacing());
|
||||
|
|
|
@ -51,7 +51,7 @@ public class OverviewCard extends BaseCard {
|
|||
super(mapActivity);
|
||||
this.actionsListener = actionsListener;
|
||||
this.selectedGpxFile = selectedGpxFile;
|
||||
blockStatisticsBuilder = new GpxBlockStatisticsBuilder(app, selectedGpxFile);
|
||||
blockStatisticsBuilder = new GpxBlockStatisticsBuilder(app, selectedGpxFile, nightMode);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -80,7 +80,7 @@ public class OverviewCard extends BaseCard {
|
|||
initEditButton(iconColorDef, iconColorPres);
|
||||
initDirectionsButton(iconColorDef, iconColorPres);
|
||||
}
|
||||
blockStatisticsBuilder.initStatBlocks(actionsListener, getActiveColor(), nightMode);
|
||||
blockStatisticsBuilder.initStatBlocks(actionsListener, getActiveColor());
|
||||
}
|
||||
|
||||
private GPXFile getGPXFile() {
|
||||
|
|
|
@ -47,7 +47,7 @@ public class SegmentsCard extends BaseCard {
|
|||
WrapContentHeightViewPager pager = segmentView.findViewById(R.id.pager);
|
||||
PagerSlidingTabStrip tabLayout = segmentView.findViewById(R.id.sliding_tabs);
|
||||
|
||||
pager.setAdapter(new GPXItemPagerAdapter(app, displayItem, displayHelper, nightMode, listener));
|
||||
pager.setAdapter(new GPXItemPagerAdapter(app, displayItem, displayHelper, nightMode, listener, false));
|
||||
tabLayout.setViewPager(pager);
|
||||
|
||||
container.addView(segmentView);
|
||||
|
|
|
@ -66,12 +66,17 @@ public class PagerSlidingTabStrip extends HorizontalScrollView {
|
|||
|
||||
public interface CustomTabProvider {
|
||||
public View getCustomTabView(@NonNull ViewGroup parent, int position);
|
||||
|
||||
public void select(View tab);
|
||||
|
||||
public void deselect(View tab);
|
||||
|
||||
public void tabStylesUpdated(View tabsContainer, int currentPosition);
|
||||
}
|
||||
|
||||
public interface OnTabReselectedListener {
|
||||
public void onTabSelected(int position);
|
||||
|
||||
public void onTabReselected(int position);
|
||||
}
|
||||
|
||||
|
@ -121,7 +126,7 @@ public class PagerSlidingTabStrip extends HorizontalScrollView {
|
|||
private int underlineHeight = 0;
|
||||
@ColorInt
|
||||
private int underlineColor;
|
||||
|
||||
|
||||
|
||||
private int dividerWidth = 0;
|
||||
private int dividerPadding = 0;
|
||||
|
@ -197,7 +202,7 @@ public class PagerSlidingTabStrip extends HorizontalScrollView {
|
|||
|
||||
//In case we have the padding they must be equal so we take the biggest
|
||||
padding = Math.max(paddingLeft, paddingRight);
|
||||
|
||||
|
||||
|
||||
// get custom attrs
|
||||
a = context.obtainStyledAttributes(attrs, R.styleable.PagerSlidingTabStrip);
|
||||
|
@ -221,7 +226,7 @@ public class PagerSlidingTabStrip extends HorizontalScrollView {
|
|||
tabTypefaceSelectedStyle = a.getInt(R.styleable.PagerSlidingTabStrip_pstsTextSelectedStyle, Typeface.NORMAL);
|
||||
tabTextAlpha = a.getFloat(R.styleable.PagerSlidingTabStrip_pstsTextAlpha, HALF_TRANSP);
|
||||
tabTextSelectedAlpha = a.getFloat(R.styleable.PagerSlidingTabStrip_pstsTextSelectedAlpha, OPAQUE);
|
||||
tabTypeface = FontCache.getRobotoMedium(context);
|
||||
tabTypeface = FontCache.getRobotoMedium(context);
|
||||
a.recycle();
|
||||
|
||||
setMarginBottomTabContainer();
|
||||
|
@ -326,6 +331,9 @@ public class PagerSlidingTabStrip extends HorizontalScrollView {
|
|||
View tab = tabsContainer.getChildAt(pager.getCurrentItem());
|
||||
notSelected(tab);
|
||||
pager.setCurrentItem(position);
|
||||
if (tabReselectedListener != null) {
|
||||
tabReselectedListener.onTabSelected(position);
|
||||
}
|
||||
} else if (tabReselectedListener != null) {
|
||||
tabReselectedListener.onTabReselected(position);
|
||||
}
|
||||
|
@ -470,7 +478,7 @@ public class PagerSlidingTabStrip extends HorizontalScrollView {
|
|||
// draw underline
|
||||
rectPaint.setColor(underlineColor); //underlineColor
|
||||
canvas.drawRect(padding, height - underlineHeight, tabsContainer.getWidth() + padding, height, rectPaint);
|
||||
|
||||
|
||||
// draw divider
|
||||
if (dividerWidth != 0) {
|
||||
dividerPaint.setStrokeWidth(dividerWidth);
|
||||
|
|
Loading…
Reference in a new issue