android简易下拉框架实现

来源:互联网 发布:数据库的原理 编辑:程序博客网 时间:2024/06/03 21:22

以前一直想写一个自己用的下拉插件,最近自己也看了很多的下拉插件。所以总结了一下,自己写了一个下拉刷新插件。实现的这个下拉刷新的框架,并不是自己的原创,在完成过程中是参考了很多开源的框架,并把自己认为比较好的东西借鉴了过来,从而形成我的东西。

实现原理

1、LoadingLayout是实现刷新头部和尾部布局的主要文件,而CustomLayout则继承自LoadingLayout的抽象类,它定义了一些自定义方法。在LoadingLayout中声明了刷新文字、时间、图片等设置和状态的改变方法。

【1】Header

Headr布局文件主要是实现下拉动画实现,据下拉的距离来改变它的状态,从而显示不同的样式。

【2】Footer

Footer布局文件是自动加载更多等状态显示已经上拉刷新状态改变,从而显示不停的样式。

2、PullRefreshBase是这个刷新框架最重要的基本组件。它是一个继承LinearLayout的抽象类,主要是实现了刷新视图T与Header和Footer以及手势滑动、状态改变的处理逻辑。由于传入的是泛型T,所以它可以支持多种刷新组件的组合。比如LinearLayout、GridView、WebView、RecycleView等,同时也可以传入自己的自定义视图来实现。

【1】OnRefreshListener刷新接口监听。

   /**    * 下拉松手后调用    *    * @param refreshView 刷新的view    */   void onPullDownRefresh(final PullRefreshBase<V> refreshView);    /**     * 加载更多或上拉时调用     *     * @param refreshView 刷新的view     */    void onPullUpToRefresh(final PullRefreshBase<V> refreshView);

【2】通过对onInterceptTouchEvent方法重写,来对Touch进行拦截来判断滑动手势的操作。同时再根据是否拦截判断是否要传递给子视图。而onTouchEvent方法则根据拦截操作的标识来判断是否消费事件,不然就传递给父视图操作。

  /**     * Touch事件拦截器     *     * @param event     * @return     */    @Override    public final boolean onInterceptTouchEvent(MotionEvent event) {        if (!isInterceptTouchEventEnabled()) {            return false;        }        if (!isPullLoadEnabled() && !isPullRefreshEnabled()) {            return false;        }        final int action = event.getAction();        if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) {            mIsHandledTouchEvent = false;            return false;        }        if (action != MotionEvent.ACTION_DOWN && mIsHandledTouchEvent) {            return true;        }        switch (action) {            case MotionEvent.ACTION_DOWN:                mLastMotionY = event.getY();                mIsHandledTouchEvent = false;                break;            case MotionEvent.ACTION_MOVE:                final float deltaY = event.getY() - mLastMotionY;                final float absDiff = Math.abs(deltaY);                // 这里有三个条件:                // 1,位移差大于mTouchSlop,这是为了防止快速拖动引发刷新                // 2,isPullRefreshing(),如果当前正在下拉刷新的话,是允许向上滑动,并把刷新的HeaderView挤上去                // 3,isPullLoading(),理由与第2条相同                if (absDiff > mTouchSlop || isPullRefreshing() || isPullLoading()) {                    mLastMotionY = event.getY();                    // 第一个显示出来,Header已经显示或拉下                    if (isPullRefreshEnabled() && isReadyForPullDown()) {                        // 1,Math.abs(getScrollY()) > 0:表示当前滑动的偏移量的绝对值大于0,表示当前HeaderView滑出来了或完全                        // 不可见,存在这样一种case,当正在刷新时并且RefreshableView已经滑到顶部,向上滑动,那么我们期望的结果是                        // 依然能向上滑动,直到HeaderView完全不可见                        // 2,deltaY > 0.5f:表示下拉的值大于0.5f                        mIsHandledTouchEvent = (Math.abs(getScrollYValue()) > 0 || deltaY > 0.5f);                        // 如果截断事件,我们则仍然把这个事件交给刷新View去处理,典型的情况是让ListView/GridView将按下                        // Child的Selector隐藏                        if (mIsHandledTouchEvent) {                            mRefreshableView.onTouchEvent(event);                        }                    } else if (isPullLoadEnabled() && isReadyForPullUp()) {                        // 原理如上                        mIsHandledTouchEvent = (Math.abs(getScrollYValue()) > 0 || deltaY < -0.5f);                    }                }                break;            default:                break;        }        return mIsHandledTouchEvent;    }

3、总体布局视图

这里写图片描述

基本组件

1、框架内置提供PullRefreshRecyclerview,PullRefreshListView,PullRefreshWebView这三种刷新组件。PullRefreshRecyclerview最强大,它可以实现LinearView和GridView。而之所以提供PullRefreshListView,是主要供自定义的ListView和adapter来实现速度更快和多种样式的ListView。

【1】PullRefreshRecyclerview是一个自定义的下拉刷新RecyclerView扩展。我们知道RecylerView是support-v7包中的新组件,是一个强大的滑动组件,与经典的ListView相比,同样拥有item回收复用的功能。可以支持GridView与ListView,它的功能更加强大。

这里主要参考了HeaderAndFooterRecyclerView和LRecyclerView。

RecyclerAdapter:这个adapter是继承RecyclerView.Adapter的抽象类。主要封装了实现Header、Footer和Contents之间逻辑处理的关系。主要包括:

 /**  * 点击事件接口  */  public interface OnItemClickLitener {     void onItemClick(View view, int position);     boolean onItemLongClick(View view, int position);  }  void addHeaderView(View header)  void addFooterView(View footer)   int getCount() /**  *数据处理逻辑  */  void add(D object)  void addAll(Collection<? extends D> collection)  void addAll(D[] items)  void insert(D object, int index)  void insertAll(D[] object, int index)  void insertAll(Collection<? extends D> object, int index)  void remove(D object)  void remove(int position)  void clear()  void sort(Comparator<? super D> comparator)  /**  * 创建视图,交给子类实现方法  *  * @param parent  * @param viewType  * @return  */ public abstract BaseViewHolder OnCreateViewHolder(ViewGroup parent, int viewType);

BaseViewHolder:这个ViewHolder是继承RecyclerView.ViewHolder的抽象类,主要是将视图处理与adapter的逻辑处理分离开来了。因此更加便于处理和操作。在建立adapter时就会要求生成BaseViewHolder。

以上RecyclerAdapter和BaseViewHolder主要参考了EasyRecyclerView

【2】PullRefreshListView是一个自定义的下拉刷新ListView扩展。之所以保留是为了更加方便的自定义和使用自己定义的adapter。

【3】PullRefreshWebView是一个自定义的下拉刷新WebView扩展。只支持下拉刷新。

2、框架内包括了几种常用的基本刷新样式,Headr样式主要包括:DefaultHeaderLoadingLayout、IndicatorViewHeaderLoadingLayout、ProgressBarHeaderLoadingLayout、RotateHeaderLoadingLayout这几种,当然你可以自定义自己的样式。Footer样式主要括:DefaultFooterLoadingLayout、IndicatorViewFooterLoadingLayout。

【1】header样式是继承CustomLoadingLayout,主要是覆盖某些必要的方法,如果要自定义可以参考DefaultHeaderLoadingLayout的样式和布局来操作。footer样式和header样式是一样的继承CustomLoadingLayout,只是处理的逻辑和显示的文字少一些。

【2】样式截图:

a、hader样式:

DefaultHeaderLoadingLayout:

这里写图片描述

IndicatorViewHeaderLoadingLayout:

这里写图片描述

ProgressBarHeaderLoadingLayout:

这里写图片描述

RotateHeaderLoadingLayout:

这里写图片描述

b、footer样式:

DefaultFooterLoadingLayout:

这里写图片描述

IndicatorViewFooterLoadingLayout:

这里写图片描述

具体用法请看demo

0 0
原创粉丝点击