Merge pull request #10857 from osmandapp/fix_gpx_context_menu_overview_actions_p5
Fix gpx context menu overview actions p5
This commit is contained in:
commit
5816feed10
6 changed files with 227 additions and 182 deletions
|
@ -1,7 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:osmand="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
@ -14,22 +13,22 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:background="?attr/dashboard_divider"
|
||||
android:visibility="gone"/>
|
||||
android:visibility="gone" />
|
||||
|
||||
<View
|
||||
android:id="@+id/list_divider"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:background="?attr/dashboard_divider"
|
||||
android:visibility="gone"
|
||||
android:layout_marginStart="@dimen/settings_divider_margin_start"
|
||||
android:layout_marginLeft="@dimen/settings_divider_margin_start"
|
||||
android:layout_marginStart="@dimen/settings_divider_margin_start" />
|
||||
android:background="?attr/dashboard_divider"
|
||||
android:visibility="gone" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:minHeight="@dimen/favorites_list_item_height"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:minHeight="@dimen/favorites_list_item_height"
|
||||
android:orientation="horizontal"
|
||||
android:paddingStart="@dimen/favorites_my_places_icon_left_padding"
|
||||
android:paddingLeft="@dimen/favorites_my_places_icon_left_padding"
|
||||
|
@ -56,19 +55,19 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:contentDescription="@string/favorite"
|
||||
tools:src="@drawable/bg_point_circle"/>
|
||||
tools:src="@drawable/bg_point_circle" />
|
||||
</FrameLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical"
|
||||
android:layout_marginStart="@dimen/favorites_my_places_icon_right_padding"
|
||||
android:layout_marginLeft="@dimen/favorites_my_places_icon_right_padding"
|
||||
android:layout_marginEnd="@dimen/favorites_my_places_icon_right_padding"
|
||||
android:layout_marginRight="@dimen/favorites_my_places_icon_right_padding"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical"
|
||||
android:paddingTop="@dimen/context_menu_padding_margin_small"
|
||||
android:paddingBottom="@dimen/context_menu_padding_margin_small">
|
||||
|
||||
|
@ -76,10 +75,10 @@
|
|||
android:id="@+id/favourite_label"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="@dimen/subHeaderPadding"
|
||||
android:maxLines="2"
|
||||
android:scrollbars="none"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:layout_marginBottom="@dimen/subHeaderPadding"
|
||||
android:textSize="@dimen/default_list_text_size"
|
||||
tools:text="@string/lorem_ipsum" />
|
||||
|
||||
|
@ -93,6 +92,7 @@
|
|||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginTop="1sp"
|
||||
android:contentDescription="@string/show_view_angle"
|
||||
osmand:srcCompat="@drawable/ic_direction_arrow" />
|
||||
|
||||
|
@ -104,8 +104,8 @@
|
|||
android:layout_marginLeft="@dimen/gpx_small_icon_margin"
|
||||
android:maxLines="1"
|
||||
android:textColor="?android:textColorSecondary"
|
||||
osmand:typeface="@string/font_roboto_medium"
|
||||
android:textSize="@dimen/default_desc_text_size"
|
||||
osmand:typeface="@string/font_roboto_medium"
|
||||
tools:text="100500 km" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
|
@ -141,8 +141,8 @@
|
|||
android:layout_marginLeft="@dimen/dashFavIconMargin"
|
||||
android:background="?attr/dashboard_button"
|
||||
android:contentDescription="@string/context_menu_item_directions_to"
|
||||
osmand:srcCompat="@drawable/ic_action_remove_dark"
|
||||
android:visibility="gone" />
|
||||
android:visibility="gone"
|
||||
osmand:srcCompat="@drawable/ic_action_remove_dark" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/options"
|
||||
|
@ -151,8 +151,8 @@
|
|||
android:layout_gravity="center_vertical"
|
||||
android:background="?attr/dashboard_button"
|
||||
android:contentDescription="@string/shared_string_more"
|
||||
osmand:srcCompat="@drawable/ic_overflow_menu_white"
|
||||
android:visibility="gone" />
|
||||
android:visibility="gone"
|
||||
osmand:srcCompat="@drawable/ic_overflow_menu_white" />
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
|
@ -38,21 +38,23 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/content_padding"
|
||||
android:layout_marginLeft="@dimen/content_padding"
|
||||
android:gravity="center"
|
||||
android:orientation="horizontal"
|
||||
android:paddingTop="@dimen/dash_margin"
|
||||
android:paddingBottom="@dimen/dash_margin">
|
||||
android:layout_marginTop="@dimen/dash_margin"
|
||||
android:layout_marginBottom="@dimen/dash_margin"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/direction"
|
||||
android:layout_width="@dimen/context_menu_transport_icon_size"
|
||||
android:layout_height="@dimen/context_menu_transport_icon_size"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginTop="1sp"
|
||||
osmand:srcCompat="@drawable/ic_direction_arrow" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/distance"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginStart="@dimen/content_padding_small_half"
|
||||
android:layout_marginLeft="@dimen/content_padding_small_half"
|
||||
android:maxLines="1"
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
android:layout_height="@dimen/list_header_height"
|
||||
android:layout_marginStart="@dimen/content_padding"
|
||||
android:layout_marginLeft="@dimen/content_padding"
|
||||
android:gravity="center_vertical"
|
||||
android:gravity="start|center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<LinearLayout
|
||||
|
@ -14,14 +14,13 @@
|
|||
android:layout_height="match_parent"
|
||||
android:layout_marginEnd="@dimen/content_padding"
|
||||
android:layout_marginRight="@dimen/content_padding"
|
||||
android:gravity="center_vertical"
|
||||
android:maxWidth="@dimen/grid_menu_item_width"
|
||||
android:gravity="start|center_vertical"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical"
|
||||
android:gravity="start|center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:weightSum="2">
|
||||
|
||||
|
@ -61,8 +60,10 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:background="@null"
|
||||
android:ellipsize="end"
|
||||
android:gravity="start|center_vertical"
|
||||
android:lines="1"
|
||||
android:maxWidth="@dimen/grid_menu_item_width"
|
||||
android:minWidth="@dimen/map_route_buttons_width"
|
||||
android:textColor="?android:attr/textColorSecondary"
|
||||
android:textSize="@dimen/default_desc_text_size"
|
||||
tools:text="@string/distance" />
|
||||
|
|
|
@ -11,6 +11,7 @@ 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;
|
||||
|
@ -18,6 +19,7 @@ import androidx.recyclerview.widget.RecyclerView;
|
|||
import net.osmand.AndroidUtils;
|
||||
import net.osmand.GPXUtilities.GPXFile;
|
||||
import net.osmand.GPXUtilities.GPXTrackAnalysis;
|
||||
import net.osmand.PlatformUtil;
|
||||
import net.osmand.plus.GpxSelectionHelper.GpxDisplayItem;
|
||||
import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile;
|
||||
import net.osmand.plus.OsmAndFormatter;
|
||||
|
@ -30,17 +32,24 @@ import net.osmand.plus.myplaces.SegmentActionsListener;
|
|||
import net.osmand.plus.widgets.TextViewEx;
|
||||
import net.osmand.util.Algorithms;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class GpxBlockStatisticsBuilder {
|
||||
|
||||
private static final Log log = PlatformUtil.getLog(GpxBlockStatisticsBuilder.class);
|
||||
private static final int GENERAL_UPDATE_INTERVAL = 1000;
|
||||
|
||||
private final OsmandApplication app;
|
||||
private RecyclerView blocksView;
|
||||
private final SelectedGpxFile selectedGpxFile;
|
||||
|
||||
private BlockStatisticsAdapter adapter;
|
||||
private final List<StatBlock> items = new ArrayList<>();
|
||||
private boolean blocksClickable = true;
|
||||
|
||||
private final Handler handler = new Handler();
|
||||
private Runnable updatingItems;
|
||||
|
@ -51,28 +60,34 @@ public class GpxBlockStatisticsBuilder {
|
|||
this.selectedGpxFile = selectedGpxFile;
|
||||
}
|
||||
|
||||
public boolean isUpdateRunning() {
|
||||
return updateRunning;
|
||||
}
|
||||
|
||||
public void setBlocksClickable(boolean blocksClickable) {
|
||||
this.blocksClickable = blocksClickable;
|
||||
}
|
||||
|
||||
public void setBlocksView(RecyclerView blocksView) {
|
||||
this.blocksView = blocksView;
|
||||
}
|
||||
|
||||
private GpxDisplayItem getDisplayItem(GPXFile gpxFile) {
|
||||
return GpxUiHelper.makeGpxDisplayItem(app, gpxFile);
|
||||
@Nullable
|
||||
public GpxDisplayItem getDisplayItem(GPXFile gpxFile) {
|
||||
return gpxFile.tracks.size() > 0 ? GpxUiHelper.makeGpxDisplayItem(app, gpxFile) : null;
|
||||
}
|
||||
|
||||
private GPXFile getGPXFile() {
|
||||
return selectedGpxFile.getGpxFile();
|
||||
}
|
||||
|
||||
public void initStatBlocks(SegmentActionsListener actionsListener, @ColorInt int activeColor, boolean nightMode) {
|
||||
public void initStatBlocks(@Nullable SegmentActionsListener actionsListener, @ColorInt int activeColor, boolean nightMode) {
|
||||
initItems();
|
||||
boolean isNotEmpty = !Algorithms.isEmpty(items);
|
||||
AndroidUiHelper.updateVisibility(blocksView, isNotEmpty);
|
||||
if (isNotEmpty) {
|
||||
adapter = new BlockStatisticsAdapter(getDisplayItem(getGPXFile()), actionsListener, activeColor, nightMode);
|
||||
adapter.setItems(items);
|
||||
blocksView.setLayoutManager(new LinearLayoutManager(app, LinearLayoutManager.HORIZONTAL, false));
|
||||
blocksView.setAdapter(adapter);
|
||||
}
|
||||
AndroidUiHelper.updateVisibility(blocksView, !Algorithms.isEmpty(items));
|
||||
}
|
||||
|
||||
public void stopUpdatingStatBlocks() {
|
||||
|
@ -80,30 +95,29 @@ public class GpxBlockStatisticsBuilder {
|
|||
updateRunning = false;
|
||||
}
|
||||
|
||||
public void runUpdatingStatBlocks() {
|
||||
public void runUpdatingStatBlocksIfNeeded() {
|
||||
if (!isUpdateRunning()) {
|
||||
updatingItems = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (adapter != null) {
|
||||
initItems();
|
||||
if (adapter != null) {
|
||||
adapter.setItems(items);
|
||||
AndroidUiHelper.updateVisibility(blocksView, !Algorithms.isEmpty(items));
|
||||
}
|
||||
AndroidUiHelper.updateVisibility(blocksView, !Algorithms.isEmpty(items));
|
||||
int interval = app.getSettings().SAVE_GLOBAL_TRACK_INTERVAL.get();
|
||||
handler.postDelayed(this, Math.max(1000, interval));
|
||||
updateRunning = handler.postDelayed(this, Math.max(GENERAL_UPDATE_INTERVAL, interval));
|
||||
}
|
||||
};
|
||||
updateRunning = handler.post(updatingItems);
|
||||
}
|
||||
}
|
||||
|
||||
public void initItems() {
|
||||
GPXFile gpxFile = getGPXFile();
|
||||
GpxDisplayItem gpxDisplayItem = null;
|
||||
GpxDisplayItem gpxDisplayItem = getDisplayItem(gpxFile);
|
||||
GPXTrackAnalysis analysis = null;
|
||||
boolean withoutGaps = true;
|
||||
if (gpxFile.tracks.size() > 0) {
|
||||
gpxDisplayItem = getDisplayItem(gpxFile);
|
||||
}
|
||||
if (gpxDisplayItem != null) {
|
||||
analysis = gpxDisplayItem.analysis;
|
||||
withoutGaps = !selectedGpxFile.isJoinSegments() && gpxDisplayItem.isGeneralTrack();
|
||||
|
@ -165,7 +179,7 @@ public class GpxBlockStatisticsBuilder {
|
|||
}
|
||||
}
|
||||
|
||||
public class StatBlock {
|
||||
public static class StatBlock {
|
||||
private final String title;
|
||||
private final String value;
|
||||
private final int imageResId;
|
||||
|
@ -201,6 +215,9 @@ public class GpxBlockStatisticsBuilder {
|
|||
@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) {
|
||||
|
@ -208,6 +225,9 @@ public class GpxBlockStatisticsBuilder {
|
|||
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);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -227,17 +247,15 @@ public class GpxBlockStatisticsBuilder {
|
|||
public void onBindViewHolder(BlockStatisticsViewHolder holder, int position) {
|
||||
final StatBlock item = items.get(position);
|
||||
holder.valueText.setText(item.value);
|
||||
holder.titleText.setText(item.title);
|
||||
if (updateRunning) {
|
||||
holder.titleText.setWidth(app.getResources().getDimensionPixelSize(R.dimen.map_route_buttons_width));
|
||||
}
|
||||
holder.valueText.setTextColor(activeColor);
|
||||
holder.titleText.setText(item.title);
|
||||
holder.titleText.setTextColor(app.getResources().getColor(R.color.text_color_secondary_light));
|
||||
holder.titleText.setWidth(calculateWidthWithin(item.title, item.value));
|
||||
holder.itemView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
GPXTrackAnalysis analysis = displayItem != null ? displayItem.analysis : null;
|
||||
if (analysis != null) {
|
||||
if (blocksClickable && analysis != null && actionsListener != null) {
|
||||
ArrayList<GPXDataSetType> list = new ArrayList<>();
|
||||
if (analysis.hasElevationData || analysis.isSpeedSpecified() || analysis.hasSpeedData) {
|
||||
if (item.firstType != null) {
|
||||
|
@ -264,9 +282,14 @@ public class GpxBlockStatisticsBuilder {
|
|||
this.items.addAll(items);
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public int calculateWidthWithin(String... texts) {
|
||||
int textWidth = AndroidUtils.getTextMaxWidth(textSize, Arrays.asList(texts));
|
||||
return Math.min(maxWidthPx, Math.max(minWidthPx, textWidth));
|
||||
}
|
||||
}
|
||||
|
||||
private class BlockStatisticsViewHolder extends RecyclerView.ViewHolder {
|
||||
private static class BlockStatisticsViewHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
private final TextViewEx valueText;
|
||||
private final TextView titleText;
|
||||
|
|
|
@ -43,6 +43,10 @@ public class OverviewCard extends BaseCard {
|
|||
private final SelectedGpxFile selectedGpxFile;
|
||||
private final GpxBlockStatisticsBuilder blockStatisticsBuilder;
|
||||
|
||||
public GpxBlockStatisticsBuilder getBlockStatisticsBuilder() {
|
||||
return blockStatisticsBuilder;
|
||||
}
|
||||
|
||||
public OverviewCard(@NonNull MapActivity mapActivity, @NonNull SegmentActionsListener actionsListener, SelectedGpxFile selectedGpxFile) {
|
||||
super(mapActivity);
|
||||
this.actionsListener = actionsListener;
|
||||
|
|
|
@ -234,7 +234,8 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
|
|||
}
|
||||
displayHelper.setGpx(selectedGpxFile.getGpxFile());
|
||||
String fileName = Algorithms.getFileWithoutDirs(getGpx().path);
|
||||
gpxTitle = GpxUiHelper.getGpxTitle(fileName);
|
||||
gpxTitle = !isCurrentRecordingTrack() ? GpxUiHelper.getGpxTitle(fileName)
|
||||
: app.getResources().getString(R.string.shared_string_currently_recording_track);
|
||||
toolbarHeightPx = getResources().getDimensionPixelSize(R.dimen.dashboard_map_toolbar);
|
||||
|
||||
FragmentActivity activity = requireMyActivity();
|
||||
|
@ -333,8 +334,13 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
|
|||
overviewCard.setListener(this);
|
||||
headerContainer.addView(overviewCard.build(getMapActivity()));
|
||||
}
|
||||
GpxBlockStatisticsBuilder blocksBuilder = overviewCard.getBlockStatisticsBuilder();
|
||||
if (isCurrentRecordingTrack()) {
|
||||
blocksBuilder.runUpdatingStatBlocksIfNeeded();
|
||||
}
|
||||
} else {
|
||||
if (overviewCard != null && overviewCard.getView() != null) {
|
||||
overviewCard.getBlockStatisticsBuilder().stopUpdatingStatBlocks();
|
||||
headerContainer.removeView(overviewCard.getView());
|
||||
}
|
||||
boolean isOptions = menuType == TrackMenuType.OPTIONS;
|
||||
|
@ -547,6 +553,10 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
|
|||
}
|
||||
updateControlsVisibility(true);
|
||||
startLocationUpdate();
|
||||
GpxBlockStatisticsBuilder blockStats = overviewCard.getBlockStatisticsBuilder();
|
||||
if (menuType == TrackMenuType.OVERVIEW && isCurrentRecordingTrack()) {
|
||||
blockStats.runUpdatingStatBlocksIfNeeded();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -558,6 +568,7 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
|
|||
}
|
||||
updateControlsVisibility(false);
|
||||
stopLocationUpdate();
|
||||
overviewCard.getBlockStatisticsBuilder().stopUpdatingStatBlocks();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1146,6 +1157,10 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
|
|||
}).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
|
||||
private boolean isCurrentRecordingTrack() {
|
||||
return app.getSavingTrackHelper().getCurrentTrack() == selectedGpxFile;
|
||||
}
|
||||
|
||||
private void hide() {
|
||||
try {
|
||||
MapActivity mapActivity = getMapActivity();
|
||||
|
|
Loading…
Reference in a new issue