[android] Detect PP size change. Stop motion event tracking when PP closing.

Banner compensate height bug fix.
This commit is contained in:
Roman Romanov 2017-05-12 16:32:40 +04:00
parent 5bc2ff63bf
commit eee5bdccff
6 changed files with 132 additions and 57 deletions

View file

@ -8,7 +8,7 @@
android:overScrollMode="never"
android:layout_above="@+id/pp__buttons">
<LinearLayout
<com.mapswithme.maps.widget.ObservableLinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
@ -31,7 +31,7 @@
android:layout_width="match_parent"
android:layout_height="0dp"
android:background="?cardBackground"/>
</LinearLayout>
</com.mapswithme.maps.widget.ObservableLinearLayout>
</com.mapswithme.maps.widget.ObservableScrollView>
<include

View file

@ -0,0 +1,54 @@
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

@ -322,6 +322,11 @@ final class BannerController
animator.start();
}
boolean isOpened()
{
return mOpened;
}
interface BannerListener
{
void onSizeChanged();

View file

@ -174,6 +174,4 @@ public abstract class BasePlacePageAnimationController implements ObservableScro
animator.setInterpolator(interpolator == null ? INTERPOLATOR : interpolator);
animator.start();
}
protected void onContentSizeChanged() {}
}

View file

@ -18,11 +18,12 @@ 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
class BottomPlacePageAnimationController extends BasePlacePageAnimationController implements ObservableLinearLayout.SizeChangedListener
{
@SuppressWarnings("unused")
private static final String TAG = BottomPlacePageAnimationController.class.getSimpleName();
@ -34,9 +35,12 @@ class BottomPlacePageAnimationController extends BasePlacePageAnimationControlle
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;
@ -49,6 +53,9 @@ class BottomPlacePageAnimationController extends BasePlacePageAnimationControlle
if (mLayoutToolbar == null)
return;
((ObservableLinearLayout) mDetailsContent).setSizeChangedListener(this);
mContentHeight = mDetailsContent.getHeight();
final Toolbar toolbar = (Toolbar) mLayoutToolbar.findViewById(R.id.toolbar);
if (toolbar != null)
{
@ -65,14 +72,17 @@ class BottomPlacePageAnimationController extends BasePlacePageAnimationControlle
}
DisplayMetrics dm = placePage.getResources().getDisplayMetrics();
float screenHeight = dm.heightPixels;
mDetailMaxHeight = screenHeight * DETAIL_RATIO;
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:
@ -102,6 +112,10 @@ class BottomPlacePageAnimationController extends BasePlacePageAnimationControlle
final boolean isBannerTouch = mPlacePage.isBannerTouched(event);
if (isInside && !isBannerTouch && mIsGestureStartedInsideView)
mGestureDetector.onTouchEvent(event);
mIsDragging = false;
break;
case MotionEvent.ACTION_CANCEL:
mIsDragging = false;
break;
}
@ -111,7 +125,7 @@ class BottomPlacePageAnimationController extends BasePlacePageAnimationControlle
@Override
protected boolean onTouchEvent(@NonNull MotionEvent event)
{
if (mIsGestureFinished)
if (mIsGestureFinished || mIsHiding)
return false;
final boolean finishedDrag = (mIsDragging &&
@ -159,7 +173,7 @@ class BottomPlacePageAnimationController extends BasePlacePageAnimationControlle
private boolean isDetailContentScrollable()
{
return mDetailsScroll.getHeight() < mDetailsContent.getHeight();
return mDetailsScroll.getHeight() < mContentHeight;
}
private boolean canScroll(float delta)
@ -177,6 +191,9 @@ class BottomPlacePageAnimationController extends BasePlacePageAnimationControlle
@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)
@ -185,7 +202,7 @@ class BottomPlacePageAnimationController extends BasePlacePageAnimationControlle
if (!translateBy(-distanceY))
{
boolean scrollable = isDetailContentScrollable();
int maxTranslationY = mDetailsScroll.getHeight() - mDetailsContent.getHeight();
int maxTranslationY = mDetailsScroll.getHeight() - mContentHeight;
if ((scrollable && mDetailsScroll.getTranslationY() == 0)
|| (!scrollable && mDetailsScroll.getTranslationY() <= maxTranslationY))
{
@ -201,6 +218,9 @@ class BottomPlacePageAnimationController extends BasePlacePageAnimationControlle
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY)
{
if (mIsHiding)
return true;
finishDrag(-velocityY);
return true;
}
@ -208,6 +228,9 @@ class BottomPlacePageAnimationController extends BasePlacePageAnimationControlle
@Override
public boolean onSingleTapConfirmed(MotionEvent e)
{
if (mIsHiding)
return true;
MotionEvent evt = MotionEvent.obtain(e.getDownTime(),
e.getEventTime(),
e.getAction(),
@ -240,6 +263,7 @@ class BottomPlacePageAnimationController extends BasePlacePageAnimationControlle
private void finishDrag(float distance)
{
mIsDragging = false;
final float currentTranslation = mDetailsScroll.getTranslationY();
if (currentTranslation > mDetailsScroll.getHeight())
{
@ -303,7 +327,7 @@ class BottomPlacePageAnimationController extends BasePlacePageAnimationControlle
float detailsTranslation = mDetailsScroll.getTranslationY() + distanceY;
final boolean isScrollable = isDetailContentScrollable();
boolean consumeEvent = true;
final float maxTranslationY = mDetailsScroll.getHeight() - mDetailsContent.getHeight();
final float maxTranslationY = mDetailsScroll.getHeight() - mContentHeight;
if ((isScrollable && detailsTranslation < 0.0f) || detailsTranslation < maxTranslationY)
{
if (isScrollable)
@ -335,6 +359,8 @@ class BottomPlacePageAnimationController extends BasePlacePageAnimationControlle
@Override
protected void onStateChanged(final State currentState, final State newState, @MapObject.MapObjectType int type)
{
if (currentState == newState && newState == State.HIDDEN)
return;
prepareYTranslations(newState, type);
mDetailsScroll.setGestureDetector(mGestureDetector);
@ -350,17 +376,7 @@ class BottomPlacePageAnimationController extends BasePlacePageAnimationControlle
hidePlacePage();
break;
case PREVIEW:
mPreview.addOnLayoutChangeListener(new View.OnLayoutChangeListener()
{
@Override
public void onLayoutChange(View v, int left, int top, int right, int bottom,
int oldLeft, int oldTop, int oldRight, int oldBottom)
{
mPreview.removeOnLayoutChangeListener(this);
showPreview(currentState);
}
});
mPreview.requestLayout();
showPreview(currentState);
break;
case DETAILS:
showDetails();
@ -368,17 +384,7 @@ class BottomPlacePageAnimationController extends BasePlacePageAnimationControlle
case FULLSCREEN:
if (isDetailContentScrollable())
mDetailsScroll.setGestureDetector(null);
mDetailsScroll.addOnLayoutChangeListener(new View.OnLayoutChangeListener()
{
@Override
public void onLayoutChange(View v, int left, int top, int right, int bottom,
int oldLeft, int oldTop, int oldRight, int oldBottom)
{
mDetailsScroll.removeOnLayoutChangeListener(this);
showFullscreen();
}
});
mDetailsScroll.requestLayout();
showFullscreen();
break;
}
}
@ -465,7 +471,7 @@ class BottomPlacePageAnimationController extends BasePlacePageAnimationControlle
else
{
mCurrentAnimator = ValueAnimator.ofFloat(mDetailsScroll.getTranslationY(),
mDetailsScroll.getHeight() - mDetailsContent.getHeight());
mDetailsScroll.getHeight() - mContentHeight);
}
mCurrentAnimator.addUpdateListener(new UpdateListener());
mCurrentAnimator.addListener(new AnimationListener());
@ -482,7 +488,7 @@ class BottomPlacePageAnimationController extends BasePlacePageAnimationControlle
else
{
mCurrentAnimator = ValueAnimator.ofFloat(mDetailsScroll.getTranslationY(),
mDetailsScroll.getHeight() - mDetailsContent.getHeight());
mDetailsScroll.getHeight() - mContentHeight);
}
mCurrentAnimator.addUpdateListener(new UpdateListener());
mCurrentAnimator.addListener(new AnimationListener());
@ -493,6 +499,7 @@ class BottomPlacePageAnimationController extends BasePlacePageAnimationControlle
@SuppressLint("NewApi")
private void hidePlacePage()
{
mIsHiding = true;
if (mLayoutToolbar != null)
UiUtils.hide(mLayoutToolbar);
@ -513,6 +520,7 @@ class BottomPlacePageAnimationController extends BasePlacePageAnimationControlle
@Override
public void onAnimationEnd(Animator animation)
{
mIsHiding = false;
initialVisibility();
mPlacePage.setTranslationY(0);
mDetailsScroll.setTranslationY(mDetailsScroll.getHeight());
@ -563,12 +571,31 @@ class BottomPlacePageAnimationController extends BasePlacePageAnimationControlle
mBannerOpenListener = bannerOpenListener;
}
@Override
protected void onContentSizeChanged()
private boolean isOverDetailState()
{
return mDetailsScroll.getTranslationY() < mScreenHeight - mDetailMaxHeight;
}
private void onContentSizeChanged()
{
if (mIsDragging || mCurrentScrollY > 0)
return;
MapObject object = mPlacePage.getMapObject();
if (object != null)
onStateChanged(getState(), getState(), object.getMapObjectType());
{
State newState = getState();
if (isOverDetailState())
newState = State.FULLSCREEN;
onStateChanged(getState(), newState, object.getMapObjectType());
}
}
@Override
public void onSizeChanged(int width, int height, int oldWidth, int oldHeight)
{
mContentHeight = height;
onContentSizeChanged();
}
private class UpdateListener implements ValueAnimator.AnimatorUpdateListener

View file

@ -740,13 +740,10 @@ public class PlacePageView extends RelativeLayout
else
{
UiUtils.show(mHotelFacilities);
boolean oldValue = mFacilitiesAdapter.isShowAll();
mFacilitiesAdapter.setShowAll(false);
mFacilitiesAdapter.setItems(Arrays.asList(info.mFacilities));
mHotelMoreFacilities.setVisibility(info.mFacilities.length > FacilitiesAdapter.MAX_COUNT
? VISIBLE : GONE);
if (oldValue != mFacilitiesAdapter.isShowAll())
mAnimationController.onContentSizeChanged();
}
}
@ -862,7 +859,11 @@ public class PlacePageView extends RelativeLayout
public void onNeedOpenBanner()
{
if (mBannerController != null)
{
if (!mBannerController.isOpened())
compensateViewHeight(0);
mBannerController.open();
}
}
private void compensateViewHeight(int height)
@ -947,12 +948,16 @@ public class PlacePageView extends RelativeLayout
int heightCompensation = 0;
if (mBannerController != null)
{
if ((state == State.HIDDEN || state == State.PREVIEW) && !UiUtils.isLandscape(getContext()))
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
else if (isLastStateNotHiddenOrPreview)
{
mBannerController.open();
}
@ -1590,14 +1595,12 @@ public class PlacePageView extends RelativeLayout
case R.id.tv__place_hotel_more:
UiUtils.hide(mHotelMoreDescription);
mTvHotelDescription.setMaxLines(Integer.MAX_VALUE);
mAnimationController.onContentSizeChanged();
break;
case R.id.tv__place_hotel_facilities_more:
if (mSponsored != null && mMapObject != null)
Statistics.INSTANCE.trackHotelEvent(PP_HOTEL_FACILITIES, mSponsored, mMapObject);
UiUtils.hide(mHotelMoreFacilities);
mFacilitiesAdapter.setShowAll(true);
mAnimationController.onContentSizeChanged();
break;
case R.id.tv__place_hotel_reviews_more:
if (isSponsored())
@ -1817,7 +1820,6 @@ public class PlacePageView extends RelativeLayout
mCurrentCountry = null;
mDownloaderIcon.show(false);
UiUtils.hide(mDownloaderInfo);
mAnimationController.onContentSizeChanged();
}
MwmActivity getActivity()
@ -1844,16 +1846,5 @@ public class PlacePageView extends RelativeLayout
mPreview.setPadding(mPreview.getPaddingLeft(), mPreview.getPaddingTop(),
getPaddingRight(), mMarginBase);
}
addOnLayoutChangeListener(new OnLayoutChangeListener()
{
@Override
public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft,
int oldTop, int oldRight, int oldBottom)
{
removeOnLayoutChangeListener(this);
mAnimationController.onContentSizeChanged();
}
});
requestLayout();
}
}