Android快速返回隐藏页脚onScrollChanged

时间:2014-08-11 10:05:18

标签: android scrollview

所以这是我的逻辑:

public void onScrollChanged(ScrollViewExt scrollView, int x, int y,
                int oldx, int oldy) {

                if (y < 200)
                  // the footer is still visible 
                   {
                    if(y > oldy) {
                        // scrolling down, need to hide footer
            TranslateAnimation slide = new TranslateAnimation(0, 0, y, 0);
            slide.setDuration(1);
            slide.setFillAfter(true);
            footerOffer.startAnimation(slide);

        } else {
            // scrolling up, need to show footer
            TranslateAnimation slide = new TranslateAnimation(0, 0, -y, 0);
            slide.setDuration(1);
            slide.setFillAfter(true);
            footerOffer.startAnimation(slide);
                }
        } else if (y == 0) {
            // scrolled to top      
        } }
    });

问题是它在滚动期间闪烁,然后当我向上滚动时,它会奇怪地向上移动。

所以,我想在向下滚动时缓慢地隐藏页脚,并在向上滚动时慢慢显示它。有人可以帮忙解决这里的逻辑吗?

1 个答案:

答案 0 :(得分:1)

看看我在下面的代码中是如何解决这个问题的。这是OnScrollListener的自定义RecyclerView

您可以在此处查看更多示例:https://github.com/lawloretienne/QuickReturn

public class QuickReturnRecyclerViewOnScrollListener extends RecyclerView.OnScrollListener {
    // region Member Variables
    private final QuickReturnViewType mQuickReturnViewType;
    private final View mHeader;
    private final int mMinHeaderTranslation;
    private final View mFooter;
    private final int mMinFooterTranslation;
    private final int mColumnCount;
    private final boolean mIsSnappable; // Can Quick Return view snap into place?
    private int mPrevScrollY = 0;
    private int mHeaderDiffTotal = 0;
    private int mFooterDiffTotal = 0;
    private List < RecyclerView.OnScrollListener > mExtraOnScrollListenerList = new ArrayList < > ();
    // endregion
    // region Constructors
    private QuickReturnRecyclerViewOnScrollListener(Builder builder) {
        mQuickReturnViewType = builder.mQuickReturnViewType;
        mHeader = builder.mHeader;
        mMinHeaderTranslation = builder.mMinHeaderTranslation;
        mFooter = builder.mFooter;
        mMinFooterTranslation = builder.mMinFooterTranslation;
        mColumnCount = builder.mColumnCount;
        mIsSnappable = builder.mIsSnappable;
    }
    // endregion
    @
    Override
    public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
        super.onScrollStateChanged(recyclerView, newState);
        // apply another list' s on scroll listener
        for (RecyclerView.OnScrollListener listener: mExtraOnScrollListenerList) {
            listener.onScrollStateChanged(recyclerView, newState);
        }
        if (newState == RecyclerView.SCROLL_STATE_IDLE && mIsSnappable) {
            int midHeader = -mMinHeaderTranslation / 2;
            int midFooter = mMinFooterTranslation / 2;
            switch (mQuickReturnViewType) {
            case HEADER:
                if (-mHeaderDiffTotal > 0 && -mHeaderDiffTotal < midHeader) {
                    ObjectAnimator anim = ObjectAnimator.ofFloat(mHeader, "translationY", mHeader.getTranslationY(), 0);
                    anim.setDuration(100);
                    anim.start();
                    mHeaderDiffTotal = 0;
                } else if (-mHeaderDiffTotal < -mMinHeaderTranslation && -mHeaderDiffTotal >= midHeader) {
                    ObjectAnimator anim = ObjectAnimator.ofFloat(mHeader, "translationY", mHeader.getTranslationY(), mMinHeaderTranslation);
                    anim.setDuration(100);
                    anim.start();
                    mHeaderDiffTotal = mMinHeaderTranslation;
                }
                break;
            case FOOTER:
                if (-mFooterDiffTotal > 0 && -mFooterDiffTotal < midFooter) { // slide up
                    ObjectAnimator anim = ObjectAnimator.ofFloat(mFooter, "translationY", mFooter.getTranslationY(), 0);
                    anim.setDuration(100);
                    anim.start();
                    mFooterDiffTotal = 0;
                } else if (-mFooterDiffTotal < mMinFooterTranslation && -mFooterDiffTotal >= midFooter) { // slide down
                    ObjectAnimator anim = ObjectAnimator.ofFloat(mFooter, "translationY", mFooter.getTranslationY(), mMinFooterTranslation);
                    anim.setDuration(100);
                    anim.start();
                    mFooterDiffTotal = -mMinFooterTranslation;
                }
                break;
            case BOTH:
                if (-mHeaderDiffTotal > 0 && -mHeaderDiffTotal < midHeader) {
                    ObjectAnimator anim = ObjectAnimator.ofFloat(mHeader, "translationY", mHeader.getTranslationY(), 0);
                    anim.setDuration(100);
                    anim.start();
                    mHeaderDiffTotal = 0;
                } else if (-mHeaderDiffTotal < -mMinHeaderTranslation && -mHeaderDiffTotal >= midHeader) {
                    ObjectAnimator anim = ObjectAnimator.ofFloat(mHeader, "translationY", mHeader.getTranslationY(), mMinHeaderTranslation);
                    anim.setDuration(100);
                    anim.start();
                    mHeaderDiffTotal = mMinHeaderTranslation;
                }
                if (-mFooterDiffTotal > 0 && -mFooterDiffTotal < midFooter) { // slide up
                    ObjectAnimator anim = ObjectAnimator.ofFloat(mFooter, "translationY", mFooter.getTranslationY(), 0);
                    anim.setDuration(100);
                    anim.start();
                    mFooterDiffTotal = 0;
                } else if (-mFooterDiffTotal < mMinFooterTranslation && -mFooterDiffTotal >= midFooter) { // slide down
                    ObjectAnimator anim = ObjectAnimator.ofFloat(mFooter, "translationY", mFooter.getTranslationY(), mMinFooterTranslation);
                    anim.setDuration(100);
                    anim.start();
                    mFooterDiffTotal = -mMinFooterTranslation;
                }
                break;
            case TWITTER:
                if (-mHeaderDiffTotal > 0 && -mHeaderDiffTotal < midHeader) {
                    ObjectAnimator anim = ObjectAnimator.ofFloat(mHeader, "translationY", mHeader.getTranslationY(), 0);
                    anim.setDuration(100);
                    anim.start();
                    mHeaderDiffTotal = 0;
                } else if (-mHeaderDiffTotal < -mMinHeaderTranslation && -mHeaderDiffTotal >= midHeader) {
                    ObjectAnimator anim = ObjectAnimator.ofFloat(mHeader, "translationY", mHeader.getTranslationY(), mMinHeaderTranslation);
                    anim.setDuration(100);
                    anim.start();
                    mHeaderDiffTotal = mMinHeaderTranslation;
                }
                if (-mFooterDiffTotal > 0 && -mFooterDiffTotal < midFooter) { // slide up
                    ObjectAnimator anim = ObjectAnimator.ofFloat(mFooter, "translationY", mFooter.getTranslationY(), 0);
                    anim.setDuration(100);
                    anim.start();
                    mFooterDiffTotal = 0;
                } else if (-mFooterDiffTotal < mMinFooterTranslation && -mFooterDiffTotal >= midFooter) { // slide down
                    ObjectAnimator anim = ObjectAnimator.ofFloat(mFooter, "translationY", mFooter.getTranslationY(), mMinFooterTranslation);
                    anim.setDuration(100);
                    anim.start();
                    mFooterDiffTotal = -mMinFooterTranslation;
                }
                break;
            }
        }
    }@
    Override
    public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
        super.onScrolled(recyclerView, dx, dy);
        // apply extra on scroll listener
        for (RecyclerView.OnScrollListener listener: mExtraOnScrollListenerList) {
            listener.onScrolled(recyclerView, dx, dy);
        }
        int scrollY = QuickReturnUtils.getScrollY(recyclerView, mColumnCount);
        //        Log.d("", "onScrolled() : scrollY - "+scrollY);
        int diff = mPrevScrollY - scrollY;
        //        Log.d("", "onScrolled() : diff - "+diff);
        if (diff != 0) {
            switch (mQuickReturnViewType) {
            case HEADER:
                if (diff < 0) { // scrolling down
                    mHeaderDiffTotal = Math.max(mHeaderDiffTotal + diff, mMinHeaderTranslation);
                } else { // scrolling up
                    mHeaderDiffTotal = Math.min(Math.max(mHeaderDiffTotal + diff, mMinHeaderTranslation), 0);
                }
                mHeader.setTranslationY(mHeaderDiffTotal);
                break;
            case FOOTER:
                if (diff < 0) { // scrolling down
                    mFooterDiffTotal = Math.max(mFooterDiffTotal + diff, -mMinFooterTranslation);
                } else { // scrolling up
                    mFooterDiffTotal = Math.min(Math.max(mFooterDiffTotal + diff, -mMinFooterTranslation), 0);
                }
                mFooter.setTranslationY(-mFooterDiffTotal);
                break;
            case BOTH:
                if (diff < 0) { // scrolling down
                    mHeaderDiffTotal = Math.max(mHeaderDiffTotal + diff, mMinHeaderTranslation);
                    mFooterDiffTotal = Math.max(mFooterDiffTotal + diff, -mMinFooterTranslation);
                } else { // scrolling up
                    mHeaderDiffTotal = Math.min(Math.max(mHeaderDiffTotal + diff, mMinHeaderTranslation), 0);
                    mFooterDiffTotal = Math.min(Math.max(mFooterDiffTotal + diff, -mMinFooterTranslation), 0);
                }
                mHeader.setTranslationY(mHeaderDiffTotal);
                mFooter.setTranslationY(-mFooterDiffTotal);
                break;
            case TWITTER:
                if (diff < 0) { // scrolling down
                    if (scrollY > -mMinHeaderTranslation)
                        mHeaderDiffTotal = Math.max(mHeaderDiffTotal + diff, mMinHeaderTranslation);
                    if (scrollY > mMinFooterTranslation)
                        mFooterDiffTotal = Math.max(mFooterDiffTotal + diff, -mMinFooterTranslation);
                } else { // scrolling up
                    mHeaderDiffTotal = Math.min(Math.max(mHeaderDiffTotal + diff, mMinHeaderTranslation), 0);
                    mFooterDiffTotal = Math.min(Math.max(mFooterDiffTotal + diff, -mMinFooterTranslation), 0);
                }
                mHeader.setTranslationY(mHeaderDiffTotal);
                mFooter.setTranslationY(-mFooterDiffTotal);
            default:
                break;
            }
        }
        mPrevScrollY = scrollY;
    }
    // region Helper Methods
    public void registerExtraOnScrollListener(RecyclerView.OnScrollListener listener) {
        mExtraOnScrollListenerList.add(listener);
    }
    // endregion
    // region Inner Classes
    public static class Builder {
        // Required parameters
        private final QuickReturnViewType mQuickReturnViewType;
        // Optional parameters - initialized to default values
        private View mHeader = null;
        private int mMinHeaderTranslation = 0;
        private View mFooter = null;
        private int mMinFooterTranslation = 0;
        private int mColumnCount = 1;
        private boolean mIsSnappable = false;
        public Builder(QuickReturnViewType quickReturnViewType) {
            mQuickReturnViewType = quickReturnViewType;
        }
        public Builder header(View header) {
            mHeader = header;
            return this;
        }
        public Builder minHeaderTranslation(int minHeaderTranslation) {
            mMinHeaderTranslation = minHeaderTranslation;
            return this;
        }
        public Builder footer(View footer) {
            mFooter = footer;
            return this;
        }
        public Builder minFooterTranslation(int minFooterTranslation) {
            mMinFooterTranslation = minFooterTranslation;
            return this;
        }
        public Builder columnCount(int columnCount) {
            mColumnCount = columnCount;
            return this;
        }
        public Builder isSnappable(boolean isSnappable) {
            mIsSnappable = isSnappable;
            return this;
        }
        public QuickReturnRecyclerViewOnScrollListener build() {
            return new QuickReturnRecyclerViewOnScrollListener(this);
        }
    }
    // endregion
}