diff --git a/OsmAnd/res/layout/online_routing_engine_fragment.xml b/OsmAnd/res/layout/online_routing_engine_fragment.xml index 69cc042252..98b3317f66 100644 --- a/OsmAnd/res/layout/online_routing_engine_fragment.xml +++ b/OsmAnd/res/layout/online_routing_engine_fragment.xml @@ -1,9 +1,8 @@ - + android:background="?attr/list_background_color"> + android:layout_height="match_parent" + android:layout_marginBottom="@dimen/dialog_button_ex_height"> + android:orientation="vertical" + android:paddingTop="@dimen/dialog_button_ex_height" + android:paddingBottom="@dimen/context_menu_buttons_bottom_height" /> - + android:layout_height="wrap_content" + android:layout_gravity="bottom" + android:orientation="vertical"> - \ No newline at end of file + + + + + + + \ No newline at end of file diff --git a/OsmAnd/res/layout/online_routing_preference_segment.xml b/OsmAnd/res/layout/online_routing_preference_segment.xml index 437ba875e5..3e5373aa6a 100644 --- a/OsmAnd/res/layout/online_routing_preference_segment.xml +++ b/OsmAnd/res/layout/online_routing_preference_segment.xml @@ -164,36 +164,4 @@ tools:visibility="visible" android:visibility="gone" /> - - - - - - - - \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/ui/OnlineRoutingCard.java b/OsmAnd/src/net/osmand/plus/onlinerouting/ui/OnlineRoutingCard.java index 66efbaa8ed..b18ee19fdb 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/ui/OnlineRoutingCard.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/ui/OnlineRoutingCard.java @@ -25,8 +25,6 @@ import net.osmand.plus.helpers.AndroidUiHelper; import net.osmand.plus.mapcontextmenu.other.HorizontalSelectionAdapter; import net.osmand.plus.mapcontextmenu.other.HorizontalSelectionAdapter.HorizontalSelectionAdapterListener; import net.osmand.plus.mapcontextmenu.other.HorizontalSelectionAdapter.HorizontalSelectionItem; -import net.osmand.plus.onlinerouting.VehicleType; -import net.osmand.plus.onlinerouting.engine.OnlineRoutingEngine; import net.osmand.plus.routepreparationmenu.cards.BaseCard; import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.widgets.OsmandTextFieldBoxes; @@ -137,23 +135,15 @@ public class OnlineRoutingCard extends BaseCard { if (callback.processResult(item)) { adapter.setSelectedItem(item); } - Object obj = item.getObject(); - updateBottomMarginSelectionMenu(obj); } }); - Object item = adapter.getItemByTitle(selectedItemTitle).getObject(); - updateBottomMarginSelectionMenu(item); rvSelectionMenu.setAdapter(adapter); } - private void updateBottomMarginSelectionMenu(Object item) { - if (item instanceof VehicleType) { - VehicleType vt = (VehicleType) item; - boolean hasPadding = vt.equals(OnlineRoutingEngine.CUSTOM_VEHICLE); - ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) rvSelectionMenu.getLayoutParams(); - int contentPadding = app.getResources().getDimensionPixelSize(R.dimen.content_padding); - params.bottomMargin = hasPadding ? contentPadding : 0; - } + private void updateBottomMarginSelectionMenu() { + ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) rvSelectionMenu.getLayoutParams(); + int contentPadding = app.getResources().getDimensionPixelSize(R.dimen.content_padding); + params.bottomMargin = isVisibleViewsBelowSelectionMenu() ? contentPadding : 0; } public void setDescription(@NonNull String description) { @@ -230,10 +220,20 @@ public class OnlineRoutingCard extends BaseCard { private void showElements(View... views) { AndroidUiHelper.setVisibility(View.VISIBLE, views); + updateBottomMarginSelectionMenu(); } private void hideElements(View... views) { AndroidUiHelper.setVisibility(View.GONE, views); + updateBottomMarginSelectionMenu(); + } + + private boolean isVisibleViewsBelowSelectionMenu() { + return isVisible(tvDescription) || isVisible(fieldBoxContainer) || isVisible(button); + } + + public boolean isVisible(View view) { + return view.getVisibility() == View.VISIBLE; } public void setOnTextChangedListener(@Nullable OnTextChangedListener onTextChangedListener) { diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/ui/OnlineRoutingEngineFragment.java b/OsmAnd/src/net/osmand/plus/onlinerouting/ui/OnlineRoutingEngineFragment.java index 0041c93853..ee8b2ee827 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/ui/OnlineRoutingEngineFragment.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/ui/OnlineRoutingEngineFragment.java @@ -14,6 +14,7 @@ import android.view.View.OnClickListener; import android.view.ViewGroup; import android.view.ViewTreeObserver; import android.view.ViewTreeObserver.OnGlobalLayoutListener; +import android.view.ViewTreeObserver.OnScrollChangedListener; import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.ScrollView; @@ -23,6 +24,7 @@ import androidx.activity.OnBackPressedCallback; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.AlertDialog; +import androidx.appcompat.widget.AppCompatImageView; import androidx.appcompat.widget.Toolbar; import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentManager; @@ -82,7 +84,9 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { private View testResultsContainer; private View saveButton; private ScrollView scrollView; + private AppCompatImageView buttonsShadow; private OnGlobalLayoutListener onGlobalLayout; + private OnScrollChangedListener onScroll; private boolean isKeyboardShown = false; private OnlineRoutingEngine engine; @@ -112,7 +116,6 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { }); } - @SuppressLint("ClickableViewAccessibility") @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @@ -121,7 +124,8 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { view = getInflater().inflate( R.layout.online_routing_engine_fragment, container, false); segmentsContainer = (ViewGroup) view.findViewById(R.id.segments_container); - scrollView = (ScrollView) segmentsContainer.getParent(); + scrollView = (ScrollView) view.findViewById(R.id.segments_scroll); + buttonsShadow = (AppCompatImageView) view.findViewById(R.id.buttons_shadow); if (Build.VERSION.SDK_INT >= 21) { AndroidUtils.addStatusBarPadding21v(getContext(), view); } @@ -138,67 +142,9 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { generateUniqueNameIfNeeded(); updateCardViews(nameCard, typeCard, vehicleCard, exampleCard); - scrollView.setOnTouchListener(new View.OnTouchListener() { - int scrollViewY = 0; - - @Override - public boolean onTouch(View v, MotionEvent event) { - int y = scrollView.getScrollY(); - if (isKeyboardShown && scrollViewY != y) { - scrollViewY = y; - View focus = mapActivity.getCurrentFocus(); - if (focus != null) { - AndroidUtils.hideSoftKeyboard(mapActivity, focus); - focus.clearFocus(); - } - } - return false; - } - }); - - onGlobalLayout = new ViewTreeObserver.OnGlobalLayoutListener() { - private int layoutHeightPrevious; - private int layoutHeightMin; - - @Override - public void onGlobalLayout() { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { - view.getViewTreeObserver().removeOnGlobalLayoutListener(this); - } else { - view.getViewTreeObserver().removeGlobalOnLayoutListener(this); - } - - Rect visibleDisplayFrame = new Rect(); - view.getWindowVisibleDisplayFrame(visibleDisplayFrame); - int layoutHeight = visibleDisplayFrame.bottom; - - if (layoutHeight < layoutHeightPrevious) { - isKeyboardShown = true; - layoutHeightMin = layoutHeight; - } else { - isKeyboardShown = layoutHeight == layoutHeightMin; - } - - if (layoutHeight != layoutHeightPrevious) { - FrameLayout.LayoutParams rootViewLayout = (FrameLayout.LayoutParams) view.getLayoutParams(); - rootViewLayout.height = layoutHeight; - view.requestLayout(); - layoutHeightPrevious = layoutHeight; - } - - view.post(new Runnable() { - @Override - public void run() { - view.getViewTreeObserver().addOnGlobalLayoutListener(onGlobalLayout); - } - }); - - } - }; - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { - view.getViewTreeObserver().addOnGlobalLayoutListener(onGlobalLayout); - } + showShadowBelowButtons(); + showButtonsAboveKeyboard(); + hideKeyboardOnScroll(); return view; } @@ -223,8 +169,7 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { actionBtn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { - onDeleteEngine(); - dismiss(); + delete(mapActivity); } }); } else { @@ -391,7 +336,7 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { private void setupResultsContainer() { testResultsContainer = getInflater().inflate( R.layout.bottom_sheet_item_with_descr_64dp, segmentsContainer, false); - testResultsContainer.setVisibility(View.INVISIBLE); + testResultsContainer.setVisibility(View.GONE); segmentsContainer.addView(testResultsContainer); } @@ -481,6 +426,22 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { helper.deleteEngine(engine); } + private void delete(Activity activity) { + if (engine != null) { + AlertDialog.Builder builder = new AlertDialog.Builder(UiUtilities.getThemedContext(activity, isNightMode())); + builder.setMessage(getString(R.string.delete_online_routing_engine)); + builder.setNegativeButton(R.string.shared_string_no, null); + builder.setPositiveButton(R.string.shared_string_yes, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + onDeleteEngine(); + dismiss(); + } + }); + builder.create().show(); + } + } + private boolean isEditingMode() { return editedEngineKey != null; } @@ -529,6 +490,12 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { tvTitle.setText(String.format(getString(R.string.message_server_error), message)); } tvDescription.setText(location.getName()); + scrollView.post(new Runnable() { + @Override + public void run() { + scrollView.scrollTo(0, scrollView.getChildAt(0).getBottom()); + } + }); } }); } @@ -632,11 +599,8 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { @Override public void onDestroyView() { super.onDestroyView(); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { - view.getViewTreeObserver().removeOnGlobalLayoutListener(onGlobalLayout); - } else { - view.getViewTreeObserver().removeGlobalOnLayoutListener(onGlobalLayout); - } + removeOnGlobalLayoutListener(); + removeOnScrollListener(); } @Override @@ -716,4 +680,127 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { .addToBackStack(TAG).commitAllowingStateLoss(); } } + + @SuppressLint("ClickableViewAccessibility") + private void hideKeyboardOnScroll() { + scrollView.setOnTouchListener(new View.OnTouchListener() { + int scrollViewY = 0; + + @Override + public boolean onTouch(View v, MotionEvent event) { + int y = scrollView.getScrollY(); + if (isKeyboardShown && scrollViewY != y) { + scrollViewY = y; + View focus = mapActivity.getCurrentFocus(); + if (focus != null) { + AndroidUtils.hideSoftKeyboard(mapActivity, focus); + focus.clearFocus(); + } + } + return false; + } + }); + } + + private void showShadowBelowButtons() { + if (onScroll != null) { + scrollView.getViewTreeObserver().addOnScrollChangedListener(onScroll); + } else { + initShowShadowOnScrollListener(); + showShadowBelowButtons(); + } + } + + private void showButtonsAboveKeyboard() { + if (onGlobalLayout != null) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { + view.getViewTreeObserver().addOnGlobalLayoutListener(onGlobalLayout); + } + } else { + initShowButtonsOnGlobalListener(); + showButtonsAboveKeyboard(); + } + } + + private void initShowShadowOnScrollListener() { + onScroll = new OnScrollChangedListener() { + @Override + public void onScrollChanged() { + boolean scrollToBottomAvailable = scrollView.canScrollVertically(1); + if (scrollToBottomAvailable) { + showShadowButton(); + } else { + hideShadowButton(); + } + } + }; + } + + private void initShowButtonsOnGlobalListener() { + onGlobalLayout = new ViewTreeObserver.OnGlobalLayoutListener() { + private int layoutHeightPrevious; + private int layoutHeightMin; + + @Override + public void onGlobalLayout() { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { + view.getViewTreeObserver().removeOnGlobalLayoutListener(this); + } else { + view.getViewTreeObserver().removeGlobalOnLayoutListener(this); + } + + Rect visibleDisplayFrame = new Rect(); + view.getWindowVisibleDisplayFrame(visibleDisplayFrame); + int layoutHeight = visibleDisplayFrame.bottom; + + if (layoutHeight < layoutHeightPrevious) { + isKeyboardShown = true; + layoutHeightMin = layoutHeight; + } else { + isKeyboardShown = layoutHeight == layoutHeightMin; + } + + if (layoutHeight != layoutHeightPrevious) { + FrameLayout.LayoutParams rootViewLayout = (FrameLayout.LayoutParams) view.getLayoutParams(); + rootViewLayout.height = layoutHeight; + view.requestLayout(); + layoutHeightPrevious = layoutHeight; + } + + view.post(new Runnable() { + @Override + public void run() { + view.getViewTreeObserver().addOnGlobalLayoutListener(onGlobalLayout); + } + }); + + } + }; + } + + private void removeOnScrollListener() { + scrollView.getViewTreeObserver().removeOnScrollChangedListener(onScroll); + } + + private void removeOnGlobalLayoutListener() { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { + view.getViewTreeObserver().removeOnGlobalLayoutListener(onGlobalLayout); + } else { + view.getViewTreeObserver().removeGlobalOnLayoutListener(onGlobalLayout); + } + } + + private void showShadowButton() { + buttonsShadow.setVisibility(View.VISIBLE); + buttonsShadow.animate() + .alpha(0.8f) + .setDuration(200) + .setListener(null); + } + + private void hideShadowButton() { + buttonsShadow.animate() + .alpha(0f) + .setDuration(200); + } }