[android] Removed custom animation controller for place page and replaced them with bottom sheet from sdk

This commit is contained in:
Александр Зацепин 2019-01-22 16:47:28 +03:00 committed by yoksnod
parent 823d823f52
commit da67f46423
25 changed files with 412 additions and 2035 deletions

View file

@ -1,91 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/coordinator"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:placePage="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="bottom">
<FrameLayout
android:id="@+id/map_fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<include
android:id="@+id/onmap_downloader"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
layout="@layout/onmap_downloader"/>
<include
android:id="@+id/position_chooser"
layout="@layout/position_chooser"/>
<include
android:id="@+id/navigation_buttons"
layout="@layout/map_navigation_buttons"/>
<include
android:id="@+id/toolbar"
layout="@layout/toolbar_with_search"
android:layout_width="match_parent"
android:layout_height="@dimen/search_box_height"
android:visibility="gone"
tools:visibility="visible"/>
<include layout="@layout/layout_nav_search"
android:visibility="gone"
tools:visibility="visible"/>
<com.mapswithme.maps.widget.FadeView
android:id="@+id/fade_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/black"
android:visibility="gone"/>
<include
layout="@layout/layout_nav"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/toolbar"
android:paddingBottom="@dimen/margin_base"
android:visibility="invisible"
tools:visibility="visible"/>
<include
layout="@layout/routing_plan"
android:visibility="invisible"/>
<include
android:id="@+id/menu_frame"
layout="@layout/menu"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"/>
<include
layout="@layout/search_filter_panel"
android:layout_width="match_parent"
android:layout_height="@dimen/height_block_base"
android:layout_alignParentBottom="true"/>
<com.mapswithme.maps.widget.placepage.PlacePageView
android:id="@+id/info_box"
style="@style/MwmWidget.Floating.Panel"
android:layout_width="@dimen/place_page_width"
android:layout_height="match_parent"
android:layout_alignWithParentIfMissing="true"
android:layout_below="@id/toolbar"
placePage:animationType="left"
placePage:docked="true"
tools:ignore="UnknownIdInLayout"/>
</RelativeLayout>
</android.support.design.widget.CoordinatorLayout>

View file

@ -1,12 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/coordinator"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:placePage="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
@ -73,12 +73,28 @@
android:layout_width="match_parent"
android:layout_height="@dimen/height_block_base"
android:layout_alignParentBottom="true"/>
<com.mapswithme.maps.widget.placepage.PlacePageView
android:id="@+id/info_box"
</RelativeLayout>
<FrameLayout
android:id="@+id/pp_bottom_sheet"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
placePage:animationType="bottom"/>
</RelativeLayout>
app:behavior_hideable="true"
app:layout_behavior="@string/bottom_sheet_behavior">
<com.mapswithme.maps.widget.placepage.PlacePageView
android:id="@+id/placepage"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</FrameLayout>
<FrameLayout
android:id="@+id/pp_buttons_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:visibility="invisible">
<include
android:id="@+id/pp_buttons"
layout="@layout/place_page_button_frame"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</FrameLayout>
</android.support.design.widget.CoordinatorLayout>

View file

@ -1,18 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<com.mapswithme.maps.widget.ObservableScrollView
<android.support.v4.widget.NestedScrollView
android:id="@+id/pp__details"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:overScrollMode="never"
android:layout_above="@+id/pp__buttons">
<com.mapswithme.maps.widget.ObservableLinearLayout
android:layout_height="wrap_content"
android:fillViewport="true">
<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"
@ -25,21 +22,8 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?panel"/>
<View
android:id="@+id/pp__height_compensation"
android:layout_width="match_parent"
android:layout_height="0dp"
android:background="?cardBackground"/>
</com.mapswithme.maps.widget.ObservableLinearLayout>
</com.mapswithme.maps.widget.ObservableScrollView>
<include
android:id="@+id/pp__buttons"
layout="@layout/place_page_button_frame"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"/>
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
<include
android:id="@+id/toolbar_layout"

View file

@ -2,8 +2,7 @@
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="@dimen/place_page_buttons_height"
android:layout_marginTop="@dimen/margin_base">
android:layout_height="@dimen/place_page_buttons_height">
<LinearLayout
android:id="@+id/container"
android:layout_width="match_parent"

View file

@ -103,11 +103,7 @@
<android.support.v4.widget.Space
android:layout_width="match_parent"
android:layout_height="@dimen/margin_base"/>
android:layout_height="@dimen/place_page_buttons_height"/>
</LinearLayout>
<include layout="@layout/shadow_top"/>
<include layout="@layout/shadow_bottom"/>
</FrameLayout>

View file

@ -6,6 +6,7 @@
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:gravity="center_vertical"
android:background="?cardBackground"
android:paddingTop="@dimen/margin_base">
<include

View file

@ -96,4 +96,5 @@
<string name="never_enum_value" translatable="false">NEVER</string>
<string name="always_enum_value" translatable="false">ALWAYS</string>
<string name="auto_enum_value" translatable="false">AUTO</string>
<string name="user_lock_bottom_sheet_behavior" translatable="false">com.mapswithme.maps.widget.UserLockBottomSheetBehavior</string>
</resources>

View file

@ -6,7 +6,6 @@ import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Configuration;
import android.graphics.Rect;
import android.location.Location;
import android.os.Build;
@ -111,9 +110,8 @@ import com.mapswithme.maps.widget.FadeView;
import com.mapswithme.maps.widget.menu.BaseMenu;
import com.mapswithme.maps.widget.menu.MainMenu;
import com.mapswithme.maps.widget.menu.MyPositionButton;
import com.mapswithme.maps.widget.placepage.BasePlacePageAnimationController;
import com.mapswithme.maps.widget.placepage.PlacePageView;
import com.mapswithme.maps.widget.placepage.PlacePageView.State;
import com.mapswithme.maps.widget.placepage.BottomSheetPlacePageController;
import com.mapswithme.maps.widget.placepage.PlacePageController;
import com.mapswithme.util.Animations;
import com.mapswithme.util.Counters;
import com.mapswithme.util.InputUtils;
@ -122,7 +120,6 @@ import com.mapswithme.util.ThemeSwitcher;
import com.mapswithme.util.ThemeUtils;
import com.mapswithme.util.UiUtils;
import com.mapswithme.util.Utils;
import com.mapswithme.util.concurrency.UiThread;
import com.mapswithme.util.log.Logger;
import com.mapswithme.util.log.LoggerFactory;
import com.mapswithme.util.permissions.PermissionsResult;
@ -130,7 +127,6 @@ import com.mapswithme.util.sharing.ShareOption;
import com.mapswithme.util.sharing.SharingHelper;
import com.mapswithme.util.sharing.TargetUtils;
import com.mapswithme.util.statistics.AlohaHelper;
import com.mapswithme.util.statistics.PlacePageTracker;
import com.mapswithme.util.statistics.Statistics;
import java.io.Serializable;
@ -141,8 +137,6 @@ import java.util.Stack;
public class MwmActivity extends BaseMwmFragmentActivity
implements MapObjectListener,
View.OnTouchListener,
BasePlacePageAnimationController.OnVisibilityChangedListener,
BasePlacePageAnimationController.OnAnimationListener,
OnClickListener,
MapFragment.MapRenderingListener,
CustomNavigateUpListener,
@ -176,8 +170,7 @@ public class MwmActivity extends BaseMwmFragmentActivity
EditorHostFragment.class.getName(),
ReportFragment.class.getName(),
DiscoveryFragment.class.getName() };
// Instance state
private static final String STATE_PP = "PpState";
private static final String STATE_MAP_OBJECT = "MapObject";
private static final String EXTRA_LOCATION_DIALOG_IS_ANNOYING = "LOCATION_DIALOG_IS_ANNOYING";
@ -192,10 +185,6 @@ public class MwmActivity extends BaseMwmFragmentActivity
@Nullable
private MapFragment mMapFragment;
@SuppressWarnings("NullableProblems")
@NonNull
private PlacePageView mPlacePage;
@SuppressWarnings("NullableProblems")
@NonNull
private FadeView mFadeView;
@ -233,8 +222,6 @@ public class MwmActivity extends BaseMwmFragmentActivity
private FloatingSearchToolbarController mSearchController;
private boolean mPlacePageRestored;
private boolean mLocationErrorDialogAnnoying = false;
@Nullable
private Dialog mLocationErrorDialog;
@ -243,13 +230,13 @@ public class MwmActivity extends BaseMwmFragmentActivity
@Nullable
private Bundle mSavedForTabletState;
@Nullable
private PlacePageTracker mPlacePageTracker;
@Nullable
private PurchaseController<PurchaseCallback> mAdsRemovalPurchaseController;
@Nullable
private PurchaseController<FailedPurchaseChecker> mBookmarkPurchaseController;
@NonNull
private final OnClickListener mOnMyPositionClickListener = new CurrentPositionClickListener();
@NonNull
private PlacePageController mPlacePageController;
public interface LeftAnimationTrackListener
{
@ -265,78 +252,6 @@ public class MwmActivity extends BaseMwmFragmentActivity
void onVisibleRectChanged(Rect rect);
}
class VisibleRectMeasurer implements View.OnLayoutChangeListener
{
private VisibleRectListener mRectListener;
private Rect mScreenFullRect = null;
private Rect mLastVisibleRect = null;
private boolean mPlacePageVisible = false;
public VisibleRectMeasurer(VisibleRectListener listener)
{
mRectListener = listener;
}
void setPlacePageVisible(boolean visible)
{
int orientation = MwmActivity.this.getResources().getConfiguration().orientation;
if(orientation == Configuration.ORIENTATION_LANDSCAPE)
{
mPlacePageVisible = visible;
recalculateVisibleRect(mScreenFullRect);
}
}
void setPreviewVisible(boolean visible)
{
int orientation = MwmActivity.this.getResources().getConfiguration().orientation;
if(orientation == Configuration.ORIENTATION_PORTRAIT)
{
mPlacePageVisible = visible;
recalculateVisibleRect(mScreenFullRect);
}
}
@Override
public void onLayoutChange(View v, int left, int top, int right, int bottom,
int oldLeft, int oldTop, int oldRight, int oldBottom)
{
mScreenFullRect = new Rect(left, top, right, bottom);
if (mPlacePageVisible && UiUtils.isHidden(mPlacePage.GetPreview()))
mPlacePageVisible = false;
recalculateVisibleRect(mScreenFullRect);
}
private void recalculateVisibleRect(Rect r)
{
if (r == null)
return;
int orientation = MwmActivity.this.getResources().getConfiguration().orientation;
Rect rect = new Rect(r.left, r.top, r.right, r.bottom);
if (mPlacePageVisible)
{
int[] loc = new int[2];
mPlacePage.GetPreview().getLocationOnScreen(loc);
if(orientation == Configuration.ORIENTATION_PORTRAIT)
rect.bottom = loc[1];
else
rect.left = mPlacePage.GetPreview().getWidth() + loc[0];
}
if (mLastVisibleRect == null || !mLastVisibleRect.equals(rect))
{
mLastVisibleRect = new Rect(rect.left, rect.top, rect.right, rect.bottom);
if (mRectListener != null)
mRectListener.onVisibleRectChanged(rect);
}
}
}
private VisibleRectMeasurer mVisibleRectMeasurer;
public static Intent createShowMapIntent(@NonNull Context context, @Nullable String countryId)
{
return new Intent(context, DownloadResourcesLegacyActivity.class)
@ -566,6 +481,8 @@ public class MwmActivity extends BaseMwmFragmentActivity
getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
setContentView(R.layout.activity_map);
mPlacePageController = new BottomSheetPlacePageController(this);
mPlacePageController.initialize();
mIsLaunchByDeepLink = getIntent().getBooleanExtra(EXTRA_LAUNCH_BY_DEEP_LINK, false);
initViews();
@ -604,11 +521,6 @@ public class MwmActivity extends BaseMwmFragmentActivity
initMap();
initNavigationButtons();
mPlacePage = findViewById(R.id.info_box);
mPlacePage.setOnVisibilityChangedListener(this);
mPlacePage.setOnAnimationListener(this);
mPlacePageTracker = new PlacePageTracker(mPlacePage);
if (!mIsTabletLayout)
{
mRoutingPlanInplaceController = new RoutingPlanInplaceController(this, this, this);
@ -784,10 +696,7 @@ public class MwmActivity extends BaseMwmFragmentActivity
public boolean closePlacePage()
{
if (mPlacePage.isHidden())
return false;
mPlacePage.hide();
mPlacePageController.close();
Framework.nativeDeactivatePopup();
return true;
}
@ -842,8 +751,9 @@ public class MwmActivity extends BaseMwmFragmentActivity
closeMenu(() -> {
RoutingController.get().prepare(canUseMyPositionAsStart, endPoint);
if (mPlacePage.isDocked() || !mPlacePage.isFloating())
closePlacePage();
// TODO: check for tablet.
/*if (mPlacePage.isDocked() || !mPlacePage.isFloating())
closePlacePage();*/
});
}
@ -871,9 +781,6 @@ public class MwmActivity extends BaseMwmFragmentActivity
mPanelAnimator.registerListener(mMainMenu.getLeftAnimationTrackListener());
return;
}
if (mPlacePage.isDocked())
mPlacePage.setLeftAnimationTrackListener(mMainMenu.getLeftAnimationTrackListener());
}
private void onItemClickOrSkipAnim(@NonNull MainMenu.Item item)
@ -907,14 +814,6 @@ public class MwmActivity extends BaseMwmFragmentActivity
@Override
protected void onSaveInstanceState(Bundle outState)
{
if (!mPlacePage.isHidden())
{
outState.putInt(STATE_PP, mPlacePage.getState().ordinal());
outState.putParcelable(STATE_MAP_OBJECT, mPlacePage.getMapObject());
if (isChangingConfigurations())
mPlacePage.setState(State.HIDDEN);
}
if (!mIsTabletLayout && RoutingController.get().isPlanning())
mRoutingPlanInplaceController.onSaveState(outState);
@ -954,24 +853,6 @@ public class MwmActivity extends BaseMwmFragmentActivity
{
super.onRestoreInstanceState(savedInstanceState);
final State state = State.values()[savedInstanceState.getInt(STATE_PP, 0)];
if (state != State.HIDDEN)
{
mPlacePageRestored = true;
MapObject mapObject = savedInstanceState.getParcelable(STATE_MAP_OBJECT);
mPlacePage.setMapObject(mapObject, true,
new PlacePageView.SetMapObjectListener()
{
@Override
public void onSetMapObjectComplete()
{
mPlacePage.setState(state);
}
});
if (mPlacePageTracker != null)
mPlacePageTracker.setMapObject(mapObject);
}
if (mIsTabletLayout)
{
RoutingPlanFragment fragment = (RoutingPlanFragment) getFragment(RoutingPlanFragment.class);
@ -1281,7 +1162,6 @@ public class MwmActivity extends BaseMwmFragmentActivity
protected void onResume()
{
super.onResume();
mPlacePageRestored = mPlacePage.getState() != State.HIDDEN;
mSearchController.refreshToolbar();
mMainMenu.onResume(new Runnable()
{
@ -1301,7 +1181,8 @@ public class MwmActivity extends BaseMwmFragmentActivity
mNavigationController.onResume();
if (mNavAnimationController != null)
mNavAnimationController.onResume();
mPlacePage.onActivityResume();
// TODO:
// mPlacePage.onActivityResume();
}
@Override
@ -1318,7 +1199,8 @@ public class MwmActivity extends BaseMwmFragmentActivity
{
super.onResumeFragments();
RoutingController.get().restore();
mPlacePage.restore();
// TODO:
// mPlacePage.restore();
if (!LikesManager.INSTANCE.isNewUser() && Counters.isShowReviewForOldUser())
{
@ -1338,7 +1220,8 @@ public class MwmActivity extends BaseMwmFragmentActivity
LikesManager.INSTANCE.cancelDialogs();
if (mOnmapDownloader != null)
mOnmapDownloader.onPause();
mPlacePage.onActivityPause();
// TODO:
// mPlacePage.onActivityPause();
super.onPause();
}
@ -1356,7 +1239,8 @@ public class MwmActivity extends BaseMwmFragmentActivity
mToggleMapLayerController.attachCore();
if (mNavigationController != null)
TrafficManager.INSTANCE.attach(mNavigationController);
mPlacePage.onActivityStarted();
// TODO:
// mPlacePage.onActivityStarted();
}
@Override
@ -1371,7 +1255,8 @@ public class MwmActivity extends BaseMwmFragmentActivity
RoutingController.get().detach();
TrafficManager.INSTANCE.detachAll();
mToggleMapLayerController.detachCore();
mPlacePage.onActivityStopped();
// TODO:
// mPlacePage.onActivityStopped();
}
@Override
@ -1384,6 +1269,7 @@ public class MwmActivity extends BaseMwmFragmentActivity
mBookmarkPurchaseController.destroy();
if (mNavigationController != null)
mNavigationController.destroy();
mPlacePageController.destroy();
}
@Override
@ -1500,19 +1386,7 @@ public class MwmActivity extends BaseMwmFragmentActivity
setFullscreen(false);
mPlacePage.setMapObject(object, true, () -> {
if (!mPlacePageRestored)
{
if (object != null)
{
mPlacePage.setState(object.isExtendedView() ? State.DETAILS : State.PREVIEW);
Framework.logLocalAdsEvent(Framework.LocalAdsEventType.LOCAL_ADS_EVENT_OPEN_INFO, object);
}
}
mPlacePageRestored = false;
});
if (mPlacePageTracker != null)
mPlacePageTracker.setMapObject(object);
mPlacePageController.openFor(object);
if (UiUtils.isVisible(mFadeView))
mFadeView.fadeOut();
@ -1531,7 +1405,7 @@ public class MwmActivity extends BaseMwmFragmentActivity
}
else
{
mPlacePage.hide();
mPlacePageController.close();
}
}
@ -1581,7 +1455,7 @@ public class MwmActivity extends BaseMwmFragmentActivity
}
else
{
if (mPlacePage.isHidden() && mNavAnimationController != null)
if (mPlacePageController.isClosed() && mNavAnimationController != null)
mNavAnimationController.appearZoomButtons();
if (!mIsFullscreenAnimating)
appearMenu(menu);
@ -1615,7 +1489,7 @@ public class MwmActivity extends BaseMwmFragmentActivity
});
}
@Override
/* @Override
public void onPreviewVisibilityChanged(boolean isVisible)
{
if (mVisibleRectMeasurer != null)
@ -1641,9 +1515,9 @@ public class MwmActivity extends BaseMwmFragmentActivity
if (mPlacePageTracker != null)
mPlacePageTracker.onHidden();
}
}
}*/
@Override
/* @Override
public void onPlacePageVisibilityChanged(boolean isVisible)
{
if (mVisibleRectMeasurer != null)
@ -1657,8 +1531,9 @@ public class MwmActivity extends BaseMwmFragmentActivity
{
mPlacePageTracker.onOpened();
}
}
}*/
/*
@Override
public void onProgress(float translationX, float translationY)
{
@ -1667,6 +1542,7 @@ public class MwmActivity extends BaseMwmFragmentActivity
if (mPlacePageTracker != null)
mPlacePageTracker.onMove();
}
*/
@Override
public void onClick(View v)
@ -1689,7 +1565,7 @@ public class MwmActivity extends BaseMwmFragmentActivity
@Override
public boolean onTouch(View view, MotionEvent event)
{
return mPlacePage.hideOnTouch() || (mMapFragment != null && mMapFragment.onTouch(view, event));
return mMapFragment != null && mMapFragment.onTouch(view, event);
}
@Override
@ -2112,7 +1988,8 @@ public class MwmActivity extends BaseMwmFragmentActivity
updateSearchBar();
}
mPlacePage.refreshViews();
// TODO:
// mPlacePage.refreshViews();
}
private void adjustCompassAndTraffic(final int offsetY)
@ -2171,7 +2048,8 @@ public class MwmActivity extends BaseMwmFragmentActivity
@Override
public void showNavigation(boolean show)
{
mPlacePage.refreshViews();
// TODO:
// mPlacePage.refreshViews();
if (mNavigationController != null)
mNavigationController.show(show);
refreshFade();
@ -2294,9 +2172,6 @@ public class MwmActivity extends BaseMwmFragmentActivity
@Override
public void onLocationUpdated(@NonNull Location location)
{
if (!mPlacePage.isHidden())
mPlacePage.refreshLocation(location);
if (!RoutingController.get().isNavigating())
return;
@ -2310,7 +2185,6 @@ public class MwmActivity extends BaseMwmFragmentActivity
public void onCompassUpdated(@NonNull CompassData compass)
{
MapFragment.nativeCompassUpdated(compass.getMagneticNorth(), compass.getTrueNorth(), false);
mPlacePage.refreshAzimuth(compass.getNorth());
if (mNavigationController != null)
mNavigationController.updateNorth(compass.getNorth());
}
@ -2789,7 +2663,8 @@ public class MwmActivity extends BaseMwmFragmentActivity
if (!getActivity().mMainMenu.isOpen())
{
Statistics.INSTANCE.trackToolbarClick(getItem());
if (getActivity().mPlacePage.isDocked() && getActivity().closePlacePage())
// TODO:
if (/*getActivity().mPlacePage.isDocked() &&*/ getActivity().closePlacePage())
return;
if (getActivity().closeSidePanel())

View file

@ -0,0 +1,7 @@
package com.mapswithme.maps.base;
public interface Initializable
{
void initialize();
void destroy();
}

View file

@ -327,9 +327,9 @@ public enum LocationHelper
}
/**
* Registers listener about location changes.
* Registers listener to obtain location updates.
*
* @param listener listener to register.
* @param listener listener to be registered.
* @param forceUpdate instantly notify given listener about available location, if any.
*/
@UiThread
@ -344,6 +344,17 @@ public enum LocationHelper
notifyLocationUpdated(listener);
}
/**
* Registers listener to obtain location updates.
*
* @param listener listener to be registered.
*/
@UiThread
public void addListener(@NonNull LocationListener listener)
{
addListener(listener, false);
}
@UiThread
/**
* Removes given location listener.

View file

@ -1,67 +0,0 @@
package com.mapswithme.maps.widget;
import android.support.annotation.IdRes;
import android.util.SparseArray;
import android.view.View;
import android.view.ViewGroup;
import com.mapswithme.maps.R;
import com.mapswithme.util.UiUtils;
public abstract class BaseShadowController<V extends ViewGroup>
{
// Shadow IDs
protected static final int TOP = 0;
protected static final int BOTTOM = 1;
private final SparseArray<View> mShadows = new SparseArray<>(1);
protected final V mList;
public BaseShadowController(V list)
{
this(list, R.id.shadow_top);
}
public BaseShadowController(V list, @IdRes int shadowId)
{
mList = list;
addShadow(TOP, shadowId);
}
protected BaseShadowController addShadow(int id, @IdRes int shadowViewId)
{
View shadow = ((ViewGroup)mList.getParent()).findViewById(shadowViewId);
if (shadow != null)
mShadows.put(id, shadow);
return this;
}
public BaseShadowController addBottomShadow()
{
return addShadow(BOTTOM, R.id.shadow_bottom);
}
public void updateShadows()
{
for (int i = 0; i < mShadows.size(); i++)
{
int id = mShadows.keyAt(i);
UiUtils.showIf(shouldShowShadow(id), mShadows.get(id));
}
}
public BaseShadowController attach()
{
updateShadows();
return this;
}
public void detach()
{
for (int i = 0; i < mShadows.size(); i++)
mShadows.get(mShadows.keyAt(i))
.setVisibility(View.GONE);
}
protected abstract boolean shouldShowShadow(int id);
}

View file

@ -1,67 +0,0 @@
package com.mapswithme.maps.widget;
import android.view.View;
import android.widget.AbsListView;
public class ListShadowController extends BaseShadowController<AbsListView>
{
public ListShadowController(AbsListView list)
{
super(list);
}
@Override
protected boolean shouldShowShadow(int id)
{
switch (id)
{
case TOP:
int first = mList.getFirstVisiblePosition();
if (first > 0)
return true;
View child = mList.getChildAt(0);
return (child.getTop() < 0);
case BOTTOM:
int last = mList.getFirstVisiblePosition() + mList.getChildCount();
if (last < mList.getAdapter().getCount())
return true;
child = mList.getChildAt(last - 1);
return (child.getBottom() > mList.getHeight());
default:
throw new IllegalArgumentException("Invalid shadow id: " + id);
}
}
@Override
public BaseShadowController attach()
{
super.attach();
mList.setOnScrollListener(new AbsListView.OnScrollListener()
{
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount)
{
updateShadows();
}
});
updateShadows();
return this;
}
@Override
public void detach()
{
super.detach();
mList.setOnScrollListener(null);
}
}

View file

@ -1,54 +0,0 @@
package com.mapswithme.maps.widget;
import android.annotation.TargetApi;
import android.content.Context;
import android.os.Build;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.widget.LinearLayout;
public class ObservableLinearLayout extends LinearLayout
{
@Nullable
private SizeChangedListener mSizeChangedListener;
public ObservableLinearLayout(@NonNull Context context)
{
super(context);
}
public ObservableLinearLayout(@NonNull Context context, @Nullable AttributeSet attrs)
{
super(context, attrs);
}
public ObservableLinearLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr)
{
super(context, attrs, defStyleAttr);
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public ObservableLinearLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes)
{
super(context, attrs, defStyleAttr, defStyleRes);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh)
{
super.onSizeChanged(w, h, oldw, oldh);
if (mSizeChangedListener != null)
mSizeChangedListener.onSizeChanged(w, h, oldw, oldh);
}
public void setSizeChangedListener(@Nullable SizeChangedListener listener)
{
mSizeChangedListener = listener;
}
public interface SizeChangedListener
{
void onSizeChanged(int width, int height, int oldWidth, int oldHeight);
}
}

View file

@ -1,135 +0,0 @@
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.support.v4.widget.NestedScrollView;
import android.util.AttributeSet;
import android.view.MotionEvent;
public class ObservableScrollView extends NestedScrollView
{
public interface ScrollListener
{
void onScroll(int left, int top);
void onScrollEnd();
}
public static class SimpleScrollListener implements ScrollListener
{
@Override
public void onScroll(int left, int top) {}
@Override
public void onScrollEnd() {}
}
private static final int SCROLL_END_DETECT_INTERVAL = 100;
private final Runnable mScrollEndDetector = new Runnable()
{
@Override
public void run()
{
if (mTouched)
return;
if (mPrevScroll == getScrollY())
{
if (mScrollListener != null)
mScrollListener.onScrollEnd();
return;
}
mPrevScroll = getScrollY();
postDelayed(this, SCROLL_END_DETECT_INTERVAL);
}
};
private ScrollListener mScrollListener;
private int mPrevScroll;
private boolean mTouched;
@Nullable
private GestureDetectorCompat mGestureDetector;
public ObservableScrollView(Context context)
{
super(context);
}
public ObservableScrollView(Context context, AttributeSet attrs)
{
super(context, attrs);
}
public ObservableScrollView(Context context, AttributeSet attrs, int defStyle)
{
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 &&
(ev.getActionMasked() == MotionEvent.ACTION_MOVE) &&
getScrollY() == mPrevScroll);
}
@Override
protected void onScrollChanged(int curLeft, int curTop, int prevLeft, int prevTop)
{
super.onScrollChanged(curLeft, curTop, prevLeft, prevTop);
if (mScrollListener != null)
mScrollListener.onScroll(curLeft, curTop);
}
@Override
public boolean onTouchEvent(@NonNull MotionEvent ev)
{
if (mGestureDetector != null)
mGestureDetector.onTouchEvent(ev);
if (!super.onTouchEvent(ev))
return false;
if (shouldSkipEvent(ev))
return true;
switch (ev.getAction() & MotionEvent.ACTION_MASK)
{
case MotionEvent.ACTION_DOWN:
mTouched = true;
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
mTouched = false;
if (mScrollListener != null)
{
mPrevScroll = getScrollY();
postDelayed(mScrollEndDetector, SCROLL_END_DETECT_INTERVAL);
}
break;
}
return true;
}
public void setScrollListener(ScrollListener scrollListener)
{
mScrollListener = scrollListener;
}
}

View file

@ -1,54 +0,0 @@
package com.mapswithme.maps.widget;
import android.view.View;
public class ScrollViewShadowController extends BaseShadowController<ObservableScrollView>
{
public ScrollViewShadowController(ObservableScrollView list)
{
super(list);
}
@Override
protected boolean shouldShowShadow(int id)
{
if (mList.getChildCount() == 0)
return false;
switch (id)
{
case TOP:
return (mList.getScrollY() > 0);
case BOTTOM:
View child = mList.getChildAt(0);
return (mList.getScrollY() + mList.getHeight() < child.getHeight());
default:
throw new IllegalArgumentException("Invalid shadow id: " + id);
}
}
@Override
public BaseShadowController attach()
{
super.attach();
mList.setScrollListener(new ObservableScrollView.SimpleScrollListener()
{
@Override
public void onScroll(int left, int top)
{
updateShadows();
}
});
return this;
}
@Override
public void detach()
{
super.detach();
mList.setScrollListener(null);
}
}

View file

@ -1,56 +0,0 @@
package com.mapswithme.maps.widget;
import com.mapswithme.util.UiUtils;
public class WebViewShadowController extends BaseShadowController<ObservableWebView>
{
public WebViewShadowController(ObservableWebView webView)
{
super(webView);
}
@Override
protected boolean shouldShowShadow(int id)
{
switch (id)
{
case TOP:
return (mList.getScrollY() > 0);
case BOTTOM:
return (mList.getScrollY() + mList.getHeight() < UiUtils.toPx(mList.getContentHeight() - 1));
default:
throw new IllegalArgumentException("Invalid shadow id: " + id);
}
}
@Override
public BaseShadowController attach()
{
super.attach();
mList.setListener(new ObservableWebView.Listener()
{
@Override
public void onScroll(int left, int top)
{
updateShadows();
}
@Override
public void onContentReady()
{
updateShadows();
}
});
return this;
}
@Override
public void detach()
{
super.detach();
mList.setListener(null);
}
}

View file

@ -420,7 +420,7 @@ final class BannerController
@Override
public void onAdLoaded(@NonNull MwmNativeAd ad)
{
LOGGER.d(TAG, "onAdLoaded, ad = " + ad);
/* LOGGER.d(TAG, "onAdLoaded, ad = " + ad);
if (mBanners == null)
return;
@ -441,7 +441,9 @@ final class BannerController
ad.registerView(mBannerView);
loadIconAndOpenIfNeeded(ad);
// TODO:
// loadIconAndOpenIfNeeded(ad);
if (mAdTracker != null)
{
@ -450,7 +452,7 @@ final class BannerController
}
if (mListener != null && mOpened)
mListener.onSizeChanged();
mListener.onSizeChanged();*/
}
@Override

View file

@ -1,177 +0,0 @@
package com.mapswithme.maps.widget.placepage;
import android.animation.TimeInterpolator;
import android.animation.ValueAnimator;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.view.GestureDetectorCompat;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.Interpolator;
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 implements ObservableScrollView.ScrollListener
{
private static final int DURATION = MwmApplication.get()
.getResources()
.getInteger(R.integer.anim_placepage);
private static final TimeInterpolator INTERPOLATOR = new AccelerateInterpolator();
State mState = State.HIDDEN;
PlacePageView mPlacePage;
ViewGroup mPreview;
ViewGroup mDetailsFrame;
ObservableScrollView mDetailsScroll;
View mDetailsContent;
ViewGroup mBookmarkDetails;
ViewGroup mButtons;
// Gestures
GestureDetectorCompat mGestureDetector;
boolean mIsDragging;
float mDownCoord;
float mTouchSlop;
int mCurrentScrollY;
private OnVisibilityChangedListener mVisibilityListener;
public interface OnVisibilityChangedListener
{
void onPreviewVisibilityChanged(boolean isVisible);
void onPlacePageVisibilityChanged(boolean isVisible);
}
@Nullable
private OnAnimationListener mProgressListener;
public interface OnAnimationListener
{
void onProgress(float translationX, float translationY);
}
protected abstract void initGestureDetector();
BasePlacePageAnimationController(@NonNull PlacePageView placePage)
{
mPlacePage = placePage;
mPreview = (ViewGroup) placePage.findViewById(R.id.pp__preview);
mDetailsFrame = (ViewGroup) placePage.findViewById(R.id.pp__details_frame);
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);
initGestureDetector();
mTouchSlop = ViewConfiguration.get(mPlacePage.getContext()).getScaledTouchSlop();
if (mPlacePage.isFloating() || mPlacePage.isDocked())
mDetailsFrame.setPadding(mDetailsFrame.getPaddingLeft(), mDetailsFrame.getPaddingTop(), mDetailsFrame
.getPaddingRight(),
UiUtils.dimen(R.dimen.place_page_buttons_height));
if (mPlacePage.isDocked())
{
ViewGroup.LayoutParams lp = mDetailsFrame.getLayoutParams();
lp.height = ViewGroup.LayoutParams.MATCH_PARENT;
mDetailsFrame.setLayoutParams(lp);
}
initialVisibility();
}
@Override
public void onScroll(int left, int top)
{
mCurrentScrollY = top;
}
@Override
public void onScrollEnd()
{
}
protected void initialVisibility()
{
UiUtils.invisible(mPlacePage, mPreview, mDetailsFrame, mBookmarkDetails);
}
public State getState()
{
return mState;
}
void setState(final State state, @MapObject.MapObjectType final int type)
{
mPlacePage.post(new Runnable()
{
@Override
public void run()
{
onStateChanged(mState, state, type);
mState = state;
}
});
}
protected abstract void onStateChanged(State currentState, State newState, int type);
void setOnVisibilityChangedListener(OnVisibilityChangedListener listener)
{
mVisibilityListener = listener;
}
void setOnProgressListener(@Nullable OnAnimationListener listener)
{
mProgressListener = listener;
}
protected abstract boolean onInterceptTouchEvent(MotionEvent event);
protected boolean onTouchEvent(@NonNull MotionEvent event)
{
return mGestureDetector.onTouchEvent(event);
}
void notifyVisibilityListener(boolean previewShown, boolean ppShown)
{
if (mVisibilityListener != null)
{
mVisibilityListener.onPreviewVisibilityChanged(previewShown);
mVisibilityListener.onPlacePageVisibilityChanged(ppShown);
}
}
void notifyProgress(float translationX, float translationY)
{
if (mProgressListener == null)
return;
mProgressListener.onProgress(translationX, translationY);
}
void startDefaultAnimator(ValueAnimator animator)
{
startDefaultAnimator(animator, new AccelerateInterpolator());
}
void startDefaultAnimator(ValueAnimator animator, Interpolator interpolator)
{
animator.setDuration(DURATION);
animator.setInterpolator(interpolator == null ? INTERPOLATOR : interpolator);
animator.start();
}
}

View file

@ -1,626 +0,0 @@
package com.mapswithme.maps.widget.placepage;
import android.animation.Animator;
import android.animation.ValueAnimator;
import android.annotation.SuppressLint;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
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.widget.LinearLayout;
import com.mapswithme.maps.R;
import com.mapswithme.maps.bookmarks.data.MapObject;
import com.mapswithme.maps.widget.ObservableLinearLayout;
import com.mapswithme.maps.widget.placepage.PlacePageView.State;
import com.mapswithme.util.UiUtils;
import com.mapswithme.util.concurrency.UiThread;
class BottomPlacePageAnimationController extends BasePlacePageAnimationController
implements ObservableLinearLayout.SizeChangedListener
{
@SuppressWarnings("unused")
private static final String TAG = BottomPlacePageAnimationController.class.getSimpleName();
private static final float DETAIL_RATIO = 0.5f;
private static final float SCROLL_DELTA = 50.0f;
private final ViewGroup mLayoutToolbar;
private ValueAnimator mCurrentAnimator;
private boolean mIsGestureStartedInsideView;
private boolean mIsGestureFinished;
private boolean mIsHiding;
private float mScreenHeight;
private float mDetailMaxHeight;
private float mScrollDelta;
private int mContentHeight;
@Nullable
private OnBannerOpenListener mBannerOpenListener;
BottomPlacePageAnimationController(@NonNull PlacePageView placePage)
{
super(placePage);
UiUtils.extendViewMarginWithStatusBar(mDetailsScroll);
mLayoutToolbar = (LinearLayout) mPlacePage.findViewById(R.id.toolbar_layout);
if (mLayoutToolbar == null)
return;
((ObservableLinearLayout) mDetailsContent).setSizeChangedListener(this);
mContentHeight = mDetailsContent.getHeight();
final Toolbar toolbar = (Toolbar) mLayoutToolbar.findViewById(R.id.toolbar);
if (toolbar != null)
{
UiUtils.extendViewWithStatusBar(toolbar);
UiUtils.showHomeUpButton(toolbar);
toolbar.setNavigationOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
mPlacePage.hide();
}
});
}
DisplayMetrics dm = placePage.getResources().getDisplayMetrics();
mScreenHeight = dm.heightPixels;
mDetailMaxHeight = mScreenHeight * DETAIL_RATIO;
mScrollDelta = SCROLL_DELTA * dm.density;
}
@Override
protected boolean onInterceptTouchEvent(MotionEvent event)
{
if (mIsHiding)
return false;
switch (event.getAction())
{
case MotionEvent.ACTION_DOWN:
if (!UiUtils.isViewTouched(event, mDetailsScroll))
{
mIsGestureStartedInsideView = false;
break;
}
mIsGestureStartedInsideView = true;
mIsDragging = false;
mIsGestureFinished = false;
mDownCoord = event.getY();
mGestureDetector.onTouchEvent(event);
break;
case MotionEvent.ACTION_MOVE:
if (!mIsGestureStartedInsideView)
break;
final float delta = mDownCoord - event.getY();
if (Math.abs(delta) > mTouchSlop && !isDetailsScroll(delta))
return true;
break;
case MotionEvent.ACTION_UP:
final boolean isInside = UiUtils.isViewTouched(event, mDetailsScroll);
if (isInside && !mPlacePage.isBannerTouched(event)
&& !mPlacePage.isLeaveReviewButtonTouched(event)
&& !mPlacePage.isSearchSimilarHotelsButtonTouched(event)
&& mIsGestureStartedInsideView)
mGestureDetector.onTouchEvent(event);
mIsDragging = false;
break;
case MotionEvent.ACTION_CANCEL:
mIsDragging = false;
break;
}
return false;
}
@Override
protected boolean onTouchEvent(@NonNull MotionEvent event)
{
if (mIsGestureFinished || mIsHiding)
return false;
final boolean finishedDrag = (mIsDragging &&
(event.getAction() == MotionEvent.ACTION_UP ||
event.getAction() == MotionEvent.ACTION_CANCEL));
if (!mIsGestureStartedInsideView || !UiUtils.isViewTouched(event, mDetailsScroll)
|| finishedDrag)
{
mIsGestureFinished = true;
finishDrag(mDownCoord - event.getY());
return false;
}
super.onTouchEvent(event);
return true;
}
@Override
public void onScroll(int left, int top)
{
super.onScroll(left, top);
resetDetailsScrollIfNeeded();
refreshToolbarVisibility();
notifyProgress();
}
private void resetDetailsScrollIfNeeded()
{
if (mCurrentScrollY > 0 && mDetailsScroll.getTranslationY() > 0)
{
mDetailsScroll.scrollTo(0, 0);
}
}
/**
* @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() < mContentHeight;
}
private boolean canScroll(float delta)
{
return mDetailsScroll.getScrollY() != 0 || delta > 0;
}
@Override
protected void initGestureDetector()
{
mGestureDetector = new GestureDetectorCompat(mPlacePage.getContext(), new GestureDetector.SimpleOnGestureListener()
{
private static final int X_TO_Y_SCROLL_RATIO = 2;
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY)
{
if (mIsHiding)
return true;
final boolean isVertical = Math.abs(distanceY) > X_TO_Y_SCROLL_RATIO * Math.abs(distanceX);
if (isVertical)
{
mIsDragging = true;
if (!translateBy(-distanceY))
{
boolean scrollable = isDetailContentScrollable();
int maxTranslationY = mDetailsScroll.getHeight() - mContentHeight;
if ((scrollable && mDetailsScroll.getTranslationY() == 0)
|| (!scrollable && mDetailsScroll.getTranslationY() <= maxTranslationY))
{
mDetailsScroll.scrollBy((int) distanceX, (int) distanceY);
mState = State.FULLSCREEN;
}
}
}
return true;
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY)
{
if (mIsHiding)
return true;
finishDrag(-velocityY);
return true;
}
@Override
public boolean onSingleTapConfirmed(MotionEvent e)
{
if (mIsHiding)
return true;
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 void finishDrag(float distance)
{
mIsDragging = false;
final float currentTranslation = mDetailsScroll.getTranslationY();
if (currentTranslation > mDetailsScroll.getHeight())
{
mPlacePage.setState(State.HIDDEN);
return;
}
boolean isDragUp = distance >= 0.0f;
if (isDragUp && mPlacePage.getState() == State.FULLSCREEN)
return;
if (isDragUp) // 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 boolean translateBy(float distanceY)
{
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() - mContentHeight;
if ((isScrollable && detailsTranslation < 0.0f) || detailsTranslation < maxTranslationY)
{
if (isScrollable)
{
detailsTranslation = 0.0f;
mDetailsScroll.setGestureDetector(null);
}
else
{
detailsTranslation = maxTranslationY;
}
mState = State.FULLSCREEN;
consumeEvent = false;
}
mDetailsScroll.setTranslationY(detailsTranslation);
notifyProgress();
refreshToolbarVisibility();
if (mBannerOpenListener != null
&& detailsTranslation < mDetailsScroll.getHeight() - mPreview.getHeight())
{
mBannerOpenListener.onNeedOpenBanner();
}
return consumeEvent;
}
@Override
protected void onStateChanged(final State currentState, final State newState, @MapObject.MapObjectType int type)
{
if (newState == State.HIDDEN && currentState == newState)
return;
prepareYTranslations(newState, type);
mDetailsScroll.setGestureDetector(mGestureDetector);
mPlacePage.post(new Runnable()
{
@Override
public void run()
{
endRunningAnimation();
switch (newState)
{
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.
*/
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()
{
@Override
public void run()
{
mDetailsScroll.setTranslationY(mDetailsScroll.getHeight());
mButtons.setTranslationY(mPreview.getHeight() + mButtons.getHeight());
UiUtils.show(mPlacePage, mPreview, mButtons, mDetailsFrame);
}
});
}
break;
case FULLSCREEN:
case DETAILS:
UiUtils.show(mPlacePage, mPreview, mButtons, mDetailsFrame);
UiUtils.showIf(type == MapObject.BOOKMARK, mBookmarkDetails);
break;
}
}
private void showPreview(final State currentState)
{
if (mLayoutToolbar != null)
UiUtils.hide(mLayoutToolbar);
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)
{
ValueAnimator buttonAnimator = ValueAnimator.ofFloat(mButtons.getTranslationY(), 0);
buttonAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener()
{
@Override
public void onAnimationUpdate(ValueAnimator animation)
{
mButtons.setTranslationY((Float) animation.getAnimatedValue());
}
});
startDefaultAnimator(buttonAnimator, interpolator);
}
mCurrentAnimator.addListener(new UiUtils.SimpleAnimatorListener()
{
@Override
public void onAnimationEnd(Animator animation)
{
notifyVisibilityListener(true, false);
}
});
startDefaultAnimator(mCurrentAnimator, interpolator);
}
private void showDetails()
{
final float translation;
if (isDetailContentScrollable())
translation = mDetailMaxHeight - mButtons.getHeight();
else
translation = mContentHeight > mDetailMaxHeight ? mDetailMaxHeight - mButtons.getHeight()
: mContentHeight;
mCurrentAnimator = ValueAnimator.ofFloat(mDetailsScroll.getTranslationY(),
mDetailsScroll.getHeight() - translation);
mCurrentAnimator.addUpdateListener(new UpdateListener());
mCurrentAnimator.addListener(new AnimationListener());
startDefaultAnimator();
}
private void showFullscreen()
{
if (isDetailContentScrollable())
{
mCurrentAnimator = ValueAnimator.ofFloat(mDetailsScroll.getTranslationY(), 0);
}
else
{
mCurrentAnimator = ValueAnimator.ofFloat(mDetailsScroll.getTranslationY(),
mDetailsScroll.getHeight() - mContentHeight);
}
mCurrentAnimator.addUpdateListener(new UpdateListener());
mCurrentAnimator.addListener(new AnimationListener());
startDefaultAnimator();
}
@SuppressLint("NewApi")
private void hidePlacePage()
{
mIsHiding = true;
if (mLayoutToolbar != null)
UiUtils.hide(mLayoutToolbar);
final float animHeight = mPlacePage.getHeight() - mPreview.getY();
mCurrentAnimator = ValueAnimator.ofFloat(0f, animHeight);
mCurrentAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener()
{
@Override
public void onAnimationUpdate(ValueAnimator animation)
{
// FIXME: This translation adds a weird jumping up at end of PP closing
mPlacePage.setTranslationY((Float) animation.getAnimatedValue());
notifyProgress();
}
});
mCurrentAnimator.addListener(new UiUtils.SimpleAnimatorListener()
{
@Override
public void onAnimationEnd(Animator animation)
{
mIsHiding = false;
initialVisibility();
mPlacePage.setTranslationY(0);
mDetailsScroll.setTranslationY(mDetailsScroll.getHeight());
notifyProgress();
notifyVisibilityListener(false, false);
}
});
startDefaultAnimator();
}
private void startDefaultAnimator()
{
startDefaultAnimator(mCurrentAnimator);
}
private void endRunningAnimation()
{
if (mCurrentAnimator != null && mCurrentAnimator.isRunning())
{
mCurrentAnimator.removeAllUpdateListeners();
mCurrentAnimator.removeAllListeners();
mCurrentAnimator.end();
mCurrentAnimator = null;
}
}
private void refreshToolbarVisibility()
{
if (mLayoutToolbar != null)
UiThread.runLater(new Runnable()
{
@Override
public void run()
{
UiUtils.showIf(mCurrentScrollY > 0, mLayoutToolbar);
}
});
}
private void notifyProgress()
{
notifyProgress(0, mDetailsScroll.getTranslationY() + mPlacePage.getTranslationY());
}
void setBannerOpenListener(@Nullable OnBannerOpenListener bannerOpenListener)
{
mBannerOpenListener = bannerOpenListener;
}
private void onContentSizeChanged()
{
if (mIsDragging || mCurrentScrollY > 0)
return;
MapObject object = mPlacePage.getMapObject();
if (object != null)
onStateChanged(getState(), getState(), object.getMapObjectType());
}
@Override
public void onSizeChanged(int width, int height, int oldWidth, int oldHeight)
{
mContentHeight = height;
onContentSizeChanged();
}
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();
}
}
interface OnBannerOpenListener
{
void onNeedOpenBanner();
}
}

View file

@ -0,0 +1,170 @@
package com.mapswithme.maps.widget.placepage;
import android.animation.Animator;
import android.animation.ObjectAnimator;
import android.app.Activity;
import android.location.Location;
import android.support.annotation.NonNull;
import android.support.design.widget.BottomSheetBehavior;
import android.view.View;
import android.view.ViewGroup;
import com.mapswithme.maps.Framework;
import com.mapswithme.maps.R;
import com.mapswithme.maps.bookmarks.data.MapObject;
import com.mapswithme.maps.location.LocationHelper;
import com.mapswithme.maps.location.LocationListener;
import com.mapswithme.util.UiUtils;
import com.mapswithme.util.statistics.PlacePageTracker;
public class BottomSheetPlacePageController implements PlacePageController, LocationListener
{
private static final int BUTTONS_ANIMATION_DURATION = 100;
@NonNull
private final Activity mActivity;
@SuppressWarnings("NullableProblems")
@NonNull
private BottomSheetBehavior<View> mPpSheetBehavior;
@SuppressWarnings("NullableProblems")
@NonNull
private View mButtonsLayout;
@SuppressWarnings("NullableProblems")
@NonNull
private PlacePageView mPlacePage;
@SuppressWarnings("NullableProblems")
@NonNull
private ViewGroup mButtons;
@SuppressWarnings("NullableProblems")
@NonNull
private PlacePageTracker mPlacePageTracker;
@NonNull
private final BottomSheetBehavior.BottomSheetCallback mSheetCallback
= new BottomSheetBehavior.BottomSheetCallback()
{
@Override
public void onStateChanged(@NonNull View bottomSheet, int newState)
{
if (newState == BottomSheetBehavior.STATE_SETTLING
|| newState == BottomSheetBehavior.STATE_DRAGGING)
return;
if (newState == BottomSheetBehavior.STATE_HIDDEN)
{
hideButtons();
return;
}
showButtons();
}
@Override
public void onSlide(@NonNull View bottomSheet, float slideOffset)
{
// TODO: coming soon.
}
};
public BottomSheetPlacePageController(@NonNull Activity activity)
{
mActivity = activity;
}
@Override
public void initialize()
{
View ppSheet = mActivity.findViewById(R.id.pp_bottom_sheet);
mPpSheetBehavior = BottomSheetBehavior.from(ppSheet);
mPpSheetBehavior.setState(BottomSheetBehavior.STATE_HIDDEN);
mPpSheetBehavior.setBottomSheetCallback(mSheetCallback);
mPlacePage = ppSheet.findViewById(R.id.placepage);
mButtonsLayout = mActivity.findViewById(R.id.pp_buttons_layout);
mButtons = mButtonsLayout.findViewById(R.id.pp_buttons);
mPlacePage.initButtons(mButtons.findViewById(R.id.container));
mPlacePageTracker = new PlacePageTracker(mPlacePage, mButtons);
LocationHelper.INSTANCE.addListener(this);
}
@Override
public void destroy()
{
LocationHelper.INSTANCE.removeListener(this);
}
@Override
public void openFor(@NonNull MapObject object)
{
mPlacePage.setMapObject(object, true, () -> {
mPpSheetBehavior.setState(object.isExtendedView() ? BottomSheetBehavior.STATE_EXPANDED
: BottomSheetBehavior.STATE_COLLAPSED);
Framework.logLocalAdsEvent(Framework.LocalAdsEventType.LOCAL_ADS_EVENT_OPEN_INFO, object);
});
mPlacePageTracker.setMapObject(object);
}
@Override
public void close()
{
mPpSheetBehavior.setState(BottomSheetBehavior.STATE_HIDDEN);
mPlacePage.hide();
}
private void showButtons()
{
ObjectAnimator animator = ObjectAnimator.ofFloat(mButtonsLayout, "translationY",
0);
animator.setDuration(BUTTONS_ANIMATION_DURATION);
animator.addListener(new UiUtils.SimpleAnimatorListener()
{
@Override
public void onAnimationStart(Animator animation)
{
UiUtils.show(mButtonsLayout);
super.onAnimationStart(animation);
}
});
animator.start();
}
private void hideButtons()
{
ObjectAnimator animator = ObjectAnimator.ofFloat(mButtonsLayout, "translationY",
mButtonsLayout.getMeasuredHeight());
animator.setDuration(BUTTONS_ANIMATION_DURATION);
animator.addListener(new UiUtils.SimpleAnimatorListener()
{
@Override
public void onAnimationEnd(Animator animation)
{
super.onAnimationEnd(animation);
UiUtils.invisible(mButtonsLayout);
}
});
animator.start();
}
@Override
public boolean isClosed()
{
return mPpSheetBehavior.getState() == BottomSheetBehavior.STATE_HIDDEN;
}
@Override
public void onLocationUpdated(Location location)
{
mPlacePage.refreshLocation(location);
}
@Override
public void onCompassUpdated(long time, double magneticNorth, double trueNorth, double accuracy)
{
double north = trueNorth >= 0.0 ? trueNorth : magneticNorth;
mPlacePage.refreshAzimuth(north);
}
@Override
public void onLocationError(int errorCode)
{
// Do nothing by default.
}
}

View file

@ -1,207 +0,0 @@
package com.mapswithme.maps.widget.placepage;
import android.animation.Animator;
import android.animation.ValueAnimator;
import android.support.annotation.NonNull;
import android.support.v4.view.GestureDetectorCompat;
import android.view.GestureDetector;
import android.view.MotionEvent;
import com.mapswithme.maps.MwmActivity;
import com.mapswithme.maps.widget.placepage.PlacePageView.State;
import com.mapswithme.util.UiUtils;
class LeftPlacePageAnimationController extends BasePlacePageAnimationController
{
LeftPlacePageAnimationController(@NonNull PlacePageView placePage)
{
super(placePage);
UiUtils.extendViewPaddingWithStatusBar(mPreview);
}
@Override
protected void initialVisibility()
{
UiUtils.hide(mPlacePage);
}
@Override
protected boolean onInterceptTouchEvent(MotionEvent event)
{
if (mPlacePage.isHorizontalScrollAreaTouched(event))
return false;
switch (event.getAction())
{
case MotionEvent.ACTION_DOWN:
mIsDragging = false;
mDownCoord = event.getX();
break;
case MotionEvent.ACTION_MOVE:
if (mDownCoord > mPlacePage.getRight())
return false;
if (Math.abs(mDownCoord - event.getX()) > mTouchSlop)
return true;
break;
}
return false;
}
@Override
protected boolean onTouchEvent(@NonNull MotionEvent event)
{
if (mDownCoord > mPlacePage.getRight())
return false;
super.onTouchEvent(event);
return true;
}
@Override
protected void initGestureDetector()
{
mGestureDetector = new GestureDetectorCompat(mPlacePage.getContext(), new GestureDetector.SimpleOnGestureListener()
{
private final int X_MIN = UiUtils.toPx(30);
private final int X_MAX = UiUtils.toPx(100);
private static final int X_TO_Y_SCROLL_RATIO = 2;
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY)
{
final boolean isHorizontal = Math.abs(distanceX) > X_TO_Y_SCROLL_RATIO * Math.abs(distanceY);
final boolean isInRange = Math.abs(distanceX) > X_MIN && Math.abs(distanceX) < X_MAX;
if (!isHorizontal || !isInRange)
return false;
if (!mIsDragging)
{
if (distanceX > 0)
mPlacePage.hide();
mIsDragging = true;
}
return true;
}
});
}
@Override
protected void onStateChanged(State currentState, State newState, int type)
{
switch (newState)
{
case HIDDEN:
hidePlacePage();
break;
case FULLSCREEN:
case DETAILS:
case PREVIEW:
showPlacePage(currentState);
break;
}
}
@Override
public void onScroll(int left, int top)
{
super.onScroll(left, top);
notifyProgress(0, 0);
}
private void startTracking(boolean collapsed)
{
MwmActivity.LeftAnimationTrackListener tracker = mPlacePage.getLeftAnimationTrackListener();
if (tracker != null)
tracker.onTrackStarted(collapsed);
notifyProgress(0, 0);
}
private void finishTracking(boolean collapsed)
{
MwmActivity.LeftAnimationTrackListener tracker = mPlacePage.getLeftAnimationTrackListener();
if (tracker != null)
tracker.onTrackFinished(collapsed);
notifyProgress(0, 0);
}
private void track(ValueAnimator animation)
{
float offset = (Float) animation.getAnimatedValue();
mPlacePage.setTranslationX(offset);
float slope = offset / mPlacePage.getDockedWidth();
mPlacePage.setAlpha(slope + 1.0f);
if (!mPlacePage.isDocked())
mPlacePage.setRotation(slope * 20.0f);
MwmActivity.LeftAnimationTrackListener tracker = mPlacePage.getLeftAnimationTrackListener();
if (tracker != null)
tracker.onTrackLeftAnimation(offset + mPlacePage.getDockedWidth());
notifyProgress(0, 0);
}
private void showPlacePage(final State currentState)
{
UiUtils.show(mPlacePage);
if (currentState != State.HIDDEN)
return;
startTracking(false);
ValueAnimator animator = ValueAnimator.ofFloat(-mPlacePage.getDockedWidth(), 0.0f);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener()
{
@Override
public void onAnimationUpdate(ValueAnimator animation)
{
track(animation);
}
});
animator.addListener(new UiUtils.SimpleAnimatorListener()
{
@Override
public void onAnimationEnd(Animator animation)
{
notifyVisibilityListener(true, true);
finishTracking(true);
}
});
startDefaultAnimator(animator);
}
private void hidePlacePage()
{
startTracking(true);
ValueAnimator animator = ValueAnimator.ofFloat(0.0f, -mPlacePage.getDockedWidth());
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener()
{
@Override
public void onAnimationUpdate(ValueAnimator animation)
{
track(animation);
}
});
animator.addListener(new UiUtils.SimpleAnimatorListener()
{
@Override
public void onAnimationEnd(Animator animation)
{
UiUtils.hide(mPlacePage);
notifyVisibilityListener(false, false);
finishTracking(false);
}
});
startDefaultAnimator(animator);
}
}

View file

@ -0,0 +1,14 @@
package com.mapswithme.maps.widget.placepage;
import android.support.annotation.NonNull;
import com.mapswithme.maps.base.Initializable;
import com.mapswithme.maps.bookmarks.data.MapObject;
public interface PlacePageController extends Initializable
{
void openFor(@NonNull MapObject object);
void close();
// TODO: probably this method is redundant
boolean isClosed();
}

View file

@ -75,11 +75,8 @@ import com.mapswithme.maps.taxi.TaxiType;
import com.mapswithme.maps.ugc.Impress;
import com.mapswithme.maps.ugc.UGCController;
import com.mapswithme.maps.widget.ArrowView;
import com.mapswithme.maps.widget.BaseShadowController;
import com.mapswithme.maps.widget.LineCountTextView;
import com.mapswithme.maps.widget.ObservableScrollView;
import com.mapswithme.maps.widget.RatingView;
import com.mapswithme.maps.widget.ScrollViewShadowController;
import com.mapswithme.maps.widget.recycler.ItemDecoratorFactory;
import com.mapswithme.maps.widget.recycler.RecyclerClickListener;
import com.mapswithme.util.ConnectionState;
@ -122,7 +119,6 @@ public class PlacePageView extends RelativeLayout
LineCountTextView.OnLineCountCalculatedListener,
RecyclerClickListener,
NearbyAdapter.OnItemClickListener,
BottomPlacePageAnimationController.OnBannerOpenListener,
EditBookmarkFragment.EditBookmarkListener,
BannerController.BannerListener
{
@ -225,13 +221,6 @@ public class PlacePageView extends RelativeLayout
@Nullable
BannerController mBannerController;
@Nullable
View mHeightCompensationView;
// Animations
private BaseShadowController mShadowController;
private BasePlacePageAnimationController mAnimationController;
private MwmActivity.LeftAnimationTrackListener mLeftAnimationTrackListener;
// Data
@Nullable
private MapObject mMapObject;
@ -471,10 +460,6 @@ public class PlacePageView extends RelativeLayout
mTvBookmarkNote = mBookmarkFrame.findViewById(R.id.tv__bookmark_notes);
initEditMapObjectBtn();
ViewGroup ppButtons = findViewById(R.id.pp__buttons).findViewById(R.id.container);
mHeightCompensationView = findViewById(R.id.pp__height_compensation);
mHotelMore = findViewById(R.id.ll__more);
mHotelMore.setOnClickListener(this);
@ -495,7 +480,25 @@ public class PlacePageView extends RelativeLayout
getActivity());
}
mButtons = new PlacePageButtons(this, ppButtons, new PlacePageButtons.ItemListener()
mDownloaderIcon = new DownloaderStatusIcon(mPreview.findViewById(R.id.downloader_status_frame));
mDownloaderInfo = mPreview.findViewById(R.id.tv__downloader_details);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
setElevation(UiUtils.dimen(R.dimen.placepage_elevation));
if (UiUtils.isLandscape(getContext()))
mDetails.setBackgroundResource(0);
Sponsored.setPriceListener(this);
Sponsored.setInfoListener(this);
initPlaceDescriptionView();
}
public void initButtons(@NonNull ViewGroup buttons)
{
mButtons = new PlacePageButtons(this, buttons, new PlacePageButtons.ItemListener()
{
public void onPrepareVisibleView(@NonNull PlacePageButtons.PlacePageButton item,
@NonNull View frame, @NonNull ImageView icon,
@ -508,18 +511,18 @@ public class PlacePageView extends RelativeLayout
case BOOKING:
case BOOKING_SEARCH:
case OPENTABLE:
// ---------------------------------------------------------------------------------------
// Warning: the following code is autogenerated.
// Do NOT change it manually.
// %PartnersExtender.Switch
// ---------------------------------------------------------------------------------------
// Warning: the following code is autogenerated.
// Do NOT change it manually.
// %PartnersExtender.Switch
case PARTNER1:
case PARTNER3:
case PARTNER18:
case PARTNER19:
case PARTNER20:
// /%PartnersExtender.Switch
// End of autogenerated code.
// ---------------------------------------------------------------------------------------
// /%PartnersExtender.Switch
// End of autogenerated code.
// ---------------------------------------------------------------------------------------
frame.setBackgroundResource(item.getBackgroundResource());
color = Color.WHITE;
break;
@ -550,135 +553,116 @@ public class PlacePageView extends RelativeLayout
{
switch (item.getType())
{
case BOOKMARK:
if (mMapObject == null)
{
LOGGER.e(TAG, "Bookmark cannot be managed, mMapObject is null!");
return;
}
case BOOKMARK:
if (mMapObject == null)
{
LOGGER.e(TAG, "Bookmark cannot be managed, mMapObject is null!");
return;
}
Statistics.INSTANCE.trackEvent(Statistics.EventName.PP_BOOKMARK);
AlohaHelper.logClick(AlohaHelper.PP_BOOKMARK);
toggleIsBookmark(mMapObject);
break;
Statistics.INSTANCE.trackEvent(Statistics.EventName.PP_BOOKMARK);
AlohaHelper.logClick(AlohaHelper.PP_BOOKMARK);
toggleIsBookmark(mMapObject);
break;
case SHARE:
if (mMapObject == null)
{
LOGGER.e(TAG, "A map object cannot be shared, it's null!");
return;
}
Statistics.INSTANCE.trackEvent(Statistics.EventName.PP_SHARE);
AlohaHelper.logClick(AlohaHelper.PP_SHARE);
ShareOption.ANY.shareMapObject(getActivity(), mMapObject, mSponsored);
break;
case SHARE:
if (mMapObject == null)
{
LOGGER.e(TAG, "A map object cannot be shared, it's null!");
return;
}
Statistics.INSTANCE.trackEvent(Statistics.EventName.PP_SHARE);
AlohaHelper.logClick(AlohaHelper.PP_SHARE);
ShareOption.ANY.shareMapObject(getActivity(), mMapObject, mSponsored);
break;
case BACK:
if (mMapObject == null)
{
LOGGER.e(TAG, "A mwm request cannot be handled, mMapObject is null!");
getActivity().finish();
return;
}
case BACK:
if (mMapObject == null)
{
LOGGER.e(TAG, "A mwm request cannot be handled, mMapObject is null!");
getActivity().finish();
return;
}
if (ParsedMwmRequest.hasRequest())
{
ParsedMwmRequest request = ParsedMwmRequest.getCurrentRequest();
if (ParsedMwmRequest.isPickPointMode())
request.setPointData(mMapObject.getLat(), mMapObject.getLon(), mMapObject.getTitle(), "");
if (ParsedMwmRequest.hasRequest())
{
ParsedMwmRequest request = ParsedMwmRequest.getCurrentRequest();
if (ParsedMwmRequest.isPickPointMode())
request.setPointData(mMapObject.getLat(), mMapObject.getLon(), mMapObject.getTitle(), "");
request.sendResponseAndFinish(getActivity(), true);
}
else
getActivity().finish();
break;
request.sendResponseAndFinish(getActivity(), true);
}
else
getActivity().finish();
break;
case ROUTE_FROM:
RoutingController controller = RoutingController.get();
if (!controller.isPlanning())
{
controller.prepare(mMapObject, null);
hide();
}
else if (controller.setStartPoint(mMapObject))
{
hide();
}
break;
case ROUTE_FROM:
RoutingController controller = RoutingController.get();
if (!controller.isPlanning())
{
controller.prepare(mMapObject, null);
hide();
}
else if (controller.setStartPoint(mMapObject))
{
hide();
}
break;
case ROUTE_TO:
if (RoutingController.get().isPlanning())
{
RoutingController.get().setEndPoint(mMapObject);
hide();
}
else
{
getActivity().startLocationToPoint(getMapObject(), true);
}
break;
case ROUTE_TO:
if (RoutingController.get().isPlanning())
{
RoutingController.get().setEndPoint(mMapObject);
hide();
}
else
{
getActivity().startLocationToPoint(getMapObject(), true);
}
break;
case ROUTE_ADD:
if (mMapObject != null)
RoutingController.get().addStop(mMapObject);
break;
case ROUTE_ADD:
if (mMapObject != null)
RoutingController.get().addStop(mMapObject);
break;
case ROUTE_REMOVE:
if (mMapObject != null)
RoutingController.get().removeStop(mMapObject);
break;
case ROUTE_REMOVE:
if (mMapObject != null)
RoutingController.get().removeStop(mMapObject);
break;
case BOOKING:
case OPENTABLE:
// -----------------------------------------------------------------------------------------
// Warning: the following code is autogenerated.
// Do NOT change it manually.
// %PartnersExtender.SwitchClick
case PARTNER1:
case PARTNER2:
case PARTNER3:
case PARTNER18:
case PARTNER19:
case PARTNER20:
// /%PartnersExtender.SwitchClick
// End of autogenerated code.
// -----------------------------------------------------------------------------------------
onSponsoredClick(true /* book */, false);
break;
case BOOKING:
case OPENTABLE:
// -----------------------------------------------------------------------------------------
// Warning: the following code is autogenerated.
// Do NOT change it manually.
// %PartnersExtender.SwitchClick
case PARTNER1:
case PARTNER2:
case PARTNER3:
case PARTNER18:
case PARTNER19:
case PARTNER20:
// /%PartnersExtender.SwitchClick
// End of autogenerated code.
// -----------------------------------------------------------------------------------------
onSponsoredClick(true /* book */, false);
break;
case BOOKING_SEARCH:
if (mMapObject != null && !TextUtils.isEmpty(mMapObject.getBookingSearchUrl()))
{
Statistics.INSTANCE.trackBookingSearchEvent(mMapObject);
Utils.openUrl(getContext(), mMapObject.getBookingSearchUrl());
}
break;
case BOOKING_SEARCH:
if (mMapObject != null && !TextUtils.isEmpty(mMapObject.getBookingSearchUrl()))
{
Statistics.INSTANCE.trackBookingSearchEvent(mMapObject);
Utils.openUrl(getContext(), mMapObject.getBookingSearchUrl());
}
break;
case CALL:
Utils.callPhone(getContext(), mTvPhone.getText().toString());
break;
case CALL:
Utils.callPhone(getContext(), mTvPhone.getText().toString());
break;
}
}
});
mDownloaderIcon = new DownloaderStatusIcon(mPreview.findViewById(R.id.downloader_status_frame));
mDownloaderInfo = mPreview.findViewById(R.id.tv__downloader_details);
mShadowController = new ScrollViewShadowController((ObservableScrollView) mDetails)
.addBottomShadow()
.attach();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
setElevation(UiUtils.dimen(R.dimen.placepage_elevation));
if (UiUtils.isLandscape(getContext()))
mDetails.setBackgroundResource(0);
Sponsored.setPriceListener(this);
Sponsored.setInfoListener(this);
initPlaceDescriptionView();
}
private void initPlaceDescriptionView()
@ -744,6 +728,7 @@ public class PlacePageView extends RelativeLayout
{
mHotelGallery = findViewById(R.id.ll__place_hotel_gallery);
mRvHotelGallery = findViewById(R.id.rv__place_hotel_gallery);
mRvHotelGallery.setNestedScrollingEnabled(false);
LinearLayoutManager layoutManager = new LinearLayoutManager(getContext(),
LinearLayoutManager.HORIZONTAL,
false);
@ -1003,27 +988,6 @@ public class PlacePageView extends RelativeLayout
});
}
@Override
public void onNeedOpenBanner()
{
if (mBannerController != null)
{
if (!mBannerController.isOpened())
compensateViewHeight(0);
mBannerController.open();
}
}
private void compensateViewHeight(int height)
{
if (mHeightCompensationView == null)
return;
ViewGroup.LayoutParams lp = mHeightCompensationView.getLayoutParams();
lp.height = height;
mHeightCompensationView.setLayoutParams(lp);
}
private void init(AttributeSet attrs, int defStyleAttr)
{
initViews();
@ -1036,12 +1000,6 @@ public class PlacePageView extends RelativeLayout
mIsDocked = attrArray.getBoolean(R.styleable.PlacePageView_docked, false);
mIsFloating = attrArray.getBoolean(R.styleable.PlacePageView_floating, false);
attrArray.recycle();
boolean isBottom = animationType == 0;
mAnimationController = isBottom ? new BottomPlacePageAnimationController(this)
: new LeftPlacePageAnimationController(this);
if (isBottom)
((BottomPlacePageAnimationController) mAnimationController).setBannerOpenListener(this);
}
public void restore()
@ -1056,18 +1014,6 @@ public class PlacePageView extends RelativeLayout
setMapObject(mMapObject, true, null);
}
@Override
public boolean onTouchEvent(@NonNull MotionEvent event)
{
return mAnimationController.onTouchEvent(event);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent event)
{
return mAnimationController.onInterceptTouchEvent(event);
}
public boolean isDocked()
{
return mIsDocked;
@ -1080,54 +1026,8 @@ public class PlacePageView extends RelativeLayout
public State getState()
{
return mAnimationController.getState();
}
public void setState(State state)
{
mDetails.scrollTo(0, 0);
// If place page is closed the state of webview should be cleared,
// otherwise the animation controller will work with stale webview height,
// since the webview caches its state completely, and animation will work wrong.
if (state == State.HIDDEN)
clearBookmarkWebView();
int heightCompensation = 0;
if (mBannerController != null)
{
State lastState = getState();
boolean isLastStateNotHiddenOrPreview = lastState != State.HIDDEN
&& lastState != State.PREVIEW;
if (isLastStateNotHiddenOrPreview && (state == State.HIDDEN || state == State.PREVIEW)
&& !UiUtils.isLandscape(getContext()))
{
if (mBannerController.close())
heightCompensation = mBannerController.getLastBannerHeight();
}
else if (isLastStateNotHiddenOrPreview)
{
mBannerController.open();
}
}
compensateViewHeight(heightCompensation);
if (mMapObject != null)
mAnimationController.setState(state, mMapObject.getMapObjectType());
if (!mIsDocked && !mIsFloating)
{
// After ninepatch background is set from code, all paddings are lost, so we need to restore it later.
int bottom = mBannerController != null && mBannerController.isBannerContainerVisible()
? 0 : (int) getResources().getDimension(R.dimen.margin_base);
int left = mPreview.getPaddingLeft();
int right = mPreview.getPaddingRight();
int top = mPreview.getPaddingTop();
mPreview.setBackgroundResource(ThemeUtils.getResource(getContext(), state == State.PREVIEW ? R.attr.ppPreviewHeadClosed
: R.attr.ppPreviewHeadOpen));
mPreview.setPadding(left, top, right, bottom);
}
// FIXME: adjust this state to the bottom sheet state.
return State.HIDDEN;
}
private void clearBookmarkWebView()
@ -1281,16 +1181,6 @@ public class PlacePageView extends RelativeLayout
setButtons(mapObject, false, false);
break;
}
UiThread.runLater(new Runnable()
{
@Override
public void run()
{
mShadowController.updateShadows();
mPreview.requestLayout();
}
});
}
private void setPlaceDescription(@NonNull MapObject mapObject)
@ -1770,16 +1660,6 @@ public class PlacePageView extends RelativeLayout
}
}
public void setOnVisibilityChangedListener(BasePlacePageAnimationController.OnVisibilityChangedListener listener)
{
mAnimationController.setOnVisibilityChangedListener(new PlacePageVisibilityProxy(listener, mBannerController));
}
public void setOnAnimationListener(@Nullable BasePlacePageAnimationController.OnAnimationListener listener)
{
mAnimationController.setOnProgressListener(listener);
}
private void addOrganisation()
{
Statistics.INSTANCE.trackEvent(Statistics.EventName.EDITOR_ADD_CLICK,
@ -1927,14 +1807,16 @@ public class PlacePageView extends RelativeLayout
setMapObject(Framework.nativeDeleteBookmarkFromMapObject(), true, null);
else
setMapObject(BookmarkManager.INSTANCE.addNewBookmark(mapObject.getLat(), mapObject.getLon()), true, null);
post(new Runnable()
// TODO:
/* post(new Runnable()
{
@Override
public void run()
{
setState(mBookmarkSet ? State.DETAILS : State.PREVIEW);
}
});
});*/
}
private void showBigDirection()
@ -2022,20 +1904,9 @@ public class PlacePageView extends RelativeLayout
return (res == 0 ? getLayoutParams().width : res);
}
MwmActivity.LeftAnimationTrackListener getLeftAnimationTrackListener()
{
return mLeftAnimationTrackListener;
}
public void setLeftAnimationTrackListener(MwmActivity.LeftAnimationTrackListener listener)
{
mLeftAnimationTrackListener = listener;
}
public void hide()
{
detachCountry();
setState(State.HIDDEN);
}
public boolean isHidden()
@ -2155,11 +2026,11 @@ public class PlacePageView extends RelativeLayout
@Override
public void onSizeChanged()
{
if (mBannerController != null && mBannerController.hasErrorOccurred())
/* if (mBannerController != null && mBannerController.hasErrorOccurred())
{
mPreview.setPadding(mPreview.getPaddingLeft(), mPreview.getPaddingTop(),
getPaddingRight(), mMarginBase);
}
}*/
}
private class EditBookmarkClickListener implements OnClickListener

View file

@ -1,35 +0,0 @@
package com.mapswithme.maps.widget.placepage;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
public class PlacePageVisibilityProxy implements BasePlacePageAnimationController.OnVisibilityChangedListener
{
@NonNull
private final BasePlacePageAnimationController.OnVisibilityChangedListener mListener;
@Nullable
private final BannerController mBannerController;
public PlacePageVisibilityProxy(@NonNull BasePlacePageAnimationController.OnVisibilityChangedListener listener,
@Nullable BannerController bannerController)
{
mListener = listener;
mBannerController = bannerController;
}
@Override
public void onPreviewVisibilityChanged(boolean isVisible)
{
if (mBannerController != null)
mBannerController.onChangedVisibility(isVisible);
mListener.onPreviewVisibilityChanged(isVisible);
}
@Override
public void onPlacePageVisibilityChanged(boolean isVisible)
{
mListener.onPlacePageVisibilityChanged(isVisible);
}
}

View file

@ -7,7 +7,6 @@ import android.view.View;
import com.mapswithme.maps.R;
import com.mapswithme.maps.bookmarks.data.MapObject;
import com.mapswithme.maps.taxi.TaxiManager;
import com.mapswithme.maps.taxi.TaxiType;
import com.mapswithme.maps.widget.placepage.PlacePageView;
import com.mapswithme.maps.widget.placepage.Sponsored;
@ -28,10 +27,10 @@ public class PlacePageTracker
private MapObject mMapObject;
private boolean mTaxiTracked;
public PlacePageTracker(@NonNull PlacePageView placePageView)
public PlacePageTracker(@NonNull PlacePageView placePageView, @NonNull View bottomButtons)
{
mPlacePageView = placePageView;
mBottomButtons = mPlacePageView.findViewById(R.id.pp__buttons);
mBottomButtons = bottomButtons;
mTaxi = mPlacePageView.findViewById(R.id.ll__place_page_taxi);
}