Ui fixes third part

This commit is contained in:
Nazar-Kutz 2020-09-14 17:42:29 +03:00
parent 721ad8280d
commit 0a48fc586e
6 changed files with 135 additions and 10 deletions

View file

@ -63,6 +63,7 @@ import androidx.core.view.ViewCompat;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.base.OnVisibilityChangeListener;
import net.osmand.util.Algorithms; import net.osmand.util.Algorithms;
import java.io.File; import java.io.File;
@ -602,6 +603,12 @@ public class AndroidUtils {
return coordinates; return coordinates;
} }
public static boolean isPointInsideView(@NonNull View view, float x, float y) {
boolean matchVertical = y >= view.getY() && y <= view.getY() + view.getHeight();
boolean mathHorizontal = x >= view.getX() && x <= view.getX() + view.getWidth();
return matchVertical && mathHorizontal;
}
public static void enterToFullScreen(Activity activity, View view) { public static void enterToFullScreen(Activity activity, View view) {
if (Build.VERSION.SDK_INT >= 21) { if (Build.VERSION.SDK_INT >= 21) {
requestLayout(view); requestLayout(view);
@ -889,4 +896,20 @@ public class AndroidUtils {
} }
return builder; return builder;
} }
public static void addVisibilityChangeListener(final @NonNull View parent,
final @NonNull View v,
final @NonNull OnVisibilityChangeListener listener) {
parent.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
int visibility = v.getVisibility();
@Override
public void onGlobalLayout() {
if (visibility != v.getVisibility()) {
visibility = v.getVisibility();
listener.onVisibilityChange(visibility);
}
}
});
}
} }

View file

@ -24,6 +24,7 @@ import android.view.animation.DecelerateInterpolator;
import android.widget.FrameLayout; import android.widget.FrameLayout;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.OverScroller; import android.widget.OverScroller;
import android.widget.ScrollView;
import android.widget.Toast; import android.widget.Toast;
import androidx.annotation.IdRes; import androidx.annotation.IdRes;
@ -49,7 +50,7 @@ import net.osmand.plus.views.controls.HorizontalSwipeConfirm;
import static net.osmand.plus.mapcontextmenu.MapContextMenuFragment.CURRENT_Y_UNDEFINED; import static net.osmand.plus.mapcontextmenu.MapContextMenuFragment.CURRENT_Y_UNDEFINED;
public abstract class ContextMenuFragment extends BaseOsmAndFragment { public abstract class ContextMenuFragment extends BaseOsmAndFragment implements OnNeedScrollUiAdapter {
public static class MenuState { public static class MenuState {
public static final int HEADER_ONLY = 1; public static final int HEADER_ONLY = 1;
@ -67,7 +68,7 @@ public abstract class ContextMenuFragment extends BaseOsmAndFragment {
private OnLayoutChangeListener containerLayoutListener; private OnLayoutChangeListener containerLayoutListener;
private View topShadow; private View topShadow;
private ViewGroup topView; private ViewGroup topView;
private View bottomScrollView; private ScrollView bottomScrollView;
private LinearLayout cardsContainer; private LinearLayout cardsContainer;
private FrameLayout bottomContainer; private FrameLayout bottomContainer;
@ -247,7 +248,7 @@ public abstract class ContextMenuFragment extends BaseOsmAndFragment {
return bottomContainer; return bottomContainer;
} }
public View getBottomScrollView() { public ScrollView getBottomScrollView() {
return bottomScrollView; return bottomScrollView;
} }
@ -318,6 +319,8 @@ public abstract class ContextMenuFragment extends BaseOsmAndFragment {
final GestureDetector swipeDetector = new GestureDetector(app, new HorizontalSwipeConfirm(true)); final GestureDetector swipeDetector = new GestureDetector(app, new HorizontalSwipeConfirm(true));
final OnTouchListener slideTouchListener = new OnTouchListener() { final OnTouchListener slideTouchListener = new OnTouchListener() {
private static final int SHORT_CLICK_DURATION_TOP_LIMIT = 500;
private float dy; private float dy;
private float dyMain; private float dyMain;
private float mDownY; private float mDownY;
@ -329,6 +332,9 @@ public abstract class ContextMenuFragment extends BaseOsmAndFragment {
private boolean slidingUp; private boolean slidingUp;
private boolean slidingDown; private boolean slidingDown;
private boolean isHolding;
private long downMotionEventTimeMs;
{ {
OsmandApplication app = requireMyApplication(); OsmandApplication app = requireMyApplication();
@ -352,6 +358,10 @@ public abstract class ContextMenuFragment extends BaseOsmAndFragment {
switch (event.getAction()) { switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: case MotionEvent.ACTION_DOWN:
if (!isHolding) {
isHolding = true;
downMotionEventTimeMs = event.getDownTime();
}
mDownY = event.getRawY(); mDownY = event.getRawY();
dy = event.getY(); dy = event.getY();
dyMain = getViewY(); dyMain = getViewY();
@ -388,6 +398,7 @@ public abstract class ContextMenuFragment extends BaseOsmAndFragment {
break; break;
case MotionEvent.ACTION_UP: case MotionEvent.ACTION_UP:
isHolding = false;
if (moving) { if (moving) {
moving = false; moving = false;
int currentY = getViewY(); int currentY = getViewY();
@ -412,6 +423,8 @@ public abstract class ContextMenuFragment extends BaseOsmAndFragment {
} }
changeMenuState(currentY, slidingUp, slidingDown, true); changeMenuState(currentY, slidingUp, slidingDown, true);
} else if (isShortClick(event.getEventTime())) {
onShortClick(v, event);
} }
recycleVelocityTracker(); recycleVelocityTracker();
break; break;
@ -445,6 +458,11 @@ public abstract class ContextMenuFragment extends BaseOsmAndFragment {
velocityTracker = null; velocityTracker = null;
} }
} }
private boolean isShortClick(long upActionTime) {
long holdingDuration = upActionTime - downMotionEventTimeMs;
return holdingDuration <= SHORT_CLICK_DURATION_TOP_LIMIT;
}
}; };
if (mainView instanceof InterceptorLinearLayout) { if (mainView instanceof InterceptorLinearLayout) {
@ -467,6 +485,8 @@ public abstract class ContextMenuFragment extends BaseOsmAndFragment {
return view; return view;
} }
protected void onShortClick(View v, MotionEvent event) { }
public float getToolbarAlpha(int y) { public float getToolbarAlpha(int y) {
float a = 0; float a = 0;
if (portrait) { if (portrait) {
@ -1047,4 +1067,16 @@ public abstract class ContextMenuFragment extends BaseOsmAndFragment {
return false; return false;
} }
} }
@Override
public void onNeedVerticalScroll(String tag, int y) { }
public void verticalScrollToYPosition(final int y) {
bottomScrollView.post(new Runnable() {
@Override
public void run() {
bottomScrollView.smoothScrollTo(0, y);
}
});
}
} }

View file

@ -0,0 +1,5 @@
package net.osmand.plus.base;
public interface OnNeedScrollUiAdapter {
void onNeedVerticalScroll(String tag, int yPosition);
}

View file

@ -0,0 +1,5 @@
package net.osmand.plus.base;
public interface OnVisibilityChangeListener {
void onVisibilityChange(int visibility);
}

View file

@ -7,6 +7,7 @@ import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.view.Gravity; import android.view.Gravity;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.ViewTreeObserver; import android.view.ViewTreeObserver;
@ -80,6 +81,8 @@ public class TrackAppearanceFragment extends ContextMenuScrollFragment implement
private ImageView trackIcon; private ImageView trackIcon;
private View buttonsShadow; private View buttonsShadow;
private View routeMenuTopShadowAll;
private View controlButtons;
@Override @Override
public int getMainLayoutId() { public int getMainLayoutId() {
@ -179,6 +182,8 @@ public class TrackAppearanceFragment extends ContextMenuScrollFragment implement
if (view != null) { if (view != null) {
trackIcon = view.findViewById(R.id.track_icon); trackIcon = view.findViewById(R.id.track_icon);
buttonsShadow = view.findViewById(R.id.buttons_shadow); buttonsShadow = view.findViewById(R.id.buttons_shadow);
controlButtons = view.findViewById(R.id.control_buttons);
routeMenuTopShadowAll = view.findViewById(R.id.route_menu_top_shadow_all);
if (isPortrait()) { if (isPortrait()) {
updateCardsLayout(); updateCardsLayout();
@ -191,7 +196,7 @@ public class TrackAppearanceFragment extends ContextMenuScrollFragment implement
int widthNoShadow = getLandscapeNoShadowWidth(); int widthNoShadow = getLandscapeNoShadowWidth();
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(widthNoShadow, ViewGroup.LayoutParams.WRAP_CONTENT); FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(widthNoShadow, ViewGroup.LayoutParams.WRAP_CONTENT);
params.gravity = Gravity.BOTTOM | Gravity.START; params.gravity = Gravity.BOTTOM | Gravity.START;
view.findViewById(R.id.control_buttons).setLayoutParams(params); controlButtons.setLayoutParams(params);
} }
enterTrackAppearanceMode(); enterTrackAppearanceMode();
runLayoutListener(); runLayoutListener();
@ -201,8 +206,8 @@ public class TrackAppearanceFragment extends ContextMenuScrollFragment implement
@Override @Override
protected void calculateLayout(View view, boolean initLayout) { protected void calculateLayout(View view, boolean initLayout) {
menuTitleHeight = view.findViewById(R.id.route_menu_top_shadow_all).getHeight() menuTitleHeight = routeMenuTopShadowAll.getHeight()
+ view.findViewById(R.id.control_buttons).getHeight() - buttonsShadow.getHeight(); + controlButtons.getHeight() - buttonsShadow.getHeight();
super.calculateLayout(view, initLayout); super.calculateLayout(view, initLayout);
} }
@ -353,6 +358,14 @@ public class TrackAppearanceFragment extends ContextMenuScrollFragment implement
trackIcon.setImageDrawable(icon); trackIcon.setImageDrawable(icon);
} }
@Override
protected void onShortClick(View v, MotionEvent event) {
if (routeMenuTopShadowAll != null &&
AndroidUtils.isPointInsideView(routeMenuTopShadowAll, event.getX(), event.getY())) {
adjustMapPosition(getViewY());
}
}
private void adjustMapPosition(int y) { private void adjustMapPosition(int y) {
MapActivity mapActivity = getMapActivity(); MapActivity mapActivity = getMapActivity();
if (mapActivity != null && mapActivity.getMapView() != null) { if (mapActivity != null && mapActivity.getMapView() != null) {
@ -583,7 +596,7 @@ public class TrackAppearanceFragment extends ContextMenuScrollFragment implement
trackColoringCard.setListener(this); trackColoringCard.setListener(this);
cardsContainer.addView(trackColoringCard.build(mapActivity)); cardsContainer.addView(trackColoringCard.build(mapActivity));
trackWidthCard = new TrackWidthCard(mapActivity, trackDrawInfo); trackWidthCard = new TrackWidthCard(mapActivity, trackDrawInfo, this);
trackWidthCard.setListener(this); trackWidthCard.setListener(this);
cardsContainer.addView(trackWidthCard.build(mapActivity)); cardsContainer.addView(trackWidthCard.build(mapActivity));
} }
@ -626,6 +639,28 @@ public class TrackAppearanceFragment extends ContextMenuScrollFragment implement
} }
} }
@Override
public void onNeedVerticalScroll(@NonNull String tag, int y) {
if (tag.equals(TrackWidthCard.TAG)) {
View trackWidthCardView = trackWidthCard.getView();
if (trackWidthCardView == null) return;
int currentScrollYPosition = getBottomScrollView().getScrollY();
int dialogHeight = getInnerScrollableHeight();
int resultYPosition = trackWidthCardView.getTop() + y;
if (resultYPosition > (currentScrollYPosition + dialogHeight)) {
verticalScrollToYPosition(resultYPosition - dialogHeight);
}
}
}
public int getInnerScrollableHeight() {
int totalScreenHeight = getViewHeight() - getMenuStatePosY(getCurrentMenuState());
int frameTotalHeight = routeMenuTopShadowAll.getHeight()
+ controlButtons.getHeight() + buttonsShadow.getHeight();
return totalScreenHeight - frameTotalHeight;
}
public static boolean showInstance(@NonNull MapActivity mapActivity, TrackAppearanceFragment fragment) { public static boolean showInstance(@NonNull MapActivity mapActivity, TrackAppearanceFragment fragment) {
try { try {
mapActivity.getSupportFragmentManager() mapActivity.getSupportFragmentManager()

View file

@ -19,6 +19,8 @@ import net.osmand.AndroidUtils;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.UiUtilities; import net.osmand.plus.UiUtilities;
import net.osmand.plus.activities.MapActivity; import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.base.OnNeedScrollUiAdapter;
import net.osmand.plus.base.OnVisibilityChangeListener;
import net.osmand.plus.dialogs.GpxAppearanceAdapter; import net.osmand.plus.dialogs.GpxAppearanceAdapter;
import net.osmand.plus.dialogs.GpxAppearanceAdapter.AppearanceListItem; import net.osmand.plus.dialogs.GpxAppearanceAdapter.AppearanceListItem;
import net.osmand.plus.dialogs.GpxAppearanceAdapter.GpxAppearanceAdapterType; import net.osmand.plus.dialogs.GpxAppearanceAdapter.GpxAppearanceAdapterType;
@ -29,21 +31,26 @@ import net.osmand.util.Algorithms;
import java.util.List; import java.util.List;
public class TrackWidthCard extends BaseCard { public class TrackWidthCard extends BaseCard {
public final static String TAG = TrackWidthCard.class.getName();
private final static String CUSTOM_WIDTH = "custom_width"; private final static String CUSTOM_WIDTH = "custom_width";
private final static int CUSTOM_WIDTH_MIN = 1; private final static int CUSTOM_WIDTH_MIN = 1;
private final static int CUSTOM_WIDTH_MAX = 24; private final static int CUSTOM_WIDTH_MAX = 24;
private TrackDrawInfo trackDrawInfo; private TrackDrawInfo trackDrawInfo;
private OnNeedScrollUiAdapter onNeedScrollUiAdapter;
private AppearanceListItem selectedItem; private AppearanceListItem selectedItem;
private List<AppearanceListItem> appearanceItems; private List<AppearanceListItem> appearanceItems;
private GpxWidthAdapter widthAdapter; private GpxWidthAdapter widthAdapter;
private View sliderContainer;
public TrackWidthCard(MapActivity mapActivity, TrackDrawInfo trackDrawInfo) { public TrackWidthCard(MapActivity mapActivity, TrackDrawInfo trackDrawInfo,
OnNeedScrollUiAdapter onNeedScrollUiAdapter) {
super(mapActivity); super(mapActivity);
this.trackDrawInfo = trackDrawInfo; this.trackDrawInfo = trackDrawInfo;
this.onNeedScrollUiAdapter = onNeedScrollUiAdapter;
appearanceItems = getWidthAppearanceItems(); appearanceItems = getWidthAppearanceItems();
} }
@ -110,6 +117,7 @@ public class TrackWidthCard extends BaseCard {
} }
private void updateCustomWidthSlider() { private void updateCustomWidthSlider() {
sliderContainer = view.findViewById(R.id.slider_container);
if (CUSTOM_WIDTH.equals(getSelectedItem().getAttrName())) { if (CUSTOM_WIDTH.equals(getSelectedItem().getAttrName())) {
Slider widthSlider = view.findViewById(R.id.width_slider); Slider widthSlider = view.findViewById(R.id.width_slider);
@ -143,9 +151,19 @@ public class TrackWidthCard extends BaseCard {
} }
}); });
UiUtilities.setupSlider(widthSlider, nightMode, null); UiUtilities.setupSlider(widthSlider, nightMode, null);
AndroidUiHelper.updateVisibility(view.findViewById(R.id.slider_container), true); AndroidUtils.addVisibilityChangeListener(view, sliderContainer,
new OnVisibilityChangeListener() {
@Override
public void onVisibilityChange(int visibility) {
if (visibility == View.VISIBLE) {
onNeedScrollUiAdapter.onNeedVerticalScroll(TAG, sliderContainer.getBottom());
}
}
}
);
AndroidUiHelper.updateVisibility(sliderContainer, true);
} else { } else {
AndroidUiHelper.updateVisibility(view.findViewById(R.id.slider_container), false); AndroidUiHelper.updateVisibility(sliderContainer, false);
} }
} }
@ -203,6 +221,13 @@ public class TrackWidthCard extends BaseCard {
if (listener != null) { if (listener != null) {
listener.onCardPressed(TrackWidthCard.this); listener.onCardPressed(TrackWidthCard.this);
} }
if (CUSTOM_WIDTH.equals(selectedItem.getAttrName())
&& sliderContainer != null
&& onNeedScrollUiAdapter != null
&& sliderContainer.getVisibility() == View.VISIBLE) {
onNeedScrollUiAdapter.onNeedVerticalScroll(TAG, sliderContainer.getBottom());
}
} }
}); });
} }