OverviewCard cleanup

This commit is contained in:
Vitaliy 2021-01-25 02:39:46 +02:00
parent b0b07c6b4e
commit 36ff140731
8 changed files with 307 additions and 329 deletions

View file

@ -1,104 +1,104 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:osmand="http://schemas.android.com/apk/res-auto" xmlns:osmand="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical"> android:orientation="vertical">
<androidx.recyclerview.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_overview" android:id="@+id/recycler_overview"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/content_padding_small_half" android:layout_marginBottom="@dimen/content_padding_small_half"
android:clipToPadding="false" android:clipToPadding="false"
android:orientation="horizontal" android:orientation="horizontal"
tools:itemCount="4" tools:itemCount="4"
tools:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" tools:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
tools:listitem="@layout/item_gpx_stat_block" /> tools:listitem="@layout/item_gpx_stat_block" />
<LinearLayout <LinearLayout
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="@dimen/content_padding" android:layout_marginStart="@dimen/content_padding"
android:layout_marginLeft="@dimen/content_padding" android:layout_marginLeft="@dimen/content_padding"
android:gravity="center" android:gravity="center"
android:orientation="horizontal" android:orientation="horizontal"
android:paddingTop="@dimen/dash_margin" android:paddingTop="@dimen/dash_margin"
android:paddingBottom="@dimen/dash_margin"> android:paddingBottom="@dimen/dash_margin">
<androidx.appcompat.widget.AppCompatImageView <androidx.appcompat.widget.AppCompatImageView
android:id="@+id/direction" android:id="@+id/direction"
android:layout_width="@dimen/context_menu_transport_icon_size" android:layout_width="@dimen/context_menu_transport_icon_size"
android:layout_height="@dimen/context_menu_transport_icon_size" android:layout_height="@dimen/context_menu_transport_icon_size"
osmand:srcCompat="@drawable/ic_direction_arrow" /> osmand:srcCompat="@drawable/ic_direction_arrow" />
<TextView <TextView
android:id="@+id/distance" android:id="@+id/distance"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="@dimen/content_padding_small_half" android:layout_marginStart="@dimen/content_padding_small_half"
android:layout_marginLeft="@dimen/content_padding_small_half" android:layout_marginLeft="@dimen/content_padding_small_half"
android:maxLines="1" android:maxLines="1"
android:textColor="?android:textColorSecondary" android:textColor="?android:textColorSecondary"
android:textSize="@dimen/default_desc_text_size" android:textSize="@dimen/default_desc_text_size"
tools:text="300 km" /> tools:text="300 km" />
</LinearLayout> </LinearLayout>
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="@dimen/content_padding" android:layout_marginStart="@dimen/content_padding"
android:layout_marginLeft="@dimen/content_padding" android:layout_marginLeft="@dimen/content_padding"
android:layout_marginEnd="@dimen/content_padding" android:layout_marginTop="@dimen/content_padding_half"
android:layout_marginRight="@dimen/content_padding" android:layout_marginEnd="@dimen/content_padding"
android:layout_marginTop="@dimen/content_padding_half" android:layout_marginRight="@dimen/content_padding"
android:layout_marginBottom="@dimen/content_padding" android:layout_marginBottom="@dimen/content_padding"
android:weightSum="4" android:orientation="horizontal"
android:orientation="horizontal"> android:weightSum="4">
<!-- todo stretch buttons correctly --> <!-- todo stretch buttons correctly -->
<include <include
android:id="@+id/show_button" android:id="@+id/show_button"
android:layout_weight="1" layout="@layout/item_gpx_action"
layout="@layout/item_gpx_action" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_width="wrap_content" /> android:layout_weight="1" />
<Space <Space
android:layout_width="@dimen/content_padding_half" android:layout_width="@dimen/content_padding_half"
android:layout_height="match_parent" /> android:layout_height="match_parent" />
<include <include
android:id="@+id/appearance_button" android:id="@+id/appearance_button"
android:layout_weight="1" layout="@layout/item_gpx_action"
android:layout_height="wrap_content" android:layout_width="wrap_content"
android:layout_width="wrap_content" android:layout_height="wrap_content"
layout="@layout/item_gpx_action" /> android:layout_weight="1" />
<Space <Space
android:layout_width="@dimen/content_padding_half" android:layout_width="@dimen/content_padding_half"
android:layout_height="match_parent" /> android:layout_height="match_parent" />
<include <include
android:id="@+id/edit_button" android:id="@+id/edit_button"
android:layout_weight="1" layout="@layout/item_gpx_action"
android:layout_height="wrap_content" android:layout_width="wrap_content"
android:layout_width="wrap_content" android:layout_height="wrap_content"
layout="@layout/item_gpx_action" /> android:layout_weight="1" />
<Space <Space
android:layout_width="@dimen/content_padding_half" android:layout_width="@dimen/content_padding_half"
android:layout_height="match_parent" /> android:layout_height="match_parent" />
<include <include
android:id="@+id/directions_button" android:id="@+id/directions_button"
android:layout_weight="1" layout="@layout/item_gpx_action"
android:layout_height="wrap_content" android:layout_width="wrap_content"
android:layout_width="wrap_content" android:layout_height="wrap_content"
layout="@layout/item_gpx_action" /> android:layout_weight="1" />
</LinearLayout> </LinearLayout>
</LinearLayout> </LinearLayout>

View file

@ -1,22 +1,21 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="wrap_content"
android:layout_width="wrap_content" android:layout_height="wrap_content">
android:layout_height="wrap_content">
<androidx.appcompat.widget.AppCompatImageView <androidx.appcompat.widget.AppCompatImageView
android:id="@+id/filled" android:id="@+id/filled"
android:layout_width="@dimen/fab_recycler_view_padding_bottom" android:layout_width="@dimen/fab_recycler_view_padding_bottom"
android:layout_height="@dimen/setting_list_item_small_height" android:layout_height="@dimen/setting_list_item_small_height"
tools:alpha="0.1" tools:alpha="0.1"
tools:srcCompat="@drawable/bg_topbar_shield_exit_ref" /> tools:srcCompat="@drawable/bg_topbar_shield_exit_ref" />
<androidx.appcompat.widget.AppCompatImageView <androidx.appcompat.widget.AppCompatImageView
android:id="@+id/image" android:id="@+id/image"
android:layout_gravity="center" android:layout_width="@dimen/standard_icon_size"
android:layout_width="@dimen/standard_icon_size" android:layout_height="@dimen/standard_icon_size"
android:layout_height="@dimen/standard_icon_size" android:layout_gravity="center"
tools:srcCompat="@drawable/ic_action_hide" /> tools:srcCompat="@drawable/ic_action_hide" />
</FrameLayout> </FrameLayout>

View file

@ -1,44 +1,44 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:osmand="http://schemas.android.com/apk/res-auto" xmlns:osmand="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical"> android:orientation="vertical">
<LinearLayout <LinearLayout
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="horizontal"> android:orientation="horizontal">
<net.osmand.plus.widgets.TextViewEx <net.osmand.plus.widgets.TextViewEx
android:id="@+id/value" android:id="@+id/value"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="@null" android:background="@null"
android:textColor="?android:attr/textColorPrimary" android:textColor="?android:attr/textColorPrimary"
android:textSize="@dimen/default_desc_text_size" android:textSize="@dimen/default_desc_text_size"
osmand:typeface="@string/font_roboto_medium" osmand:typeface="@string/font_roboto_medium"
tools:text="700 km" /> tools:text="700 km" />
<androidx.appcompat.widget.AppCompatImageView <androidx.appcompat.widget.AppCompatImageView
android:id="@+id/image" android:id="@+id/image"
android:layout_width="@dimen/context_menu_transport_icon_size" android:layout_width="@dimen/context_menu_transport_icon_size"
android:layout_height="@dimen/context_menu_transport_icon_size" android:layout_height="@dimen/context_menu_transport_icon_size"
android:layout_gravity="center_vertical" android:layout_gravity="center_vertical"
android:layout_marginStart="@dimen/context_menu_first_line_top_margin" android:layout_marginStart="@dimen/context_menu_first_line_top_margin"
android:layout_marginLeft="@dimen/context_menu_first_line_top_margin" android:layout_marginLeft="@dimen/context_menu_first_line_top_margin"
tools:src="@drawable/ic_action_track_16" /> tools:src="@drawable/ic_action_track_16" />
</LinearLayout> </LinearLayout>
<TextView <TextView
android:id="@+id/title" android:id="@+id/title"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="@null" android:background="@null"
android:textColor="?android:attr/textColorSecondary" android:textColor="?android:attr/textColorSecondary"
android:textSize="@dimen/default_desc_text_size" android:textSize="@dimen/default_desc_text_size"
tools:text="@string/distance" /> tools:text="@string/distance" />
</LinearLayout> </LinearLayout>

View file

@ -38,6 +38,7 @@ import net.osmand.plus.UiUtilities;
import net.osmand.plus.helpers.AndroidUiHelper; import net.osmand.plus.helpers.AndroidUiHelper;
import net.osmand.plus.helpers.GpxUiHelper; import net.osmand.plus.helpers.GpxUiHelper;
import net.osmand.plus.helpers.GpxUiHelper.GPXDataSetAxisType; import net.osmand.plus.helpers.GpxUiHelper.GPXDataSetAxisType;
import net.osmand.plus.helpers.GpxUiHelper.GPXDataSetType;
import net.osmand.plus.helpers.GpxUiHelper.LineGraphType; import net.osmand.plus.helpers.GpxUiHelper.LineGraphType;
import net.osmand.plus.helpers.GpxUiHelper.OrderedLineDataSet; import net.osmand.plus.helpers.GpxUiHelper.OrderedLineDataSet;
import net.osmand.plus.track.TrackDisplayHelper; import net.osmand.plus.track.TrackDisplayHelper;
@ -687,8 +688,50 @@ public class GPXItemPagerAdapter extends PagerAdapter implements CustomTabProvid
} }
void openAnalyzeOnMap(GPXTabItemType tabType) { void openAnalyzeOnMap(GPXTabItemType tabType) {
List<ILineDataSet> ds = getDataSets(null, tabType, null, null); List<ILineDataSet> dataSets = getDataSets(null, tabType, null, null);
actionsListener.openAnalyzeOnMap(gpxItem, ds, tabType); prepareGpxItemChartTypes(gpxItem, dataSets);
actionsListener.openAnalyzeOnMap(gpxItem);
}
public static void prepareGpxItemChartTypes(GpxDisplayItem gpxItem, List<ILineDataSet> dataSets) {
WptPt wpt = null;
gpxItem.chartTypes = null;
if (dataSets != null && dataSets.size() > 0) {
gpxItem.chartTypes = new GPXDataSetType[dataSets.size()];
for (int i = 0; i < dataSets.size(); i++) {
OrderedLineDataSet orderedDataSet = (OrderedLineDataSet) dataSets.get(i);
gpxItem.chartTypes[i] = orderedDataSet.getDataSetType();
}
if (gpxItem.chartHighlightPos != -1) {
TrkSegment segment = null;
for (Track t : gpxItem.group.getGpx().tracks) {
for (TrkSegment s : t.segments) {
if (s.points.size() > 0 && s.points.get(0).equals(gpxItem.analysis.locationStart)) {
segment = s;
break;
}
}
if (segment != null) {
break;
}
}
if (segment != null) {
OrderedLineDataSet dataSet = (OrderedLineDataSet) dataSets.get(0);
float distance = gpxItem.chartHighlightPos * dataSet.getDivX();
for (WptPt p : segment.points) {
if (p.distance >= distance) {
wpt = p;
break;
}
}
}
}
}
if (wpt != null) {
gpxItem.locationOnMap = wpt;
} else {
gpxItem.locationOnMap = gpxItem.locationStart;
}
} }
private void openSplitIntervalScreen() { private void openSplitIntervalScreen() {

View file

@ -2,13 +2,9 @@ package net.osmand.plus.myplaces;
import android.view.View; import android.view.View;
import com.github.mikephil.charting.interfaces.datasets.ILineDataSet;
import net.osmand.GPXUtilities.TrkSegment; import net.osmand.GPXUtilities.TrkSegment;
import net.osmand.plus.GpxSelectionHelper.GpxDisplayItem; import net.osmand.plus.GpxSelectionHelper.GpxDisplayItem;
import java.util.List;
public interface SegmentActionsListener { public interface SegmentActionsListener {
void updateContent(); void updateContent();
@ -23,5 +19,5 @@ public interface SegmentActionsListener {
void showOptionsPopupMenu(View view, TrkSegment trkSegment, boolean confirmDeletion); void showOptionsPopupMenu(View view, TrkSegment trkSegment, boolean confirmDeletion);
void openAnalyzeOnMap(GpxDisplayItem gpxItem, List<ILineDataSet> dataSets, GPXTabItemType tabType); void openAnalyzeOnMap(GpxDisplayItem gpxItem);
} }

View file

@ -22,16 +22,11 @@ import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentManager;
import com.github.mikephil.charting.interfaces.datasets.ILineDataSet;
import net.osmand.AndroidUtils; import net.osmand.AndroidUtils;
import net.osmand.FileUtils; import net.osmand.FileUtils;
import net.osmand.FileUtils.RenameCallback; import net.osmand.FileUtils.RenameCallback;
import net.osmand.GPXUtilities.GPXFile; import net.osmand.GPXUtilities.GPXFile;
import net.osmand.GPXUtilities.Track;
import net.osmand.GPXUtilities.TrkSegment; import net.osmand.GPXUtilities.TrkSegment;
import net.osmand.GPXUtilities.WptPt;
import net.osmand.data.LatLon;
import net.osmand.data.PointDescription; import net.osmand.data.PointDescription;
import net.osmand.plus.GpxSelectionHelper.GpxDisplayGroup; import net.osmand.plus.GpxSelectionHelper.GpxDisplayGroup;
import net.osmand.plus.GpxSelectionHelper.GpxDisplayItem; import net.osmand.plus.GpxSelectionHelper.GpxDisplayItem;
@ -43,8 +38,6 @@ import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.activities.TrackActivity; import net.osmand.plus.activities.TrackActivity;
import net.osmand.plus.base.OsmAndListFragment; import net.osmand.plus.base.OsmAndListFragment;
import net.osmand.plus.helpers.GpxUiHelper; import net.osmand.plus.helpers.GpxUiHelper;
import net.osmand.plus.helpers.GpxUiHelper.GPXDataSetType;
import net.osmand.plus.helpers.GpxUiHelper.OrderedLineDataSet;
import net.osmand.plus.myplaces.TrackBitmapDrawer.TrackBitmapDrawerListener; import net.osmand.plus.myplaces.TrackBitmapDrawer.TrackBitmapDrawerListener;
import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.settings.backend.OsmandSettings;
import net.osmand.plus.track.SaveGpxAsyncTask; import net.osmand.plus.track.SaveGpxAsyncTask;
@ -299,55 +292,9 @@ public class TrackSegmentFragment extends OsmAndListFragment implements TrackBit
} }
@Override @Override
public void openAnalyzeOnMap(GpxDisplayItem gpxItem, List<ILineDataSet> dataSets, GPXTabItemType tabType) { public void openAnalyzeOnMap(GpxDisplayItem gpxItem) {
LatLon location = null;
WptPt wpt = null;
gpxItem.chartTypes = null;
if (dataSets != null && dataSets.size() > 0) {
gpxItem.chartTypes = new GPXDataSetType[dataSets.size()];
for (int i = 0; i < dataSets.size(); i++) {
OrderedLineDataSet orderedDataSet = (OrderedLineDataSet) dataSets.get(i);
gpxItem.chartTypes[i] = orderedDataSet.getDataSetType();
}
if (gpxItem.chartHighlightPos != -1) {
TrkSegment segment = null;
for (Track t : gpxItem.group.getGpx().tracks) {
for (TrkSegment s : t.segments) {
if (s.points.size() > 0 && s.points.get(0).equals(gpxItem.analysis.locationStart)) {
segment = s;
break;
}
}
if (segment != null) {
break;
}
}
if (segment != null) {
OrderedLineDataSet dataSet = (OrderedLineDataSet) dataSets.get(0);
float distance = gpxItem.chartHighlightPos * dataSet.getDivX();
for (WptPt p : segment.points) {
if (p.distance >= distance) {
wpt = p;
break;
}
}
if (wpt != null) {
location = new LatLon(wpt.lat, wpt.lon);
}
}
}
}
if (location == null) {
location = new LatLon(gpxItem.locationStart.lat, gpxItem.locationStart.lon);
}
if (wpt != null) {
gpxItem.locationOnMap = wpt;
} else {
gpxItem.locationOnMap = gpxItem.locationStart;
}
OsmandSettings settings = app.getSettings(); OsmandSettings settings = app.getSettings();
settings.setMapLocationToShow(location.getLatitude(), location.getLongitude(), settings.setMapLocationToShow(gpxItem.locationOnMap.lat, gpxItem.locationOnMap.lon,
settings.getLastKnownMapZoom(), settings.getLastKnownMapZoom(),
new PointDescription(PointDescription.POINT_TYPE_WPT, gpxItem.name), new PointDescription(PointDescription.POINT_TYPE_WPT, gpxItem.name),
false, false,

View file

@ -20,25 +20,22 @@ import androidx.appcompat.widget.AppCompatImageView;
import androidx.recyclerview.widget.DefaultItemAnimator; import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.RecyclerView.ItemDecoration;
import com.github.mikephil.charting.charts.LineChart;
import com.github.mikephil.charting.interfaces.datasets.ILineDataSet;
import net.osmand.GPXUtilities.GPXFile; import net.osmand.GPXUtilities.GPXFile;
import net.osmand.GPXUtilities.GPXTrackAnalysis; import net.osmand.GPXUtilities.GPXTrackAnalysis;
import net.osmand.plus.GPXDatabase.GpxDataItem;
import net.osmand.plus.GpxSelectionHelper.GpxDisplayItem; import net.osmand.plus.GpxSelectionHelper.GpxDisplayItem;
import net.osmand.plus.GpxSelectionHelper.GpxDisplayItemType; import net.osmand.plus.GpxSelectionHelper.GpxDisplayItemType;
import net.osmand.plus.OsmAndFormatter; import net.osmand.plus.OsmAndFormatter;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity; import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.helpers.GpxUiHelper; import net.osmand.plus.helpers.GpxUiHelper.GPXDataSetType;
import net.osmand.plus.helpers.GpxUiHelper.LineGraphType;
import net.osmand.plus.myplaces.SegmentActionsListener; import net.osmand.plus.myplaces.SegmentActionsListener;
import net.osmand.plus.routepreparationmenu.cards.BaseCard; import net.osmand.plus.routepreparationmenu.cards.BaseCard;
import net.osmand.plus.widgets.TextViewEx; import net.osmand.plus.widgets.TextViewEx;
import net.osmand.util.Algorithms; import net.osmand.util.Algorithms;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
@ -58,7 +55,7 @@ public class OverviewCard extends BaseCard {
private final TrackDisplayHelper displayHelper; private final TrackDisplayHelper displayHelper;
private final GPXFile gpxFile; private final GPXFile gpxFile;
private final GpxDisplayItemType[] filterTypes = new GpxDisplayItemType[]{GpxDisplayItemType.TRACK_SEGMENT}; private final GpxDisplayItemType[] filterTypes = new GpxDisplayItemType[] {GpxDisplayItemType.TRACK_SEGMENT};
private final SegmentActionsListener listener; private final SegmentActionsListener listener;
public OverviewCard(@NonNull MapActivity mapActivity, @NonNull TrackDisplayHelper displayHelper, public OverviewCard(@NonNull MapActivity mapActivity, @NonNull TrackDisplayHelper displayHelper,
@ -106,19 +103,19 @@ public class OverviewCard extends BaseCard {
String avg = OsmAndFormatter.getFormattedSpeed(analysis.avgSpeed, app); String avg = OsmAndFormatter.getFormattedSpeed(analysis.avgSpeed, app);
String max = OsmAndFormatter.getFormattedSpeed(analysis.maxSpeed, app); String max = OsmAndFormatter.getFormattedSpeed(analysis.maxSpeed, app);
StatBlock sDistance = new StatBlock(app.getResources().getString(R.string.distance), OsmAndFormatter.getFormattedDistance(totalDistance, app), StatBlock sDistance = new StatBlock(app.getString(R.string.distance), OsmAndFormatter.getFormattedDistance(totalDistance, app),
R.drawable.ic_action_track_16, R.color.icon_color_default_light, LineGraphType.ALTITUDE, LineGraphType.SPEED); R.drawable.ic_action_track_16, R.color.icon_color_default_light, GPXDataSetType.ALTITUDE, GPXDataSetType.SPEED);
StatBlock sAscent = new StatBlock(app.getResources().getString(R.string.altitude_ascent), asc, StatBlock sAscent = new StatBlock(app.getString(R.string.altitude_ascent), asc,
R.drawable.ic_action_arrow_up_16, R.color.gpx_chart_red, LineGraphType.SLOPE, null); R.drawable.ic_action_arrow_up_16, R.color.gpx_chart_red, GPXDataSetType.SLOPE, null);
StatBlock sDescent = new StatBlock(app.getResources().getString(R.string.altitude_descent), desc, StatBlock sDescent = new StatBlock(app.getString(R.string.altitude_descent), desc,
R.drawable.ic_action_arrow_down_16, R.color.gpx_pale_green, LineGraphType.ALTITUDE, LineGraphType.SLOPE); R.drawable.ic_action_arrow_down_16, R.color.gpx_pale_green, GPXDataSetType.ALTITUDE, GPXDataSetType.SLOPE);
StatBlock sAvSpeed = new StatBlock(app.getResources().getString(R.string.average_speed), avg, StatBlock sAvSpeed = new StatBlock(app.getString(R.string.average_speed), avg,
R.drawable.ic_action_speed_16, R.color.icon_color_default_light, LineGraphType.SPEED, null); R.drawable.ic_action_speed_16, R.color.icon_color_default_light, GPXDataSetType.SPEED, null);
StatBlock sMaxSpeed = new StatBlock(app.getResources().getString(R.string.max_speed), max, StatBlock sMaxSpeed = new StatBlock(app.getString(R.string.max_speed), max,
R.drawable.ic_action_max_speed_16, R.color.icon_color_default_light, LineGraphType.SPEED, null); R.drawable.ic_action_max_speed_16, R.color.icon_color_default_light, GPXDataSetType.SPEED, null);
StatBlock sTimeSpan = new StatBlock(app.getResources().getString(R.string.shared_string_time_span), StatBlock sTimeSpan = new StatBlock(app.getString(R.string.shared_string_time_span),
Algorithms.formatDuration((int) (timeSpan / 1000), app.accessibilityEnabled()), Algorithms.formatDuration((int) (timeSpan / 1000), app.accessibilityEnabled()),
R.drawable.ic_action_time_span_16, R.color.icon_color_default_light, LineGraphType.SPEED, null); R.drawable.ic_action_time_span_16, R.color.icon_color_default_light, GPXDataSetType.SPEED, null);
LinearLayoutManager llManager = new LinearLayoutManager(app); LinearLayoutManager llManager = new LinearLayoutManager(app);
llManager.setOrientation(LinearLayoutManager.HORIZONTAL); llManager.setOrientation(LinearLayoutManager.HORIZONTAL);
@ -213,16 +210,17 @@ public class OverviewCard extends BaseCard {
}); });
} }
private class StatBlockAdapter extends RecyclerView.Adapter<StatBlockAdapter.StatBlockViewHolder> { private class StatBlockAdapter extends RecyclerView.Adapter<StatBlockViewHolder> {
private final List<StatBlock> StatBlocks;
private final List<StatBlock> statBlocks;
public StatBlockAdapter(List<StatBlock> StatBlocks) { public StatBlockAdapter(List<StatBlock> StatBlocks) {
this.StatBlocks = StatBlocks; this.statBlocks = StatBlocks;
} }
@Override @Override
public int getItemCount() { public int getItemCount() {
return StatBlocks.size(); return statBlocks.size();
} }
@NonNull @NonNull
@ -235,52 +233,65 @@ public class OverviewCard extends BaseCard {
@Override @Override
public void onBindViewHolder(StatBlockViewHolder holder, int position) { public void onBindViewHolder(StatBlockViewHolder holder, int position) {
StatBlock item = StatBlocks.get(position); final StatBlock item = statBlocks.get(position);
holder.bind(item);
}
class StatBlockViewHolder extends RecyclerView.ViewHolder { holder.valueText.setText(item.value);
private final TextViewEx valueText; holder.titleText.setText(item.title);
private final TextView titleText; holder.valueText.setTextColor(app.getResources().getColor(R.color.active_color_primary_light));
private final AppCompatImageView imageView; holder.titleText.setTextColor(app.getResources().getColor(R.color.text_color_secondary_light));
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
GpxDisplayItem gpxItem = TrackDisplayHelper.flatten(displayHelper.getOriginalGroups(filterTypes)).get(0);
if (gpxItem != null && gpxItem.analysis != null) {
ArrayList<GPXDataSetType> list = new ArrayList<>();
if (item.firstType != null) {
list.add(item.firstType);
}
if (item.secondType != null) {
list.add(item.secondType);
}
if (list.size() > 0) {
gpxItem.chartTypes = list.toArray(new GPXDataSetType[0]);
}
gpxItem.locationOnMap = gpxItem.locationStart;
StatBlockViewHolder(View view) { listener.openAnalyzeOnMap(gpxItem);
super(view);
valueText = view.findViewById(R.id.value);
titleText = view.findViewById(R.id.title);
imageView = view.findViewById(R.id.image);
}
public void bind(final StatBlock overviewItem) {
valueText.setText(overviewItem.value);
valueText.setTextColor(app.getResources().getColor(R.color.active_color_primary_light));
titleText.setText(overviewItem.title);
titleText.setTextColor(app.getResources().getColor(R.color.text_color_secondary_light));
setImageDrawable(imageView, overviewItem.imageResId, overviewItem.imageColorId);
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
GpxDisplayItem gpxItem = TrackDisplayHelper.flatten(displayHelper.getOriginalGroups(filterTypes)).get(0);
GPXTrackAnalysis analysis = gpxItem.analysis;
GpxDataItem gpxDataItem = displayHelper.getGpxDataItem();
boolean calcWithoutGaps = gpxItem.isGeneralTrack() && gpxDataItem != null && !gpxDataItem.isJoinSegments();
List<ILineDataSet> dataSets = GpxUiHelper.getDataSets(new LineChart(app), app, analysis, overviewItem.firstType, overviewItem.secondType, calcWithoutGaps);
listener.openAnalyzeOnMap(gpxItem, dataSets, null);
} }
}); }
} });
setImageDrawable(holder.imageView, item.imageResId, item.imageColorId);
} }
} }
private class HorizontalDividerDecoration extends RecyclerView.ItemDecoration { private static class StatBlockViewHolder extends RecyclerView.ViewHolder {
private final TextViewEx valueText;
private final TextView titleText;
private final AppCompatImageView imageView;
StatBlockViewHolder(View view) {
super(view);
valueText = view.findViewById(R.id.value);
titleText = view.findViewById(R.id.title);
imageView = view.findViewById(R.id.image);
}
}
private static class HorizontalDividerDecoration extends ItemDecoration {
private final Drawable divider; private final Drawable divider;
private final int marginV;
private final int marginH;
public HorizontalDividerDecoration(Context context) { public HorizontalDividerDecoration(Context context) {
int[] ATTRS = new int[]{android.R.attr.listDivider}; int[] ATTRS = new int[] {android.R.attr.listDivider};
final TypedArray ta = context.obtainStyledAttributes(ATTRS); final TypedArray ta = context.obtainStyledAttributes(ATTRS);
divider = ta.getDrawable(0); divider = ta.getDrawable(0);
// DrawableCompat.setTint(divider, context.getResources().getColor(R.color.divider_color_light)); //todo change drawable color // DrawableCompat.setTint(divider, context.getResources().getColor(R.color.divider_color_light)); //todo change drawable color
ta.recycle(); ta.recycle();
marginV = context.getResources().getDimensionPixelSize(R.dimen.map_small_button_margin);
marginH = context.getResources().getDimensionPixelSize(R.dimen.content_padding);
} }
@Override @Override
@ -289,10 +300,7 @@ public class OverviewCard extends BaseCard {
} }
public void drawHorizontal(Canvas c, RecyclerView parent) { public void drawHorizontal(Canvas c, RecyclerView parent) {
final int marginV = parent.getContext().getResources().getDimensionPixelSize(R.dimen.map_small_button_margin); for (int i = 0; i < parent.getChildCount(); i++) {
final int marginH = parent.getContext().getResources().getDimensionPixelSize(R.dimen.content_padding);
final int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {
final View child = parent.getChildAt(i); final View child = parent.getChildAt(i);
final int left = child.getRight() - divider.getIntrinsicWidth() + marginH; final int left = child.getRight() - divider.getIntrinsicWidth() + marginH;
final int right = left + divider.getIntrinsicHeight(); final int right = left + divider.getIntrinsicHeight();
@ -305,21 +313,21 @@ public class OverviewCard extends BaseCard {
@Override @Override
public void getItemOffsets(Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) { public void getItemOffsets(Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
int marginV = parent.getContext().getResources().getDimensionPixelSize(R.dimen.map_small_button_margin);
int marginH = parent.getContext().getResources().getDimensionPixelSize(R.dimen.content_padding);
outRect.set(marginH - divider.getIntrinsicWidth(), marginV, marginH + divider.getIntrinsicWidth(), marginV); outRect.set(marginH - divider.getIntrinsicWidth(), marginV, marginH + divider.getIntrinsicWidth(), marginV);
} }
} }
private static class StatBlock { private static class StatBlock {
private String title;
private String value;
private int imageResId;
private int imageColorId;
private LineGraphType firstType;
private LineGraphType secondType;
public StatBlock(String title, String value, @DrawableRes int imageResId, @ColorRes int imageColorId, LineGraphType firstType, LineGraphType secondType) { private final String title;
private final String value;
private final int imageResId;
private final int imageColorId;
private final GPXDataSetType firstType;
private final GPXDataSetType secondType;
public StatBlock(String title, String value, @DrawableRes int imageResId, @ColorRes int imageColorId,
GPXDataSetType firstType, GPXDataSetType secondType) {
this.title = title; this.title = title;
this.value = value; this.value = value;
this.imageResId = imageResId; this.imageResId = imageResId;
@ -327,6 +335,5 @@ public class OverviewCard extends BaseCard {
this.firstType = firstType; this.firstType = firstType;
this.secondType = secondType; this.secondType = secondType;
} }
} }
} }

View file

@ -43,6 +43,7 @@ import net.osmand.plus.GpxSelectionHelper.GpxDisplayGroup;
import net.osmand.plus.GpxSelectionHelper.GpxDisplayItem; import net.osmand.plus.GpxSelectionHelper.GpxDisplayItem;
import net.osmand.plus.GpxSelectionHelper.GpxDisplayItemType; import net.osmand.plus.GpxSelectionHelper.GpxDisplayItemType;
import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile; import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile;
import net.osmand.plus.OsmAndLocationProvider.OsmAndCompassListener;
import net.osmand.plus.OsmAndLocationProvider.OsmAndLocationListener; import net.osmand.plus.OsmAndLocationProvider.OsmAndLocationListener;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandPlugin; import net.osmand.plus.OsmandPlugin;
@ -77,6 +78,7 @@ import net.osmand.plus.routepreparationmenu.cards.BaseCard.CardListener;
import net.osmand.plus.track.SaveGpxAsyncTask.SaveGpxListener; import net.osmand.plus.track.SaveGpxAsyncTask.SaveGpxListener;
import net.osmand.plus.widgets.IconPopupMenu; import net.osmand.plus.widgets.IconPopupMenu;
import net.osmand.util.Algorithms; import net.osmand.util.Algorithms;
import net.osmand.util.MapUtils;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
@ -100,7 +102,7 @@ import static net.osmand.plus.track.OptionsCard.SHOW_ON_MAP_BUTTON_INDEX;
import static net.osmand.plus.track.OptionsCard.UPLOAD_OSM_BUTTON_INDEX; import static net.osmand.plus.track.OptionsCard.UPLOAD_OSM_BUTTON_INDEX;
public class TrackMenuFragment extends ContextMenuScrollFragment implements CardListener, public class TrackMenuFragment extends ContextMenuScrollFragment implements CardListener,
SegmentActionsListener, RenameCallback, OnTrackFileMoveListener, OsmAndLocationListener { SegmentActionsListener, RenameCallback, OnTrackFileMoveListener, OsmAndLocationListener, OsmAndCompassListener {
public static final String TAG = TrackMenuFragment.class.getName(); public static final String TAG = TrackMenuFragment.class.getName();
private static final Log log = PlatformUtil.getLog(TrackMenuFragment.class); private static final Log log = PlatformUtil.getLog(TrackMenuFragment.class);
@ -123,8 +125,9 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
private int menuTitleHeight; private int menuTitleHeight;
private String gpxTitle; private String gpxTitle;
private UpdateLocationViewCache updateLocationViewCache; private UpdateLocationViewCache updateLocationViewCache;
private MapContextMenu menu; private Location lastLocation = null;
private Location location = null; private Float heading;
private boolean locationUpdateStarted;
public enum TrackMenuType { public enum TrackMenuType {
OVERVIEW(R.id.action_overview, R.string.shared_string_overview), OVERVIEW(R.id.action_overview, R.string.shared_string_overview),
@ -217,15 +220,11 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
headerTitle = view.findViewById(R.id.title); headerTitle = view.findViewById(R.id.title);
headerIcon = view.findViewById(R.id.icon_view); headerIcon = view.findViewById(R.id.icon_view);
updateLocationViewCache = app.getUIUtilities().getUpdateLocationViewCache(); updateLocationViewCache = app.getUIUtilities().getUpdateLocationViewCache();
menu = ((MapActivity) getActivity()).getContextMenu();
location = app.getLocationProvider().getLastKnownLocation();
if (isPortrait()) { if (isPortrait()) {
View mainView = getMainView(); AndroidUiHelper.updateVisibility(getTopShadow(), true);
View topShadow = getTopShadow(); AndroidUtils.setBackground(view.getContext(), getBottomContainer(), isNightMode(),
FrameLayout bottomContainer = getBottomContainer(); R.color.list_background_color_light, R.color.list_background_color_dark);
topShadow.setVisibility(View.VISIBLE);
AndroidUtils.setBackground(mainView.getContext(), bottomContainer, isNightMode(), R.color.list_background_color_light, R.color.list_background_color_dark);
} else { } else {
int widthNoShadow = getLandscapeNoShadowWidth(); int widthNoShadow = getLandscapeNoShadowWidth();
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(widthNoShadow, ViewGroup.LayoutParams.WRAP_CONTENT); FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(widthNoShadow, ViewGroup.LayoutParams.WRAP_CONTENT);
@ -362,9 +361,28 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
} }
@Override @Override
public void updateLocation(final Location location) { public void updateLocation(Location location) {
this.location = location; if (!MapUtils.areLatLonEqual(lastLocation, location)) {
getMyApplication().runInUIThread(new Runnable() { lastLocation = location;
updateLocationUi();
}
}
@Override
public void updateCompassValue(float value) {
// 99 in next line used to one-time initialize arrows (with reference vs. fixed-north direction)
// on non-compass devices
float lastHeading = heading != null ? heading : 99;
heading = value;
if (Math.abs(MapUtils.degreesDiff(lastHeading, heading)) > 5) {
updateLocationUi();
} else {
heading = lastHeading;
}
}
private void updateLocationUi() {
app.runInUIThread(new Runnable() {
@Override @Override
public void run() { public void run() {
updateDistanceDirection(); updateDistanceDirection();
@ -373,10 +391,10 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
} }
private void updateDistanceDirection() { private void updateDistanceDirection() {
OsmandApplication app = getMyApplication(); MapActivity mapActivity = getMapActivity();
FragmentActivity activity = getActivity();
View view = overviewCard.getView(); View view = overviewCard.getView();
if (app != null && activity != null && view != null) { if (mapActivity != null && view != null) {
MapContextMenu menu = mapActivity.getContextMenu();
TextView distanceText = (TextView) view.findViewById(R.id.distance); TextView distanceText = (TextView) view.findViewById(R.id.distance);
ImageView direction = (ImageView) view.findViewById(R.id.direction); ImageView direction = (ImageView) view.findViewById(R.id.direction);
app.getUIUtilities().updateLocationView(updateLocationViewCache, direction, distanceText, menu.getLatLon()); app.getUIUtilities().updateLocationView(updateLocationViewCache, direction, distanceText, menu.getLatLon());
@ -385,14 +403,21 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
private void startLocationUpdate() { private void startLocationUpdate() {
OsmandApplication app = getMyApplication(); OsmandApplication app = getMyApplication();
app.getLocationProvider().addLocationListener(this); if (app != null && !locationUpdateStarted) {
location = app.getLocationProvider().getLastKnownLocation(); locationUpdateStarted = true;
updateLocation(location); app.getLocationProvider().addCompassListener(this);
app.getLocationProvider().addLocationListener(this);
updateLocationUi();
}
} }
private void stopLocationUpdate() { private void stopLocationUpdate() {
OsmandApplication app = getMyApplication(); OsmandApplication app = getMyApplication();
app.getLocationProvider().removeLocationListener(this); if (app != null && locationUpdateStarted) {
locationUpdateStarted = false;
app.getLocationProvider().removeLocationListener(this);
app.getLocationProvider().removeCompassListener(this);
}
} }
@Override @Override
@ -708,46 +733,7 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
} }
@Override @Override
public void openAnalyzeOnMap(GpxDisplayItem gpxItem, List<ILineDataSet> dataSets, GPXTabItemType tabType) { public void openAnalyzeOnMap(GpxDisplayItem gpxItem) {
WptPt wpt = null;
gpxItem.chartTypes = null;
if (dataSets != null && dataSets.size() > 0) {
gpxItem.chartTypes = new GPXDataSetType[dataSets.size()];
for (int i = 0; i < dataSets.size(); i++) {
OrderedLineDataSet orderedDataSet = (OrderedLineDataSet) dataSets.get(i);
gpxItem.chartTypes[i] = orderedDataSet.getDataSetType();
}
if (gpxItem.chartHighlightPos != -1) {
TrkSegment segment = null;
for (Track t : gpxItem.group.getGpx().tracks) {
for (TrkSegment s : t.segments) {
if (s.points.size() > 0 && s.points.get(0).equals(gpxItem.analysis.locationStart)) {
segment = s;
break;
}
}
if (segment != null) {
break;
}
}
if (segment != null) {
OrderedLineDataSet dataSet = (OrderedLineDataSet) dataSets.get(0);
float distance = gpxItem.chartHighlightPos * dataSet.getDivX();
for (WptPt p : segment.points) {
if (p.distance >= distance) {
wpt = p;
break;
}
}
}
}
}
if (wpt != null) {
gpxItem.locationOnMap = wpt;
} else {
gpxItem.locationOnMap = gpxItem.locationStart;
}
TrackDetailsMenu trackDetailsMenu = getMapActivity().getTrackDetailsMenu(); TrackDetailsMenu trackDetailsMenu = getMapActivity().getTrackDetailsMenu();
trackDetailsMenu.setGpxItem(gpxItem); trackDetailsMenu.setGpxItem(gpxItem);
trackDetailsMenu.show(); trackDetailsMenu.show();