/* * Copyright (C) ${YEAR} Raul Hernandez Lopez * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.raulh82vlc.topratemovies.widgets; import android.animation.Animator; import android.animation.ObjectAnimator; import android.support.v7.widget.RecyclerView; import android.view.View; import android.view.ViewGroup; import android.view.animation.AccelerateInterpolator; import android.view.animation.DecelerateInterpolator; import android.view.animation.Interpolator; import com.raulh82vlc.topratemovies.models.Constants; import java.util.HashMap; import java.util.Map; /** * ScrollManagerHandler where the toolbar and fab buttons * are hidden or shown * * Created by Raul Hernandez Lopez on 06/03/2015. * */ public class ScrollManagerHandler extends RecyclerView.OnScrollListener { /* Params declaration */ private static final int MIN_HIDING_SCROLL = 15; private boolean isHidden; private int concentratedDyFactor; private int finalDyFactor; private int offsetFactor; private Map<View, Constants.TOWARDS> viewsListToHide; /** * Constructor ScrollManagerHandler * * */ public ScrollManagerHandler() { viewsListToHide = new HashMap<>(); isHidden = false; concentratedDyFactor = 0; finalDyFactor = 0; offsetFactor = 0; } /** * Override Method onScrolled * this method handles the behaviour * whether All elements have to be shown or hidden * * @param recyclerView View to hide * @param iDx the distance in x-axis, not used here * @param iDy the distance to move on on y-axis * */ @Override public void onScrolled(RecyclerView recyclerView, int iDx, int iDy) { super.onScrolled(recyclerView, iDx, iDy); finalDyFactor += iDy; if(finalDyFactor < offsetFactor) { return; } if(iDy > 0) { concentratedDyFactor = concentratedDyFactor > 0 ? concentratedDyFactor + iDy : iDy; if(concentratedDyFactor > MIN_HIDING_SCROLL) { hideAllViews(); } } else if(iDy < 0) { concentratedDyFactor = concentratedDyFactor < 0 ? concentratedDyFactor + iDy : iDy; if(concentratedDyFactor < -MIN_HIDING_SCROLL) { showAllViews(); } } } /** * Method addViewToHide * this method add a view to hide * * @param iView View to hide * @param whichDirection in which direction we hide * */ public void addViewToHide(View iView, Constants.TOWARDS whichDirection) { viewsListToHide.put(iView, whichDirection); } /** * Method hideAllViews * this method Hides all views stored in the HashTable * */ public void hideAllViews() { if(!isHidden) { isHidden = true; for(View aView : viewsListToHide.keySet()) { hideOneView(aView, viewsListToHide.get(aView)); } } } /** * Method hideOneView * this method hides one view in one direction * is calculated the direction with the negative sign * and then the animation is started with an interpolator * @param iView view to hide * @param towards direction to hide * */ private void hideOneView(View iView, Constants.TOWARDS towards) { int aHeight = computeHowMuchTranslation(iView); int aTranslateY = towards == Constants.TOWARDS.TOP ? -aHeight : aHeight; startTranslationAnim(iView, aTranslateY, new AccelerateInterpolator(2)); } /** * Method startTranslationAnim * this method hides one view in one direction * @param iView view to hide * @param iTranslateY translate to a concrete height * @param accelerateInterpolator * */ private void startTranslationAnim(View iView, int iTranslateY, Interpolator accelerateInterpolator) { Animator aSlideEntersAnim = ObjectAnimator.ofFloat(iView, "translationY", iTranslateY); aSlideEntersAnim.setDuration(iView.getContext().getResources().getInteger(android.R.integer.config_mediumAnimTime)); aSlideEntersAnim.setInterpolator(accelerateInterpolator); aSlideEntersAnim.start(); } /** * Method computeHowMuchTranslation * this method computes the required translation * in the Y-axis * @param iView view to hide * @return height + margins * */ private int computeHowMuchTranslation(View iView) { int aHeight = iView.getHeight(); ViewGroup.MarginLayoutParams aParams = (ViewGroup.MarginLayoutParams) iView.getLayoutParams(); int aMargins = aParams.bottomMargin + aParams.topMargin; return aMargins + aHeight; } /** * Method showOneView * this method show the previously * hidden view * @param iView view to show * */ private void showOneView(View iView) { startTranslationAnim(iView, 0, new DecelerateInterpolator(2)); } /** * Method showAllViews * this method Shows all views stored in the HashTable * */ public void showAllViews() { if(isHidden) { isHidden = false; for(View aView : viewsListToHide.keySet()) { showOneView(aView); } } } /** * Method setToRecyclerView * set the ScrollListener to a preferred RecyclerView * @param iRecyclerView * */ public void setToRecyclerView(RecyclerView iRecyclerView) { iRecyclerView.setOnScrollListener(this); } /** * Method setToRecyclerView * set the ScrollListener to a preferred RecyclerView * @param offsetFactor the offset of the toolbar * */ public void setOffsetFactor(int offsetFactor) { this.offsetFactor = offsetFactor; } }