From ced9a3555e54316d4e44cc6a57de74097079060c Mon Sep 17 00:00:00 2001 From: nazar-kutz Date: Mon, 19 Apr 2021 16:49:03 +0300 Subject: [PATCH 1/3] Implement icon radio toggle Implement landscape for Plan Route --- .../layout-land/fragment_measurement_tool.xml | 14 +++ OsmAnd/res/layout-land/map_hud_top.xml | 1 + .../res/layout/custom_icon_radio_buttons.xml | 23 ++++ .../res/layout/custom_radio_btn_icon_item.xml | 20 ++++ .../layout/measurement_tool_graph_card.xml | 1 + .../LiveUpdatesSettingsBottomSheet.java | 27 ++--- .../plus/measurementtool/GraphsCard.java | 8 ++ .../MeasurementToolFragment.java | 110 ++++++++++-------- .../routing/cards/RouteLineColorCard.java | 17 +-- .../plus/track/SplitIntervalBottomSheet.java | 20 ++-- .../multistatetoggle/IconToggleButton.java | 70 +++++++++++ .../MultiStateToggleButton.java | 97 +++++++-------- .../widgets/multistatetoggle/RadioItem.java | 20 ++++ .../multistatetoggle/TextToggleButton.java | 54 +++++++++ 14 files changed, 349 insertions(+), 133 deletions(-) create mode 100644 OsmAnd/res/layout/custom_icon_radio_buttons.xml create mode 100644 OsmAnd/res/layout/custom_radio_btn_icon_item.xml create mode 100644 OsmAnd/src/net/osmand/plus/widgets/multistatetoggle/IconToggleButton.java rename OsmAnd/src/net/osmand/plus/widgets/{ => multistatetoggle}/MultiStateToggleButton.java (70%) create mode 100644 OsmAnd/src/net/osmand/plus/widgets/multistatetoggle/RadioItem.java create mode 100644 OsmAnd/src/net/osmand/plus/widgets/multistatetoggle/TextToggleButton.java diff --git a/OsmAnd/res/layout-land/fragment_measurement_tool.xml b/OsmAnd/res/layout-land/fragment_measurement_tool.xml index 505e680262..85e4cfd4d5 100644 --- a/OsmAnd/res/layout-land/fragment_measurement_tool.xml +++ b/OsmAnd/res/layout-land/fragment_measurement_tool.xml @@ -53,6 +53,19 @@ android:background="@null" tools:src="@drawable/ic_action_ruler"/> + + diff --git a/OsmAnd/res/layout/custom_icon_radio_buttons.xml b/OsmAnd/res/layout/custom_icon_radio_buttons.xml new file mode 100644 index 0000000000..bdfe2f4f5f --- /dev/null +++ b/OsmAnd/res/layout/custom_icon_radio_buttons.xml @@ -0,0 +1,23 @@ + + + + + + + + \ No newline at end of file diff --git a/OsmAnd/res/layout/custom_radio_btn_icon_item.xml b/OsmAnd/res/layout/custom_radio_btn_icon_item.xml new file mode 100644 index 0000000000..8a54559283 --- /dev/null +++ b/OsmAnd/res/layout/custom_radio_btn_icon_item.xml @@ -0,0 +1,20 @@ + + + + + + \ No newline at end of file diff --git a/OsmAnd/res/layout/measurement_tool_graph_card.xml b/OsmAnd/res/layout/measurement_tool_graph_card.xml index fecbe7ae89..272b9a4d2e 100644 --- a/OsmAnd/res/layout/measurement_tool_graph_card.xml +++ b/OsmAnd/res/layout/measurement_tool_graph_card.xml @@ -4,6 +4,7 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="wrap_content" + android:background="?attr/list_background_color" android:orientation="vertical"> { + + public IconToggleButton(@NonNull OsmandApplication app, + @NonNull LinearLayout container, + boolean nightMode) { + super(app, container, nightMode); + } + + @Override + protected int getRadioItemLayoutId() { + return R.layout.custom_radio_btn_icon_item; + } + + @Override + protected void initItemView(@NonNull ViewGroup view, + @NonNull IconRadioItem item) { + if (item.isUseDefaultColor()) { + ImageView ivIcon = view.findViewById(R.id.icon); + ivIcon.setImageDrawable(uiUtilities.getIcon(item.getIconId())); + } + } + + @Override + protected void updateItemView(@NonNull ViewGroup view, + @NonNull IconRadioItem item, + @ColorInt int color) { + if (!item.isUseDefaultColor()) { + ImageView ivIcon = view.findViewById(R.id.icon); + Drawable icon = uiUtilities.getPaintedIcon(item.getIconId(), color); + ivIcon.setImageDrawable(icon); + } + } + + public static class IconRadioItem extends RadioItem { + + private final int iconId; + private final boolean useDefaultColor; + + public IconRadioItem(int iconId) { + this(iconId, false); + } + + public IconRadioItem(int iconId, boolean useDefaultColor) { + this.iconId = iconId; + this.useDefaultColor = useDefaultColor; + } + + public int getIconId() { + return iconId; + } + + public boolean isUseDefaultColor() { + return useDefaultColor; + } + } +} diff --git a/OsmAnd/src/net/osmand/plus/widgets/MultiStateToggleButton.java b/OsmAnd/src/net/osmand/plus/widgets/multistatetoggle/MultiStateToggleButton.java similarity index 70% rename from OsmAnd/src/net/osmand/plus/widgets/MultiStateToggleButton.java rename to OsmAnd/src/net/osmand/plus/widgets/multistatetoggle/MultiStateToggleButton.java index 605584f5b8..2207933acc 100644 --- a/OsmAnd/src/net/osmand/plus/widgets/MultiStateToggleButton.java +++ b/OsmAnd/src/net/osmand/plus/widgets/multistatetoggle/MultiStateToggleButton.java @@ -1,4 +1,4 @@ -package net.osmand.plus.widgets; +package net.osmand.plus.widgets.multistatetoggle; import android.graphics.Color; import android.graphics.drawable.GradientDrawable; @@ -6,38 +6,49 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.LinearLayout; -import android.widget.TextView; +import androidx.annotation.ColorInt; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; 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 net.osmand.plus.widgets.multistatetoggle.RadioItem.OnRadioItemClickListener; import java.util.ArrayList; import java.util.Arrays; import java.util.List; -public class MultiStateToggleButton { +public abstract class MultiStateToggleButton<_Radio extends RadioItem> { - private List items = new ArrayList<>(); - private OsmandApplication app; - private List buttons = new ArrayList<>(); - private List dividers = new ArrayList<>(); - private RadioItem selectedItem; + protected final OsmandApplication app; + protected final UiUtilities uiUtilities; - private LinearLayout container; - private boolean nightMode; + private final LinearLayout container; + private final List buttons = new ArrayList<>(); + private final List dividers = new ArrayList<>(); - public MultiStateToggleButton(OsmandApplication app, LinearLayout container, boolean nightMode) { + protected final List<_Radio> items = new ArrayList<>(); + protected final boolean nightMode; + protected boolean isEnabled; + protected RadioItem selectedItem; + + public MultiStateToggleButton(@NonNull OsmandApplication app, + @NonNull LinearLayout container, + boolean nightMode) { this.app = app; + this.uiUtilities = app.getUIUtilities(); this.container = container; this.nightMode = nightMode; } - public void setItems(RadioItem firstBtn, RadioItem secondBtn, RadioItem... other) { + @SafeVarargs + public final void setItems(@NonNull _Radio firstBtn, + @NonNull _Radio secondBtn, + @Nullable _Radio... other) { items.clear(); items.add(firstBtn); items.add(secondBtn); @@ -47,6 +58,11 @@ public class MultiStateToggleButton { initView(); } + public final void setSelectedItem(@Nullable RadioItem selectedItem) { + this.selectedItem = selectedItem; + updateView(); + } + private void initView() { buttons.clear(); dividers.clear(); @@ -60,16 +76,10 @@ public class MultiStateToggleButton { updateView(); } - private boolean isLastItem(int index) { - return index == items.size() - 1; - } - - private void createBtn(@NonNull final RadioItem item) { + private void createBtn(@NonNull final _Radio item) { LayoutInflater inflater = UiUtilities.getInflater(app, nightMode); ViewGroup button = (ViewGroup) inflater.inflate( - R.layout.custom_radio_btn_text_item, container, false); - TextView title = button.findViewById(R.id.title); - title.setText(item.getTitle()); + getRadioItemLayoutId(), container, false); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { @@ -79,6 +89,7 @@ public class MultiStateToggleButton { } } }); + initItemView(button, item); buttons.add(button); container.addView(button); } @@ -95,11 +106,6 @@ public class MultiStateToggleButton { container.addView(divider); } - public void setSelectedItem(RadioItem selectedItem) { - this.selectedItem = selectedItem; - updateView(); - } - private void updateView() { updateView(true); } @@ -123,15 +129,14 @@ public class MultiStateToggleButton { showAllDividers(); for (int i = 0; i < items.size(); i++) { - RadioItem item = items.get(i); + _Radio item = items.get(i); ViewGroup container = buttons.get(i); container.setEnabled(isEnabled); - 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) { + } else if (isLastItem(i)) { background.setCornerRadii(isLayoutRtl ? leftBtnRadii : rightBtnRadii); hideDividers(dividers.size() - 1); } else { @@ -139,14 +144,21 @@ public class MultiStateToggleButton { hideDividers(i - 1, i); } container.setBackgroundDrawable(background); - tvTitle.setTextColor(textColor); + updateItemView(container, item, textColor); } else { container.setBackgroundColor(Color.TRANSPARENT); - tvTitle.setTextColor(activeColor); + updateItemView(container, item, activeColor); } } } + protected abstract int getRadioItemLayoutId(); + + protected abstract void initItemView(@NonNull ViewGroup view, @NonNull _Radio item); + + protected abstract void updateItemView(@NonNull ViewGroup view, @NonNull _Radio item, + @ColorInt int color); + private void showAllDividers() { for (View divider : dividers) { divider.setVisibility(View.VISIBLE); @@ -161,28 +173,7 @@ public class MultiStateToggleButton { } } - 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); + private boolean isLastItem(int index) { + return index == items.size() - 1; } } diff --git a/OsmAnd/src/net/osmand/plus/widgets/multistatetoggle/RadioItem.java b/OsmAnd/src/net/osmand/plus/widgets/multistatetoggle/RadioItem.java new file mode 100644 index 0000000000..c23f6a925f --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/widgets/multistatetoggle/RadioItem.java @@ -0,0 +1,20 @@ +package net.osmand.plus.widgets.multistatetoggle; + +import android.view.View; + +public class RadioItem { + + private OnRadioItemClickListener listener; + + public void setOnClickListener(OnRadioItemClickListener listener) { + this.listener = listener; + } + + public OnRadioItemClickListener getListener() { + return listener; + } + + public interface OnRadioItemClickListener { + boolean onRadioItemClick(RadioItem radioItem, View view); + } +} diff --git a/OsmAnd/src/net/osmand/plus/widgets/multistatetoggle/TextToggleButton.java b/OsmAnd/src/net/osmand/plus/widgets/multistatetoggle/TextToggleButton.java new file mode 100644 index 0000000000..048ebca622 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/widgets/multistatetoggle/TextToggleButton.java @@ -0,0 +1,54 @@ +package net.osmand.plus.widgets.multistatetoggle; + +import android.view.ViewGroup; +import android.widget.LinearLayout; +import android.widget.TextView; + +import androidx.annotation.ColorInt; +import androidx.annotation.NonNull; + +import net.osmand.plus.OsmandApplication; +import net.osmand.plus.R; +import net.osmand.plus.widgets.multistatetoggle.TextToggleButton.TextRadioItem; + +public class TextToggleButton extends MultiStateToggleButton { + + public TextToggleButton(@NonNull OsmandApplication app, + @NonNull LinearLayout container, + boolean nightMode) { + super(app, container, nightMode); + } + + @Override + protected int getRadioItemLayoutId() { + return R.layout.custom_radio_btn_text_item; + } + + @Override + protected void initItemView(@NonNull ViewGroup view, @NonNull TextRadioItem item) { + TextView title = view.findViewById(R.id.title); + title.setText(item.getTitle()); + } + + @Override + protected void updateItemView(@NonNull ViewGroup view, + @NonNull TextRadioItem item, + @ColorInt int color) { + TextView tvTitle = (TextView) view.findViewById(R.id.title); + tvTitle.setTextColor(color); + } + + public static class TextRadioItem extends RadioItem { + + private final String title; + + public TextRadioItem(String title) { + this.title = title; + } + + public String getTitle() { + return title; + } + } + +} From e65eb4cb84a19244f118a4df35bdc08869f79afd Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Tue, 20 Apr 2021 11:02:03 +0300 Subject: [PATCH 2/3] Fix graphs card touches passing through --- OsmAnd/res/layout/measurement_tool_graph_card.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/OsmAnd/res/layout/measurement_tool_graph_card.xml b/OsmAnd/res/layout/measurement_tool_graph_card.xml index 272b9a4d2e..aebc1554a7 100644 --- a/OsmAnd/res/layout/measurement_tool_graph_card.xml +++ b/OsmAnd/res/layout/measurement_tool_graph_card.xml @@ -5,6 +5,8 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:background="?attr/list_background_color" + android:clickable="true" + android:focusable="true" android:orientation="vertical"> Date: Tue, 20 Apr 2021 11:23:27 +0300 Subject: [PATCH 3/3] fix after merge --- .../src/net/osmand/plus/base/ModeSelectionBottomSheet.java | 2 +- .../plus/base/MultipleSelectionWithModeBottomSheet.java | 2 +- OsmAnd/src/net/osmand/plus/base/SelectionBottomSheet.java | 7 ++++--- .../net/osmand/plus/download/SelectIndexesUiHelper.java | 7 ++++--- 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/base/ModeSelectionBottomSheet.java b/OsmAnd/src/net/osmand/plus/base/ModeSelectionBottomSheet.java index f8355c8805..a19e304299 100644 --- a/OsmAnd/src/net/osmand/plus/base/ModeSelectionBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/base/ModeSelectionBottomSheet.java @@ -14,7 +14,7 @@ import androidx.fragment.app.FragmentManager; import net.osmand.AndroidUtils; import net.osmand.plus.R; -import net.osmand.plus.widgets.MultiStateToggleButton.RadioItem; +import net.osmand.plus.widgets.multistatetoggle.RadioItem; import java.util.Collections; import java.util.List; diff --git a/OsmAnd/src/net/osmand/plus/base/MultipleSelectionWithModeBottomSheet.java b/OsmAnd/src/net/osmand/plus/base/MultipleSelectionWithModeBottomSheet.java index 261e8dfdea..9ac4948937 100644 --- a/OsmAnd/src/net/osmand/plus/base/MultipleSelectionWithModeBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/base/MultipleSelectionWithModeBottomSheet.java @@ -8,7 +8,7 @@ import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; import androidx.fragment.app.FragmentManager; -import net.osmand.plus.widgets.MultiStateToggleButton.RadioItem; +import net.osmand.plus.widgets.multistatetoggle.RadioItem; import java.util.List; diff --git a/OsmAnd/src/net/osmand/plus/base/SelectionBottomSheet.java b/OsmAnd/src/net/osmand/plus/base/SelectionBottomSheet.java index 18c91f8cf5..f861500078 100644 --- a/OsmAnd/src/net/osmand/plus/base/SelectionBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/base/SelectionBottomSheet.java @@ -19,8 +19,9 @@ import net.osmand.plus.base.bottomsheetmenu.BaseBottomSheetItem; import net.osmand.plus.base.bottomsheetmenu.SimpleBottomSheetItem; import net.osmand.plus.base.bottomsheetmenu.simpleitems.SimpleDividerItem; import net.osmand.plus.helpers.AndroidUiHelper; -import net.osmand.plus.widgets.MultiStateToggleButton; -import net.osmand.plus.widgets.MultiStateToggleButton.RadioItem; +import net.osmand.plus.widgets.multistatetoggle.MultiStateToggleButton; +import net.osmand.plus.widgets.multistatetoggle.RadioItem; +import net.osmand.plus.widgets.multistatetoggle.TextToggleButton; import net.osmand.util.Algorithms; import net.osmand.view.ThreeStateCheckbox; @@ -91,7 +92,7 @@ public abstract class SelectionBottomSheet extends MenuBottomSheetDialogFragment secondaryDescription = view.findViewById(R.id.secondary_description); selectedSize = view.findViewById(R.id.selected_size); toggleContainer = view.findViewById(R.id.custom_radio_buttons); - radioGroup = new MultiStateToggleButton(app, toggleContainer, nightMode); + radioGroup = new TextToggleButton(app, toggleContainer, nightMode); selectAllButton = view.findViewById(R.id.select_all_button); checkBoxTitle = view.findViewById(R.id.check_box_title); checkBox = view.findViewById(R.id.check_box); diff --git a/OsmAnd/src/net/osmand/plus/download/SelectIndexesUiHelper.java b/OsmAnd/src/net/osmand/plus/download/SelectIndexesUiHelper.java index f7835ce348..845082daae 100644 --- a/OsmAnd/src/net/osmand/plus/download/SelectIndexesUiHelper.java +++ b/OsmAnd/src/net/osmand/plus/download/SelectIndexesUiHelper.java @@ -15,8 +15,9 @@ import net.osmand.plus.base.SelectionBottomSheet; import net.osmand.plus.base.SelectionBottomSheet.OnApplySelectionListener; import net.osmand.plus.base.SelectionBottomSheet.OnUiInitializedAdapter; import net.osmand.plus.base.SelectionBottomSheet.SelectableItem; -import net.osmand.plus.widgets.MultiStateToggleButton.OnRadioItemClickListener; -import net.osmand.plus.widgets.MultiStateToggleButton.RadioItem; +import net.osmand.plus.widgets.multistatetoggle.RadioItem; +import net.osmand.plus.widgets.multistatetoggle.RadioItem.OnRadioItemClickListener; +import net.osmand.plus.widgets.multistatetoggle.TextToggleButton.TextRadioItem; import net.osmand.util.Algorithms; import java.text.DateFormat; @@ -176,7 +177,7 @@ public class SelectIndexesUiHelper { private RadioItem createSrtmRadioBtn(int titleId, final boolean useMeters) { String title = Algorithms.capitalizeFirstLetter(app.getString(titleId)); - RadioItem radioItem = new RadioItem(title); + RadioItem radioItem = new TextRadioItem(title); radioItem.setOnClickListener(new OnRadioItemClickListener() { @Override public boolean onRadioItemClick(RadioItem radioItem, View view) {