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.R;
import net.osmand.plus.base.OnVisibilityChangeListener;
import net.osmand.util.Algorithms;
import java.io.File;
@ -602,6 +603,12 @@ public class AndroidUtils {
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) {
if (Build.VERSION.SDK_INT >= 21) {
requestLayout(view);
@ -889,4 +896,20 @@ public class AndroidUtils {
}
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.LinearLayout;
import android.widget.OverScroller;
import android.widget.ScrollView;
import android.widget.Toast;
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;
public abstract class ContextMenuFragment extends BaseOsmAndFragment {
public abstract class ContextMenuFragment extends BaseOsmAndFragment implements OnNeedScrollUiAdapter {
public static class MenuState {
public static final int HEADER_ONLY = 1;
@ -67,7 +68,7 @@ public abstract class ContextMenuFragment extends BaseOsmAndFragment {
private OnLayoutChangeListener containerLayoutListener;
private View topShadow;
private ViewGroup topView;
private View bottomScrollView;
private ScrollView bottomScrollView;
private LinearLayout cardsContainer;
private FrameLayout bottomContainer;
@ -247,7 +248,7 @@ public abstract class ContextMenuFragment extends BaseOsmAndFragment {
return bottomContainer;
}
public View getBottomScrollView() {
public ScrollView getBottomScrollView() {
return bottomScrollView;
}
@ -318,6 +319,8 @@ public abstract class ContextMenuFragment extends BaseOsmAndFragment {
final GestureDetector swipeDetector = new GestureDetector(app, new HorizontalSwipeConfirm(true));
final OnTouchListener slideTouchListener = new OnTouchListener() {
private static final int SHORT_CLICK_DURATION_TOP_LIMIT = 500;
private float dy;
private float dyMain;
private float mDownY;
@ -329,6 +332,9 @@ public abstract class ContextMenuFragment extends BaseOsmAndFragment {
private boolean slidingUp;
private boolean slidingDown;
private boolean isHolding;
private long downMotionEventTimeMs;
{
OsmandApplication app = requireMyApplication();
@ -352,6 +358,10 @@ public abstract class ContextMenuFragment extends BaseOsmAndFragment {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
if (!isHolding) {
isHolding = true;
downMotionEventTimeMs = event.getDownTime();
}
mDownY = event.getRawY();
dy = event.getY();
dyMain = getViewY();
@ -388,6 +398,7 @@ public abstract class ContextMenuFragment extends BaseOsmAndFragment {
break;
case MotionEvent.ACTION_UP:
isHolding = false;
if (moving) {
moving = false;
int currentY = getViewY();
@ -412,6 +423,8 @@ public abstract class ContextMenuFragment extends BaseOsmAndFragment {
}
changeMenuState(currentY, slidingUp, slidingDown, true);
} else if (isShortClick(event.getEventTime())) {
onShortClick(v, event);
}
recycleVelocityTracker();
break;
@ -445,6 +458,11 @@ public abstract class ContextMenuFragment extends BaseOsmAndFragment {
velocityTracker = null;
}
}
private boolean isShortClick(long upActionTime) {
long holdingDuration = upActionTime - downMotionEventTimeMs;
return holdingDuration <= SHORT_CLICK_DURATION_TOP_LIMIT;
}
};
if (mainView instanceof InterceptorLinearLayout) {
@ -467,6 +485,8 @@ public abstract class ContextMenuFragment extends BaseOsmAndFragment {
return view;
}
protected void onShortClick(View v, MotionEvent event) { }
public float getToolbarAlpha(int y) {
float a = 0;
if (portrait) {
@ -1047,4 +1067,16 @@ public abstract class ContextMenuFragment extends BaseOsmAndFragment {
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.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
@ -80,6 +81,8 @@ public class TrackAppearanceFragment extends ContextMenuScrollFragment implement
private ImageView trackIcon;
private View buttonsShadow;
private View routeMenuTopShadowAll;
private View controlButtons;
@Override
public int getMainLayoutId() {
@ -179,6 +182,8 @@ public class TrackAppearanceFragment extends ContextMenuScrollFragment implement
if (view != null) {
trackIcon = view.findViewById(R.id.track_icon);
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()) {
updateCardsLayout();
@ -191,7 +196,7 @@ public class TrackAppearanceFragment extends ContextMenuScrollFragment implement
int widthNoShadow = getLandscapeNoShadowWidth();
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(widthNoShadow, ViewGroup.LayoutParams.WRAP_CONTENT);
params.gravity = Gravity.BOTTOM | Gravity.START;
view.findViewById(R.id.control_buttons).setLayoutParams(params);
controlButtons.setLayoutParams(params);
}
enterTrackAppearanceMode();
runLayoutListener();
@ -201,8 +206,8 @@ public class TrackAppearanceFragment extends ContextMenuScrollFragment implement
@Override
protected void calculateLayout(View view, boolean initLayout) {
menuTitleHeight = view.findViewById(R.id.route_menu_top_shadow_all).getHeight()
+ view.findViewById(R.id.control_buttons).getHeight() - buttonsShadow.getHeight();
menuTitleHeight = routeMenuTopShadowAll.getHeight()
+ controlButtons.getHeight() - buttonsShadow.getHeight();
super.calculateLayout(view, initLayout);
}
@ -353,6 +358,14 @@ public class TrackAppearanceFragment extends ContextMenuScrollFragment implement
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) {
MapActivity mapActivity = getMapActivity();
if (mapActivity != null && mapActivity.getMapView() != null) {
@ -583,7 +596,7 @@ public class TrackAppearanceFragment extends ContextMenuScrollFragment implement
trackColoringCard.setListener(this);
cardsContainer.addView(trackColoringCard.build(mapActivity));
trackWidthCard = new TrackWidthCard(mapActivity, trackDrawInfo);
trackWidthCard = new TrackWidthCard(mapActivity, trackDrawInfo, this);
trackWidthCard.setListener(this);
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) {
try {
mapActivity.getSupportFragmentManager()

View file

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