package com.zulip.android.util;
import android.animation.Animator;
import android.annotation.SuppressLint;
import android.content.Context;
import android.support.design.widget.AppBarLayout;
import android.support.design.widget.CoordinatorLayout;
import android.support.design.widget.FloatingActionButton;
import android.support.v4.view.ViewCompat;
import android.support.v4.view.animation.FastOutSlowInInterpolator;
import android.support.v7.widget.LinearLayoutManager;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.View;
import android.view.ViewPropertyAnimator;
import android.view.animation.Interpolator;
import android.widget.LinearLayout;
import com.zulip.android.R;
import com.zulip.android.ZulipApp;
import com.zulip.android.activities.RecyclerMessageAdapter;
/**
* This hides the {@link AppBarLayout} and {@link android.support.design.widget.FloatingActionButton} when the
* recyclerView is scrolled, used in here {@link com.zulip.android.R.layout#main} as a behaviour.
*/
public class RemoveViewsOnScroll extends CoordinatorLayout.Behavior<View> {
private static final Interpolator FAST_OUT_SLOW_IN_INTERPOLATOR = new FastOutSlowInInterpolator();
private static float toolbarHeight;
private int changeInYDir;
private boolean mIsShowing;
private boolean isViewHidden;
private View chatBox;
private LinearLayoutManager linearLayoutManager;
private RecyclerMessageAdapter adapter;
public RemoveViewsOnScroll(Context context, AttributeSet attrs) {
super(context, attrs);
TypedValue tv = new TypedValue();
if (context.getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true))
toolbarHeight = TypedValue.complexToDimensionPixelSize(tv.data, context.getResources().getDisplayMetrics());
}
public RemoveViewsOnScroll(LinearLayoutManager linearLayoutManager, RecyclerMessageAdapter adapter) {
this.linearLayoutManager = linearLayoutManager;
this.adapter = adapter;
}
@Override
public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout, View child, View directTargetChild, View target, int nestedScrollAxes) {
return (nestedScrollAxes & ViewCompat.SCROLL_AXIS_VERTICAL) != 0;
}
@SuppressLint("NewApi")
@Override
public void onNestedPreScroll(CoordinatorLayout coordinatorLayout, View child, View target, int dx, int dy, int[] consumed) throws NullPointerException {
//count index starts from 1 where as position starts from 0, thus difference 1
//we have 2 loading layouts one at top and another at bottom of the messages which should be ignored
//resulting in a overall difference of 3
if (linearLayoutManager.findLastCompletelyVisibleItemPosition() < adapter.getItemCount() - 3) {
if (dy > 0 && changeInYDir < 0 || dy < 0 && changeInYDir > 0) {
child.animate().cancel();
changeInYDir = 0;
}
changeInYDir += dy;
if ((changeInYDir > toolbarHeight && child.getVisibility() == View.VISIBLE) && (!isViewHidden || isTopSnackBar(child)))
hideView(child);
else if (changeInYDir < 0 && (child.getVisibility() == View.GONE && !mIsShowing) || isTopSnackBar(child)) {
if (child instanceof FloatingActionButton) {
if (chatBox == null)
chatBox = coordinatorLayout.findViewById(R.id.messageBoxContainer);
if (chatBox.getVisibility() == View.VISIBLE) {
return;
}
}
showView(child);
}
}
}
private boolean isTopSnackBar(View child) {
return (child.getId() != R.id.appBarLayout && !(child instanceof FloatingActionButton));
}
@SuppressLint("NewApi")
private void hideView(final View view) {
isViewHidden = true;
int y = view.getHeight();
;
if (view instanceof AppBarLayout) {
y = -1 * view.getHeight();
ZulipApp.get().getZulipActivity().onHideActionBar();
} else if (view instanceof LinearLayout) {
y = 0;
}
ViewPropertyAnimator animator = view.animate()
.translationY(y)
.setInterpolator(FAST_OUT_SLOW_IN_INTERPOLATOR)
.setDuration(200);
animator.setListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animator) {
}
@Override
public void onAnimationEnd(Animator animator) {
isViewHidden = false;
view.setVisibility(View.GONE);
}
@Override
public void onAnimationCancel(Animator animator) {
isViewHidden = false;
if (!mIsShowing)
showView(view);
}
@Override
public void onAnimationRepeat(Animator animator) {
}
});
animator.start();
}
@SuppressLint("NewApi")
public void showView(final View view) {
mIsShowing = true;
float translationY = toolbarHeight;
if (view.getId() == R.id.appBarLayout) {
ZulipApp.get().getZulipActivity().onShowActionBar();
translationY = 0;
} else if (view instanceof FloatingActionButton) {
translationY = 0;
}
ViewPropertyAnimator animator = view.animate()
.translationY(translationY)
.setInterpolator(FAST_OUT_SLOW_IN_INTERPOLATOR)
.setDuration(200);
animator.setListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animator) {
view.setVisibility(View.VISIBLE);
}
@Override
public void onAnimationEnd(Animator animator) {
mIsShowing = false;
}
@Override
public void onAnimationCancel(Animator animator) {
mIsShowing = false;
if (!isViewHidden)
hideView(view);
}
@Override
public void onAnimationRepeat(Animator animator) {
}
});
animator.start();
}
}