diff --git a/OsmAnd/res/layout/custom_radio_btn_text_item.xml b/OsmAnd/res/layout/custom_radio_btn_text_item.xml
new file mode 100644
index 0000000000..3bd1efbfc1
--- /dev/null
+++ b/OsmAnd/res/layout/custom_radio_btn_text_item.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/OsmAnd/res/layout/fragment_measurement_tool.xml b/OsmAnd/res/layout/fragment_measurement_tool.xml
index 2fe4dc1416..982f0840b3 100644
--- a/OsmAnd/res/layout/fragment_measurement_tool.xml
+++ b/OsmAnd/res/layout/fragment_measurement_tool.xml
@@ -130,25 +130,32 @@
tools:text="@string/add_point_after"/>
-
+ android:layout_height="wrap_content">
-
-
-
+ android:layout_height="@dimen/measurement_tool_button_height"
+ android:layout_marginStart="@dimen/content_padding"
+ android:layout_marginEnd="@dimen/content_padding"
+ android:layout_marginBottom="@dimen/measurement_tool_content_padding_medium" />
-
+
-
+
+
+
+ android:visibility="invisible" />
-
-
\ No newline at end of file
diff --git a/OsmAnd/res/layout/fragment_measurement_tool_points_list.xml b/OsmAnd/res/layout/measurement_tool_points_card.xml
similarity index 91%
rename from OsmAnd/res/layout/fragment_measurement_tool_points_list.xml
rename to OsmAnd/res/layout/measurement_tool_points_card.xml
index a0684707ea..47e8bd9d4b 100644
--- a/OsmAnd/res/layout/fragment_measurement_tool_points_list.xml
+++ b/OsmAnd/res/layout/measurement_tool_points_card.xml
@@ -3,7 +3,7 @@
xmlns:osmand="http://schemas.android.com/apk/res-auto"
android:id="@+id/points_list_container"
android:layout_width="match_parent"
- android:layout_height="@dimen/measurement_tool_points_list_container_height"
+ android:layout_height="wrap_content"
android:background="?attr/activity_background_color">
12dp
18dp
12dp
- 330dp
+ 330dp
48dp
18dp
24dp
diff --git a/OsmAnd/res/values/sizes.xml b/OsmAnd/res/values/sizes.xml
index f91581adf6..a086849297 100644
--- a/OsmAnd/res/values/sizes.xml
+++ b/OsmAnd/res/values/sizes.xml
@@ -257,7 +257,7 @@
12dp
4dp
8dp
- 220dp
+ 220dp
60dp
52dp
8dp
diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/other/HorizontalSelectionAdapter.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/other/HorizontalSelectionAdapter.java
index 06783d6f50..23d7886d55 100644
--- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/other/HorizontalSelectionAdapter.java
+++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/other/HorizontalSelectionAdapter.java
@@ -63,6 +63,8 @@ public class HorizontalSelectionAdapter extends RecyclerView.Adapter 0 && editingCtx.getSelectedPointPosition() == -1) {
- expandAdditionalInfoView();
- } else {
- collapseAdditionalInfoView();
+ public void onClick(View v) {
+ if (isPortrait) {
+ if (infoExpanded) {
+ collapseInfoView();
+ } else if (setInfoType(InfoType.POINTS)) {
+ infoTypeBtn.setSelectedItem(pointsBtn);
+ }
}
}
});
View applyMovePointButton = mainView.findViewById(R.id.apply_move_point_button);
- UiUtilities.setupDialogButton(nightMode, applyMovePointButton, UiUtilities.DialogButtonType.PRIMARY,
- R.string.shared_string_apply);
+ UiUtilities.setupDialogButton(nightMode, applyMovePointButton,
+ UiUtilities.DialogButtonType.PRIMARY, R.string.shared_string_apply);
+ applyMovePointButton.setMinimumWidth(btnWidth);
applyMovePointButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
@@ -349,8 +342,9 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
View applyPointBeforeAfterButton = mainView.findViewById(R.id.apply_point_before_after_point_button);
- UiUtilities.setupDialogButton(nightMode, applyPointBeforeAfterButton, UiUtilities.DialogButtonType.PRIMARY,
- R.string.shared_string_apply);
+ UiUtilities.setupDialogButton(nightMode, applyPointBeforeAfterButton,
+ UiUtilities.DialogButtonType.PRIMARY, R.string.shared_string_apply);
+ applyPointBeforeAfterButton.setMinimumWidth(btnWidth);
applyPointBeforeAfterButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
@@ -359,8 +353,9 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
});
View addPointBeforeAfterButton = mainView.findViewById(R.id.add_point_before_after_button);
- UiUtilities.setupDialogButton(nightMode, addPointBeforeAfterButton, UiUtilities.DialogButtonType.PRIMARY,
- R.string.shared_string_add);
+ UiUtilities.setupDialogButton(nightMode, addPointBeforeAfterButton,
+ UiUtilities.DialogButtonType.PRIMARY, R.string.shared_string_add);
+ addPointBeforeAfterButton.setMinimumWidth(btnWidth);
addPointBeforeAfterButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
@@ -408,8 +403,9 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
});
View addPointButton = mainView.findViewById(R.id.add_point_button);
- UiUtilities.setupDialogButton(nightMode, addPointButton, UiUtilities.DialogButtonType.PRIMARY,
- R.string.shared_string_add);
+ UiUtilities.setupDialogButton(nightMode, addPointButton,
+ UiUtilities.DialogButtonType.PRIMARY, R.string.shared_string_add);
+ addPointButton.setMinimumWidth(btnWidth);
addPointButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
@@ -425,9 +421,6 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
@Override
public void onSelectPoint(int selectedPointPos) {
- if (additionalInfoExpanded) {
- collapseAdditionalInfoView();
- }
if (selectedPointPos != -1) {
openSelectedPointMenu(mapActivity);
}
@@ -449,9 +442,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
measurementLayer.setOnEnterMovePointModeListener(new MeasurementToolLayer.OnEnterMovePointModeListener() {
@Override
public void onEnterMovePointMode() {
- if (additionalInfoExpanded) {
- collapseAdditionalInfoView();
- }
+ collapseInfoViewIfExpanded();
switchMovePointMode(true);
}
});
@@ -529,37 +520,90 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
return view;
}
- private void changeAdditionalInfoType(@NonNull AdditionalInfoType type) {
- if (!additionalInfoExpanded || !isCurrentAdditionalInfoType(type)) {
- MapActivity ma = getMapActivity();
- if (ma == null) return;
-
- OsmandApplication app = ma.getMyApplication();
- if (AdditionalInfoType.POINTS == type) {
- visibleCard = pointsCard;
- UiUtilities.updateCustomRadioButtons(app, customRadioButton, nightMode, START);
- } else if (AdditionalInfoType.GRAPH == type) {
- visibleCard = graphsCard;
- UiUtilities.updateCustomRadioButtons(app, customRadioButton, nightMode, END);
+ private OnRadioItemClickListener getInfoTypeBtnListener(@NonNull final InfoType type) {
+ return new OnRadioItemClickListener() {
+ @Override
+ public boolean onRadioItemClick(RadioItem radioItem, View view) {
+ if (isCurrentInfoType(type)) {
+ collapseInfoView();
+ return false;
+ }
+ return setInfoType(type);
}
- cardsContainer.removeAllViews();
- View cardView = visibleCard.getView() != null ? visibleCard.getView() : visibleCard.build(ma);
- cardsContainer.addView(cardView);
+ };
+ }
- currentAdditionalInfoType = type;
- additionalInfoExpanded = true;
+ private boolean setInfoType(@NonNull InfoType type) {
+ OsmandApplication app = getMyApplication();
+ if ((!infoExpanded || !isCurrentInfoType(type)) && app != null) {
+ if (editingCtx.getPointsCount() > 0 && editingCtx.getSelectedPointPosition() == -1) {
+ expandInfoView();
+ currentInfoType = type;
+ if (InfoType.POINTS == type) {
+ visibleCard = pointsCard;
+ } else if (InfoType.GRAPH == type) {
+ visibleCard = graphsCard;
+ }
+ cardsContainer.removeAllViews();
+ View cardView = visibleCard.getView() != null ? visibleCard.getView() : visibleCard.build(app);
+ cardsContainer.addView(cardView);
+ return true;
+ } else {
+ collapseInfoView();
+ }
+ }
+ return false;
+ }
+
+ private void expandInfoView() {
+ if (isPortrait) {
+ infoExpanded = true;
+ cardsContainer.setVisibility(View.VISIBLE);
+ setMapPosition(isPortrait
+ ? OsmandSettings.MIDDLE_TOP_CONSTANT
+ : OsmandSettings.LANDSCAPE_MIDDLE_RIGHT_CONSTANT);
updateUpDownBtn();
}
}
- private void updateAdditionalInfoView() {
- updateAdditionalInfoView(pointsCard);
- updateAdditionalInfoView(graphsCard);
+ private void collapseInfoViewIfExpanded() {
+ if (infoExpanded) {
+ collapseInfoView();
+ }
}
- private void updateAdditionalInfoView(OnUpdateAdditionalInfoListener listener) {
+ private void collapseInfoView() {
+ if (isPortrait) {
+ infoExpanded = false;
+ currentInfoType = null;
+ infoTypeBtn.setSelectedItem(null);
+ cardsContainer.setVisibility(View.GONE);
+ setDefaultMapPosition();
+ updateUpDownBtn();
+ }
+ }
+
+ private void collapseInfoIfNotEnoughPoints() {
+ MeasurementToolLayer measurementLayer = getMeasurementLayer();
+ if (measurementLayer != null) {
+ int pointsCount = editingCtx.getPointsCount();
+ if (isCurrentInfoType(InfoType.GRAPH) && pointsCount < 2) {
+ collapseInfoView();
+ } else if (pointsCount < 1) {
+ disable(upDownBtn);
+ collapseInfoViewIfExpanded();
+ }
+ }
+ }
+
+ private void updateInfoView() {
+ updateInfoView(pointsCard);
+ updateInfoView(graphsCard);
+ }
+
+ private void updateInfoView(OnUpdateInfoListener listener) {
if (listener != null) {
- listener.onUpdateAdditionalInfo();
+ listener.onUpdateInfo();
}
}
@@ -576,11 +620,11 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
}
private void updateUndoRedoCommonStuff() {
- collapseAdditionalInfoIfNoPointsEnough();
+ collapseInfoIfNotEnoughPoints();
if (editingCtx.getPointsCount() > 0) {
enable(upDownBtn);
}
- updateAdditionalInfoView();
+ updateInfoView();
updateDistancePointsText();
updateSnapToRoadControls();
}
@@ -638,9 +682,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
super.onDestroyView();
cancelModes();
exitMeasurementMode();
- if (additionalInfoExpanded) {
- collapseAdditionalInfoView();
- }
+ collapseInfoViewIfExpanded();
MeasurementToolLayer layer = getMeasurementLayer();
if (layer != null) {
layer.setOnSingleTapListener(null);
@@ -891,9 +933,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
MeasurementToolLayer measurementLayer = getMeasurementLayer();
editingCtx.getCommandManager().execute(new ClearPointsCommand(measurementLayer, ALL));
editingCtx.cancelSnapToRoad();
- if (additionalInfoExpanded) {
- collapseAdditionalInfoView();
- }
+ collapseInfoViewIfExpanded();
updateUndoRedoButton(false, redoBtn);
disable(upDownBtn);
updateDistancePointsText();
@@ -907,9 +947,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
if (points.size() > 1) {
MeasurementToolLayer measurementLayer = getMeasurementLayer();
editingCtx.getCommandManager().execute(new ReversePointsCommand(measurementLayer));
- if (additionalInfoExpanded) {
- collapseAdditionalInfoView();
- }
+ collapseInfoViewIfExpanded();
updateUndoRedoButton(false, redoBtn);
updateUndoRedoButton(true, undoBtn);
updateDistancePointsText();
@@ -976,9 +1014,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
private void trimRoute(ClearCommandMode before) {
MeasurementToolLayer measurementLayer = getMeasurementLayer();
editingCtx.getCommandManager().execute(new ClearPointsCommand(measurementLayer, before));
- if (additionalInfoExpanded) {
- collapseAdditionalInfoView();
- }
+ collapseInfoViewIfExpanded();
editingCtx.setSelectedPointPosition(-1);
editingCtx.splitSegments(editingCtx.getBeforePoints().size() + editingCtx.getAfterPoints().size());
updateUndoRedoButton(false, redoBtn);
@@ -1130,11 +1166,11 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
private void removePoint(MeasurementToolLayer measurementLayer, int position) {
if (measurementLayer != null) {
editingCtx.getCommandManager().execute(new RemovePointCommand(measurementLayer, position));
- updateAdditionalInfoView();
+ updateInfoView();
updateUndoRedoButton(true, undoBtn);
updateUndoRedoButton(false, redoBtn);
updateDistancePointsText();
- collapseAdditionalInfoIfNoPointsEnough();
+ collapseInfoIfNotEnoughPoints();
}
}
@@ -1159,10 +1195,8 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
@Override
public void onItemClick(int position) {
if (mapActivity != null && measurementLayer != null) {
- if (additionalInfoExpanded) {
- collapseAdditionalInfoView();
- }
- if (portrait) {
+ collapseInfoViewIfExpanded();
+ if (isPortrait) {
setMapPosition(OsmandSettings.MIDDLE_TOP_CONSTANT);
}
measurementLayer.moveMapToPoint(position);
@@ -1182,7 +1216,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
toPosition = holder.getAdapterPosition();
if (toPosition >= 0 && fromPosition >= 0 && toPosition != fromPosition) {
editingCtx.getCommandManager().execute(new ReorderPointCommand(measurementLayer, fromPosition, toPosition));
- updateAdditionalInfoView();
+ updateInfoView();
updateUndoRedoButton(false, redoBtn);
updateDistancePointsText();
mapActivity.refreshMap();
@@ -1248,7 +1282,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
if (!isUndoMode()) {
editingCtx.addPoints();
}
- updateAdditionalInfoView();
+ updateInfoView();
updateDistancePointsText();
}
}
@@ -1406,7 +1440,9 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
R.id.measurement_points_text_view,
R.id.distance_to_center_text_view,
R.id.up_down_button,
- R.id.measure_mode_controls);
+ R.id.measure_mode_controls,
+ R.id.info_type_buttons_container,
+ R.id.bottom_panel_divider);
}
}
@@ -1444,46 +1480,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
updateUndoRedoButton(true, undoBtn);
updateUndoRedoButton(false, redoBtn);
updateDistancePointsText();
- updateAdditionalInfoView();
- }
-
- private void expandAdditionalInfoView() {
- if (portrait) {
- MapActivity mapActivity = getMapActivity();
- if (mapActivity != null) {
- additionalInfoContainer.setVisibility(View.VISIBLE);
- AdditionalInfoType typeToShow = currentAdditionalInfoType == null
- ? AdditionalInfoType.POINTS : currentAdditionalInfoType;
- changeAdditionalInfoType(typeToShow);
- setMapPosition(portrait
- ? OsmandSettings.MIDDLE_TOP_CONSTANT
- : OsmandSettings.LANDSCAPE_MIDDLE_RIGHT_CONSTANT);
- }
- }
- }
-
- private void collapseAdditionalInfoView() {
- if (portrait) {
- additionalInfoExpanded = false;
- updateUpDownBtn();
- additionalInfoContainer.setVisibility(View.GONE);
- setDefaultMapPosition();
- }
- }
-
- private void collapseAdditionalInfoIfNoPointsEnough() {
- MeasurementToolLayer measurementLayer = getMeasurementLayer();
- if (measurementLayer != null) {
- int pointsCount = editingCtx.getPointsCount();
- if (isCurrentAdditionalInfoType(AdditionalInfoType.GRAPH) && pointsCount < 2) {
- collapseAdditionalInfoView();
- } else if (pointsCount < 1) {
- disable(upDownBtn);
- if (additionalInfoExpanded) {
- collapseAdditionalInfoView();
- }
- }
- }
+ updateInfoView();
}
private void setDefaultMapPosition() {
@@ -1510,13 +1507,13 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
}
private void updateUpDownBtn() {
- Drawable icon = getContentIcon(additionalInfoExpanded
+ Drawable icon = getContentIcon(infoExpanded
? R.drawable.ic_action_arrow_down : R.drawable.ic_action_arrow_up);
upDownBtn.setImageDrawable(icon);
}
- private boolean isCurrentAdditionalInfoType(@NonNull AdditionalInfoType type) {
- return type.equals(currentAdditionalInfoType);
+ private boolean isCurrentInfoType(@NonNull InfoType type) {
+ return Algorithms.objectEquals(currentInfoType, type);
}
public boolean hasVisibleGraph() {
@@ -1600,7 +1597,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
switch (finalSaveAction) {
case SHOW_SNACK_BAR_AND_CLOSE:
final WeakReference mapActivityRef = new WeakReference<>(mapActivity);
- snackbar = Snackbar.make(mapActivity.getLayout(),
+ Snackbar snackbar = Snackbar.make(mapActivity.getLayout(),
MessageFormat.format(getString(R.string.gpx_saved_sucessfully), outFile.getName()),
Snackbar.LENGTH_LONG)
.setAction(R.string.shared_string_undo, new OnClickListener() {
@@ -1693,7 +1690,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
if (measurementLayer != null) {
String distanceStr = OsmAndFormatter.getFormattedDistance((float) editingCtx.getRouteDistance(), requireMyApplication());
distanceTv.setText(distanceStr + ",");
- pointsTv.setText((portrait ? pointsSt + ": " : "") + editingCtx.getPointsCount());
+ pointsTv.setText((isPortrait ? pointsSt + ": " : "") + editingCtx.getPointsCount());
}
updateToolbar();
}
@@ -1724,7 +1721,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
mapActivity.refreshMap();
mapActivity.disableDrawer();
- AndroidUiHelper.setVisibility(mapActivity, portrait ? View.INVISIBLE : View.GONE,
+ AndroidUiHelper.setVisibility(mapActivity, isPortrait ? View.INVISIBLE : View.GONE,
R.id.map_left_widgets_panel,
R.id.map_right_widgets_panel,
R.id.map_center_info);
@@ -1778,7 +1775,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
}
}
- public void quit(boolean hidePointsListFirst) {
+ public void quit(boolean hideInfoViewFirst) {
if (editingCtx.getOriginalPointToMove() != null) {
cancelMovePointMode();
return;
@@ -1793,16 +1790,16 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
dismiss(mapActivity);
}
} else {
- showQuitDialog(hidePointsListFirst);
+ showQuitDialog(hideInfoViewFirst);
}
}
- private void showQuitDialog(boolean hidePointsListFirst) {
+ private void showQuitDialog(boolean hideInfoViewFirst) {
final MapActivity mapActivity = getMapActivity();
MeasurementToolLayer measurementLayer = getMeasurementLayer();
if (mapActivity != null && measurementLayer != null) {
- if (additionalInfoExpanded && hidePointsListFirst) {
- collapseAdditionalInfoView();
+ if (infoExpanded && hideInfoViewFirst) {
+ collapseInfoView();
return;
}
if (!editingCtx.hasChanges()) {
@@ -1822,9 +1819,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
if (clearContext) {
editingCtx.clearSegments();
}
- if (additionalInfoExpanded) {
- collapseAdditionalInfoView();
- }
+ collapseInfoViewIfExpanded();
resetAppMode();
hideSnapToRoadIcon();
if (isInEditMode()) {
@@ -1961,9 +1956,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
if (!approximationMode || !editingCtx.getCommandManager().update(command)) {
editingCtx.getCommandManager().execute(command);
}
- if (additionalInfoExpanded) {
- collapseAdditionalInfoView();
- }
+ collapseInfoViewIfExpanded();
updateSnapToRoadControls();
}
}
@@ -2036,7 +2029,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
return nightMode;
}
- public interface OnUpdateAdditionalInfoListener {
- void onUpdateAdditionalInfo();
+ public interface OnUpdateInfoListener {
+ void onUpdateInfo();
}
}
\ No newline at end of file
diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/PointsCard.java b/OsmAnd/src/net/osmand/plus/measurementtool/PointsCard.java
index f3b55473bc..4507fe5270 100644
--- a/OsmAnd/src/net/osmand/plus/measurementtool/PointsCard.java
+++ b/OsmAnd/src/net/osmand/plus/measurementtool/PointsCard.java
@@ -7,12 +7,12 @@ import androidx.recyclerview.widget.RecyclerView;
import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity;
-import net.osmand.plus.measurementtool.MeasurementToolFragment.OnUpdateAdditionalInfoListener;
+import net.osmand.plus.measurementtool.MeasurementToolFragment.OnUpdateInfoListener;
import net.osmand.plus.measurementtool.adapter.MeasurementToolAdapter;
import net.osmand.plus.routepreparationmenu.cards.BaseCard;
import net.osmand.plus.views.controls.ReorderItemTouchHelperCallback;
-public class PointsCard extends BaseCard implements OnUpdateAdditionalInfoListener {
+public class PointsCard extends BaseCard implements OnUpdateInfoListener {
private MeasurementToolAdapter adapter;
private MeasurementToolFragment fragment;
@@ -23,7 +23,7 @@ public class PointsCard extends BaseCard implements OnUpdateAdditionalInfoListen
}
@Override
- public void onUpdateAdditionalInfo() {
+ public void onUpdateInfo() {
if (adapter != null) {
adapter.notifyDataSetChanged();
}
@@ -31,7 +31,7 @@ public class PointsCard extends BaseCard implements OnUpdateAdditionalInfoListen
@Override
public int getCardLayoutId() {
- return R.layout.fragment_measurement_tool_points_list;
+ return R.layout.measurement_tool_points_card;
}
@Override
diff --git a/OsmAnd/src/net/osmand/plus/widgets/HorizontalRadioGroup.java b/OsmAnd/src/net/osmand/plus/widgets/HorizontalRadioGroup.java
new file mode 100644
index 0000000000..edd54c9d16
--- /dev/null
+++ b/OsmAnd/src/net/osmand/plus/widgets/HorizontalRadioGroup.java
@@ -0,0 +1,206 @@
+package net.osmand.plus.widgets;
+
+import android.content.Context;
+import android.graphics.Color;
+import android.graphics.drawable.GradientDrawable;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+import androidx.core.content.ContextCompat;
+
+import net.osmand.AndroidUtils;
+import net.osmand.plus.OsmandApplication;
+import net.osmand.plus.R;
+import net.osmand.plus.UiUtilities;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class HorizontalRadioGroup {
+
+ private List items = new ArrayList<>();
+ private List buttons = new ArrayList<>();
+ private List dividers = new ArrayList<>();
+ private RadioItem selectedItem;
+
+ private LinearLayout container;
+ private boolean nightMode;
+
+ public HorizontalRadioGroup(LinearLayout container, boolean nightMode) {
+ this.container = container;
+ this.nightMode = nightMode;
+ }
+
+ public void setItems(RadioItem firstBtn, RadioItem secondBtn, RadioItem ... other) {
+ items.clear();
+ items.add(firstBtn);
+ items.add(secondBtn);
+ if (other != null && other.length > 0) {
+ items.addAll(Arrays.asList(other));
+ }
+ initView();
+ }
+
+ private void initView() {
+ buttons.clear();
+ dividers.clear();
+ container.removeAllViews();
+ for (int i = 0; i < items.size(); i++) {
+ RadioItem item = items.get(i);
+
+ ViewGroup button = createBtn();
+ TextView title = button.findViewById(R.id.title);
+ title.setText(item.getTitle());
+ button.setOnClickListener(getSelectClickListener(item));
+ buttons.add(button);
+ container.addView(button);
+
+ boolean lastItem = i == items.size() - 1;
+ if (!lastItem) {
+ View divider = createDivider();
+ dividers.add(divider);
+ container.addView(divider);
+ }
+ }
+ updateView();
+ }
+
+ private View.OnClickListener getSelectClickListener(final RadioItem item) {
+ return new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ OnRadioItemClickListener l = item.getListener();
+ if (l != null && l.onRadioItemClick(item, container)) {
+ setSelectedItem(item);
+ }
+ }
+ };
+ }
+
+ @NonNull
+ private ViewGroup createBtn() {
+ Context ctx = getThemedCtx();
+ LayoutInflater inflater = LayoutInflater.from(ctx);
+ return (ViewGroup) inflater.inflate(R.layout.custom_radio_btn_text_item, container, false);
+ }
+
+ @NonNull
+ private View createDivider() {
+ Context ctx = getThemedCtx();
+ int dividerColor = nightMode ?
+ R.color.stroked_buttons_and_links_outline_dark :
+ R.color.stroked_buttons_and_links_outline_light;
+ int width = AndroidUtils.dpToPx(ctx, 1.0f);
+ View divider = new View(ctx);
+ divider.setLayoutParams(new ViewGroup.LayoutParams(width, ViewGroup.LayoutParams.MATCH_PARENT));
+ divider.setBackgroundColor(ContextCompat.getColor(ctx, dividerColor));
+ return divider;
+ }
+
+ public void setSelectedItem(RadioItem selectedItem) {
+ this.selectedItem = selectedItem;
+ updateView();
+ }
+
+ private void updateView() {
+ OsmandApplication app = getMyApplication();
+ if (app == null) {
+ return;
+ }
+ int activeColor = ContextCompat.getColor(app, nightMode
+ ? R.color.active_color_primary_dark
+ : R.color.active_color_primary_light);
+ int textColor = ContextCompat.getColor(app, nightMode
+ ? R.color.text_color_primary_dark
+ : R.color.text_color_primary_light);
+ int radius = AndroidUtils.dpToPx(app, 4);
+ float[] leftBtnRadii = new float[]{radius, radius, 0, 0, 0, 0, radius, radius};
+ float[] rightBtnRadii = new float[]{0, 0, radius, radius, radius, radius, 0, 0};
+ float[] centerBtnRadii = new float[]{0, 0, 0, 0, 0, 0, 0, 0};
+ boolean isLayoutRtl = AndroidUtils.isLayoutRtl(app);
+
+ GradientDrawable background = new GradientDrawable();
+ background.setColor(UiUtilities.getColorWithAlpha(activeColor, 0.1f));
+ background.setStroke(AndroidUtils.dpToPx(app, 1), UiUtilities.getColorWithAlpha(activeColor, 0.5f));
+
+ showAllDividers();
+ for (int i = 0; i < items.size(); i++) {
+ RadioItem item = items.get(i);
+ ViewGroup container = buttons.get(i);
+ TextView tvTitle = (TextView) container.findViewById(R.id.title);
+ if (selectedItem == item) {
+ if (i == 0) {
+ background.setCornerRadii(isLayoutRtl ? rightBtnRadii : leftBtnRadii);
+ hideDividers(0);
+ } else if (i == items.size() - 1) {
+ background.setCornerRadii(isLayoutRtl ? leftBtnRadii : rightBtnRadii);
+ hideDividers(dividers.size() - 1);
+ } else {
+ background.setCornerRadii(centerBtnRadii);
+ hideDividers(i - 1, i);
+ }
+ container.setBackgroundDrawable(background);
+ tvTitle.setTextColor(textColor);
+ } else {
+ container.setBackgroundColor(Color.TRANSPARENT);
+ tvTitle.setTextColor(activeColor);
+ }
+ }
+ }
+
+ private void showAllDividers() {
+ for (View divider : dividers) {
+ divider.setVisibility(View.VISIBLE);
+ }
+ }
+
+ private void hideDividers(int ... dividerIndexes) {
+ for (int dividerIndex : dividerIndexes) {
+ if (dividerIndex >= 0 && dividerIndex < dividers.size()) {
+ dividers.get(dividerIndex).setVisibility(View.GONE);
+ }
+ }
+ }
+
+ private Context getThemedCtx() {
+ Context ctx = container.getContext();
+ return UiUtilities.getThemedContext(ctx, nightMode);
+ }
+
+ private OsmandApplication getMyApplication() {
+ if (container != null) {
+ return (OsmandApplication) container.getContext().getApplicationContext();
+ }
+ return null;
+ }
+
+ public static class RadioItem {
+ private String title;
+ private OnRadioItemClickListener listener;
+
+ public RadioItem(String title) {
+ this.title = title;
+ }
+
+ public void setOnClickListener(OnRadioItemClickListener listener) {
+ this.listener = listener;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public OnRadioItemClickListener getListener() {
+ return listener;
+ }
+ }
+
+ public interface OnRadioItemClickListener {
+ boolean onRadioItemClick(RadioItem radioItem, View view);
+ }
+}