forked from organicmaps/organicmaps
Merge pull request #4810 from goblinr/MAPSME-86-ext-screen-transition-animations
[android] Transition animations
This commit is contained in:
commit
a2c5ebe00a
15 changed files with 639 additions and 270 deletions
|
@ -22,21 +22,25 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
<android.support.design.widget.TabLayout
|
||||
android:id="@+id/tabs"
|
||||
android:theme="@style/ThemeOverlay.AppCompat"
|
||||
<LinearLayout
|
||||
android:id="@+id/tabs_layout"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/tabs_height"
|
||||
android:elevation="@dimen/appbar_elevation"
|
||||
app:tabIndicatorColor="?colorAccent"
|
||||
app:tabMode="fixed"
|
||||
app:tabGravity="fill"/>
|
||||
android:layout_height="wrap_content">
|
||||
<android.support.design.widget.TabLayout
|
||||
android:id="@+id/tabs"
|
||||
android:theme="@style/ThemeOverlay.AppCompat"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/tabs_height"
|
||||
app:tabIndicatorColor="?colorAccent"
|
||||
app:tabMode="fixed"
|
||||
app:tabGravity="fill"/>
|
||||
|
||||
<View
|
||||
android:id="@+id/tabs_divider"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:background="?dividerHorizontal"/>
|
||||
<FrameLayout
|
||||
style="@style/MwmWidget.FrameLayout.Elevation"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"/>
|
||||
</LinearLayout>
|
||||
|
||||
<android.support.v4.view.ViewPager
|
||||
android:id="@+id/pages"
|
||||
|
|
9
android/res/layout/fragment_search_categories.xml
Normal file
9
android/res/layout/fragment_search_categories.xml
Normal file
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
style="@style/MwmWidget.FrameLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
<include
|
||||
layout="@layout/recycler_default"/>
|
||||
</FrameLayout>
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
style="@style/MwmWidget.FrameLayout.Elevation"
|
||||
style="@style/MwmWidget.FrameLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
<include layout="@layout/recycler_default"/>
|
||||
|
|
|
@ -20,6 +20,7 @@ import android.support.v7.widget.Toolbar;
|
|||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.ImageButton;
|
||||
|
||||
|
@ -105,6 +106,7 @@ public class MwmActivity extends BaseMwmFragmentActivity
|
|||
RoutingController.Container,
|
||||
LocationHelper.UiCallback,
|
||||
RoutingPlanController.OnToggleListener,
|
||||
RoutingPlanController.SearchPoiTransitionListener,
|
||||
FloatingSearchToolbarController.VisibilityListener
|
||||
{
|
||||
public static final String EXTRA_TASK = "map_task";
|
||||
|
@ -148,6 +150,8 @@ public class MwmActivity extends BaseMwmFragmentActivity
|
|||
|
||||
private View mPositionChooser;
|
||||
|
||||
private ViewGroup mRootView;
|
||||
|
||||
private boolean mIsFragmentContainer;
|
||||
private boolean mIsFullscreen;
|
||||
private boolean mIsFullscreenAnimating;
|
||||
|
@ -452,6 +456,7 @@ public class MwmActivity extends BaseMwmFragmentActivity
|
|||
{
|
||||
mRoutingPlanInplaceController = new RoutingPlanInplaceController(this);
|
||||
mRoutingPlanInplaceController.setOnToggleListener(this);
|
||||
mRoutingPlanInplaceController.setPoiTransitionListener(this);
|
||||
removeCurrentFragment(false);
|
||||
}
|
||||
|
||||
|
@ -529,7 +534,9 @@ public class MwmActivity extends BaseMwmFragmentActivity
|
|||
.commit();
|
||||
}
|
||||
|
||||
findViewById(R.id.map_fragment_container).setOnTouchListener(this);
|
||||
View container = findViewById(R.id.map_fragment_container);
|
||||
container.setOnTouchListener(this);
|
||||
mRootView = (ViewGroup) container.getParent();
|
||||
}
|
||||
|
||||
private void initNavigationButtons()
|
||||
|
@ -544,7 +551,8 @@ public class MwmActivity extends BaseMwmFragmentActivity
|
|||
ImageButton traffic = (ImageButton) frame.findViewById(R.id.traffic);
|
||||
mTraffic = new TrafficButton(this, traffic);
|
||||
mTrafficButtonController = new TrafficButtonController(mTraffic, this);
|
||||
mNavAnimationController = new NavigationButtonsAnimationController(zoomIn, zoomOut, myPosition);
|
||||
mNavAnimationController = new NavigationButtonsAnimationController(
|
||||
zoomIn, zoomOut, myPosition, getWindow().getDecorView().getRootView());
|
||||
}
|
||||
|
||||
public boolean closePlacePage()
|
||||
|
@ -1169,9 +1177,6 @@ public class MwmActivity extends BaseMwmFragmentActivity
|
|||
Framework.nativeDeactivatePopup();
|
||||
mPlacePage.setMapObject(null, false);
|
||||
}
|
||||
|
||||
if (mNavAnimationController != null)
|
||||
mNavAnimationController.onPlacePageVisibilityChanged(isVisible);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1355,48 +1360,83 @@ public class MwmActivity extends BaseMwmFragmentActivity
|
|||
@Override
|
||||
public void updateMenu()
|
||||
{
|
||||
adjustMenuLineFrameVisibility();
|
||||
|
||||
if (RoutingController.get().isNavigating())
|
||||
adjustMenuLineFrameVisibility(new Runnable()
|
||||
{
|
||||
if (mNavigationController != null)
|
||||
mNavigationController.show(true);
|
||||
mSearchController.hide();
|
||||
mMainMenu.setState(MainMenu.State.NAVIGATION, false, mIsFullscreen);
|
||||
return;
|
||||
}
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
if (RoutingController.get().isNavigating())
|
||||
{
|
||||
if (mNavigationController != null)
|
||||
mNavigationController.show(true);
|
||||
mSearchController.hide();
|
||||
mMainMenu.setState(MainMenu.State.NAVIGATION, false, mIsFullscreen);
|
||||
return;
|
||||
}
|
||||
|
||||
if (mIsFragmentContainer)
|
||||
{
|
||||
mMainMenu.setEnabled(MainMenu.Item.P2P, !RoutingController.get().isPlanning());
|
||||
mMainMenu.setEnabled(MainMenu.Item.SEARCH, !RoutingController.get().isWaitingPoiPick());
|
||||
}
|
||||
else if (RoutingController.get().isPlanning())
|
||||
{
|
||||
mMainMenu.setState(MainMenu.State.ROUTE_PREPARE, false, mIsFullscreen);
|
||||
return;
|
||||
}
|
||||
if (mIsFragmentContainer)
|
||||
{
|
||||
mMainMenu.setEnabled(MainMenu.Item.P2P, !RoutingController.get().isPlanning());
|
||||
mMainMenu.setEnabled(MainMenu.Item.SEARCH, !RoutingController.get().isWaitingPoiPick());
|
||||
}
|
||||
else if (RoutingController.get().isPlanning())
|
||||
{
|
||||
mMainMenu.setState(MainMenu.State.ROUTE_PREPARE, false, mIsFullscreen);
|
||||
return;
|
||||
}
|
||||
|
||||
mMainMenu.setState(MainMenu.State.MENU, false, mIsFullscreen);
|
||||
mMainMenu.setState(MainMenu.State.MENU, false, mIsFullscreen);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void adjustMenuLineFrameVisibility()
|
||||
private void adjustMenuLineFrameVisibility(@Nullable final Runnable completion)
|
||||
{
|
||||
final RoutingController controller = RoutingController.get();
|
||||
|
||||
if (controller.isBuilt() || controller.isUberRequestHandled())
|
||||
{
|
||||
mMainMenu.showLineFrame(true);
|
||||
mMainMenu.showLineFrame(true, new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
adjustRuler(0, 0);
|
||||
}
|
||||
});
|
||||
|
||||
if (completion != null)
|
||||
completion.run();
|
||||
return;
|
||||
}
|
||||
|
||||
if (controller.isPlanning() || controller.isBuilding() || controller.isErrorEncountered())
|
||||
{
|
||||
mMainMenu.showLineFrame(false);
|
||||
mMainMenu.showLineFrame(false, new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
final int menuHeight = getCurrentMenu().getFrame().getHeight();
|
||||
adjustRuler(0, menuHeight);
|
||||
if (completion != null)
|
||||
completion.run();
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
mMainMenu.showLineFrame(true);
|
||||
mMainMenu.showLineFrame(true, new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
adjustRuler(0, 0);
|
||||
}
|
||||
});
|
||||
|
||||
if (completion != null)
|
||||
completion.run();
|
||||
}
|
||||
|
||||
private void setNavButtonsTopLimit(int limit)
|
||||
|
@ -1410,6 +1450,11 @@ public class MwmActivity extends BaseMwmFragmentActivity
|
|||
@Override
|
||||
public void showRoutePlan(boolean show, @Nullable Runnable completionListener)
|
||||
{
|
||||
if (mNavAnimationController != null && !mIsFragmentContainer)
|
||||
{
|
||||
mNavAnimationController.setBottomLimit(show ? 0 : getCurrentMenu().getFrame().getHeight());
|
||||
mNavAnimationController.slide(show, getCurrentMenu().getFrame().getHeight());
|
||||
}
|
||||
if (show)
|
||||
{
|
||||
mSearchController.hide();
|
||||
|
@ -1529,6 +1574,13 @@ public class MwmActivity extends BaseMwmFragmentActivity
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void animateSearchPoiTransition(@NonNull final Rect startRect,
|
||||
@Nullable final Runnable runnable)
|
||||
{
|
||||
Animations.riseTransition(mRootView, startRect, runnable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUberInfoReceived(@NonNull UberInfo info)
|
||||
{
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
package com.mapswithme.maps;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.content.res.Resources;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.view.View;
|
||||
|
||||
|
@ -7,12 +10,11 @@ import com.mapswithme.maps.routing.RoutingController;
|
|||
import com.mapswithme.util.Animations;
|
||||
import com.mapswithme.util.Config;
|
||||
import com.mapswithme.util.UiUtils;
|
||||
import com.mapswithme.util.log.DebugLogger;
|
||||
|
||||
class NavigationButtonsAnimationController
|
||||
{
|
||||
private static final DebugLogger LOGGER =
|
||||
new DebugLogger(NavigationButtonsAnimationController.class.getSimpleName());
|
||||
private static final int ANIM_TOGGLE = MwmApplication.get().getResources().getInteger(R.integer.anim_slots_toggle);
|
||||
|
||||
@NonNull
|
||||
private final View mZoomIn;
|
||||
@NonNull
|
||||
|
@ -20,19 +22,40 @@ class NavigationButtonsAnimationController
|
|||
@NonNull
|
||||
private final View mMyPosition;
|
||||
|
||||
private float mBottomLimit;
|
||||
private float mTopLimit;
|
||||
private final float mMargin;
|
||||
private float mContentHeight;
|
||||
private float mMyPositionBottom;
|
||||
|
||||
private boolean mMyPosAnimate;
|
||||
private boolean mZoomAnimating;
|
||||
private boolean mMyPosAnimating;
|
||||
private boolean mSlidingDown;
|
||||
|
||||
private float mTopLimit;
|
||||
private float mBottomLimit;
|
||||
|
||||
private float mCurrentOffset;
|
||||
|
||||
NavigationButtonsAnimationController(@NonNull View zoomIn, @NonNull View zoomOut,
|
||||
@NonNull View myPosition)
|
||||
@NonNull View myPosition, @NonNull final View contentView)
|
||||
{
|
||||
mZoomIn = zoomIn;
|
||||
mZoomOut = zoomOut;
|
||||
checkZoomButtonsVisibility();
|
||||
mMyPosition = myPosition;
|
||||
calculateBottomLimit();
|
||||
Resources res = mZoomIn.getResources();
|
||||
mMargin = res.getDimension(R.dimen.margin_base_plus);
|
||||
mBottomLimit = res.getDimension(R.dimen.menu_line_height);
|
||||
calculateLimitTranslations();
|
||||
contentView.addOnLayoutChangeListener(new View.OnLayoutChangeListener()
|
||||
{
|
||||
@Override
|
||||
public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft,
|
||||
int oldTop, int oldRight, int oldBottom)
|
||||
{
|
||||
mContentHeight = bottom - top;
|
||||
contentView.removeOnLayoutChangeListener(this);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void checkZoomButtonsVisibility()
|
||||
|
@ -40,6 +63,193 @@ class NavigationButtonsAnimationController
|
|||
UiUtils.showIf(showZoomButtons(), mZoomIn, mZoomOut);
|
||||
}
|
||||
|
||||
|
||||
private void calculateLimitTranslations()
|
||||
{
|
||||
mTopLimit = mMargin;
|
||||
mMyPosition.addOnLayoutChangeListener(new View.OnLayoutChangeListener()
|
||||
{
|
||||
@Override
|
||||
public void onLayoutChange(View v, int left, int top, int right, int bottom,
|
||||
int oldLeft, int oldTop, int oldRight, int oldBottom)
|
||||
{
|
||||
mMyPositionBottom = bottom;
|
||||
mMyPosition.removeOnLayoutChangeListener(this);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void setTopLimit(float limit)
|
||||
{
|
||||
mTopLimit = limit + mMargin;
|
||||
update();
|
||||
}
|
||||
|
||||
void setBottomLimit(float limit)
|
||||
{
|
||||
mBottomLimit = limit;
|
||||
update();
|
||||
}
|
||||
|
||||
private void fadeOutZoom()
|
||||
{
|
||||
if (mSlidingDown)
|
||||
return;
|
||||
|
||||
mZoomAnimating = true;
|
||||
Animations.fadeOutView(mZoomIn, new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
mZoomIn.setVisibility(View.INVISIBLE);
|
||||
mZoomAnimating = false;
|
||||
}
|
||||
});
|
||||
Animations.fadeOutView(mZoomOut, new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
mZoomOut.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void fadeInZoom()
|
||||
{
|
||||
mZoomAnimating = true;
|
||||
mZoomIn.setVisibility(View.VISIBLE);
|
||||
mZoomOut.setVisibility(View.VISIBLE);
|
||||
Animations.fadeInView(mZoomIn, new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
mZoomAnimating = false;
|
||||
}
|
||||
});
|
||||
Animations.fadeInView(mZoomOut, null);
|
||||
}
|
||||
|
||||
private void fadeOutMyPosition()
|
||||
{
|
||||
if (mSlidingDown)
|
||||
return;
|
||||
|
||||
mMyPosAnimating = true;
|
||||
Animations.fadeOutView(mMyPosition, new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
UiUtils.invisible(mMyPosition);
|
||||
mMyPosAnimating = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void fadeInMyPosition()
|
||||
{
|
||||
mMyPosAnimating = true;
|
||||
mMyPosition.setVisibility(View.VISIBLE);
|
||||
Animations.fadeInView(mMyPosition, new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
mMyPosAnimating = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void onPlacePageMoved(float translationY)
|
||||
{
|
||||
if (UiUtils.isLandscape(mMyPosition.getContext()) || mMyPositionBottom == 0 || mContentHeight == 0)
|
||||
return;
|
||||
|
||||
final float amount = mCurrentOffset > 0 ? mMargin : -mMargin;
|
||||
final float translation = translationY - (mMyPositionBottom - mCurrentOffset + amount);
|
||||
update(translation <= mCurrentOffset ? translation : mCurrentOffset);
|
||||
}
|
||||
|
||||
private void update()
|
||||
{
|
||||
update(mZoomIn.getTranslationY());
|
||||
}
|
||||
|
||||
private void update(final float translation)
|
||||
{
|
||||
mMyPosition.setTranslationY(translation);
|
||||
mZoomOut.setTranslationY(translation);
|
||||
mZoomIn.setTranslationY(translation);
|
||||
if (!mZoomAnimating && mZoomIn.getVisibility() == View.VISIBLE
|
||||
&& !isViewInsideLimits(mZoomIn))
|
||||
{
|
||||
fadeOutZoom();
|
||||
}
|
||||
else if (!mZoomAnimating && mZoomIn.getVisibility() == View.INVISIBLE
|
||||
&& isViewInsideLimits(mZoomIn))
|
||||
{
|
||||
fadeInZoom();
|
||||
}
|
||||
|
||||
if (!shouldBeHidden() && !mMyPosAnimating
|
||||
&& mMyPosition.getVisibility() == View.VISIBLE && !isViewInsideLimits(mMyPosition))
|
||||
{
|
||||
fadeOutMyPosition();
|
||||
}
|
||||
else if (!shouldBeHidden() && !mMyPosAnimating
|
||||
&& mMyPosition.getVisibility() == View.INVISIBLE && isViewInsideLimits(mMyPosition))
|
||||
{
|
||||
fadeInMyPosition();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isViewInsideLimits(@NonNull View view)
|
||||
{
|
||||
return view.getY() >= mTopLimit &&
|
||||
view.getBottom() + view.getTranslationY() <= mContentHeight - mBottomLimit;
|
||||
}
|
||||
|
||||
private boolean shouldBeHidden()
|
||||
{
|
||||
return LocationState.getMode() == LocationState.FOLLOW_AND_ROTATE
|
||||
&& (RoutingController.get().isPlanning() || RoutingController.get().isNavigating());
|
||||
}
|
||||
|
||||
void slide(boolean isDown, float distance)
|
||||
{
|
||||
if (UiUtils.isLandscape(mMyPosition.getContext())
|
||||
|| (!isDown && mZoomIn.getTranslationY() <= 0))
|
||||
return;
|
||||
|
||||
mSlidingDown = isDown;
|
||||
mCurrentOffset = isDown ? distance : 0;
|
||||
|
||||
ValueAnimator animator = ValueAnimator.ofFloat(isDown ? 0 : distance, isDown ? distance : 0);
|
||||
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener()
|
||||
{
|
||||
@Override
|
||||
public void onAnimationUpdate(ValueAnimator animation)
|
||||
{
|
||||
float value = (float) animation.getAnimatedValue();
|
||||
update(value);
|
||||
}
|
||||
});
|
||||
animator.addListener(new UiUtils.SimpleAnimatorListener()
|
||||
{
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation)
|
||||
{
|
||||
mSlidingDown = false;
|
||||
update();
|
||||
}
|
||||
});
|
||||
animator.setDuration(ANIM_TOGGLE);
|
||||
animator.start();
|
||||
}
|
||||
|
||||
void disappearZoomButtons()
|
||||
{
|
||||
if (!showZoomButtons())
|
||||
|
@ -54,204 +264,8 @@ class NavigationButtonsAnimationController
|
|||
if (!showZoomButtons())
|
||||
return;
|
||||
|
||||
if (!canZoomButtonsFitInScreen())
|
||||
return;
|
||||
|
||||
Animations.appearSliding(mZoomIn, Animations.RIGHT, null);
|
||||
Animations.appearSliding(mZoomOut, Animations.RIGHT, null);
|
||||
updateZoomButtonsPosition();
|
||||
}
|
||||
|
||||
void setTopLimit(float limit)
|
||||
{
|
||||
mTopLimit = limit;
|
||||
updateZoomButtonsPosition();
|
||||
}
|
||||
|
||||
void onPlacePageVisibilityChanged(boolean isVisible)
|
||||
{
|
||||
if (isVisible)
|
||||
fadeOutZooms();
|
||||
else
|
||||
fadeInZooms();
|
||||
}
|
||||
|
||||
void onPlacePageMoved(float translationY)
|
||||
{
|
||||
if (mBottomLimit == 0)
|
||||
return;
|
||||
|
||||
float translation = translationY - mBottomLimit;
|
||||
animateMyPosition(translation <= 0 ? translation : 0);
|
||||
}
|
||||
|
||||
private void calculateBottomLimit()
|
||||
{
|
||||
mMyPosition.addOnLayoutChangeListener(new View.OnLayoutChangeListener()
|
||||
{
|
||||
@Override
|
||||
public void onLayoutChange(View v, int left, int top, int right, int bottom,
|
||||
int oldLeft, int oldTop, int oldRight, int oldBottom)
|
||||
{
|
||||
mBottomLimit = bottom;
|
||||
mMyPosition.removeOnLayoutChangeListener(this);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void updateZoomButtonsPosition()
|
||||
{
|
||||
// It means that the zoom buttons fit in screen perfectly,
|
||||
// any updates of position are no needed.
|
||||
if (mZoomIn.getTop() >= mTopLimit && UiUtils.isVisible(mZoomIn))
|
||||
return;
|
||||
|
||||
// If the top limit is decreased we try to return zoom buttons at initial position.
|
||||
if (mTopLimit < mZoomIn.getTop() && tryPlaceZoomButtonsAtInitialPosition())
|
||||
{
|
||||
LOGGER.d("Zoom buttons were come back to initial position");
|
||||
return;
|
||||
}
|
||||
|
||||
// If top view overlaps the zoomIn button.
|
||||
if (mTopLimit > mZoomIn.getTop())
|
||||
{
|
||||
// We should try to pull out the zoomIn button from under the top view
|
||||
// if available space allows us doing that.
|
||||
if (tryPlaceZoomButtonsUnderTopLimit())
|
||||
return;
|
||||
|
||||
// Otherwise, we just fade out the zoom buttons
|
||||
// since there is not enough space on the screen for them.
|
||||
fadeOutZooms();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean tryPlaceZoomButtonsAtInitialPosition()
|
||||
{
|
||||
float availableSpace = mBottomLimit - mTopLimit;
|
||||
float requiredSpace = mBottomLimit - mZoomIn.getTop() - mZoomIn.getTranslationY();
|
||||
if (requiredSpace > availableSpace)
|
||||
return false;
|
||||
|
||||
mZoomIn.setTranslationY(0);
|
||||
mZoomOut.setTranslationY(0);
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean tryPlaceZoomButtonsUnderTopLimit()
|
||||
{
|
||||
if (!canZoomButtonsFitInScreen())
|
||||
return false;
|
||||
|
||||
float requiredTranslate = mTopLimit - mZoomIn.getTop();
|
||||
mZoomIn.setTranslationY(requiredTranslate);
|
||||
mZoomOut.setTranslationY(requiredTranslate);
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean canZoomButtonsFitInScreen()
|
||||
{
|
||||
float availableSpace = mBottomLimit - mTopLimit;
|
||||
return getMinimumRequiredHeightForButtons() <= availableSpace;
|
||||
}
|
||||
|
||||
private float getMinimumRequiredHeightForButtons()
|
||||
{
|
||||
return mZoomIn.getHeight() + mZoomOut.getHeight() + mMyPosition.getHeight();
|
||||
}
|
||||
|
||||
private void fadeOutZooms()
|
||||
{
|
||||
Animations.fadeOutView(mZoomIn, new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
mZoomIn.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
});
|
||||
Animations.fadeOutView(mZoomOut, new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
mZoomOut.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void fadeInZooms()
|
||||
{
|
||||
if (!showZoomButtons())
|
||||
return;
|
||||
|
||||
if (!canZoomButtonsFitInScreen())
|
||||
return;
|
||||
|
||||
mZoomIn.setVisibility(View.VISIBLE);
|
||||
mZoomOut.setVisibility(View.VISIBLE);
|
||||
Animations.fadeInView(mZoomIn, null);
|
||||
Animations.fadeInView(mZoomOut, null);
|
||||
}
|
||||
|
||||
private void fadeOutMyPosition()
|
||||
{
|
||||
mMyPosAnimate = true;
|
||||
Animations.fadeOutView(mMyPosition, new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
UiUtils.invisible(mMyPosition);
|
||||
mMyPosAnimate = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void fadeInMyPosition()
|
||||
{
|
||||
mMyPosAnimate = true;
|
||||
mMyPosition.setVisibility(View.VISIBLE);
|
||||
Animations.fadeInView(mMyPosition, new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
mMyPosAnimate = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void animateMyPosition(float translation)
|
||||
{
|
||||
mMyPosition.setTranslationY(translation);
|
||||
if (!shouldMyPositionBeHidden() && !mMyPosAnimate
|
||||
&& isOverTopLimit(mMyPosition))
|
||||
{
|
||||
fadeOutMyPosition();
|
||||
}
|
||||
else if (!shouldMyPositionBeHidden() && !mMyPosAnimate
|
||||
&& satisfyTopLimit(mMyPosition))
|
||||
{
|
||||
fadeInMyPosition();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isOverTopLimit(@NonNull View view)
|
||||
{
|
||||
return view.getVisibility() == View.VISIBLE && view.getY() <= mTopLimit;
|
||||
}
|
||||
|
||||
private boolean satisfyTopLimit(@NonNull View view)
|
||||
{
|
||||
return view.getVisibility() == View.INVISIBLE && view.getY() >= mTopLimit;
|
||||
}
|
||||
|
||||
private boolean shouldMyPositionBeHidden()
|
||||
{
|
||||
return LocationState.getMode() == LocationState.FOLLOW_AND_ROTATE
|
||||
&& (RoutingController.get().isPlanning());
|
||||
Animations.appearSliding(mZoomIn, Animations.LEFT, null);
|
||||
Animations.appearSliding(mZoomOut, Animations.LEFT, null);
|
||||
}
|
||||
|
||||
private static boolean showZoomButtons()
|
||||
|
|
|
@ -3,6 +3,7 @@ package com.mapswithme.maps.routing;
|
|||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.graphics.Rect;
|
||||
import android.support.annotation.DimenRes;
|
||||
import android.support.annotation.IntRange;
|
||||
import android.support.annotation.MainThread;
|
||||
|
|
|
@ -4,6 +4,7 @@ import android.animation.Animator;
|
|||
import android.animation.ValueAnimator;
|
||||
import android.app.Activity;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Rect;
|
||||
import android.location.Location;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.DrawableRes;
|
||||
|
@ -42,7 +43,7 @@ import com.mapswithme.util.Utils;
|
|||
import com.mapswithme.util.statistics.AlohaHelper;
|
||||
import com.mapswithme.util.statistics.Statistics;
|
||||
|
||||
public class RoutingPlanController extends ToolbarController
|
||||
public class RoutingPlanController extends ToolbarController implements SlotFrame.SlotClickListener
|
||||
{
|
||||
static final int ANIM_TOGGLE = MwmApplication.get().getResources().getInteger(R.integer.anim_slots_toggle);
|
||||
private static final String STATE_ALTITUDE_CHART_SHOWN = "altitude_chart_shown";
|
||||
|
@ -62,7 +63,7 @@ public class RoutingPlanController extends ToolbarController
|
|||
private final View mUberFrame;
|
||||
|
||||
private final RotateDrawable mToggleImage = new RotateDrawable(R.drawable.ic_down);
|
||||
private int mFrameHeight;
|
||||
int mFrameHeight;
|
||||
private int mToolbarHeight;
|
||||
private boolean mOpen;
|
||||
@Nullable
|
||||
|
@ -74,11 +75,20 @@ public class RoutingPlanController extends ToolbarController
|
|||
@Nullable
|
||||
private OnToggleListener mToggleListener;
|
||||
|
||||
@Nullable
|
||||
private SearchPoiTransitionListener mPoiTransitionListener;
|
||||
|
||||
public interface OnToggleListener
|
||||
{
|
||||
void onToggle(boolean state);
|
||||
}
|
||||
|
||||
public interface SearchPoiTransitionListener
|
||||
{
|
||||
void animateSearchPoiTransition(@NonNull final Rect startRect,
|
||||
@Nullable final Runnable runnable);
|
||||
}
|
||||
|
||||
private RadioButton setupRouterButton(@IdRes int buttonId, final @DrawableRes int iconRes, View.OnClickListener clickListener)
|
||||
{
|
||||
CompoundButton.OnCheckedChangeListener listener = new CompoundButton.OnCheckedChangeListener()
|
||||
|
@ -109,6 +119,7 @@ public class RoutingPlanController extends ToolbarController
|
|||
|
||||
mToggle = (ImageView) mToolbar.findViewById(R.id.toggle);
|
||||
mSlotFrame = (SlotFrame) root.findViewById(R.id.slots);
|
||||
mSlotFrame.setSlotClickListener(this);
|
||||
mRouterTypes = (RadioGroup) mToolbar.findViewById(R.id.route_type);
|
||||
|
||||
setupRouterButton(R.id.vehicle, R.drawable.ic_car, new View.OnClickListener()
|
||||
|
@ -186,7 +197,32 @@ public class RoutingPlanController extends ToolbarController
|
|||
RoutingController.get().cancelPlanning();
|
||||
}
|
||||
|
||||
private boolean checkFrameHeight()
|
||||
@Override
|
||||
public void onSlotClicked(final int order, @NonNull Rect rect)
|
||||
{
|
||||
if (mPoiTransitionListener != null)
|
||||
{
|
||||
mPoiTransitionListener.animateSearchPoiTransition(rect, new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
RoutingController.get().searchPoi(order);
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
RoutingController.get().searchPoi(order);
|
||||
}
|
||||
}
|
||||
|
||||
public void setPoiTransitionListener(@Nullable SearchPoiTransitionListener poiTransitionListener)
|
||||
{
|
||||
mPoiTransitionListener = poiTransitionListener;
|
||||
}
|
||||
|
||||
boolean checkFrameHeight()
|
||||
{
|
||||
if (mFrameHeight > 0)
|
||||
return true;
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
package com.mapswithme.maps.routing;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import com.mapswithme.maps.MwmActivity;
|
||||
|
@ -20,7 +23,7 @@ public class RoutingPlanInplaceController extends RoutingPlanController
|
|||
super(activity.findViewById(R.id.routing_plan_frame), activity);
|
||||
}
|
||||
|
||||
public void show(boolean show)
|
||||
public void show(final boolean show)
|
||||
{
|
||||
if (show == UiUtils.isVisible(mFrame))
|
||||
return;
|
||||
|
@ -36,9 +39,21 @@ public class RoutingPlanInplaceController extends RoutingPlanController
|
|||
mSlotsRestoredState = null;
|
||||
}
|
||||
|
||||
UiUtils.showIf(show, mFrame);
|
||||
if (show)
|
||||
{
|
||||
UiUtils.show(mFrame);
|
||||
updatePoints();
|
||||
}
|
||||
|
||||
animateFrame(show, new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
if (!show)
|
||||
UiUtils.hide(mFrame);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void onSaveState(@NonNull Bundle outState)
|
||||
|
@ -61,4 +76,42 @@ public class RoutingPlanInplaceController extends RoutingPlanController
|
|||
ImageView altitudeChart = (ImageView) mActivity.findViewById(R.id.altitude_chart);
|
||||
showRouteAltitudeChartInternal(altitudeChart);
|
||||
}
|
||||
|
||||
private void animateFrame(final boolean show, final @Nullable Runnable completion)
|
||||
{
|
||||
if (!checkFrameHeight())
|
||||
{
|
||||
mFrame.post(new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
animateFrame(show, completion);
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
ValueAnimator animator =
|
||||
ValueAnimator.ofFloat(show ? -mFrameHeight : 0, show ? 0 : -mFrameHeight);
|
||||
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener()
|
||||
{
|
||||
@Override
|
||||
public void onAnimationUpdate(ValueAnimator animation)
|
||||
{
|
||||
mFrame.setTranslationY((Float) animation.getAnimatedValue());
|
||||
}
|
||||
});
|
||||
animator.addListener(new UiUtils.SimpleAnimatorListener()
|
||||
{
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation)
|
||||
{
|
||||
if (completion != null)
|
||||
completion.run();
|
||||
}
|
||||
});
|
||||
animator.setDuration(ANIM_TOGGLE);
|
||||
animator.start();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ import android.graphics.Rect;
|
|||
import android.os.Build;
|
||||
import android.support.annotation.IdRes;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.text.TextUtils;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
|
@ -35,6 +36,14 @@ public class SlotFrame extends LinearLayout
|
|||
private int mTextColor;
|
||||
private int mHintColor;
|
||||
|
||||
@Nullable
|
||||
private SlotClickListener mSlotClickListener;
|
||||
|
||||
interface SlotClickListener
|
||||
{
|
||||
void onSlotClicked(int order, @NonNull Rect rect);
|
||||
}
|
||||
|
||||
private class Slot
|
||||
{
|
||||
private final View mFrame;
|
||||
|
@ -74,7 +83,10 @@ public class SlotFrame extends LinearLayout
|
|||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
RoutingController.get().searchPoi(mOrder);
|
||||
Rect rect = new Rect();
|
||||
mFrame.getGlobalVisibleRect(rect);
|
||||
if (mSlotClickListener != null)
|
||||
mSlotClickListener.onSlotClicked(mOrder, rect);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -334,6 +346,11 @@ public class SlotFrame extends LinearLayout
|
|||
super(context, attrs, defStyleAttr);
|
||||
}
|
||||
|
||||
public void setSlotClickListener(@Nullable SlotClickListener slotClickListener)
|
||||
{
|
||||
mSlotClickListener = slotClickListener;
|
||||
}
|
||||
|
||||
public void update()
|
||||
{
|
||||
mSlotFrom.setMapObject(RoutingController.get().getStartPoint());
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package com.mapswithme.maps.search;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.support.annotation.NonNull;
|
||||
|
@ -17,11 +18,12 @@ public class SearchActivity extends BaseMwmFragmentActivity implements CustomNav
|
|||
{
|
||||
public static final String EXTRA_QUERY = "search_query";
|
||||
|
||||
public static void start(Context context, String query)
|
||||
public static void start(@NonNull Activity activity, String query)
|
||||
{
|
||||
final Intent i = new Intent(context, SearchActivity.class);
|
||||
final Intent i = new Intent(activity, SearchActivity.class);
|
||||
i.putExtra(EXTRA_QUERY, query);
|
||||
context.startActivity(i);
|
||||
activity.startActivity(i);
|
||||
activity.overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -44,6 +46,7 @@ public class SearchActivity extends BaseMwmFragmentActivity implements CustomNav
|
|||
if (manager.getBackStackEntryCount() == 0)
|
||||
{
|
||||
NavUtils.navigateUpFromSameTask(this);
|
||||
overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -58,5 +61,6 @@ public class SearchActivity extends BaseMwmFragmentActivity implements CustomNav
|
|||
return;
|
||||
|
||||
super.onBackPressed();
|
||||
overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
package com.mapswithme.maps.search;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.view.View;
|
||||
|
||||
import com.mapswithme.maps.MwmApplication;
|
||||
import com.mapswithme.maps.R;
|
||||
import com.mapswithme.util.UiUtils;
|
||||
|
||||
final class SearchAnimationController
|
||||
{
|
||||
private static final int DURATION = MwmApplication.get().getResources().getInteger(R.integer.anim_menu);
|
||||
|
||||
@NonNull
|
||||
private final View mToolbar;
|
||||
@NonNull
|
||||
private final View mTabBar;
|
||||
|
||||
SearchAnimationController(@NonNull View toolbar, @NonNull View tabBar)
|
||||
{
|
||||
mToolbar = toolbar;
|
||||
mTabBar = tabBar;
|
||||
}
|
||||
|
||||
void animate(final boolean show, @Nullable final Runnable completion)
|
||||
{
|
||||
if (mToolbar.getHeight() == 0 || mTabBar.getHeight() == 0)
|
||||
{
|
||||
mToolbar.post(new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
animate(show, completion);
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
final float translation = -mTabBar.getHeight() - mToolbar.getHeight();
|
||||
ValueAnimator animator =
|
||||
ValueAnimator.ofFloat(show ? translation: 0, show ? 0 : translation);
|
||||
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener()
|
||||
{
|
||||
@Override
|
||||
public void onAnimationUpdate(ValueAnimator animation)
|
||||
{
|
||||
final float value = (float) animation.getAnimatedValue();
|
||||
mToolbar.setTranslationY(value);
|
||||
mTabBar.setTranslationY(value);
|
||||
}
|
||||
});
|
||||
animator.addListener(new UiUtils.SimpleAnimatorListener()
|
||||
{
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation)
|
||||
{
|
||||
if (completion != null)
|
||||
completion.run();
|
||||
}
|
||||
});
|
||||
animator.setDuration(DURATION);
|
||||
animator.start();
|
||||
}
|
||||
}
|
|
@ -3,6 +3,8 @@ package com.mapswithme.maps.search;
|
|||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
|
||||
import com.mapswithme.maps.R;
|
||||
import com.mapswithme.maps.base.BaseMwmRecyclerFragment;
|
||||
|
||||
public class SearchCategoriesFragment extends BaseMwmRecyclerFragment
|
||||
|
@ -14,6 +16,12 @@ public class SearchCategoriesFragment extends BaseMwmRecyclerFragment
|
|||
return new CategoriesAdapter(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getLayoutRes()
|
||||
{
|
||||
return R.layout.fragment_search_categories;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(@Nullable Bundle savedInstanceState)
|
||||
{
|
||||
|
|
|
@ -224,12 +224,10 @@ public class SearchFragment extends BaseMwmFragment
|
|||
mTabFrame = root.findViewById(R.id.tab_frame);
|
||||
ViewPager pager = (ViewPager) mTabFrame.findViewById(R.id.pages);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
|
||||
UiUtils.hide(mTabFrame.findViewById(R.id.tabs_divider));
|
||||
|
||||
mToolbarController = new ToolbarController(view);
|
||||
|
||||
final TabAdapter tabAdapter = new TabAdapter(getChildFragmentManager(), pager, (TabLayout) root.findViewById(R.id.tabs));
|
||||
TabLayout tabLayout = (TabLayout) root.findViewById(R.id.tabs);
|
||||
final TabAdapter tabAdapter = new TabAdapter(getChildFragmentManager(), pager, tabLayout);
|
||||
|
||||
mResultsFrame = root.findViewById(R.id.results_frame);
|
||||
RecyclerView results = (RecyclerView) mResultsFrame.findViewById(R.id.recycler);
|
||||
|
@ -480,10 +478,20 @@ public class SearchFragment extends BaseMwmFragment
|
|||
if (mFromRoutePlan)
|
||||
{
|
||||
RoutingController.get().onPoiSelected(null);
|
||||
return !(getActivity() instanceof SearchActivity);
|
||||
final boolean isSearchActivity = getActivity() instanceof SearchActivity;
|
||||
if (isSearchActivity)
|
||||
closeSearch();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
closeSearch();
|
||||
return true;
|
||||
}
|
||||
|
||||
private void closeSearch()
|
||||
{
|
||||
getActivity().finish();
|
||||
getActivity().overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);
|
||||
}
|
||||
|
||||
public void setRecyclerScrollListener(RecyclerView recycler)
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
package com.mapswithme.maps.widget.menu;
|
||||
|
||||
import android.support.annotation.Nullable;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.mapswithme.maps.MwmActivity;
|
||||
|
@ -11,9 +11,9 @@ import com.mapswithme.maps.R;
|
|||
import com.mapswithme.maps.downloader.MapManager;
|
||||
import com.mapswithme.maps.downloader.UpdateInfo;
|
||||
import com.mapswithme.maps.routing.RoutingController;
|
||||
import com.mapswithme.util.Animations;
|
||||
import com.mapswithme.util.Graphics;
|
||||
import com.mapswithme.util.UiUtils;
|
||||
import ru.mail.android.mytarget.core.models.Stat;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
@ -263,9 +263,9 @@ public class MainMenu extends BaseMenu
|
|||
{
|
||||
UiUtils.show(mButtonsFrame);
|
||||
expandContent = false;
|
||||
} else
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
UiUtils.showIf(state == State.MENU, mButtonsFrame);
|
||||
UiUtils.showIf(isRouting, mRoutePlanFrame);
|
||||
if (isRouting)
|
||||
|
@ -313,8 +313,17 @@ public class MainMenu extends BaseMenu
|
|||
return mAnimationTrackListener;
|
||||
}
|
||||
|
||||
public void showLineFrame(boolean show)
|
||||
public void showLineFrame(boolean show, @Nullable Runnable completion)
|
||||
{
|
||||
UiUtils.showIf(show, mLineFrame);
|
||||
if (show)
|
||||
{
|
||||
UiUtils.hide(mFrame);
|
||||
Animations.appearSliding(mFrame, Animations.BOTTOM, completion);
|
||||
}
|
||||
else
|
||||
{
|
||||
UiUtils.show(mFrame);
|
||||
Animations.disappearSliding(mFrame, Animations.BOTTOM, completion);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,17 @@
|
|||
package com.mapswithme.util;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Rect;
|
||||
import android.support.annotation.IntDef;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewPropertyAnimator;
|
||||
|
||||
import com.mapswithme.maps.MwmApplication;
|
||||
|
@ -26,6 +33,7 @@ public final class Animations
|
|||
public static final int BOTTOM = 3;
|
||||
|
||||
private static final int DURATION_DEFAULT = MwmApplication.get().getResources().getInteger(R.integer.anim_default);
|
||||
private static final int DURATION_MENU = MwmApplication.get().getResources().getInteger(R.integer.anim_menu);
|
||||
|
||||
public static void appearSliding(final View view, @AnimationDirection int appearFrom, @Nullable final Runnable completionListener)
|
||||
{
|
||||
|
@ -134,4 +142,83 @@ public final class Animations
|
|||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void riseTransition(@NonNull final ViewGroup rootView, @NonNull final Rect startRect,
|
||||
@Nullable final Runnable runnable)
|
||||
{
|
||||
final Context context = rootView.getContext();
|
||||
final View view = new View(context);
|
||||
setCardBackgroundColor(view);
|
||||
|
||||
DisplayMetrics dm = context.getResources().getDisplayMetrics();
|
||||
final float screenWidth = dm.widthPixels;
|
||||
final float screenHeight = dm.heightPixels;
|
||||
final float width = startRect.width();
|
||||
final float height = startRect.height();
|
||||
ViewGroup.MarginLayoutParams lp = new ViewGroup.MarginLayoutParams((int) width,
|
||||
(int) height);
|
||||
lp.topMargin = startRect.top;
|
||||
lp.leftMargin = startRect.left;
|
||||
final float right = screenWidth - startRect.right;
|
||||
lp.rightMargin = (int) right;
|
||||
rootView.addView(view, lp);
|
||||
|
||||
ValueAnimator animator = ValueAnimator.ofFloat(0.0f, 1.0f);
|
||||
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener()
|
||||
{
|
||||
@Override
|
||||
public void onAnimationUpdate(ValueAnimator animation)
|
||||
{
|
||||
final float t = (float) animation.getAnimatedValue();
|
||||
final float topMargin = startRect.top - t * startRect.top;
|
||||
final float leftMargin = startRect.left - t * startRect.left;
|
||||
final float rightMargin = right - t * right;
|
||||
final float newWidth = width + t * (screenWidth - width);
|
||||
final float newHeight = height + t * (screenHeight - height);
|
||||
ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) view.getLayoutParams();
|
||||
lp.width = (int) newWidth;
|
||||
lp.height = (int) newHeight;
|
||||
lp.topMargin = (int) topMargin;
|
||||
lp.leftMargin = (int) leftMargin;
|
||||
lp.rightMargin = (int) rightMargin;
|
||||
view.setLayoutParams(lp);
|
||||
}
|
||||
});
|
||||
animator.addListener(new UiUtils.SimpleAnimatorListener()
|
||||
{
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation)
|
||||
{
|
||||
if (runnable != null)
|
||||
runnable.run();
|
||||
rootView.postDelayed(new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
rootView.removeView(view);
|
||||
}
|
||||
}, context.getResources().getInteger(android.R.integer.config_longAnimTime));
|
||||
}
|
||||
});
|
||||
animator.setDuration(DURATION_MENU);
|
||||
animator.start();
|
||||
}
|
||||
|
||||
private static void setCardBackgroundColor(@NonNull View view)
|
||||
{
|
||||
Context context = view.getContext();
|
||||
TypedArray a = null;
|
||||
try
|
||||
{
|
||||
a = context.obtainStyledAttributes(new int[] { R.attr.cardBackgroundColor });
|
||||
int color = a.getColor(0, ContextCompat.getColor(context, R.color.bg_cards));
|
||||
view.setBackgroundColor(color);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (a != null)
|
||||
a.recycle();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue