forked from organicmaps/organicmaps
Merge pull request #4452 from goblinr/MAPSME-18-external-place-page-states
[android] New Place Page opening and scrolling behavior
This commit is contained in:
commit
1379a7f2dc
16 changed files with 573 additions and 291 deletions
80
android/res/layout-land/place_page_details.xml
Normal file
80
android/res/layout-land/place_page_details.xml
Normal file
|
@ -0,0 +1,80 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<com.mapswithme.maps.widget.ObservableScrollView
|
||||
android:id="@+id/pp__details"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="?ppBackground"
|
||||
android:overScrollMode="never">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<include
|
||||
layout="@layout/divider_horizontal"/>
|
||||
|
||||
<include
|
||||
layout="@layout/place_page_bookmark_details"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="@dimen/margin_half"
|
||||
tools:visibility="gone"/>
|
||||
|
||||
<include layout="@layout/place_page_hotel_gallery"/>
|
||||
|
||||
<include layout="@layout/place_page_hotel_facilities"/>
|
||||
|
||||
<include layout="@layout/place_page_hotel_description"/>
|
||||
|
||||
<include layout="@layout/place_page_placename"/>
|
||||
|
||||
<include layout="@layout/place_page_opening_hours"/>
|
||||
|
||||
<include layout="@layout/place_page_entrance"/>
|
||||
|
||||
<include layout="@layout/place_page_phone"/>
|
||||
|
||||
<include layout="@layout/place_page_website"/>
|
||||
|
||||
<include layout="@layout/place_page_wiki"/>
|
||||
|
||||
<include layout="@layout/place_page_email"/>
|
||||
|
||||
<include layout="@layout/place_page_latlon"/>
|
||||
|
||||
<include layout="@layout/place_page_wifi"/>
|
||||
|
||||
<include layout="@layout/place_page_operator"/>
|
||||
|
||||
<include layout="@layout/place_page_cuisine"/>
|
||||
|
||||
<include layout="@layout/place_page_hotel_nearby"/>
|
||||
|
||||
<include layout="@layout/place_page_hotel_rating"/>
|
||||
|
||||
<!--TODO: remove this after booking_api.cpp will be done-->
|
||||
<include layout="@layout/place_page_more"/>
|
||||
|
||||
<include layout="@layout/divider_horizontal"/>
|
||||
|
||||
<include layout="@layout/place_page_editor"/>
|
||||
|
||||
<include layout="@layout/place_page_add_business"/>
|
||||
|
||||
<include layout="@layout/place_page_add"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</com.mapswithme.maps.widget.ObservableScrollView>
|
||||
|
||||
<include layout="@layout/shadow_top"/>
|
||||
|
||||
<include layout="@layout/shadow_bottom"/>
|
||||
</FrameLayout>
|
|
@ -1,13 +1,18 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="vertical"
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@android:color/black">
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/pb__loading_image"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv__image"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"/>
|
||||
|
||||
</LinearLayout>
|
||||
</FrameLayout>
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/height_block_base"
|
||||
android:background="?clickableBackground"
|
||||
android:fontFamily="@string/robotoLight"
|
||||
android:fontFamily="@string/robotoMedium"
|
||||
android:gravity="center_vertical"
|
||||
android:paddingLeft="@dimen/margin_base"
|
||||
android:paddingRight="@dimen/margin_base"
|
||||
|
|
|
@ -1,20 +1,32 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<merge xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<include
|
||||
android:id="@+id/pp__preview"
|
||||
layout="@layout/place_page_preview"
|
||||
<com.mapswithme.maps.widget.ObservableScrollView
|
||||
android:id="@+id/pp__details"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_above="@+id/pp__buttons"/>
|
||||
android:layout_height="match_parent"
|
||||
android:overScrollMode="never"
|
||||
android:layout_above="@+id/pp__buttons">
|
||||
|
||||
<include
|
||||
android:id="@+id/pp__details_frame"
|
||||
layout="@layout/place_page_details"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_above="@+id/pp__buttons"
|
||||
android:background="?panel"/>
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<include
|
||||
android:id="@+id/pp__preview"
|
||||
layout="@layout/place_page_preview"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<include
|
||||
android:id="@+id/pp__details_frame"
|
||||
layout="@layout/place_page_details"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?panel"/>
|
||||
</LinearLayout>
|
||||
</com.mapswithme.maps.widget.ObservableScrollView>
|
||||
|
||||
<include
|
||||
android:id="@+id/pp__buttons"
|
||||
|
|
|
@ -5,74 +5,66 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<com.mapswithme.maps.widget.ObservableScrollView
|
||||
android:id="@+id/pp__details"
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?ppBackground"
|
||||
android:overScrollMode="never">
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
<include
|
||||
layout="@layout/divider_horizontal"/>
|
||||
|
||||
<include
|
||||
layout="@layout/place_page_bookmark_details"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
android:layout_marginBottom="@dimen/margin_half"
|
||||
tools:visibility="gone"/>
|
||||
|
||||
<include
|
||||
layout="@layout/divider_horizontal"/>
|
||||
<include layout="@layout/place_page_hotel_gallery"/>
|
||||
|
||||
<include
|
||||
layout="@layout/place_page_bookmark_details"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="@dimen/margin_half"
|
||||
tools:visibility="gone"/>
|
||||
<include layout="@layout/place_page_hotel_facilities"/>
|
||||
|
||||
<include layout="@layout/place_page_hotel_gallery"/>
|
||||
<include layout="@layout/place_page_hotel_description"/>
|
||||
|
||||
<include layout="@layout/place_page_hotel_facilities"/>
|
||||
<include layout="@layout/place_page_placename"/>
|
||||
|
||||
<include layout="@layout/place_page_hotel_description"/>
|
||||
<include layout="@layout/place_page_opening_hours"/>
|
||||
|
||||
<include layout="@layout/place_page_placename"/>
|
||||
<include layout="@layout/place_page_entrance"/>
|
||||
|
||||
<include layout="@layout/place_page_opening_hours"/>
|
||||
<include layout="@layout/place_page_phone"/>
|
||||
|
||||
<include layout="@layout/place_page_entrance"/>
|
||||
<include layout="@layout/place_page_website"/>
|
||||
|
||||
<include layout="@layout/place_page_phone"/>
|
||||
<include layout="@layout/place_page_wiki"/>
|
||||
|
||||
<include layout="@layout/place_page_website"/>
|
||||
<include layout="@layout/place_page_email"/>
|
||||
|
||||
<include layout="@layout/place_page_wiki"/>
|
||||
<include layout="@layout/place_page_latlon"/>
|
||||
|
||||
<include layout="@layout/place_page_email"/>
|
||||
<include layout="@layout/place_page_wifi"/>
|
||||
|
||||
<include layout="@layout/place_page_latlon"/>
|
||||
<include layout="@layout/place_page_operator"/>
|
||||
|
||||
<include layout="@layout/place_page_wifi"/>
|
||||
<include layout="@layout/place_page_cuisine"/>
|
||||
|
||||
<include layout="@layout/place_page_operator"/>
|
||||
<include layout="@layout/place_page_hotel_nearby"/>
|
||||
|
||||
<include layout="@layout/place_page_cuisine"/>
|
||||
<include layout="@layout/place_page_hotel_rating"/>
|
||||
|
||||
<include layout="@layout/place_page_hotel_nearby"/>
|
||||
<!--TODO: remove this after booking_api.cpp will be done-->
|
||||
<include layout="@layout/place_page_more"/>
|
||||
|
||||
<include layout="@layout/place_page_hotel_rating"/>
|
||||
<include layout="@layout/divider_horizontal"/>
|
||||
|
||||
<!--TODO: remove this after booking_api.cpp will be done-->
|
||||
<include layout="@layout/place_page_more"/>
|
||||
<include layout="@layout/place_page_editor"/>
|
||||
|
||||
<include layout="@layout/divider_horizontal"/>
|
||||
<include layout="@layout/place_page_add_business"/>
|
||||
|
||||
<include layout="@layout/place_page_editor"/>
|
||||
<include layout="@layout/place_page_add"/>
|
||||
|
||||
<include layout="@layout/place_page_add_business"/>
|
||||
|
||||
<include layout="@layout/place_page_add"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</com.mapswithme.maps.widget.ObservableScrollView>
|
||||
</LinearLayout>
|
||||
|
||||
<include layout="@layout/shadow_top"/>
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
style="@style/MwmWidget.ToolbarStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
android:theme="@style/MwmWidget.ToolbarTheme"/>
|
||||
android:theme="@style/MwmWidget.ToolbarTheme.DownButton"/>
|
||||
|
||||
<FrameLayout
|
||||
style="@style/MwmWidget.FrameLayout.Elevation"
|
||||
|
|
|
@ -102,6 +102,14 @@
|
|||
<item name="windowActionBarOverlay">true</item>
|
||||
</style>
|
||||
|
||||
<style
|
||||
name="MwmWidget.ToolbarTheme.DownButton"
|
||||
parent="ThemeOverlay.AppCompat.Dark.ActionBar">
|
||||
<item name="android:gravity">center_vertical</item>
|
||||
<item name="colorAccent">@android:color/white</item>
|
||||
<item name="android:homeAsUpIndicator">@drawable/ic_down</item>
|
||||
</style>
|
||||
|
||||
<style name="MwmWidget.ListView" parent="Widget.AppCompat.ListView">
|
||||
<item name="android:fadingEdge">none</item>
|
||||
<item name="android:divider">@color/divider</item>
|
||||
|
|
|
@ -108,7 +108,7 @@ public class MwmActivity extends BaseMwmFragmentActivity
|
|||
EditorHostFragment.class.getName(),
|
||||
ReportFragment.class.getName() };
|
||||
// Instance state
|
||||
private static final String STATE_PP_OPENED = "PpOpened";
|
||||
private static final String STATE_PP = "PpState";
|
||||
private static final String STATE_MAP_OBJECT = "MapObject";
|
||||
|
||||
// Map tasks that we run AFTER rendering initialized
|
||||
|
@ -143,6 +143,7 @@ public class MwmActivity extends BaseMwmFragmentActivity
|
|||
|
||||
// The first launch of application ever - onboarding screen will be shown.
|
||||
private boolean mFirstStart;
|
||||
private boolean mPlacePageRestored;
|
||||
|
||||
public interface LeftAnimationTrackListener
|
||||
{
|
||||
|
@ -522,7 +523,7 @@ public class MwmActivity extends BaseMwmFragmentActivity
|
|||
mNavMyPosition = new MyPositionButton(frame.findViewById(R.id.my_position));
|
||||
}
|
||||
|
||||
private boolean closePlacePage()
|
||||
public boolean closePlacePage()
|
||||
{
|
||||
if (mPlacePage.isHidden())
|
||||
return false;
|
||||
|
@ -735,7 +736,7 @@ public class MwmActivity extends BaseMwmFragmentActivity
|
|||
{
|
||||
if (!mPlacePage.isHidden())
|
||||
{
|
||||
outState.putBoolean(STATE_PP_OPENED, true);
|
||||
outState.putInt(STATE_PP, mPlacePage.getState().ordinal());
|
||||
outState.putParcelable(STATE_MAP_OBJECT, mPlacePage.getMapObject());
|
||||
}
|
||||
|
||||
|
@ -761,8 +762,13 @@ public class MwmActivity extends BaseMwmFragmentActivity
|
|||
{
|
||||
super.onRestoreInstanceState(savedInstanceState);
|
||||
|
||||
if (savedInstanceState.getBoolean(STATE_PP_OPENED))
|
||||
mPlacePage.setState(State.PREVIEW);
|
||||
State state = State.values()[savedInstanceState.getInt(STATE_PP, 0)];
|
||||
if (state != State.HIDDEN)
|
||||
{
|
||||
mPlacePageRestored = true;
|
||||
mPlacePage.setMapObject((MapObject) savedInstanceState.getParcelable(STATE_MAP_OBJECT), true);
|
||||
mPlacePage.setState(state);
|
||||
}
|
||||
|
||||
if (!mIsFragmentContainer && RoutingController.get().isPlanning())
|
||||
mRoutingPlanInplaceController.restoreState(savedInstanceState);
|
||||
|
@ -820,6 +826,7 @@ public class MwmActivity extends BaseMwmFragmentActivity
|
|||
{
|
||||
super.onResume();
|
||||
|
||||
mPlacePageRestored = mPlacePage.getState() != State.HIDDEN;
|
||||
mSearchController.refreshToolbar();
|
||||
mMainMenu.onResume(new Runnable()
|
||||
{
|
||||
|
@ -1025,7 +1032,9 @@ public class MwmActivity extends BaseMwmFragmentActivity
|
|||
setFullscreen(false);
|
||||
|
||||
mPlacePage.setMapObject(object, true);
|
||||
mPlacePage.setState(State.PREVIEW);
|
||||
if (!mPlacePageRestored)
|
||||
mPlacePage.setState(State.PREVIEW);
|
||||
mPlacePageRestored = false;
|
||||
|
||||
if (UiUtils.isVisible(mFadeView))
|
||||
mFadeView.fadeOut();
|
||||
|
|
|
@ -120,7 +120,7 @@ class DownloaderAdapter extends RecyclerView.Adapter<DownloaderAdapter.ViewHolde
|
|||
}
|
||||
|
||||
@Override
|
||||
void invoke(final CountryItem item, DownloaderAdapter adapter)
|
||||
void invoke(final CountryItem item, final DownloaderAdapter adapter)
|
||||
{
|
||||
if (RoutingController.get().isNavigating())
|
||||
{
|
||||
|
@ -134,7 +134,7 @@ class DownloaderAdapter extends RecyclerView.Adapter<DownloaderAdapter.ViewHolde
|
|||
|
||||
if (!MapManager.nativeHasUnsavedEditorChanges(item.id))
|
||||
{
|
||||
deleteNode(item);
|
||||
deleteNode(item, adapter);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -147,10 +147,19 @@ class DownloaderAdapter extends RecyclerView.Adapter<DownloaderAdapter.ViewHolde
|
|||
@Override
|
||||
public void onClick(DialogInterface dialog, int which)
|
||||
{
|
||||
deleteNode(item);
|
||||
deleteNode(item, adapter);
|
||||
}
|
||||
}).show();
|
||||
}
|
||||
|
||||
private void deleteNode(CountryItem item, DownloaderAdapter adapter)
|
||||
{
|
||||
if (adapter.mActivity instanceof MwmActivity)
|
||||
{
|
||||
((MwmActivity) adapter.mActivity).closePlacePage();
|
||||
}
|
||||
deleteNode(item);
|
||||
}
|
||||
},
|
||||
|
||||
CANCEL(R.drawable.ic_cancel, R.string.cancel)
|
||||
|
|
|
@ -6,8 +6,12 @@ import android.view.LayoutInflater;
|
|||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.bumptech.glide.load.resource.drawable.GlideDrawable;
|
||||
import com.bumptech.glide.request.RequestListener;
|
||||
import com.bumptech.glide.request.target.Target;
|
||||
import com.mapswithme.maps.R;
|
||||
import com.mapswithme.maps.base.BaseMwmFragment;
|
||||
|
||||
|
@ -35,8 +39,34 @@ public class FullScreenGalleryFragment extends BaseMwmFragment
|
|||
if (mImage != null)
|
||||
{
|
||||
ImageView imageView = (ImageView) view.findViewById(R.id.iv__image);
|
||||
final View progress = view.findViewById(R.id.pb__loading_image);
|
||||
Glide.with(view.getContext())
|
||||
.load(mImage.getUrl())
|
||||
.listener(new RequestListener<String, GlideDrawable>()
|
||||
{
|
||||
@Override
|
||||
public boolean onException(Exception e, String model, Target<GlideDrawable> target,
|
||||
boolean isFirstResource)
|
||||
{
|
||||
if (isVisible())
|
||||
{
|
||||
progress.setVisibility(View.GONE);
|
||||
Toast.makeText(getContext(), getString(R.string.download_failed),
|
||||
Toast.LENGTH_LONG).show();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onResourceReady(GlideDrawable resource, String model,
|
||||
Target<GlideDrawable> target, boolean isFromMemoryCache,
|
||||
boolean isFirstResource)
|
||||
{
|
||||
if (isVisible())
|
||||
progress.setVisibility(View.GONE);
|
||||
return false;
|
||||
}
|
||||
})
|
||||
.into(imageView);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,8 @@ package com.mapswithme.maps.widget;
|
|||
|
||||
import android.content.Context;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.view.GestureDetectorCompat;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
import android.widget.ScrollView;
|
||||
|
@ -48,6 +50,8 @@ public class ObservableScrollView extends ScrollView
|
|||
private ScrollListener mScrollListener;
|
||||
private int mPrevScroll;
|
||||
private boolean mTouched;
|
||||
@Nullable
|
||||
private GestureDetectorCompat mGestureDetector;
|
||||
|
||||
|
||||
public ObservableScrollView(Context context)
|
||||
|
@ -65,6 +69,17 @@ public class ObservableScrollView extends ScrollView
|
|||
super(context, attrs, defStyle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Translate all {@link MotionEvent}s to specified {@link GestureDetectorCompat}
|
||||
* all consuming flags from GestureDetectorCompat.onTouchEvent are ignored.
|
||||
*
|
||||
* @param gestureDetector {@link GestureDetectorCompat} to use.
|
||||
*/
|
||||
public void setGestureDetector(@Nullable GestureDetectorCompat gestureDetector)
|
||||
{
|
||||
mGestureDetector = gestureDetector;
|
||||
}
|
||||
|
||||
private boolean shouldSkipEvent(MotionEvent ev)
|
||||
{
|
||||
return (mTouched &&
|
||||
|
@ -83,6 +98,9 @@ public class ObservableScrollView extends ScrollView
|
|||
@Override
|
||||
public boolean onTouchEvent(@NonNull MotionEvent ev)
|
||||
{
|
||||
if (mGestureDetector != null)
|
||||
mGestureDetector.onTouchEvent(ev);
|
||||
|
||||
if (!super.onTouchEvent(ev))
|
||||
return false;
|
||||
|
||||
|
|
|
@ -10,58 +10,65 @@ import android.view.ViewConfiguration;
|
|||
import android.view.ViewGroup;
|
||||
import android.view.animation.AccelerateInterpolator;
|
||||
import android.view.animation.Interpolator;
|
||||
import android.widget.ScrollView;
|
||||
|
||||
import com.mapswithme.maps.MwmApplication;
|
||||
import com.mapswithme.maps.R;
|
||||
import com.mapswithme.maps.bookmarks.data.MapObject;
|
||||
import com.mapswithme.maps.widget.ObservableScrollView;
|
||||
import com.mapswithme.maps.widget.placepage.PlacePageView.State;
|
||||
import com.mapswithme.util.UiUtils;
|
||||
|
||||
/**
|
||||
* Class is responsible for animations of PP(place page) and PPP(place page preview).
|
||||
*/
|
||||
public abstract class BasePlacePageAnimationController
|
||||
public abstract class BasePlacePageAnimationController implements ObservableScrollView.ScrollListener
|
||||
{
|
||||
protected static final int DURATION = MwmApplication.get().getResources().getInteger(R.integer.anim_placepage);
|
||||
protected static final TimeInterpolator INTERPOLATOR = new AccelerateInterpolator();
|
||||
protected State mState = State.HIDDEN;
|
||||
private static final int DURATION = MwmApplication.get()
|
||||
.getResources()
|
||||
.getInteger(R.integer.anim_placepage);
|
||||
private static final TimeInterpolator INTERPOLATOR = new AccelerateInterpolator();
|
||||
State mState = State.HIDDEN;
|
||||
|
||||
protected PlacePageView mPlacePage;
|
||||
protected ViewGroup mPreview;
|
||||
protected ViewGroup mDetailsFrame;
|
||||
protected ScrollView mDetailsScroll;
|
||||
protected View mDetailsContent;
|
||||
protected ViewGroup mBookmarkDetails;
|
||||
protected ViewGroup mButtons;
|
||||
PlacePageView mPlacePage;
|
||||
ViewGroup mPreview;
|
||||
ViewGroup mDetailsFrame;
|
||||
ObservableScrollView mDetailsScroll;
|
||||
View mDetailsContent;
|
||||
ViewGroup mBookmarkDetails;
|
||||
ViewGroup mButtons;
|
||||
// Gestures
|
||||
protected GestureDetectorCompat mGestureDetector;
|
||||
protected boolean mIsDragging;
|
||||
protected float mDownCoord;
|
||||
protected float mTouchSlop;
|
||||
GestureDetectorCompat mGestureDetector;
|
||||
boolean mIsDragging;
|
||||
float mDownCoord;
|
||||
float mTouchSlop;
|
||||
int mCurrentScrollY;
|
||||
|
||||
protected OnVisibilityChangedListener mVisibilityListener;
|
||||
private OnVisibilityChangedListener mVisibilityListener;
|
||||
|
||||
public interface OnVisibilityChangedListener
|
||||
{
|
||||
|
||||
void onPreviewVisibilityChanged(boolean isVisible);
|
||||
|
||||
void onPlacePageVisibilityChanged(boolean isVisible);
|
||||
}
|
||||
protected OnAnimationListener mProgressListener;
|
||||
|
||||
public interface OnAnimationListener
|
||||
private OnAnimationListener mProgressListener;
|
||||
|
||||
interface OnAnimationListener
|
||||
{
|
||||
void onProgress(float translationX, float translationY);
|
||||
}
|
||||
|
||||
protected abstract void initGestureDetector();
|
||||
|
||||
public BasePlacePageAnimationController(@NonNull PlacePageView placePage)
|
||||
BasePlacePageAnimationController(@NonNull PlacePageView placePage)
|
||||
{
|
||||
mPlacePage = placePage;
|
||||
mPreview = (ViewGroup) placePage.findViewById(R.id.pp__preview);
|
||||
mDetailsFrame = (ViewGroup) placePage.findViewById(R.id.pp__details_frame);
|
||||
mDetailsScroll = (ScrollView) placePage.findViewById(R.id.pp__details);
|
||||
mDetailsScroll = (ObservableScrollView) placePage.findViewById(R.id.pp__details);
|
||||
mDetailsScroll.setScrollListener(this);
|
||||
mDetailsContent = mDetailsScroll.getChildAt(0);
|
||||
mBookmarkDetails = (ViewGroup) mDetailsFrame.findViewById(R.id.bookmark_frame);
|
||||
mButtons = (ViewGroup) placePage.findViewById(R.id.pp__buttons);
|
||||
|
@ -70,7 +77,8 @@ public abstract class BasePlacePageAnimationController
|
|||
mTouchSlop = ViewConfiguration.get(mPlacePage.getContext()).getScaledTouchSlop();
|
||||
|
||||
if (mPlacePage.isFloating() || mPlacePage.isDocked())
|
||||
mDetailsFrame.setPadding(mDetailsFrame.getPaddingLeft(), mDetailsFrame.getPaddingTop(), mDetailsFrame.getPaddingRight(),
|
||||
mDetailsFrame.setPadding(mDetailsFrame.getPaddingLeft(), mDetailsFrame.getPaddingTop(), mDetailsFrame
|
||||
.getPaddingRight(),
|
||||
UiUtils.dimen(R.dimen.place_page_buttons_height));
|
||||
|
||||
if (mPlacePage.isDocked())
|
||||
|
@ -83,6 +91,17 @@ public abstract class BasePlacePageAnimationController
|
|||
initialVisibility();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScroll(int left, int top)
|
||||
{
|
||||
mCurrentScrollY = top;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScrollEnd()
|
||||
{
|
||||
}
|
||||
|
||||
protected void initialVisibility()
|
||||
{
|
||||
UiUtils.invisible(mPlacePage, mPreview, mDetailsFrame, mBookmarkDetails);
|
||||
|
@ -93,9 +112,10 @@ public abstract class BasePlacePageAnimationController
|
|||
return mState;
|
||||
}
|
||||
|
||||
public void setState(final State state, @MapObject.MapObjectType final int type)
|
||||
void setState(final State state, @MapObject.MapObjectType final int type)
|
||||
{
|
||||
mPlacePage.post(new Runnable() {
|
||||
mPlacePage.post(new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
|
@ -107,7 +127,7 @@ public abstract class BasePlacePageAnimationController
|
|||
|
||||
protected abstract void onStateChanged(State currentState, State newState, int type);
|
||||
|
||||
public void setOnVisibilityChangedListener(OnVisibilityChangedListener listener)
|
||||
void setOnVisibilityChangedListener(OnVisibilityChangedListener listener)
|
||||
{
|
||||
mVisibilityListener = listener;
|
||||
}
|
||||
|
@ -124,7 +144,7 @@ public abstract class BasePlacePageAnimationController
|
|||
return mGestureDetector.onTouchEvent(event);
|
||||
}
|
||||
|
||||
protected void notifyVisibilityListener(boolean previewShown, boolean ppShown)
|
||||
void notifyVisibilityListener(boolean previewShown, boolean ppShown)
|
||||
{
|
||||
if (mVisibilityListener != null)
|
||||
{
|
||||
|
@ -133,7 +153,7 @@ public abstract class BasePlacePageAnimationController
|
|||
}
|
||||
}
|
||||
|
||||
protected void notifyProgress(float translationX, float translationY)
|
||||
void notifyProgress(float translationX, float translationY)
|
||||
{
|
||||
if (mProgressListener == null)
|
||||
return;
|
||||
|
@ -141,12 +161,12 @@ public abstract class BasePlacePageAnimationController
|
|||
mProgressListener.onProgress(translationX, translationY);
|
||||
}
|
||||
|
||||
protected void startDefaultAnimator(ValueAnimator animator)
|
||||
void startDefaultAnimator(ValueAnimator animator)
|
||||
{
|
||||
startDefaultAnimator(animator, new AccelerateInterpolator());
|
||||
}
|
||||
|
||||
protected void startDefaultAnimator(ValueAnimator animator, Interpolator interpolator)
|
||||
void startDefaultAnimator(ValueAnimator animator, Interpolator interpolator)
|
||||
{
|
||||
animator.setDuration(DURATION);
|
||||
animator.setInterpolator(interpolator == null ? INTERPOLATOR : interpolator);
|
||||
|
|
|
@ -6,13 +6,13 @@ import android.annotation.SuppressLint;
|
|||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.view.GestureDetectorCompat;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.view.GestureDetector;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.animation.AccelerateInterpolator;
|
||||
import android.view.animation.Interpolator;
|
||||
import android.view.animation.OvershootInterpolator;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import com.mapswithme.maps.R;
|
||||
|
@ -23,32 +23,21 @@ import com.mapswithme.util.concurrency.UiThread;
|
|||
|
||||
class BottomPlacePageAnimationController extends BasePlacePageAnimationController
|
||||
{
|
||||
@SuppressWarnings("unused")
|
||||
private static final String TAG = BottomPlacePageAnimationController.class.getSimpleName();
|
||||
private static final float DETAIL_RATIO = 0.7f;
|
||||
private static final float SCROLL_DELTA = 50.0f;
|
||||
private final ViewGroup mLayoutToolbar;
|
||||
|
||||
private final AnimationHelper mAnimationHelper = new AnimationHelper();
|
||||
private ValueAnimator mCurrentAnimator;
|
||||
|
||||
private boolean mIsGestureStartedInsideView;
|
||||
private boolean mIsGestureFinished;
|
||||
|
||||
private class AnimationHelper
|
||||
{
|
||||
final View.OnLayoutChangeListener mListener = 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)
|
||||
{
|
||||
if (mState == State.DETAILS && v.getId() == mDetailsFrame.getId() && top != oldTop)
|
||||
{
|
||||
mPreview.setTranslationY(-mDetailsContent.getHeight());
|
||||
refreshToolbarVisibility();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
private float mDetailMaxHeight;
|
||||
private float mScrollDelta;
|
||||
|
||||
public BottomPlacePageAnimationController(@NonNull PlacePageView placePage)
|
||||
BottomPlacePageAnimationController(@NonNull PlacePageView placePage)
|
||||
{
|
||||
super(placePage);
|
||||
mLayoutToolbar = (LinearLayout) mPlacePage.findViewById(R.id.toolbar_layout);
|
||||
|
@ -68,6 +57,11 @@ class BottomPlacePageAnimationController extends BasePlacePageAnimationControlle
|
|||
}
|
||||
});
|
||||
}
|
||||
|
||||
DisplayMetrics dm = placePage.getResources().getDisplayMetrics();
|
||||
float screenHeight = dm.heightPixels;
|
||||
mDetailMaxHeight = screenHeight * DETAIL_RATIO;
|
||||
mScrollDelta = SCROLL_DELTA * dm.density;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -75,60 +69,32 @@ class BottomPlacePageAnimationController extends BasePlacePageAnimationControlle
|
|||
{
|
||||
switch (event.getAction())
|
||||
{
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
if (!isInsideView(event.getY()))
|
||||
{
|
||||
mIsGestureStartedInsideView = false;
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
if (!UiUtils.isViewTouched(event, mDetailsScroll))
|
||||
{
|
||||
mIsGestureStartedInsideView = false;
|
||||
break;
|
||||
}
|
||||
|
||||
mIsGestureStartedInsideView = true;
|
||||
mIsDragging = false;
|
||||
mIsGestureFinished = false;
|
||||
mDownCoord = event.getY();
|
||||
break;
|
||||
}
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
if (!mIsGestureStartedInsideView)
|
||||
break;
|
||||
|
||||
final float delta = mDownCoord - event.getY();
|
||||
if (Math.abs(delta) > mTouchSlop && !isDetailsScroll(delta))
|
||||
return true;
|
||||
|
||||
mIsGestureStartedInsideView = true;
|
||||
mIsDragging = false;
|
||||
mIsGestureFinished = false;
|
||||
mDownCoord = event.getY();
|
||||
break;
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
if (!mIsGestureStartedInsideView)
|
||||
break;
|
||||
|
||||
final float delta = mDownCoord - event.getY();
|
||||
if (Math.abs(delta) > mTouchSlop && !isDetailsScroll(mDownCoord, delta))
|
||||
return true;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isInsideView(float y)
|
||||
{
|
||||
return y > mPreview.getY() && y < mButtons.getY();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return whether gesture is scrolling of details content(and not dragging PP itself).
|
||||
*/
|
||||
private boolean isDetailsScroll(float y, float delta)
|
||||
{
|
||||
return isOnDetails(y) && isDetailsScrollable() && canScroll(delta);
|
||||
}
|
||||
|
||||
private boolean isOnDetails(float y)
|
||||
{
|
||||
return y > mDetailsFrame.getY() && y < mButtons.getY();
|
||||
}
|
||||
|
||||
private boolean isDetailsScrollable()
|
||||
{
|
||||
return mDetailsFrame.getHeight() < mDetailsContent.getHeight();
|
||||
}
|
||||
|
||||
private boolean canScroll(float delta)
|
||||
{
|
||||
return mDetailsScroll.getScrollY() != 0 || delta > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean onTouchEvent(@NonNull MotionEvent event)
|
||||
{
|
||||
|
@ -136,14 +102,13 @@ class BottomPlacePageAnimationController extends BasePlacePageAnimationControlle
|
|||
return false;
|
||||
|
||||
final boolean finishedDrag = (mIsDragging &&
|
||||
(event.getAction() == MotionEvent.ACTION_UP ||
|
||||
event.getAction() == MotionEvent.ACTION_CANCEL));
|
||||
if (!mIsGestureStartedInsideView ||
|
||||
!isInsideView(event.getY()) ||
|
||||
finishedDrag)
|
||||
(event.getAction() == MotionEvent.ACTION_UP ||
|
||||
event.getAction() == MotionEvent.ACTION_CANCEL));
|
||||
if (!mIsGestureStartedInsideView || !UiUtils.isViewTouched(event, mDetailsScroll)
|
||||
|| finishedDrag)
|
||||
{
|
||||
mIsGestureFinished = true;
|
||||
finishDrag();
|
||||
finishDrag(mDownCoord - event.getY());
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -151,6 +116,41 @@ class BottomPlacePageAnimationController extends BasePlacePageAnimationControlle
|
|||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScroll(int left, int top)
|
||||
{
|
||||
super.onScroll(left, top);
|
||||
|
||||
if (mCurrentScrollY > 0 && mDetailsScroll.getTranslationY() > 0)
|
||||
{
|
||||
mPlacePage.setState(State.HIDDEN);
|
||||
}
|
||||
refreshToolbarVisibility();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return whether gesture is scrolling of details content(and not dragging PP itself).
|
||||
*/
|
||||
private boolean isDetailsScroll(float delta)
|
||||
{
|
||||
return isDetailsScrollable() && canScroll(delta);
|
||||
}
|
||||
|
||||
private boolean isDetailsScrollable()
|
||||
{
|
||||
return mPlacePage.getState() == State.FULLSCREEN && isDetailContentScrollable();
|
||||
}
|
||||
|
||||
private boolean isDetailContentScrollable()
|
||||
{
|
||||
return mDetailsScroll.getHeight() < mDetailsContent.getHeight();
|
||||
}
|
||||
|
||||
private boolean canScroll(float delta)
|
||||
{
|
||||
return mDetailsScroll.getScrollY() != 0 || delta > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initGestureDetector()
|
||||
{
|
||||
|
@ -166,7 +166,18 @@ class BottomPlacePageAnimationController extends BasePlacePageAnimationControlle
|
|||
if (isVertical)
|
||||
{
|
||||
mIsDragging = true;
|
||||
translateBy(-distanceY);
|
||||
if (!translateBy(-distanceY))
|
||||
{
|
||||
if (mDetailsScroll.getTranslationY() == 0)
|
||||
{
|
||||
mDetailsScroll.scrollBy((int) distanceX, (int) distanceY);
|
||||
mState = State.FULLSCREEN;
|
||||
}
|
||||
else
|
||||
{
|
||||
mPlacePage.setState(State.HIDDEN);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -175,67 +186,136 @@ class BottomPlacePageAnimationController extends BasePlacePageAnimationControlle
|
|||
@Override
|
||||
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY)
|
||||
{
|
||||
mPlacePage.setState(velocityY > 0 ? State.HIDDEN : State.DETAILS);
|
||||
return super.onFling(e1, e2, velocityX, velocityY);
|
||||
finishDrag(-velocityY);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onSingleTapConfirmed(MotionEvent e)
|
||||
{
|
||||
if (!isInPreview(e.getY()))
|
||||
return false;
|
||||
|
||||
mPlacePage.setState(mPlacePage.getState() == State.PREVIEW ? State.DETAILS
|
||||
: State.PREVIEW);
|
||||
|
||||
MotionEvent evt = MotionEvent.obtain(e.getDownTime(),
|
||||
e.getEventTime(),
|
||||
e.getAction(),
|
||||
e.getX(),
|
||||
mDownCoord,
|
||||
e.getMetaState());
|
||||
if (UiUtils.isViewTouched(evt, mPreview))
|
||||
{
|
||||
if (mPlacePage.getState() == State.PREVIEW)
|
||||
{
|
||||
if (isDetailContentScrollable())
|
||||
{
|
||||
mPlacePage.setState(State.DETAILS);
|
||||
}
|
||||
else
|
||||
{
|
||||
mPlacePage.setState(State.FULLSCREEN);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mPlacePage.setState(State.PREVIEW);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
mDetailsScroll.setGestureDetector(mGestureDetector);
|
||||
}
|
||||
|
||||
private boolean isInPreview(float y)
|
||||
private void finishDrag(float distance)
|
||||
{
|
||||
return y > (mPreview.getTop() + mPreview.getTranslationY())
|
||||
&& y < (mPreview.getBottom() + mPreview.getTranslationY());
|
||||
}
|
||||
|
||||
private void finishDrag()
|
||||
{
|
||||
final float currentTranslation = mDetailsFrame.getTranslationY();
|
||||
final float currentTranslation = mDetailsScroll.getTranslationY();
|
||||
if (currentTranslation > mDetailsScroll.getHeight())
|
||||
{
|
||||
mPlacePage.setState(State.HIDDEN);
|
||||
return;
|
||||
}
|
||||
|
||||
@SuppressWarnings("UnnecessaryLocalVariable")
|
||||
final float deltaTop = currentTranslation;
|
||||
final float deltaBottom = mDetailsContent.getHeight() - currentTranslation;
|
||||
|
||||
mPlacePage.setState(deltaBottom > deltaTop ? State.DETAILS
|
||||
: State.PREVIEW);
|
||||
if (distance >= 0.0f) // drag up
|
||||
{
|
||||
if (mPlacePage.getState() == State.PREVIEW)
|
||||
{
|
||||
if (isDetailContentScrollable())
|
||||
{
|
||||
mPlacePage.setState(State.DETAILS);
|
||||
}
|
||||
else
|
||||
{
|
||||
mPlacePage.setState(State.FULLSCREEN);
|
||||
}
|
||||
}
|
||||
else if (mPlacePage.getState() != State.FULLSCREEN)
|
||||
{
|
||||
mPlacePage.setState(State.FULLSCREEN);
|
||||
}
|
||||
else if (mCurrentScrollY == 0 || mDetailsScroll.getTranslationY() > 0)
|
||||
{
|
||||
mPlacePage.setState(State.DETAILS);
|
||||
}
|
||||
}
|
||||
else // drag down
|
||||
{
|
||||
if (mPlacePage.getState() == State.FULLSCREEN)
|
||||
{
|
||||
if (isDetailContentScrollable())
|
||||
{
|
||||
mPlacePage.setState(State.DETAILS);
|
||||
}
|
||||
else
|
||||
{
|
||||
mPlacePage.setState(State.PREVIEW);
|
||||
}
|
||||
}
|
||||
else if (mPlacePage.getState() == State.DETAILS)
|
||||
{
|
||||
mPlacePage.setState(State.PREVIEW);
|
||||
}
|
||||
else
|
||||
{
|
||||
mPlacePage.setState(State.HIDDEN);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void translateBy(float distanceY)
|
||||
private boolean translateBy(float distanceY)
|
||||
{
|
||||
final float detailsHeight = mDetailsScroll.getHeight();
|
||||
float detailsTranslation = mDetailsFrame.getTranslationY() + distanceY;
|
||||
float previewTranslation = mPreview.getTranslationY() + distanceY;
|
||||
if (detailsTranslation < 0)
|
||||
if (mCurrentScrollY > 0)
|
||||
return false;
|
||||
|
||||
if (Math.abs(distanceY) > mScrollDelta)
|
||||
distanceY = 0.0f;
|
||||
float detailsTranslation = mDetailsScroll.getTranslationY() + distanceY;
|
||||
final boolean isScrollable = isDetailContentScrollable();
|
||||
boolean consumeEvent = true;
|
||||
final float maxTranslationY = mDetailsScroll.getHeight() - mDetailsContent.getHeight();
|
||||
if ((isScrollable && detailsTranslation < 0.0f) || detailsTranslation < maxTranslationY)
|
||||
{
|
||||
detailsTranslation = 0;
|
||||
previewTranslation = -detailsHeight;
|
||||
if (isScrollable)
|
||||
{
|
||||
detailsTranslation = 0.0f;
|
||||
mDetailsScroll.setGestureDetector(null);
|
||||
}
|
||||
else
|
||||
{
|
||||
detailsTranslation = maxTranslationY;
|
||||
}
|
||||
|
||||
mState = State.FULLSCREEN;
|
||||
consumeEvent = false;
|
||||
}
|
||||
|
||||
mPreview.setTranslationY(previewTranslation);
|
||||
mDetailsFrame.setTranslationY(detailsTranslation);
|
||||
mDetailsScroll.setTranslationY(detailsTranslation);
|
||||
refreshToolbarVisibility();
|
||||
return consumeEvent;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStateChanged(final State currentState, final State newState, @MapObject.MapObjectType int type)
|
||||
{
|
||||
prepareYTranslations(currentState, newState, type);
|
||||
prepareYTranslations(newState, type);
|
||||
|
||||
mDetailsScroll.setGestureDetector(mGestureDetector);
|
||||
mPlacePage.post(new Runnable()
|
||||
{
|
||||
@Override
|
||||
|
@ -244,79 +324,72 @@ class BottomPlacePageAnimationController extends BasePlacePageAnimationControlle
|
|||
endRunningAnimation();
|
||||
switch (newState)
|
||||
{
|
||||
case HIDDEN:
|
||||
hidePlacePage();
|
||||
break;
|
||||
case PREVIEW:
|
||||
showPreview(currentState);
|
||||
break;
|
||||
case DETAILS:
|
||||
showDetails(currentState);
|
||||
break;
|
||||
case HIDDEN:
|
||||
hidePlacePage();
|
||||
break;
|
||||
case PREVIEW:
|
||||
showPreview(currentState);
|
||||
break;
|
||||
case DETAILS:
|
||||
showDetails();
|
||||
break;
|
||||
case FULLSCREEN:
|
||||
if (isDetailContentScrollable())
|
||||
mDetailsScroll.setGestureDetector(null);
|
||||
showFullscreen();
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares widgets for animating, places them vertically accordingly to their supposed positions.
|
||||
* Prepares widgets for animating, places them vertically accordingly to their supposed
|
||||
* positions.
|
||||
*/
|
||||
private void prepareYTranslations(State currentState, State newState, @MapObject.MapObjectType int type)
|
||||
private void prepareYTranslations(State newState, @MapObject.MapObjectType int type)
|
||||
{
|
||||
switch (newState)
|
||||
{
|
||||
case PREVIEW:
|
||||
if (mState == State.HIDDEN)
|
||||
{
|
||||
UiUtils.invisible(mPlacePage, mPreview, mDetailsFrame, mButtons);
|
||||
UiUtils.showIf(type == MapObject.BOOKMARK, mBookmarkDetails);
|
||||
mPlacePage.post(new Runnable()
|
||||
case PREVIEW:
|
||||
if (mState == State.HIDDEN)
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
UiUtils.invisible(mPlacePage, mPreview, mDetailsFrame, mButtons);
|
||||
UiUtils.showIf(type == MapObject.BOOKMARK, mBookmarkDetails);
|
||||
mPlacePage.post(new Runnable()
|
||||
{
|
||||
final float previewTranslation = mPreview.getHeight() + mButtons.getHeight();
|
||||
mPreview.setTranslationY(previewTranslation);
|
||||
mDetailsFrame.setTranslationY(mDetailsFrame.getHeight());
|
||||
mButtons.setTranslationY(previewTranslation);
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
mDetailsScroll.setTranslationY(mDetailsScroll.getHeight());
|
||||
mButtons.setTranslationY(mPreview.getHeight() + mButtons.getHeight());
|
||||
|
||||
UiUtils.show(mPlacePage, mPreview, mButtons, mDetailsFrame);
|
||||
}
|
||||
});
|
||||
}
|
||||
break;
|
||||
case DETAILS:
|
||||
UiUtils.show(mPlacePage, mPreview, mDetailsFrame);
|
||||
UiUtils.showIf(type == MapObject.BOOKMARK, mBookmarkDetails);
|
||||
break;
|
||||
UiUtils.show(mPlacePage, mPreview, mButtons, mDetailsFrame);
|
||||
}
|
||||
});
|
||||
}
|
||||
break;
|
||||
case FULLSCREEN:
|
||||
case DETAILS:
|
||||
UiUtils.show(mPlacePage, mPreview, mButtons, mDetailsFrame);
|
||||
UiUtils.showIf(type == MapObject.BOOKMARK, mBookmarkDetails);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
protected void showPreview(final State currentState)
|
||||
private void showPreview(final State currentState)
|
||||
{
|
||||
if (mLayoutToolbar != null)
|
||||
UiUtils.hide(mLayoutToolbar);
|
||||
|
||||
mDetailsFrame.addOnLayoutChangeListener(mAnimationHelper.mListener);
|
||||
|
||||
mCurrentAnimator = ValueAnimator.ofFloat(mPreview.getTranslationY(), 0f);
|
||||
final float detailsHeight = mDetailsFrame.getHeight();
|
||||
mCurrentAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener()
|
||||
{
|
||||
@Override
|
||||
public void onAnimationUpdate(ValueAnimator animation)
|
||||
{
|
||||
float translationY = (Float) animation.getAnimatedValue();
|
||||
mPreview.setTranslationY(translationY);
|
||||
mDetailsFrame.setTranslationY(translationY + detailsHeight);
|
||||
notifyProgress();
|
||||
}
|
||||
});
|
||||
Interpolator interpolator;
|
||||
final float translation = mDetailsScroll.getHeight() - mPreview.getHeight();
|
||||
mCurrentAnimator = ValueAnimator.ofFloat(mDetailsScroll.getTranslationY(), translation);
|
||||
mCurrentAnimator.addUpdateListener(new UpdateListener());
|
||||
Interpolator interpolator = new AccelerateInterpolator();
|
||||
if (currentState == State.HIDDEN)
|
||||
{
|
||||
interpolator = new OvershootInterpolator();
|
||||
mCurrentAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener()
|
||||
ValueAnimator buttonAnimator = ValueAnimator.ofFloat(mButtons.getTranslationY(), 0);
|
||||
buttonAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener()
|
||||
{
|
||||
@Override
|
||||
public void onAnimationUpdate(ValueAnimator animation)
|
||||
|
@ -324,10 +397,7 @@ class BottomPlacePageAnimationController extends BasePlacePageAnimationControlle
|
|||
mButtons.setTranslationY((Float) animation.getAnimatedValue());
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
interpolator = new AccelerateInterpolator();
|
||||
startDefaultAnimator(buttonAnimator, interpolator);
|
||||
}
|
||||
|
||||
mCurrentAnimator.addListener(new UiUtils.SimpleAnimatorListener()
|
||||
|
@ -342,45 +412,48 @@ class BottomPlacePageAnimationController extends BasePlacePageAnimationControlle
|
|||
startDefaultAnimator(mCurrentAnimator, interpolator);
|
||||
}
|
||||
|
||||
protected void showDetails(final State currentState)
|
||||
private void showDetails()
|
||||
{
|
||||
final float detailsScreenHeight = mDetailsScroll.getHeight();
|
||||
if (isDetailContentScrollable())
|
||||
{
|
||||
mCurrentAnimator = ValueAnimator.ofFloat(mDetailsScroll.getTranslationY(),
|
||||
mDetailsScroll.getHeight() - mDetailMaxHeight + mButtons
|
||||
.getHeight());
|
||||
}
|
||||
else
|
||||
{
|
||||
mCurrentAnimator = ValueAnimator.ofFloat(mDetailsScroll.getTranslationY(),
|
||||
mDetailsScroll.getHeight() - mDetailsContent.getHeight());
|
||||
}
|
||||
mCurrentAnimator.addUpdateListener(new UpdateListener());
|
||||
mCurrentAnimator.addListener(new AnimationListener());
|
||||
|
||||
mCurrentAnimator = ValueAnimator.ofFloat(mPreview.getTranslationY(), -detailsScreenHeight);
|
||||
mCurrentAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener()
|
||||
startDefaultAnimator();
|
||||
}
|
||||
|
||||
private void showFullscreen()
|
||||
{
|
||||
if (isDetailContentScrollable())
|
||||
{
|
||||
@Override
|
||||
public void onAnimationUpdate(ValueAnimator animation)
|
||||
{
|
||||
float translationY = (Float) animation.getAnimatedValue();
|
||||
mPreview.setTranslationY(translationY);
|
||||
mDetailsFrame.setTranslationY(translationY + detailsScreenHeight);
|
||||
notifyProgress();
|
||||
}
|
||||
});
|
||||
mCurrentAnimator.addListener(new UiUtils.SimpleAnimatorListener()
|
||||
mCurrentAnimator = ValueAnimator.ofFloat(mDetailsScroll.getTranslationY(), 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation)
|
||||
{
|
||||
refreshToolbarVisibility();
|
||||
notifyVisibilityListener(true, true);
|
||||
mDetailsScroll.scrollTo(0, 0);
|
||||
notifyProgress();
|
||||
}
|
||||
});
|
||||
mCurrentAnimator = ValueAnimator.ofFloat(mDetailsScroll.getTranslationY(),
|
||||
mDetailsScroll.getHeight() - mDetailsContent.getHeight());
|
||||
}
|
||||
mCurrentAnimator.addUpdateListener(new UpdateListener());
|
||||
mCurrentAnimator.addListener(new AnimationListener());
|
||||
|
||||
startDefaultAnimator();
|
||||
}
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
protected void hidePlacePage()
|
||||
private void hidePlacePage()
|
||||
{
|
||||
if (mLayoutToolbar != null)
|
||||
UiUtils.hide(mLayoutToolbar);
|
||||
|
||||
mDetailsFrame.removeOnLayoutChangeListener(mAnimationHelper.mListener);
|
||||
|
||||
final float animHeight = mPlacePage.getHeight() - mPreview.getY();
|
||||
mCurrentAnimator = ValueAnimator.ofFloat(0f, animHeight);
|
||||
mCurrentAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener()
|
||||
|
@ -423,7 +496,7 @@ class BottomPlacePageAnimationController extends BasePlacePageAnimationControlle
|
|||
}
|
||||
}
|
||||
|
||||
protected void refreshToolbarVisibility()
|
||||
private void refreshToolbarVisibility()
|
||||
{
|
||||
if (mLayoutToolbar != null)
|
||||
UiThread.runLater(new Runnable()
|
||||
|
@ -431,7 +504,7 @@ class BottomPlacePageAnimationController extends BasePlacePageAnimationControlle
|
|||
@Override
|
||||
public void run()
|
||||
{
|
||||
UiUtils.showIf(mPreview.getY() < 0, mLayoutToolbar);
|
||||
UiUtils.showIf(mCurrentScrollY > 0, mLayoutToolbar);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -440,4 +513,27 @@ class BottomPlacePageAnimationController extends BasePlacePageAnimationControlle
|
|||
{
|
||||
notifyProgress(0, mPreview.getTranslationY());
|
||||
}
|
||||
|
||||
private class UpdateListener implements ValueAnimator.AnimatorUpdateListener
|
||||
{
|
||||
@Override
|
||||
public void onAnimationUpdate(ValueAnimator animation)
|
||||
{
|
||||
float translationY = (Float) animation.getAnimatedValue();
|
||||
mDetailsScroll.setTranslationY(translationY);
|
||||
notifyProgress();
|
||||
}
|
||||
}
|
||||
|
||||
private class AnimationListener extends UiUtils.SimpleAnimatorListener
|
||||
{
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation)
|
||||
{
|
||||
refreshToolbarVisibility();
|
||||
notifyVisibilityListener(true, true);
|
||||
mDetailsScroll.scrollTo(0, 0);
|
||||
notifyProgress();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,7 +22,6 @@ import com.mapswithme.maps.bookmarks.ChooseBookmarkCategoryFragment.Listener;
|
|||
import com.mapswithme.maps.bookmarks.data.Bookmark;
|
||||
import com.mapswithme.maps.bookmarks.data.BookmarkManager;
|
||||
import com.mapswithme.maps.bookmarks.data.Icon;
|
||||
import com.mapswithme.util.InputUtils;
|
||||
import com.mapswithme.util.UiUtils;
|
||||
import com.mapswithme.util.statistics.Statistics;
|
||||
|
||||
|
@ -171,11 +170,11 @@ public class EditBookmarkFragment extends BaseMwmDialogFragment implements View.
|
|||
|
||||
private void refreshBookmark()
|
||||
{
|
||||
mEtName.setText(mBookmark.getTitle());
|
||||
mEtName.selectAll();
|
||||
InputUtils.showKeyboard(mEtName);
|
||||
if (TextUtils.isEmpty(mEtName.getText()))
|
||||
mEtName.setText(mBookmark.getTitle());
|
||||
|
||||
mEtDescription.setText(mBookmark.getBookmarkDescription());
|
||||
if (TextUtils.isEmpty(mEtDescription.getText()))
|
||||
mEtDescription.setText(mBookmark.getBookmarkDescription());
|
||||
mTvBookmarkGroup.setText(mBookmark.getCategoryName());
|
||||
refreshColorMarker();
|
||||
}
|
||||
|
|
|
@ -96,6 +96,7 @@ class LeftPlacePageAnimationController extends BasePlacePageAnimationController
|
|||
case HIDDEN:
|
||||
hidePlacePage();
|
||||
break;
|
||||
case FULLSCREEN:
|
||||
case DETAILS:
|
||||
case PREVIEW:
|
||||
showPlacePage(currentState);
|
||||
|
|
|
@ -20,6 +20,7 @@ import android.text.SpannableStringBuilder;
|
|||
import android.text.Spanned;
|
||||
import android.text.TextUtils;
|
||||
import android.text.style.ForegroundColorSpan;
|
||||
import android.text.util.Linkify;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
|
@ -96,7 +97,7 @@ public class PlacePageView extends RelativeLayout
|
|||
private static final String PREF_USE_DMS = "use_dms";
|
||||
|
||||
//TODO: remove this after booking_api.cpp will be done
|
||||
private static final boolean USE_OLD_BOOKING = true;
|
||||
private static final boolean USE_OLD_BOOKING = false;
|
||||
|
||||
private boolean mIsDocked;
|
||||
private boolean mIsFloating;
|
||||
|
@ -218,7 +219,8 @@ public class PlacePageView extends RelativeLayout
|
|||
{
|
||||
HIDDEN,
|
||||
PREVIEW,
|
||||
DETAILS
|
||||
DETAILS,
|
||||
FULLSCREEN
|
||||
}
|
||||
|
||||
public PlacePageView(Context context)
|
||||
|
@ -976,6 +978,7 @@ public class PlacePageView extends RelativeLayout
|
|||
mBookmarkSet = true;
|
||||
UiUtils.show(mBookmarkFrame);
|
||||
UiUtils.setTextAndHideIfEmpty(mBookmarkNote, ((Bookmark) mMapObject).getBookmarkDescription());
|
||||
Linkify.addLinks(mBookmarkNote, Linkify.ALL);
|
||||
updateButtons();
|
||||
}
|
||||
|
||||
|
@ -1209,7 +1212,7 @@ public class PlacePageView extends RelativeLayout
|
|||
@Override
|
||||
public void run()
|
||||
{
|
||||
setState(State.DETAILS);
|
||||
setState(mBookmarkSet ? State.DETAILS : State.PREVIEW);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -1316,7 +1319,7 @@ public class PlacePageView extends RelativeLayout
|
|||
if (mIsDocked || mIsFloating)
|
||||
return false;
|
||||
|
||||
if (getState() == State.DETAILS)
|
||||
if (getState() == State.DETAILS || getState() == State.FULLSCREEN)
|
||||
{
|
||||
hide();
|
||||
return true;
|
||||
|
|
Loading…
Add table
Reference in a new issue