Context menu states in progress
This commit is contained in:
parent
90ce687568
commit
2547b4b020
4 changed files with 198 additions and 42 deletions
|
@ -8,7 +8,7 @@
|
|||
android:layout_height="match_parent"
|
||||
android:background="@android:color/transparent">
|
||||
|
||||
<LinearLayout
|
||||
<net.osmand.plus.mapcontextmenu.InterceptorLinearLayout
|
||||
android:id="@+id/context_menu_main"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
|
@ -19,7 +19,6 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/bg_map_context_menu"
|
||||
android:clickable="true"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
|
@ -398,7 +397,6 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:background="?selectableItemBackground"
|
||||
android:clickable="true"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical"
|
||||
android:paddingBottom="@dimen/context_menu_main_actions_padding_bottom"
|
||||
|
@ -581,7 +579,7 @@
|
|||
android:foreground="@drawable/bg_contextmenu_shadow"
|
||||
android:foregroundGravity="top|fill_horizontal">
|
||||
|
||||
<ScrollView
|
||||
<net.osmand.plus.LockableScrollView
|
||||
android:id="@+id/context_menu_bottom_scroll"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
|
@ -596,10 +594,11 @@
|
|||
|
||||
</LinearLayout>
|
||||
|
||||
</ScrollView>
|
||||
</net.osmand.plus.LockableScrollView>
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
</LinearLayout>
|
||||
</net.osmand.plus.mapcontextmenu.InterceptorLinearLayout>
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/context_menu_fab_container"
|
||||
|
|
56
OsmAnd/src/net/osmand/plus/LockableScrollView.java
Normal file
56
OsmAnd/src/net/osmand/plus/LockableScrollView.java
Normal file
|
@ -0,0 +1,56 @@
|
|||
package net.osmand.plus;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
import android.widget.ScrollView;
|
||||
|
||||
public class LockableScrollView extends ScrollView {
|
||||
|
||||
// true if we can scroll (not locked)
|
||||
// false if we cannot scroll (locked)
|
||||
private boolean mScrollable = true;
|
||||
|
||||
public LockableScrollView(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public LockableScrollView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
public void setScrollingEnabled(boolean enabled) {
|
||||
mScrollable = enabled;
|
||||
}
|
||||
|
||||
public boolean isScrollable() {
|
||||
return mScrollable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent ev) {
|
||||
switch (ev.getAction()) {
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
// if we can scroll pass the event to the superclass
|
||||
if (mScrollable) {
|
||||
return super.onTouchEvent(ev);
|
||||
}
|
||||
// only continue to handle the touch event if scrolling enabled
|
||||
return mScrollable;
|
||||
default:
|
||||
return super.onTouchEvent(ev);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onInterceptTouchEvent(MotionEvent ev) {
|
||||
// Don't do anything with intercepted touch events if
|
||||
// we are not scrollable
|
||||
if (!mScrollable) {
|
||||
return false;
|
||||
} else {
|
||||
return super.onInterceptTouchEvent(ev);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,89 @@
|
|||
package net.osmand.plus.mapcontextmenu;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.ViewConfiguration;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
public class InterceptorLinearLayout extends LinearLayout {
|
||||
private int mTouchSlop;
|
||||
private boolean mIsScrolling;
|
||||
private float mDownY;
|
||||
private OnTouchListener listener;
|
||||
|
||||
public InterceptorLinearLayout(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public InterceptorLinearLayout(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
ViewConfiguration vc = ViewConfiguration.get(context);
|
||||
mTouchSlop = vc.getScaledTouchSlop();
|
||||
}
|
||||
|
||||
public InterceptorLinearLayout(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
ViewConfiguration vc = ViewConfiguration.get(context);
|
||||
mTouchSlop = vc.getScaledTouchSlop();
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
||||
public InterceptorLinearLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
||||
super(context, attrs, defStyleAttr, defStyleRes);
|
||||
ViewConfiguration vc = ViewConfiguration.get(context);
|
||||
mTouchSlop = vc.getScaledTouchSlop();
|
||||
}
|
||||
|
||||
public int getTouchSlop() {
|
||||
return mTouchSlop;
|
||||
}
|
||||
|
||||
public boolean isScrolling() {
|
||||
return mIsScrolling;
|
||||
}
|
||||
|
||||
public void setListener(OnTouchListener listener) {
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onInterceptTouchEvent(MotionEvent ev) {
|
||||
boolean handled = false;
|
||||
final int action = ev.getAction();
|
||||
|
||||
if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) {
|
||||
mIsScrolling = false;
|
||||
handled = false;
|
||||
} else {
|
||||
switch (action) {
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
mIsScrolling = false;
|
||||
mDownY = ev.getRawY();
|
||||
handled = false;
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
if (mIsScrolling) {
|
||||
handled = true;
|
||||
} else {
|
||||
final int yDiff = calculateDistanceY(ev);
|
||||
if (Math.abs(yDiff) > mTouchSlop) {
|
||||
mIsScrolling = true;
|
||||
handled = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (listener != null) {
|
||||
listener.onTouch(this, ev);
|
||||
}
|
||||
return handled;
|
||||
}
|
||||
|
||||
private int calculateDistanceY(MotionEvent ev) {
|
||||
return (int) (ev.getRawY() - mDownY);
|
||||
}
|
||||
}
|
|
@ -37,6 +37,7 @@ import net.osmand.data.LatLon;
|
|||
import net.osmand.data.PointDescription;
|
||||
import net.osmand.data.QuadPoint;
|
||||
import net.osmand.data.RotatedTileBox;
|
||||
import net.osmand.plus.LockableScrollView;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.OsmandSettings;
|
||||
import net.osmand.plus.R;
|
||||
|
@ -71,8 +72,10 @@ public class MapContextMenuFragment extends BaseOsmAndFragment implements Downlo
|
|||
public static final float SKIP_HALF_SCREEN_STATE_KOEF = .21f;
|
||||
public static final int ZOOM_IN_STANDARD = 17;
|
||||
|
||||
public static final int CURRENT_Y_UNDEFINED = Integer.MAX_VALUE;
|
||||
|
||||
private View view;
|
||||
private View mainView;
|
||||
private InterceptorLinearLayout mainView;
|
||||
private View zoomButtonsView;
|
||||
private ImageButton zoomInButtonView;
|
||||
private ImageButton zoomOutButtonView;
|
||||
|
@ -246,6 +249,7 @@ public class MapContextMenuFragment extends BaseOsmAndFragment implements Downlo
|
|||
final View.OnTouchListener slideTouchListener = new View.OnTouchListener() {
|
||||
private float dy;
|
||||
private float dyMain;
|
||||
private float mDownY;
|
||||
private VelocityTracker velocity;
|
||||
private boolean slidingUp;
|
||||
private boolean slidingDown;
|
||||
|
@ -257,6 +261,7 @@ public class MapContextMenuFragment extends BaseOsmAndFragment implements Downlo
|
|||
@Override
|
||||
public boolean onTouch(View v, MotionEvent event) {
|
||||
|
||||
if (event.getY() <= menuTopViewHeight) {
|
||||
if (singleTapDetector.onTouchEvent(event)) {
|
||||
moving = false;
|
||||
if (hasMoved) {
|
||||
|
@ -272,20 +277,24 @@ public class MapContextMenuFragment extends BaseOsmAndFragment implements Downlo
|
|||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
switch (event.getAction()) {
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
hasMoved = false;
|
||||
mDownY = event.getRawY();
|
||||
dy = event.getY();
|
||||
dyMain = getViewY();
|
||||
velocity = VelocityTracker.obtain();
|
||||
velocityY = 0;
|
||||
maxVelocityY = 0;
|
||||
velocity.addMovement(event);
|
||||
moving = true;
|
||||
break;
|
||||
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
if (Math.abs(event.getRawY() - mDownY) > mainView.getTouchSlop()) {
|
||||
moving = true;
|
||||
}
|
||||
if (moving) {
|
||||
hasMoved = true;
|
||||
float y = event.getY();
|
||||
|
@ -328,20 +337,12 @@ public class MapContextMenuFragment extends BaseOsmAndFragment implements Downlo
|
|||
}
|
||||
};
|
||||
|
||||
View topView = view.findViewById(R.id.context_menu_top_view);
|
||||
topView.setOnTouchListener(slideTouchListener);
|
||||
View topShadowAllView = view.findViewById(R.id.context_menu_top_shadow_all);
|
||||
AndroidUtils.setBackground(getMapActivity(), topShadowAllView, nightMode, R.drawable.bg_map_context_menu_light,
|
||||
R.drawable.bg_map_context_menu_dark);
|
||||
topShadowAllView.setOnTouchListener(new View.OnTouchListener() {
|
||||
@Override
|
||||
public boolean onTouch(View v, MotionEvent event) {
|
||||
if (event.getY() <= dpToPx(SHADOW_HEIGHT_TOP_DP) || event.getAction() != MotionEvent.ACTION_DOWN)
|
||||
return slideTouchListener.onTouch(v, event);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
((InterceptorLinearLayout) mainView).setListener(slideTouchListener);
|
||||
mainView.setOnTouchListener(slideTouchListener);
|
||||
|
||||
buildHeader();
|
||||
|
||||
|
@ -507,7 +508,9 @@ public class MapContextMenuFragment extends BaseOsmAndFragment implements Downlo
|
|||
|
||||
buildBottomView();
|
||||
|
||||
view.findViewById(R.id.context_menu_bottom_scroll).setBackgroundColor(getResources()
|
||||
LockableScrollView bottomScrollView = (LockableScrollView) view.findViewById(R.id.context_menu_bottom_scroll);
|
||||
bottomScrollView.setScrollingEnabled(false);
|
||||
bottomScrollView.setBackgroundColor(getResources()
|
||||
.getColor(nightMode ? R.color.ctx_menu_bottom_view_bg_dark : R.color.ctx_menu_bottom_view_bg_light));
|
||||
view.findViewById(R.id.context_menu_bottom_view).setBackgroundColor(getResources()
|
||||
.getColor(nightMode ? R.color.ctx_menu_bottom_view_bg_dark : R.color.ctx_menu_bottom_view_bg_light));
|
||||
|
@ -659,7 +662,7 @@ public class MapContextMenuFragment extends BaseOsmAndFragment implements Downlo
|
|||
|
||||
private void applyPosY(final int currentY, final boolean needCloseMenu, boolean needMapAdjust,
|
||||
final int previousMenuState, final int newMenuState, int dZoom) {
|
||||
final int posY = getPosY(needCloseMenu);
|
||||
final int posY = getPosY(currentY, needCloseMenu);
|
||||
if (currentY != posY || dZoom != 0) {
|
||||
if (posY < currentY) {
|
||||
updateMainViewLayout(posY);
|
||||
|
@ -897,12 +900,6 @@ public class MapContextMenuFragment extends BaseOsmAndFragment implements Downlo
|
|||
if (view != null) {
|
||||
View bottomView = view.findViewById(R.id.context_menu_bottom_view);
|
||||
if (menu.isExtended()) {
|
||||
bottomView.setOnTouchListener(new View.OnTouchListener() {
|
||||
@Override
|
||||
public boolean onTouch(View v, MotionEvent event) {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
menu.build(bottomView);
|
||||
}
|
||||
}
|
||||
|
@ -1244,10 +1241,10 @@ public class MapContextMenuFragment extends BaseOsmAndFragment implements Downlo
|
|||
}
|
||||
|
||||
private int getPosY() {
|
||||
return getPosY(false);
|
||||
return getPosY(CURRENT_Y_UNDEFINED, false);
|
||||
}
|
||||
|
||||
private int getPosY(boolean needCloseMenu) {
|
||||
private int getPosY(final int currentY, boolean needCloseMenu) {
|
||||
if (needCloseMenu) {
|
||||
return screenHeight;
|
||||
}
|
||||
|
@ -1272,8 +1269,23 @@ public class MapContextMenuFragment extends BaseOsmAndFragment implements Downlo
|
|||
posY = Math.max(posY, minHalfY);
|
||||
break;
|
||||
case MenuState.FULL_SCREEN:
|
||||
if (currentY != CURRENT_Y_UNDEFINED) {
|
||||
int maxPosY = viewHeight - menuFullHeightMax;
|
||||
int minPosY = Math.max(maxPosY, minHalfY);
|
||||
if (maxPosY > minPosY) {
|
||||
maxPosY = minPosY;
|
||||
}
|
||||
if (currentY > minPosY) {
|
||||
posY = minPosY;
|
||||
} else if (currentY < maxPosY) {
|
||||
posY = maxPosY;
|
||||
} else {
|
||||
posY = currentY;
|
||||
}
|
||||
} else {
|
||||
posY = -dpToPx(SHADOW_HEIGHT_TOP_DP);
|
||||
posY = addStatusBarHeightIfNeeded(posY);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
Loading…
Reference in a new issue