易生活(五)-APP--上拉加载更多工具类封装思路及实现

版权声明:本文为博主高远原创文章,转载请注明出处:http://blog.csdn.net/wgyscsf https://blog.csdn.net/wgyscsf/article/details/51578456

背景

  1. 在项目开发过程中遇到这样一个问题:我们团队有用到RecyclerView,由于这是新特性,许多刷新框架还不支持,于是就选择了google官方的刷新框架SwipeRefreshLayout,但是这个框架只有下拉刷新,没有上拉加载更多。
  2. 在《ListView刷新原理及实现》已经说过自己动手写刷新以及加载原理,于是项目中打算自己写上拉加载更多,刷新用SwipeRefreshLayout。
  3. 问题是,自己写上拉加载更多会用到大量的代码去实现这个逻辑,非常繁琐。
  4. 现尝试对这一块进行封装。[已解决]

思路、实现及问题

思路

  • 将判断手指滑动到控件底部以及滑动到底部这一块逻辑抽离到父类,在子类中直接实现这个父类即可。这一块有大量代码,如果能实现就可以大量节俭代码量,提高工作效率。
  • 同时,需要通过一定的手段通知子类什么时候滑动到底部,以便子类去执行“加载更多”操作。这里我们通过回调实现。
  • 难点在于,在安卓activity和fragment中不能像我们平时写代码可以“实例化”(new xxx(传递子类对象通知父类))。我们通过super.init(子类对象)去通知父类。
  • 那么,问题又来了,现在这是一个“工具类”,如果使用super.init(子类对象),如何实现共用?太过局限,不能实现共用。
  • 我们通过“接口”的形式解决这个问题。让子类全部实现一个接口,在父类中实例化接口即可!

实现

  • 工具类

    import android.os.Handler;
    import android.os.Message;
    import android.support.v7.app.AppCompatActivity;
    import android.widget.AbsListView;
    
    /**
     * Created by wgyscsf on 2016/6/1.
     * 邮箱:[email protected]
     * 博客:http://blog.csdn.net/wgyscsf
     */
    
    
    /**
     * 作用:该工具类简化了滑到底部的逻辑判断以及何时触发上拉加在更多;可以直接写上拉加载更多操作。(简单来说,你不用再去写何时到listview的底部这一块的操作以及发送加载更多的handler请求)
     * 使用方式(三步):
     * 1、让你的activity继承这个LoadMoreActivity(不再继承原有AppCompatActivity)
     * 2、在你的onCreate方法中写 super.initLoadMore(this);
     * 3、让你的activity实现LoadMoreActivity.LoadMoreActivityListener接口,在实现的方法中即可以写上拉加载更多的操作(自己维护页码变化)。
     * 注意:原有操作不便,例如添加footer、添加ScrollListener监听( listview.setOnScrollListener(this);)。
     */
    
    public class LoadMoreActivity extends AppCompatActivity implements  AbsListView.OnScrollListener{
        private LoadMoreActivityListener mLoadMoreActivityListener;
        //这个方法靠子类调用,完成自身的初始化(这个“自身”指的是实现LoadMoreActivityListener接口的activity)。
        public void initLoadMore(LoadMoreActivityListener loadMoreActivityListener){
            this.mLoadMoreActivityListener=loadMoreActivityListener;
        }
        public static final int LOAD_LOGIC = 1;//上拉逻辑
        private  int result1;//上拉加载更多相关
        private  int result2;//上拉加载更多相关
        //上拉加载更多操作
        Handler mHandler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                switch (msg.what) {
                    case LOAD_LOGIC:
                        mLoadMoreActivityListener.loadMore();//核心代码:这里通知子类可以加载更多了。
                        break;
                }
    
            }
        };
        //监听状态改变
        @Override
        public void onScrollStateChanged(AbsListView view, int scrollState) {
            switch (scrollState) {
                case SCROLL_STATE_IDLE:
                    //滑动结束
                    if (result1 >= result2) {
                        //只发送一次,防止多次加载数据
                        if (!mHandler.hasMessages(LOAD_LOGIC))
                            mHandler.sendEmptyMessage(LOAD_LOGIC);
                    }
                    break;
                case SCROLL_STATE_FLING:
    
                    break;
                case SCROLL_STATE_TOUCH_SCROLL:
                    //滑动中
                    break;
            }
        }
    
        //滑动结束之后执行
        @Override
        public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
            result1 = firstVisibleItem + visibleItemCount;
            result2 = totalItemCount;
        }
    
    //接口,这个接口要靠继承上述LoadMoreActivity去实现,在loadMore()中实现加载更多操作
        public interface LoadMoreActivityListener{
            //这里写加载更多的逻辑,这个方法要靠实现类去实现,去完成加载更多操作。
            public void loadMore();
        }
    }
    
  • 使用

    1. 让你的activity extends LoadMoreActivity implements LoadMoreActivity.LoadMoreActivityListener
    2. onCreate(Bundle savedInstanceState)中写super.onCreate(savedInstanceState);
    3. 在实现的方法loadMore()中写加载更多操作即可。

问题

  • 问题也是很明显的,这个工具类只能应用于activity之中,对于在fragment是不能使用的。
  • 我也尝试解决着去解决,但是fragment和activity根本没有直接的父类关系。
  • 所以很难封装到一起,共用一个工具类。
  • 另一方面,由于RecyclerView的新特性,这个工具类也不能应用于RecyclerView。

总结

  • 虽然这个工具类有很大的局限性,但是仍然比较实用。至少对于一般的需要实现上拉加载更多是可以实现基本的功能的,并且大量减少代码量。
  • 我们可以看出,在上述这个工具类的抽取过程中,运用到了继承、接口(重点)、回调去实现这个工具类。
  • 灵活运用继承关系、面向接口编程、回调思想可以很大程度上优化我们的代码以及实现对代码的封装。

附,fragment上拉加载更多工具类(实现和上述工具类一致,只是继承的父类变了)

    import android.os.Handler;
    import android.os.Message;
    import android.support.v4.app.Fragment;
    import android.widget.AbsListView;

    /**
     * Created by wgyscsf on 2016/6/1.
     * 邮箱:[email protected]
     * 博客:http://blog.csdn.net/wgyscsf
     */


    /**
     * 作用:该工具类简化了滑到底部的逻辑判断以及何时触发上拉加在更多;可以直接写上拉加载更多操作。(简单来说,你不用再去写何时到listview的底部这一块的操作以及发送加载更多的handler请求)
     * 使用方式(三步):
     * 1、让你的Fragment继承这个LoadMoreFragment(不再继承原有Fragment)
     * 2、在你的onCreateView方法中写 super.initLoadMore(this);
     * 3、让你的Fragment实现 LoadMoreFragment.LoadMoreFragmentListener 接口,在实现的方法中即可以写上拉加载更多的操作(自己维护页码变化)。
     * 注意:原有操作不便,例如添加footer、添加ScrollListener监听( listview.setOnScrollListener(this);)。
     */



    public class LoadMoreFragment extends Fragment implements  AbsListView.OnScrollListener{
        private LoadMoreFragmentListener mLoadMoreFragmentListener;
        public void initLoadMore(LoadMoreFragmentListener loadMoreFragmentListener){
            this.mLoadMoreFragmentListener=loadMoreFragmentListener;
        }
        public static final int LOAD_LOGIC = 1;//上拉逻辑
        private  int result1;//上拉加载更多相关
        private  int result2;//上拉加载更多相关
        //这里进行刷新、上拉加载更多逻辑、上拉加载更多操作
        Handler mHandler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                switch (msg.what) {
                    case LOAD_LOGIC:
                        mLoadMoreFragmentListener.loadMore();
                        break;
                }

            }
        };

        //监听状态改变
        @Override
        public void onScrollStateChanged(AbsListView view, int scrollState) {
            switch (scrollState) {
                case SCROLL_STATE_IDLE:
                    //滑动结束
                    if (result1 >= result2) {
                        //只发送一次,防止多次加载数据
                        if (!mHandler.hasMessages(LOAD_LOGIC))
                            mHandler.sendEmptyMessage(LOAD_LOGIC);
                    }
                    break;
                case SCROLL_STATE_FLING:

                    break;
                case SCROLL_STATE_TOUCH_SCROLL:
                    //滑动中
                    break;
            }
        }

        //滑动结束之后执行
        @Override
        public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
            result1 = firstVisibleItem + visibleItemCount;
            result2 = totalItemCount;
        }


        public interface LoadMoreFragmentListener{
            //这里写加载更多的逻辑
            public void loadMore();
        }
    }

猜你喜欢

转载自blog.csdn.net/wgyscsf/article/details/51578456
今日推荐