Added fling to context menu

This commit is contained in:
Alexey Kulish 2018-02-03 10:34:10 +03:00
parent e595400e34
commit f42acc168c
4 changed files with 67 additions and 25 deletions

View file

@ -91,7 +91,7 @@
android:layout_height= "wrap_content" android:layout_height= "wrap_content"
android:layout_marginBottom="@dimen/context_menu_direction_margin" android:layout_marginBottom="@dimen/context_menu_direction_margin"
android:layout_marginTop="@dimen/context_menu_padding_margin_tiny" android:layout_marginTop="@dimen/context_menu_padding_margin_tiny"
android:gravity="center_vertical" android:gravity="top"
android:orientation="horizontal" android:orientation="horizontal"
android:paddingTop="3dp" android:paddingTop="3dp"
android:paddingBottom="3dp" android:paddingBottom="3dp"
@ -615,7 +615,7 @@
android:layout_height="@dimen/dashboard_map_toolbar" android:layout_height="@dimen/dashboard_map_toolbar"
android:layout_marginLeft="4dp" android:layout_marginLeft="4dp"
android:layout_marginStart="4dp" android:layout_marginStart="4dp"
android:alpha="1"> android:alpha="0">
<LinearLayout <LinearLayout
android:layout_width="@dimen/list_item_height" android:layout_width="@dimen/list_item_height"

View file

@ -36,7 +36,7 @@ public class LockableScrollView extends ScrollView {
return super.onTouchEvent(ev); return super.onTouchEvent(ev);
} }
// only continue to handle the touch event if scrolling enabled // only continue to handle the touch event if scrolling enabled
return mScrollable; return false;
default: default:
return super.onTouchEvent(ev); return super.onTouchEvent(ev);
} }

View file

@ -20,6 +20,7 @@ import android.view.MotionEvent;
import android.view.VelocityTracker; import android.view.VelocityTracker;
import android.view.View; import android.view.View;
import android.view.View.OnLayoutChangeListener; import android.view.View.OnLayoutChangeListener;
import android.view.ViewConfiguration;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.ViewParent; import android.view.ViewParent;
import android.view.ViewTreeObserver; import android.view.ViewTreeObserver;
@ -29,6 +30,7 @@ import android.widget.GridView;
import android.widget.ImageButton; import android.widget.ImageButton;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.OverScroller;
import android.widget.ProgressBar; import android.widget.ProgressBar;
import android.widget.TextView; import android.widget.TextView;
@ -82,6 +84,7 @@ public class MapContextMenuFragment extends BaseOsmAndFragment implements Downlo
private View toolbarBackButton; private View toolbarBackButton;
private TextView toolbarTextView; private TextView toolbarTextView;
private View topButtonContainer; private View topButtonContainer;
private LockableScrollView menuScrollView;
private View zoomButtonsView; private View zoomButtonsView;
private ImageButton zoomInButtonView; private ImageButton zoomInButtonView;
@ -292,13 +295,24 @@ public class MapContextMenuFragment extends BaseOsmAndFragment implements Downlo
private float dy; private float dy;
private float dyMain; private float dyMain;
private float mDownY; private float mDownY;
private int minimumVelocity;
private int maximumVelocity;
private VelocityTracker velocityTracker; private VelocityTracker velocityTracker;
private OverScroller scroller;
private boolean slidingUp; private boolean slidingUp;
private boolean slidingDown; private boolean slidingDown;
private float maxVelocityY;
private boolean hasMoved; private boolean hasMoved;
{
scroller = new OverScroller(getContext());
final ViewConfiguration configuration = ViewConfiguration.get(getContext());
minimumVelocity = configuration.getScaledMinimumFlingVelocity();
maximumVelocity = configuration.getScaledMaximumFlingVelocity();
}
@Override @Override
public boolean onTouch(View v, MotionEvent event) { public boolean onTouch(View v, MotionEvent event) {
@ -330,7 +344,6 @@ public class MapContextMenuFragment extends BaseOsmAndFragment implements Downlo
dy = event.getY(); dy = event.getY();
dyMain = getViewY(); dyMain = getViewY();
maxVelocityY = 0;
initOrResetVelocityTracker(); initOrResetVelocityTracker();
velocityTracker.addMovement(event); velocityTracker.addMovement(event);
break; break;
@ -354,14 +367,12 @@ public class MapContextMenuFragment extends BaseOsmAndFragment implements Downlo
mainView.setLayoutParams(lp); mainView.setLayoutParams(lp);
mainView.requestLayout(); mainView.requestLayout();
if (velocityTracker != null) { float newEventY = newY - (dyMain - dy);
velocityTracker.addMovement(event); MotionEvent ev = MotionEvent.obtain(event.getDownTime(), event.getEventTime(), event.getAction(),
velocityTracker.computeCurrentVelocity(1000); event.getX(), newEventY, event.getMetaState());
float velocityY = Math.abs(velocityTracker.getYVelocity());
if (velocityY > maxVelocityY) { initVelocityTrackerIfNotExists();
maxVelocityY = velocityY; velocityTracker.addMovement(ev);
}
}
updateToolbar(); updateToolbar();
updateTopButton(); updateTopButton();
@ -374,10 +385,28 @@ public class MapContextMenuFragment extends BaseOsmAndFragment implements Downlo
moving = false; moving = false;
int currentY = getViewY(); int currentY = getViewY();
slidingUp = Math.abs(maxVelocityY) > 500 && (currentY - dyMain) < -50; final VelocityTracker velocityTracker = this.velocityTracker;
slidingDown = Math.abs(maxVelocityY) > 500 && (currentY - dyMain) > 50; velocityTracker.computeCurrentVelocity(1000, maximumVelocity);
int initialVelocity = (int) velocityTracker.getYVelocity();
boolean skipScreenState = Math.abs(currentY - dyMain) > skipScreenStateLimit; if ((Math.abs(initialVelocity) > minimumVelocity)) {
scroller.abortAnimation();
scroller.fling(0, currentY, 0, initialVelocity, 0, 0,
viewHeight - menuFullHeightMax,
minHalfY,
0, 0);
currentY = scroller.getFinalY();
scroller.abortAnimation();
slidingUp = initialVelocity < -2000;
slidingDown = initialVelocity > 2000;
} else {
slidingUp = false;
slidingDown = false;
}
boolean skipScreenState = Math.abs(getViewY() - dyMain) > skipScreenStateLimit;
changeMenuState(currentY, skipScreenState, slidingUp, slidingDown); changeMenuState(currentY, skipScreenState, slidingUp, slidingDown);
} }
recycleVelocityTracker(); recycleVelocityTracker();
@ -399,6 +428,13 @@ public class MapContextMenuFragment extends BaseOsmAndFragment implements Downlo
} }
} }
private void initVelocityTrackerIfNotExists() {
if (velocityTracker == null) {
velocityTracker = VelocityTracker.obtain();
velocityTracker.clear();
}
}
private void recycleVelocityTracker() { private void recycleVelocityTracker() {
if (velocityTracker != null) { if (velocityTracker != null) {
velocityTracker.recycle(); velocityTracker.recycle();
@ -732,8 +768,7 @@ public class MapContextMenuFragment extends BaseOsmAndFragment implements Downlo
int oldMenuState = menu.getCurrentMenuState(); int oldMenuState = menu.getCurrentMenuState();
if (!menu.isLandscapeLayout()) { if (!menu.isLandscapeLayout()) {
if (slidingDown && !skipScreenState && oldMenuState == MenuState.FULL_SCREEN if (slidingDown && oldMenuState == MenuState.FULL_SCREEN && getViewY() < getFullScreenTopPosY()) {
&& currentY < (-menuTitleHeight + menuButtonsHeight)) {
slidingDown = false; slidingDown = false;
} }
if (menuBottomViewHeight > 0 && slidingUp) { if (menuBottomViewHeight > 0 && slidingUp) {
@ -798,9 +833,9 @@ public class MapContextMenuFragment extends BaseOsmAndFragment implements Downlo
private void applyPosY(final int currentY, final boolean needCloseMenu, boolean needMapAdjust, private void applyPosY(final int currentY, final boolean needCloseMenu, boolean needMapAdjust,
final int previousMenuState, final int newMenuState, int dZoom) { final int previousMenuState, final int newMenuState, int dZoom) {
final int posY = getPosY(currentY, needCloseMenu); final int posY = getPosY(currentY, needCloseMenu, previousMenuState);
if (currentY != posY || dZoom != 0) { if (getViewY() != posY || dZoom != 0) {
if (posY < currentY) { if (posY < getViewY()) {
updateMainViewLayout(posY); updateMainViewLayout(posY);
} }
@ -1428,12 +1463,19 @@ public class MapContextMenuFragment extends BaseOsmAndFragment implements Downlo
return viewHeight - menuTitleHeight; return viewHeight - menuTitleHeight;
} }
private int getFullScreenTopPosY() {
return -menuTitleHeight + menuButtonsHeight + bottomToolbarPosY;
}
private int getPosY() { private int getPosY() {
return getPosY(CURRENT_Y_UNDEFINED, false); return getPosY(CURRENT_Y_UNDEFINED, false);
} }
private int getPosY(final int currentY, boolean needCloseMenu) { private int getPosY(final int currentY, boolean needCloseMenu) {
return getPosY(currentY, needCloseMenu, 0);
}
private int getPosY(final int currentY, boolean needCloseMenu, int previousState) {
if (needCloseMenu) { if (needCloseMenu) {
return screenHeight; return screenHeight;
} }
@ -1462,12 +1504,12 @@ public class MapContextMenuFragment extends BaseOsmAndFragment implements Downlo
if (menu.isLandscapeLayout()) { if (menu.isLandscapeLayout()) {
minPosY = topScreenPosY; minPosY = topScreenPosY;
} else { } else {
minPosY = -menuTitleHeight + menuButtonsHeight + bottomToolbarPosY; minPosY = getFullScreenTopPosY();
} }
if (maxPosY > minPosY) { if (maxPosY > minPosY) {
maxPosY = minPosY; maxPosY = minPosY;
} }
if (currentY > minPosY) { if (currentY > minPosY || previousState != MenuState.FULL_SCREEN) {
posY = minPosY; posY = minPosY;
} else if (currentY < maxPosY) { } else if (currentY < maxPosY) {
posY = maxPosY; posY = maxPosY;
@ -1478,7 +1520,7 @@ public class MapContextMenuFragment extends BaseOsmAndFragment implements Downlo
if (menu.isLandscapeLayout()) { if (menu.isLandscapeLayout()) {
posY = topScreenPosY; posY = topScreenPosY;
} else { } else {
posY = -menuTitleHeight + menuButtonsHeight + bottomToolbarPosY; posY = getFullScreenTopPosY();
} }
} }
break; break;

View file

@ -162,7 +162,7 @@ public abstract class MenuController extends BaseMenuController implements Colla
@Override @Override
public void onCollapseExpand(boolean collapsed) { public void onCollapseExpand(boolean collapsed) {
if (mapContextMenu != null) { if (mapContextMenu != null) {
mapContextMenu.updateMenuUI(); mapContextMenu.updateLayout();
} }
} }