[android] add: Animated slots frame collapsing/expansion.

This commit is contained in:
Alexander Marchuk 2015-11-18 13:31:50 +03:00
parent 767df7076b
commit 04b4bc2d7c
11 changed files with 196 additions and 51 deletions

View file

@ -29,7 +29,7 @@
<include
layout="@layout/routing_plan"
android:visibility="gone"/>
android:visibility="invisible"/>
<include
android:id="@+id/navigation_buttons"

View file

@ -27,7 +27,7 @@
<include
layout="@layout/routing_plan"
android:visibility="gone"/>
android:visibility="invisible"/>
<include
android:id="@+id/navigation_buttons"

View file

@ -9,26 +9,32 @@
android:orientation="vertical"
android:paddingBottom="8dp"
android:clipToPadding="false">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
style="@style/MwmWidget.ToolbarStyle"
android:theme="@style/MwmWidget.ToolbarTheme"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:elevation="0dp">
<ImageView
android:id="@+id/toggle"
android:layout_width="wrap_content"
<FrameLayout android:layout_width="match_parent"
android:layout_height="wrap_content">
<include
layout="@layout/routing_plan_slots"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="right|center_horizontal"
android:background="?attr/selectableItemBackgroundBorderless"
android:scaleType="center"
android:src="@drawable/ic_down"/>
</android.support.v7.widget.Toolbar>
android:layout_marginTop="?attr/actionBarSize"
android:clickable="true"/>
<include
layout="@layout/routing_plan_slots"
android:clickable="true"/>
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
style="@style/MwmWidget.ToolbarStyle"
android:theme="@style/MwmWidget.ToolbarTheme"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:elevation="0dp">
<ImageView
android:id="@+id/toggle"
android:layout_width="?attr/actionBarSize"
android:layout_height="?attr/actionBarSize"
android:layout_gravity="right|center_horizontal"
android:background="?attr/selectableItemBackgroundBorderless"
android:scaleType="center"
tools:src="@drawable/ic_down"/>
</android.support.v7.widget.Toolbar>
</FrameLayout>
<RelativeLayout
android:id="@+id/planning_frame"

View file

@ -6,5 +6,6 @@
<integer name="anim_fade_main">@integer/anim_default</integer>
<integer name="anim_menu">200</integer>
<integer name="anim_location_pending_item">50</integer>
<integer name="anim_slot_swap">200</integer>
<integer name="anim_slots_swap">@integer/anim_default</integer>
<integer name="anim_slots_toggle">@integer/anim_default</integer>
</resources>

View file

@ -224,10 +224,7 @@ public class RoutingController
public void restore()
{
if (isPlanning())
{
// TODO: Restore search fragment
showRoutePlan();
}
mContainer.showNavigation(isNavigating());
mContainer.updateMenu();

View file

@ -1,12 +1,16 @@
package com.mapswithme.maps.routing;
import android.animation.ValueAnimator;
import android.app.Activity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.RadioGroup;
import android.widget.TextView;
import com.mapswithme.maps.Framework;
import com.mapswithme.maps.MwmApplication;
import com.mapswithme.maps.R;
import com.mapswithme.maps.widget.RotateDrawable;
import com.mapswithme.maps.widget.ToolbarController;
import com.mapswithme.maps.widget.WheelProgressView;
import com.mapswithme.util.UiUtils;
@ -15,6 +19,8 @@ import com.mapswithme.util.statistics.AlohaHelper;
public class RoutingPlanController extends ToolbarController
{
static final int ANIM_TOGGLE = MwmApplication.get().getResources().getInteger(R.integer.anim_slots_toggle);
protected final View mFrame;
private final ImageView mToggle;
private final SlotFrame mSlotFrame;
@ -27,6 +33,11 @@ public class RoutingPlanController extends ToolbarController
private final TextView mNumbersTime;
private final TextView mNumbersDistance;
private final RotateDrawable mToggleImage = new RotateDrawable(R.drawable.ic_down);
private int mFrameHeight;
private int mToolbarHeight;
private boolean mOpen;
public RoutingPlanController(View root, Activity activity)
{
super(root, activity);
@ -78,6 +89,7 @@ public class RoutingPlanController extends ToolbarController
setTitle(R.string.route);
mToggle.setImageDrawable(mToggleImage);
mToggle.setOnClickListener(new View.OnClickListener()
{
@Override
@ -95,12 +107,21 @@ public class RoutingPlanController extends ToolbarController
RoutingController.get().cancelPlanning();
}
private void updateToggle()
private boolean checkFrameHeight()
{
if (!UiUtils.isVisible(mToggle))
return;
if (mFrameHeight > 0)
return true;
mFrameHeight = mSlotFrame.getHeight();
mToolbarHeight = mToolbar.getHeight();
return (mFrameHeight > 0);
}
private void animateSlotFrame(int offset)
{
ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) mSlotFrame.getLayoutParams();
lp.topMargin = (mToolbarHeight - offset);
mSlotFrame.setLayoutParams(lp);
}
public void updatePoints()
@ -150,15 +171,49 @@ public class RoutingPlanController extends ToolbarController
private void toggleSlots()
{
// TODO
updateToggle();
showSlots(!mOpen, true);
}
private void showSlots(boolean show, boolean animate)
protected void showSlots(final boolean show, final boolean animate)
{
// TODO: Animation
UiUtils.showIf(show, mSlotFrame);
updateToggle();
if (!checkFrameHeight())
{
mFrame.post(new Runnable()
{
@Override
public void run()
{
showSlots(show, animate);
}
});
return;
}
mOpen = show;
if (animate)
{
ValueAnimator animator = ValueAnimator.ofFloat(mOpen ? 1.0f : 0, mOpen ? 0 : 1.0f);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener()
{
@Override
public void onAnimationUpdate(ValueAnimator animation)
{
float fraction = (float)animation.getAnimatedValue();
animateSlotFrame((int)(fraction * mFrameHeight));
mToggleImage.setAngle(fraction * 180.0f);
}
});
animator.setDuration(ANIM_TOGGLE);
animator.start();
mSlotFrame.fadeSlots(!mOpen);
} else
{
animateSlotFrame(mOpen ? 0 : mFrameHeight);
mToggleImage.setAngle(mOpen ? 0.0f : 180.0f);
mSlotFrame.unfadeSlots();
}
}
public void disableToggle()

View file

@ -20,7 +20,6 @@ public class RoutingPlanFragment extends BaseMwmFragment
View res = inflater.inflate(R.layout.fragment_routing, container, false);
mPlanController = new RoutingPlanController(res, getActivity());
mPlanController.disableToggle();
updatePoints();
View start = res.findViewById(R.id.start);
@ -37,6 +36,12 @@ public class RoutingPlanFragment extends BaseMwmFragment
return res;
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState)
{
mPlanController.disableToggle();
}
@Override
public void onDestroyView()
{

View file

@ -3,6 +3,7 @@ package com.mapswithme.maps.routing;
import android.view.View;
import com.mapswithme.maps.MwmActivity;
import com.mapswithme.maps.R;
import com.mapswithme.maps.bookmarks.data.MapObject;
import com.mapswithme.util.UiUtils;
import com.mapswithme.util.statistics.AlohaHelper;
@ -18,6 +19,12 @@ public class RoutingPlanInplaceController extends RoutingPlanController
if (show == UiUtils.isVisible(mFrame))
return;
if (show)
{
showSlots(!(RoutingController.get().getStartPoint() instanceof MapObject.MyPosition) ||
(RoutingController.get().getEndPoint() == null), false);
}
UiUtils.showIf(show, mFrame);
if (show)
updatePoints();

View file

@ -20,6 +20,7 @@ public class SlotFrame extends LinearLayout
{
private static final int COLOR_TEXT = MwmApplication.get().getResources().getColor(R.color.text_dark);
private static final int COLOR_HINT = MwmApplication.get().getResources().getColor(R.color.text_dark_hint);
private static final int ANIM_SWAP = MwmApplication.get().getResources().getInteger(R.integer.anim_slots_swap);
private OnSlotClickListener mClickListener;
private Slot mSlotFrom;
@ -173,12 +174,10 @@ public class SlotFrame extends LinearLayout
float otherOffsetX = (mFrame.getTranslationX() - offsetX);
float otherOffsetY = (mFrame.getTranslationY() - offsetY);
int duration = getResources().getInteger(R.integer.anim_slot_swap);
mFrame.setTranslationX(offsetX);
mFrame.setTranslationY(offsetY);
mFrame.animate()
.setDuration(duration)
.setDuration(ANIM_SWAP)
.translationX(0.0f)
.translationY(0.0f)
.setListener(mCancelAnimationListener)
@ -187,7 +186,7 @@ public class SlotFrame extends LinearLayout
other.mFrame.setTranslationX(otherOffsetX);
other.mFrame.setTranslationY(otherOffsetY);
other.mFrame.animate()
.setDuration(duration)
.setDuration(ANIM_SWAP)
.translationX(0.0f)
.translationY(0.0f)
.setListener(null)
@ -203,6 +202,7 @@ public class SlotFrame extends LinearLayout
setBackgroundColor(getContext().getResources().getColor(R.color.base_green));
setBaselineAligned(false);
setClipChildren(false);
setClipToPadding(false);
setClickable(true);
int padding = UiUtils.dp(8);
@ -219,6 +219,9 @@ public class SlotFrame extends LinearLayout
private void cancelDrag()
{
if (mDraggedSlot == null)
return;
mDraggedSlot.moveViewTo(mDragStartPoint.x, mDragStartPoint.y);
mDraggedSlot.setDragging(false);
@ -316,4 +319,28 @@ public class SlotFrame extends LinearLayout
mSlotFrom.setMapObject(RoutingController.get().getStartPoint());
mSlotTo.setMapObject(RoutingController.get().getEndPoint());
}
private void fadeSlot(Slot slot, boolean out)
{
slot.mFrame.setAlpha(out ? 1.0f : 0.1f);
slot.mFrame.animate()
.alpha(out ? 0.1f : 1.0f)
.setDuration(RoutingPlanController.ANIM_TOGGLE)
.start();
}
public void fadeSlots(boolean out)
{
fadeSlot(mSlotFrom, out);
fadeSlot(mSlotTo, out);
}
public void unfadeSlots()
{
mSlotFrom.mFrame.clearAnimation();
mSlotFrom.mFrame.setAlpha(1.0f);
mSlotTo.mFrame.clearAnimation();
mSlotTo.mFrame.setAlpha(1.0f);
}
}

View file

@ -0,0 +1,60 @@
package com.mapswithme.maps.widget;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.support.annotation.DrawableRes;
import com.mapswithme.maps.MwmApplication;
public class RotateDrawable extends Drawable
{
private final Drawable mBaseDrawable;
private float mAngle;
public RotateDrawable(@DrawableRes int resId)
{
super();
mBaseDrawable = MwmApplication.get().getResources().getDrawable(resId);
}
@Override
public void setAlpha(int alpha)
{
mBaseDrawable.setAlpha(alpha);
}
@Override
public void setColorFilter(ColorFilter cf)
{
mBaseDrawable.setColorFilter(cf);
}
@Override
public int getOpacity()
{
return mBaseDrawable.getOpacity();
}
@Override
protected void onBoundsChange(Rect bounds)
{
super.onBoundsChange(bounds);
mBaseDrawable.setBounds(bounds);
}
@Override
public void draw(Canvas canvas)
{
canvas.save();
canvas.rotate(mAngle, mBaseDrawable.getBounds().width() / 2, mBaseDrawable.getBounds().height() / 2);
mBaseDrawable.draw(canvas);
canvas.restore();
}
public void setAngle(float angle)
{
mAngle = angle;
invalidateSelf();
}
}

View file

@ -167,7 +167,6 @@ class PlacePageBottomAnimationController extends BasePlacePageAnimationControlle
}
}
@SuppressLint("NewApi")
protected void showPreview(final State currentState)
{
UiUtils.show(mPlacePage, mPreview);
@ -231,18 +230,6 @@ class PlacePageBottomAnimationController extends BasePlacePageAnimationControlle
animator.start();
}
private void correctPreviewTranslation()
{
UiThread.runLater(new Runnable()
{
@Override
public void run()
{
mPreview.setTranslationY(-mDetailsContent.getHeight());
}
});
}
private void showPreviewFrame()
{
UiUtils.show(mPlacePage, mPreview, mFrame);