Context menu layout fixes

This commit is contained in:
Alexey Kulish 2015-09-11 19:13:40 +03:00
parent b2df586347
commit 0bfc9c1c2a
4 changed files with 110 additions and 108 deletions

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout <FrameLayout
android:id="@+id/context_menu_layout" android:id="@+id/context_menu_layout"
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_width="fill_parent"
@ -10,15 +10,14 @@
<LinearLayout <LinearLayout
android:id="@+id/context_menu_shadow_view" android:id="@+id/context_menu_shadow_view"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="0dp" android:layout_height="fill_parent"
android:layout_weight="0" android:gravity="center"
android:orientation="vertical"/> android:orientation="vertical"/>
<LinearLayout <LinearLayout
android:id="@+id/context_menu_main" android:id="@+id/context_menu_main"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:layout_height="fill_parent"
android:layout_gravity="bottom"
android:orientation="vertical"> android:orientation="vertical">
<LinearLayout <LinearLayout
@ -182,24 +181,25 @@
</LinearLayout> </LinearLayout>
<LinearLayout <ScrollView
android:id="@+id/context_menu_bottom_view" android:id="@+id/context_menu_bottom_scroll"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:layout_height="fill_parent"
android:background="?attr/ctx_menu_info_view_bg" android:background="?attr/ctx_menu_info_view_bg"
android:orientation="vertical"> android:fillViewport="true">
</LinearLayout> <LinearLayout
android:id="@+id/context_menu_bottom_view"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
</LinearLayout>
</ScrollView>
</LinearLayout> </LinearLayout>
<LinearLayout
android:id="@+id/context_menu_bottom_border"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:background="?attr/ctx_menu_info_view_bg"
android:orientation="vertical">
</LinearLayout>
</LinearLayout> </FrameLayout>

View file

@ -1,12 +1,12 @@
package net.osmand.plus.mapcontextmenu; package net.osmand.plus.mapcontextmenu;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.annotation.TargetApi; import android.annotation.TargetApi;
import android.app.Activity; import android.app.Activity;
import android.content.res.Resources; import android.content.res.Resources;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.support.v4.app.Fragment; import android.support.v4.app.Fragment;
import android.util.DisplayMetrics; import android.util.DisplayMetrics;
import android.util.TypedValue; import android.util.TypedValue;
@ -45,15 +45,17 @@ public class MapContextMenuFragment extends Fragment {
private View mainView; private View mainView;
private View bottomView; private View bottomView;
private View shadowView; private View shadowView;
private View bottomBorder;
MenuController menuController; MenuController menuController;
private int menuTopHeight; private int menuTopHeight;
private int menuTopShadowHeight; private int menuTopShadowHeight;
private int menuTopShadowAllHeight;
private int menuTitleHeight;
private int menuButtonsHeight; private int menuButtonsHeight;
private int menuBottomViewHeight; private int menuBottomViewHeight;
private int menuFullHeight; private int menuFullHeight;
private int menuFullHeightMax;
@Override @Override
public void onAttach(Activity activity) { public void onAttach(Activity activity) {
@ -113,10 +115,13 @@ public class MapContextMenuFragment extends Fragment {
menuTopHeight = view.findViewById(R.id.context_menu_top_view).getHeight(); menuTopHeight = view.findViewById(R.id.context_menu_top_view).getHeight();
menuTopShadowHeight = view.findViewById(R.id.context_menu_top_shadow).getHeight(); menuTopShadowHeight = view.findViewById(R.id.context_menu_top_shadow).getHeight();
menuTopShadowAllHeight = view.findViewById(R.id.context_menu_top_shadow_all).getHeight();
menuButtonsHeight = view.findViewById(R.id.context_menu_buttons).getHeight(); menuButtonsHeight = view.findViewById(R.id.context_menu_buttons).getHeight();
menuBottomViewHeight = view.findViewById(R.id.context_menu_bottom_view).getHeight();
menuFullHeight = view.findViewById(R.id.context_menu_main).getHeight(); menuFullHeight = view.findViewById(R.id.context_menu_main).getHeight();
menuTitleHeight = menuTopShadowHeight + menuTopShadowAllHeight;
menuFullHeightMax = menuTitleHeight + menuBottomViewHeight + dpToPx(2f);
ViewTreeObserver obs = view.getViewTreeObserver(); ViewTreeObserver obs = view.getViewTreeObserver();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
@ -130,14 +135,6 @@ public class MapContextMenuFragment extends Fragment {
}); });
bottomBorder = view.findViewById(R.id.context_menu_bottom_border);
bottomBorder.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
return true;
}
});
shadowView = view.findViewById(R.id.context_menu_shadow_view); shadowView = view.findViewById(R.id.context_menu_shadow_view);
shadowView.setOnTouchListener(new View.OnTouchListener() { shadowView.setOnTouchListener(new View.OnTouchListener() {
public boolean onTouch(View view, MotionEvent event) { public boolean onTouch(View view, MotionEvent event) {
@ -151,12 +148,13 @@ public class MapContextMenuFragment extends Fragment {
final View.OnTouchListener slideTouchListener = new View.OnTouchListener() { final View.OnTouchListener slideTouchListener = new View.OnTouchListener() {
private float dy; private float dy;
private float dyMain; private float dyMain;
private int destinationState;
private VelocityTracker velocity; private VelocityTracker velocity;
private boolean slidingUp; private boolean slidingUp;
private boolean slidingDown; private boolean slidingDown;
private float velocityX;
private float velocityY; private float velocityY;
private float maxVelocityY;
private float startX; private float startX;
private float startY; private float startY;
@ -166,7 +164,11 @@ public class MapContextMenuFragment extends Fragment {
private boolean isClick(float endX, float endY) { private boolean isClick(float endX, float endY) {
float differenceX = Math.abs(startX - endX); float differenceX = Math.abs(startX - endX);
float differenceY = Math.abs(startY - endY); float differenceY = Math.abs(startY - endY);
if (differenceX > 1 || differenceY > 1 || System.currentTimeMillis() - lastTouchDown > CLICK_ACTION_THRESHHOLD) { if (differenceX > 1 ||
differenceY > 1 ||
Math.abs(velocityX) > 10 ||
Math.abs(velocityY) > 10 ||
System.currentTimeMillis() - lastTouchDown > CLICK_ACTION_THRESHHOLD) {
return false; return false;
} }
return true; return true;
@ -184,26 +186,29 @@ public class MapContextMenuFragment extends Fragment {
dy = event.getY(); dy = event.getY();
dyMain = mainView.getY(); dyMain = mainView.getY();
velocity = VelocityTracker.obtain(); velocity = VelocityTracker.obtain();
velocityX = 0;
velocityY = 0; velocityY = 0;
maxVelocityY = 0;
velocity.addMovement(event); velocity.addMovement(event);
break; break;
case MotionEvent.ACTION_MOVE: case MotionEvent.ACTION_MOVE:
float y = event.getY(); float y = event.getY();
float newY = mainView.getY() + (y - dy); float newY = mainView.getY() + (y - dy);
mainView.setY(newY); mainView.setY((int)newY);
ViewGroup.LayoutParams lp = bottomBorder.getLayoutParams(); menuFullHeight = view.getHeight() - (int) newY + 10;
lp.height = (int)(view.getHeight() - newY - menuFullHeight) + 10; ViewGroup.LayoutParams lp = mainView.getLayoutParams();
bottomBorder.setLayoutParams(lp); lp.height = Math.max(menuFullHeight, menuTitleHeight);
bottomBorder.setY(newY + menuFullHeight); mainView.setLayoutParams(lp);
bottomBorder.requestLayout(); mainView.requestLayout();
velocity.addMovement(event); velocity.addMovement(event);
velocity.computeCurrentVelocity(1000); velocity.computeCurrentVelocity(1000);
float vel = Math.abs(velocity.getYVelocity()); velocityX = Math.abs(velocity.getXVelocity());
if (vel > velocityY) velocityY = Math.abs(velocity.getYVelocity());
velocityY = vel; if (velocityY > maxVelocityY)
maxVelocityY = velocityY;
break; break;
@ -212,8 +217,8 @@ public class MapContextMenuFragment extends Fragment {
float endX = event.getX(); float endX = event.getX();
float endY = event.getY(); float endY = event.getY();
slidingUp = Math.abs(velocityY) > 500 && (mainView.getY() - dyMain) < -50; slidingUp = Math.abs(maxVelocityY) > 500 && (mainView.getY() - dyMain) < -50;
slidingDown = Math.abs(velocityY) > 500 && (mainView.getY() - dyMain) > 50; slidingDown = Math.abs(maxVelocityY) > 500 && (mainView.getY() - dyMain) > 50;
velocity.recycle(); velocity.recycle();
@ -223,37 +228,31 @@ public class MapContextMenuFragment extends Fragment {
} else if (slidingDown) { } else if (slidingDown) {
menuController.slideDown(); menuController.slideDown();
} }
destinationState = menuController.getCurrentMenuState();
} else {
destinationState = MenuController.MenuState.HEADER_ONLY;
} }
float posY = 0; final int posY = getPosY();
switch (destinationState) {
case MenuController.MenuState.HEADER_ONLY:
posY = view.getHeight() - (menuFullHeight - menuBottomViewHeight - dpToPx(SHADOW_HEIGHT_BOTTOM_DP));
break;
case MenuController.MenuState.HALF_SCREEN:
posY = view.getHeight() - menuFullHeight;
break;
case MenuController.MenuState.FULL_SCREEN:
posY = -menuTopShadowHeight - dpToPx(SHADOW_HEIGHT_TOP_DP);
break;
default:
break;
}
float minY = Math.min(posY, mainView.getY());
lp = bottomBorder.getLayoutParams();
lp.height = (int)(view.getHeight() - minY - menuFullHeight) + 10;
if (lp.height < 0)
lp.height = 0;
bottomBorder.setLayoutParams(lp);
bottomBorder.requestLayout();
if (mainView.getY() != posY) { if (mainView.getY() != posY) {
mainView.animate().y(posY).setDuration(200).setInterpolator(new DecelerateInterpolator()).start();
bottomBorder.animate().y(posY + menuFullHeight).setDuration(200).setInterpolator(new DecelerateInterpolator()).start(); if (posY < mainView.getY()) {
updateMainViewLayout(posY);
}
mainView.animate().y(posY)
.setDuration(200)
.setInterpolator(new DecelerateInterpolator())
.setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationCancel(Animator animation) {
updateMainViewLayout(posY);
}
@Override
public void onAnimationEnd(Animator animation) {
updateMainViewLayout(posY);
}
})
.start();
} }
// OnClick event // OnClick event
@ -323,7 +322,7 @@ public class MapContextMenuFragment extends Fragment {
// Action buttons // Action buttons
final ImageButton buttonNavigate = (ImageButton) view.findViewById(R.id.context_menu_route_button); final ImageButton buttonNavigate = (ImageButton) view.findViewById(R.id.context_menu_route_button);
buttonNavigate.setImageDrawable(iconsCache.getIcon(R.drawable.map_directions, buttonNavigate.setImageDrawable(iconsCache.getIcon(R.drawable.map_directions,
light ? R.color.icon_color : R.color.dash_search_icon_dark)); light ? R.color.icon_color : R.color.dashboard_subheader_text_dark));
buttonNavigate.setOnClickListener(new View.OnClickListener() { buttonNavigate.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
@ -333,7 +332,7 @@ public class MapContextMenuFragment extends Fragment {
final ImageButton buttonFavorite = (ImageButton) view.findViewById(R.id.context_menu_fav_button); final ImageButton buttonFavorite = (ImageButton) view.findViewById(R.id.context_menu_fav_button);
buttonFavorite.setImageDrawable(iconsCache.getIcon(R.drawable.ic_action_fav_dark, buttonFavorite.setImageDrawable(iconsCache.getIcon(R.drawable.ic_action_fav_dark,
light ? R.color.icon_color : R.color.dash_search_icon_dark)); light ? R.color.icon_color : R.color.dashboard_subheader_text_dark));
buttonFavorite.setOnClickListener(new View.OnClickListener() { buttonFavorite.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
@ -343,7 +342,7 @@ public class MapContextMenuFragment extends Fragment {
final ImageButton buttonShare = (ImageButton) view.findViewById(R.id.context_menu_share_button); final ImageButton buttonShare = (ImageButton) view.findViewById(R.id.context_menu_share_button);
buttonShare.setImageDrawable(iconsCache.getIcon(R.drawable.abc_ic_menu_share_mtrl_alpha, buttonShare.setImageDrawable(iconsCache.getIcon(R.drawable.abc_ic_menu_share_mtrl_alpha,
light ? R.color.icon_color : R.color.dash_search_icon_dark)); light ? R.color.icon_color : R.color.dashboard_subheader_text_dark));
buttonShare.setOnClickListener(new View.OnClickListener() { buttonShare.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
@ -353,7 +352,7 @@ public class MapContextMenuFragment extends Fragment {
final ImageButton buttonMore = (ImageButton) view.findViewById(R.id.context_menu_more_button); final ImageButton buttonMore = (ImageButton) view.findViewById(R.id.context_menu_more_button);
buttonMore.setImageDrawable(iconsCache.getIcon(R.drawable.ic_overflow_menu_white, buttonMore.setImageDrawable(iconsCache.getIcon(R.drawable.ic_overflow_menu_white,
light ? R.color.icon_color : R.color.dash_search_icon_dark)); light ? R.color.icon_color : R.color.dashboard_subheader_text_dark));
buttonMore.setOnClickListener(new View.OnClickListener() { buttonMore.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
@ -374,56 +373,54 @@ public class MapContextMenuFragment extends Fragment {
menuController.build(bottomView); menuController.build(bottomView);
} }
bottomView.measure(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
menuBottomViewHeight = bottomView.getMeasuredHeight();
return view; return view;
} }
private void doLayoutMenu() { private int getPosY() {
int shadowViewHeight = 0; int destinationState;
int bottomBorderHeight = 0; int minHalfY;
if (menuController != null) {
destinationState = menuController.getCurrentMenuState();
minHalfY = view.getHeight() - (int)(view.getHeight() * menuController.getHalfScreenMaxHeightKoef());
} else {
destinationState = MenuController.MenuState.HEADER_ONLY;
minHalfY = view.getHeight();
}
int menuState; int posY = 0;
if (menuController != null) switch (destinationState) {
menuState = menuController.getCurrentMenuState();
else
menuState = MenuController.MenuState.HEADER_ONLY;
switch (menuState) {
case MenuController.MenuState.HEADER_ONLY: case MenuController.MenuState.HEADER_ONLY:
shadowViewHeight = view.getHeight() - (menuFullHeight - menuBottomViewHeight) + dpToPx(SHADOW_HEIGHT_BOTTOM_DP); posY = view.getHeight() - (menuTitleHeight - dpToPx(SHADOW_HEIGHT_BOTTOM_DP));
bottomBorderHeight = 0;
break; break;
case MenuController.MenuState.HALF_SCREEN: case MenuController.MenuState.HALF_SCREEN:
int maxHeight = (int)(menuController.getHalfScreenMaxHeightKoef() * view.getHeight()); posY = view.getHeight() - menuFullHeightMax;
if (maxHeight > menuFullHeight) { posY = Math.max(posY, minHalfY);
shadowViewHeight = view.getHeight() - menuFullHeight;
bottomBorderHeight = 0;
} else {
shadowViewHeight = view.getHeight() - maxHeight;
bottomBorderHeight = 0;
mainView.setY(shadowViewHeight);
}
break; break;
case MenuController.MenuState.FULL_SCREEN: case MenuController.MenuState.FULL_SCREEN:
shadowViewHeight = 0; posY = -menuTopShadowHeight - dpToPx(SHADOW_HEIGHT_TOP_DP);
bottomBorderHeight = view.getHeight() - menuFullHeight + menuTopShadowHeight + dpToPx(SHADOW_HEIGHT_TOP_DP);
break; break;
default: default:
break; break;
} }
return posY;
}
ViewGroup.LayoutParams lp = bottomBorder.getLayoutParams(); private void updateMainViewLayout(int posY) {
lp.height = bottomBorderHeight + 10; ViewGroup.LayoutParams lp;
bottomBorder.setLayoutParams(lp); menuFullHeight = view.getHeight() - posY;
bottomBorder.setY(view.getHeight() - bottomBorderHeight);
lp = shadowView.getLayoutParams();
lp.height = shadowViewHeight;
shadowView.setLayoutParams(lp);
lp = mainView.getLayoutParams(); lp = mainView.getLayoutParams();
lp.height = menuFullHeight; lp.height = Math.max(menuFullHeight, menuTitleHeight);
mainView.setLayoutParams(lp); mainView.setLayoutParams(lp);
mainView.requestLayout();
}
private void doLayoutMenu() {
final int posY = getPosY();
mainView.setY(posY);
updateMainViewLayout(posY);
} }
public void dismissMenu() { public void dismissMenu() {

View file

@ -9,6 +9,11 @@ public class AmenityInfoMenuController extends MenuController {
super(new AmenityInfoMenuBuilder(app, amenity)); super(new AmenityInfoMenuBuilder(app, amenity));
} }
@Override
public int getInitialMenuState() {
return MenuState.HALF_SCREEN;
}
@Override @Override
public int getSupportedMenuStates() { public int getSupportedMenuStates() {
return MenuState.HEADER_ONLY | MenuState.HALF_SCREEN | MenuState.FULL_SCREEN; return MenuState.HEADER_ONLY | MenuState.HALF_SCREEN | MenuState.FULL_SCREEN;

View file

@ -63,7 +63,7 @@ public abstract class MenuController {
} }
public float getHalfScreenMaxHeightKoef() { public float getHalfScreenMaxHeightKoef() {
return .6f; return .7f;
} }
public boolean shouldShowButtons() { public boolean shouldShowButtons() {