Shadow should be shown below the "Save/Cancel" buttons (when content is below buttons);

Add confirmation dialog before deleting online routing;
fix descrease padding below scroll buttons for all blocks;
fix padding of results container;
minor fixes;
This commit is contained in:
Skalii 2021-01-22 16:52:33 +02:00
parent f3bee7262e
commit e85cc65441
4 changed files with 201 additions and 127 deletions

View file

@ -1,9 +1,8 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="?attr/list_background_color" android:background="?attr/list_background_color">
android:orientation="vertical">
<com.google.android.material.appbar.AppBarLayout <com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar" android:id="@+id/appbar"
@ -15,21 +14,41 @@
</com.google.android.material.appbar.AppBarLayout> </com.google.android.material.appbar.AppBarLayout>
<ScrollView <ScrollView
android:id="@+id/segments_scroll"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="0dp" android:layout_height="match_parent"
android:layout_weight="1"> android:layout_marginBottom="@dimen/dialog_button_ex_height">
<LinearLayout <LinearLayout
android:id="@+id/segments_container" android:id="@+id/segments_container"
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"
android:paddingTop="@dimen/dialog_button_ex_height"
android:paddingBottom="@dimen/context_menu_buttons_bottom_height" />
</ScrollView> </ScrollView>
<include <LinearLayout
layout="@layout/bottom_buttons" android:id="@+id/control_buttons"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="@dimen/dialog_button_ex_height" /> android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:orientation="vertical">
</LinearLayout> <androidx.appcompat.widget.AppCompatImageView
android:id="@+id/buttons_shadow"
android:layout_width="match_parent"
android:layout_height="8dp"
android:layout_gravity="bottom"
android:background="@drawable/shadow" />
<include
layout="@layout/bottom_buttons"
android:layout_width="match_parent"
android:layout_height="@dimen/dialog_button_ex_height"
android:layout_gravity="bottom" />
</LinearLayout>
</FrameLayout>

View file

@ -164,36 +164,4 @@
tools:visibility="visible" tools:visibility="visible"
android:visibility="gone" /> android:visibility="gone" />
<LinearLayout
android:id="@+id/result_container"
android:layout_width="match_parent"
android:layout_height="@dimen/setting_list_item_group_height"
android:orientation="horizontal"
tools:visibility="visible"
android:visibility="gone">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/result_icon"
android:layout_width="@dimen/standard_icon_size"
android:layout_height="@dimen/standard_icon_size"
android:layout_gravity="center_vertical"
android:layout_marginRight="@dimen/content_padding"
android:layout_marginLeft="@dimen/content_padding"
android:tint="?attr/default_icon_color"
tools:src="@drawable/ic_action_gdirections_dark" />
<net.osmand.plus.widgets.TextViewEx
android:id="@+id/result_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="start|center_vertical"
android:letterSpacing="@dimen/description_letter_spacing"
android:singleLine="true"
android:textColor="?android:attr/textColorPrimary"
android:textSize="@dimen/default_list_text_size"
osmand:typeface="@string/font_roboto_regular"
tools:text="OK" />
</LinearLayout>
</LinearLayout> </LinearLayout>

View file

@ -25,8 +25,6 @@ import net.osmand.plus.helpers.AndroidUiHelper;
import net.osmand.plus.mapcontextmenu.other.HorizontalSelectionAdapter; import net.osmand.plus.mapcontextmenu.other.HorizontalSelectionAdapter;
import net.osmand.plus.mapcontextmenu.other.HorizontalSelectionAdapter.HorizontalSelectionAdapterListener; import net.osmand.plus.mapcontextmenu.other.HorizontalSelectionAdapter.HorizontalSelectionAdapterListener;
import net.osmand.plus.mapcontextmenu.other.HorizontalSelectionAdapter.HorizontalSelectionItem; 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.routepreparationmenu.cards.BaseCard;
import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.settings.backend.ApplicationMode;
import net.osmand.plus.widgets.OsmandTextFieldBoxes; import net.osmand.plus.widgets.OsmandTextFieldBoxes;
@ -137,23 +135,15 @@ public class OnlineRoutingCard extends BaseCard {
if (callback.processResult(item)) { if (callback.processResult(item)) {
adapter.setSelectedItem(item); adapter.setSelectedItem(item);
} }
Object obj = item.getObject();
updateBottomMarginSelectionMenu(obj);
} }
}); });
Object item = adapter.getItemByTitle(selectedItemTitle).getObject();
updateBottomMarginSelectionMenu(item);
rvSelectionMenu.setAdapter(adapter); rvSelectionMenu.setAdapter(adapter);
} }
private void updateBottomMarginSelectionMenu(Object item) { private void updateBottomMarginSelectionMenu() {
if (item instanceof VehicleType) { ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) rvSelectionMenu.getLayoutParams();
VehicleType vt = (VehicleType) item; int contentPadding = app.getResources().getDimensionPixelSize(R.dimen.content_padding);
boolean hasPadding = vt.equals(OnlineRoutingEngine.CUSTOM_VEHICLE); params.bottomMargin = isVisibleViewsBelowSelectionMenu() ? contentPadding : 0;
ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) rvSelectionMenu.getLayoutParams();
int contentPadding = app.getResources().getDimensionPixelSize(R.dimen.content_padding);
params.bottomMargin = hasPadding ? contentPadding : 0;
}
} }
public void setDescription(@NonNull String description) { public void setDescription(@NonNull String description) {
@ -230,10 +220,20 @@ public class OnlineRoutingCard extends BaseCard {
private void showElements(View... views) { private void showElements(View... views) {
AndroidUiHelper.setVisibility(View.VISIBLE, views); AndroidUiHelper.setVisibility(View.VISIBLE, views);
updateBottomMarginSelectionMenu();
} }
private void hideElements(View... views) { private void hideElements(View... views) {
AndroidUiHelper.setVisibility(View.GONE, 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) { public void setOnTextChangedListener(@Nullable OnTextChangedListener onTextChangedListener) {

View file

@ -14,6 +14,7 @@ import android.view.View.OnClickListener;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.ViewTreeObserver; import android.view.ViewTreeObserver;
import android.view.ViewTreeObserver.OnGlobalLayoutListener; import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.view.ViewTreeObserver.OnScrollChangedListener;
import android.widget.FrameLayout; import android.widget.FrameLayout;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.ScrollView; import android.widget.ScrollView;
@ -23,6 +24,7 @@ import androidx.activity.OnBackPressedCallback;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.widget.AppCompatImageView;
import androidx.appcompat.widget.Toolbar; import androidx.appcompat.widget.Toolbar;
import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentManager;
@ -82,7 +84,9 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment {
private View testResultsContainer; private View testResultsContainer;
private View saveButton; private View saveButton;
private ScrollView scrollView; private ScrollView scrollView;
private AppCompatImageView buttonsShadow;
private OnGlobalLayoutListener onGlobalLayout; private OnGlobalLayoutListener onGlobalLayout;
private OnScrollChangedListener onScroll;
private boolean isKeyboardShown = false; private boolean isKeyboardShown = false;
private OnlineRoutingEngine engine; private OnlineRoutingEngine engine;
@ -112,7 +116,6 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment {
}); });
} }
@SuppressLint("ClickableViewAccessibility")
@Nullable @Nullable
@Override @Override
public View onCreateView(@NonNull LayoutInflater inflater, public View onCreateView(@NonNull LayoutInflater inflater,
@ -121,7 +124,8 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment {
view = getInflater().inflate( view = getInflater().inflate(
R.layout.online_routing_engine_fragment, container, false); R.layout.online_routing_engine_fragment, container, false);
segmentsContainer = (ViewGroup) view.findViewById(R.id.segments_container); 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) { if (Build.VERSION.SDK_INT >= 21) {
AndroidUtils.addStatusBarPadding21v(getContext(), view); AndroidUtils.addStatusBarPadding21v(getContext(), view);
} }
@ -138,67 +142,9 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment {
generateUniqueNameIfNeeded(); generateUniqueNameIfNeeded();
updateCardViews(nameCard, typeCard, vehicleCard, exampleCard); updateCardViews(nameCard, typeCard, vehicleCard, exampleCard);
scrollView.setOnTouchListener(new View.OnTouchListener() { showShadowBelowButtons();
int scrollViewY = 0; showButtonsAboveKeyboard();
hideKeyboardOnScroll();
@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);
}
return view; return view;
} }
@ -223,8 +169,7 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment {
actionBtn.setOnClickListener(new OnClickListener() { actionBtn.setOnClickListener(new OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
onDeleteEngine(); delete(mapActivity);
dismiss();
} }
}); });
} else { } else {
@ -391,7 +336,7 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment {
private void setupResultsContainer() { private void setupResultsContainer() {
testResultsContainer = getInflater().inflate( testResultsContainer = getInflater().inflate(
R.layout.bottom_sheet_item_with_descr_64dp, segmentsContainer, false); R.layout.bottom_sheet_item_with_descr_64dp, segmentsContainer, false);
testResultsContainer.setVisibility(View.INVISIBLE); testResultsContainer.setVisibility(View.GONE);
segmentsContainer.addView(testResultsContainer); segmentsContainer.addView(testResultsContainer);
} }
@ -481,6 +426,22 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment {
helper.deleteEngine(engine); 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() { private boolean isEditingMode() {
return editedEngineKey != null; return editedEngineKey != null;
} }
@ -529,6 +490,12 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment {
tvTitle.setText(String.format(getString(R.string.message_server_error), message)); tvTitle.setText(String.format(getString(R.string.message_server_error), message));
} }
tvDescription.setText(location.getName()); 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 @Override
public void onDestroyView() { public void onDestroyView() {
super.onDestroyView(); super.onDestroyView();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { removeOnGlobalLayoutListener();
view.getViewTreeObserver().removeOnGlobalLayoutListener(onGlobalLayout); removeOnScrollListener();
} else {
view.getViewTreeObserver().removeGlobalOnLayoutListener(onGlobalLayout);
}
} }
@Override @Override
@ -716,4 +680,127 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment {
.addToBackStack(TAG).commitAllowingStateLoss(); .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);
}
} }