com.baoyz.dribble.widget.SuperRecyclerView.java Source code

Java tutorial

Introduction

Here is the source code for com.baoyz.dribble.widget.SuperRecyclerView.java

Source

/*
 * The MIT License (MIT)
 * 
 * Copyright (c) 2015 baoyongzhang <baoyz94@gmail.com>
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package com.baoyz.dribble.widget;

import android.content.Context;
import android.support.v4.view.GestureDetectorCompat;
import android.support.v4.view.MotionEventCompat;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;

import com.baoyz.dribble.R;

/**
 * Created by baoyz on 15/1/16.
 */
public class SuperRecyclerView extends RecyclerView {

    private OnScrollListener mScrollListener;
    private boolean isLoading;
    private WrapperAdapter mAdapter;
    private OnLoadMoreListener mOnLoadMoreListener;
    private float mDownX;
    private boolean mInterceptTouch;
    private int mTouchDistance;
    private float mDownY;
    private OnQuickScrollListener mOnQuickScrollListener;
    private GestureDetectorCompat mGesutureDetector;
    private int mFlingVelocity;

    public SuperRecyclerView(Context context) {
        this(context, null);
    }

    public SuperRecyclerView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public SuperRecyclerView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);

        super.setOnScrollListener(new OnScrollListener() {
            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                if (newState == RecyclerView.SCROLL_STATE_IDLE) {
                    LinearLayoutManager layoutManager = (LinearLayoutManager) getLayoutManager();
                    if (layoutManager.findLastVisibleItemPosition() == (layoutManager.getItemCount() - 1)) {
                        setLoadMore(true);
                    }
                }

                if (mScrollListener != null)
                    mScrollListener.onScrollStateChanged(recyclerView, newState);
            }

            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
                if (mScrollListener != null)
                    mScrollListener.onScrolled(recyclerView, dx, dy);
            }
        });

        ViewConfiguration viewConfiguration = ViewConfiguration.get(context);
        mTouchDistance = viewConfiguration.getScaledOverflingDistance();
        mFlingVelocity = viewConfiguration.getScaledMinimumFlingVelocity();

        mGesutureDetector = new GestureDetectorCompat(context, new GestureDetector.SimpleOnGestureListener() {
            @Override
            public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
                if (mOnQuickScrollListener != null && Math.abs(velocityY) > mFlingVelocity) {
                    if (velocityY > 0)
                        mOnQuickScrollListener.onQuickDown();
                    else
                        mOnQuickScrollListener.onQuickUp();
                }
                return super.onFling(e1, e2, velocityX, velocityY);
            }
        });
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent e) {

        boolean b = super.onInterceptTouchEvent(e);

        int actionMasked = MotionEventCompat.getActionMasked(e);
        switch (actionMasked) {
        case MotionEvent.ACTION_DOWN:
            mDownX = e.getX();
            mDownY = e.getY();
            mInterceptTouch = false;
            break;
        case MotionEvent.ACTION_MOVE:
            float offsetX = e.getX() - mDownX;
            if (!b && Math.abs(offsetX) > mTouchDistance)
                mInterceptTouch = true;
            break;
        }

        if (mInterceptTouch)
            return false;

        return b;
    }

    @Override
    public boolean onTouchEvent(MotionEvent e) {
        mGesutureDetector.onTouchEvent(e);
        return super.onTouchEvent(e);
    }

    public void setLoadMore(boolean load) {
        if (isLoading == load)
            return;
        isLoading = load;
        mAdapter.setFooterVisibility(isLoading ? View.VISIBLE : View.GONE);
        if (isLoading && mOnLoadMoreListener != null)
            mOnLoadMoreListener.onLoadMore(this);
        mAdapter.notifyDataSetChanged();
    }

    public void setOnLoadMoreListener(OnLoadMoreListener listener) {
        mOnLoadMoreListener = listener;
    }

    public void setOnQuickScrollListener(OnQuickScrollListener listener) {
        mOnQuickScrollListener = listener;
    }

    @Override
    public void setOnScrollListener(OnScrollListener listener) {
        mScrollListener = listener;
    }

    @Override
    public void setAdapter(Adapter adapter) {
        mAdapter = new WrapperAdapter(adapter);
        super.setAdapter(mAdapter);
    }

    static class FooterViewHolder extends ViewHolder {

        View mItemView;

        public FooterViewHolder(View itemView) {
            super(itemView);
            mItemView = itemView;
        }
    }

    static class WrapperAdapter extends Adapter {

        public static final int TYPE_FOOTER = 0xFFFF01;

        private Adapter mBase;
        private int mFooterVisibility;

        public WrapperAdapter(Adapter adapter) {
            super();
            mBase = adapter;
        }

        public void setFooterVisibility(int visibility) {
            mFooterVisibility = visibility;
        }

        @Override
        public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            if (viewType == TYPE_FOOTER)
                return new FooterViewHolder(
                        LayoutInflater.from(parent.getContext()).inflate(R.layout.footer_load, parent, false));
            return mBase.onCreateViewHolder(parent, viewType);
        }

        @Override
        public void onBindViewHolder(ViewHolder holder, int position) {
            if (position == (getItemCount() - 1)) {
                FooterViewHolder vh = (FooterViewHolder) holder;
                //                vh.mItemView.setVisibility(mFooterVisibility);
                return;
            }
            mBase.onBindViewHolder(holder, position);
        }

        @Override
        public int getItemViewType(int position) {
            if (position == (getItemCount() - 1))
                return TYPE_FOOTER;
            return mBase.getItemViewType(position);
        }

        @Override
        public void setHasStableIds(boolean hasStableIds) {
            mBase.setHasStableIds(hasStableIds);
        }

        @Override
        public long getItemId(int position) {
            return mBase.getItemId(position);
        }

        @Override
        public int getItemCount() {
            return mBase.getItemCount() + 1;
        }

        @Override
        public void onViewRecycled(ViewHolder holder) {
            mBase.onViewRecycled(holder);
        }

        @Override
        public void onViewAttachedToWindow(ViewHolder holder) {
            mBase.onViewAttachedToWindow(holder);
        }

        @Override
        public void onViewDetachedFromWindow(ViewHolder holder) {
            mBase.onViewDetachedFromWindow(holder);
        }

        @Override
        public void registerAdapterDataObserver(AdapterDataObserver observer) {
            mBase.registerAdapterDataObserver(observer);
        }

        @Override
        public void unregisterAdapterDataObserver(AdapterDataObserver observer) {
            mBase.unregisterAdapterDataObserver(observer);
        }

        @Override
        public void onAttachedToRecyclerView(RecyclerView recyclerView) {
            mBase.onAttachedToRecyclerView(recyclerView);
        }

        @Override
        public void onDetachedFromRecyclerView(RecyclerView recyclerView) {
            mBase.onDetachedFromRecyclerView(recyclerView);
        }
    }

    //    @Override
    //    public int getChildCount() {
    //        return super.getChildCount() - 1;
    //    }

    public static interface OnLoadMoreListener {
        public void onLoadMore(RecyclerView recyclerView);
    }

    public static interface OnQuickScrollListener {
        public void onQuickUp();

        public void onQuickDown();
    }
}