翻翻git之---实现下拉到底刷新RecycleView InfiniteScroll

转载请注明出处:王亟亟的大牛之路

因为今天还有点工作上的事没做完,所以就不吹B了,介绍完库写完解释就吃饭去了,下午还要干活呢

InfiniteScroll

在传统的ListView李有PullToFressh做下拉刷新之类的实现,今天上一个类似的效果InfiniteScroll,不过他是寄存在RecycleView下的更符合发展趋势

效果图:

拉到底就加在更多出现Dialog的效果,使用场景很多

how to use?

Grade:

dependencies {
  compile ‘com.github.pwittchen:infinitescroll:0.0.1‘
}

Maven:

<dependency>
    <groupId>com.github.pwittchen</groupId>
    <artifactId>infinitescroll</artifactId>
    <version>0.0.1</version>
</dependency>

Eclipse:把圈圈那部分Copy了就行



再来说下具体怎么引用,直接贴例子代码在里面有详细解释

public class MainActivity extends AppCompatActivity {
    private static final int MAX_ITEMS_PER_REQUEST = 20;//每次请求item数
    private static final int NUMBER_OF_ITEMS = 100;//最大item数
    private static final int SIMULATED_LOADING_TIME_IN_MS = 1500;//模拟耗时操作睡线程的时间

    public Toolbar toolbar;
    public RecyclerView recyclerView;
    public ProgressBar progressBar;

    private MyAdapter myAdapter;
    private LinearLayoutManager layoutManager;
    private List<String> items;
    private int page = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //初始化数据源
        this.items = createItems();
        //获取控件id
        initViews();
        //初始化RecyclerView
        initRecyclerView();
        setSupportActionBar(toolbar);
    }
    //如果<10 那就前面+"0"
    private List<String> createItems() {
        List<String> items = new LinkedList<>();
        for (int i = 0; i < NUMBER_OF_ITEMS; i++) {
            String prefix = i < 10 ? "0" : "";
            items.add("Item #".concat(prefix).concat(String.valueOf(i)));
        }
        return items;
    }

    private void initViews() {
        toolbar = (Toolbar) findViewById(R.id.toolbar);
        recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
        progressBar = (ProgressBar) findViewById(R.id.progress_bar);
    }

    private void initRecyclerView() {
        layoutManager = new LinearLayoutManager(this);
        //如果item高度不变,提升性能操作
        recyclerView.setHasFixedSize(true);
        //设置ListView样式
        recyclerView.setLayoutManager(layoutManager);
        //添加适配器,subList方法截取了原本100长度的ArrayList的0->MAX_ITEMS_PER_REQUEST 部分
        myAdapter = new MyAdapter(items.subList(page, MAX_ITEMS_PER_REQUEST));
        recyclerView.setAdapter(myAdapter);
        //添加滑动监听
        recyclerView.addOnScrollListener(createInfiniteScrollListener());

        myAdapter.setOnItemClickListener(new MyAdapter.OnRecyclerViewItemClickListener() {
            @Override
            public void onItemClick(View view, int position) {
                Toast.makeText(MainActivity.this, "第" + position + "被点击", Toast.LENGTH_SHORT).show();
            }
        });
    }

    @NonNull
    private InfiniteScrollListener createInfiniteScrollListener() {
        return new InfiniteScrollListener(MAX_ITEMS_PER_REQUEST, layoutManager) {
            //刷新后第一个可见的item位置
            @Override
            public void onScrolledToEnd(final int firstVisibleItemPosition) {
                Log.d("-->firstVisible","firstVisibleItemPosition : "+firstVisibleItemPosition);
                simulateLoading();
                //每次加载X * 20个item
                int start = ++page * MAX_ITEMS_PER_REQUEST;
                final boolean allItemsLoaded = start >= items.size();
                if (allItemsLoaded) {
                    progressBar.setVisibility(View.GONE);
                } else {
                    int end = start + MAX_ITEMS_PER_REQUEST;
                    //合成新的数据源
                    final List<String> items = getItemsToBeLoaded(start, end);
                    //重新刷新View
                    refreshView(recyclerView, new MyAdapter(items), firstVisibleItemPosition);
                }
            }
        };
    }

    @NonNull
    private List<String> getItemsToBeLoaded(int start, int end) {
        List<String> newItems = items.subList(start, end);
        final List<String> oldItems = ((MyAdapter) recyclerView.getAdapter()).getItems();
        final List<String> items = new LinkedList<>();
        items.addAll(oldItems);
        items.addAll(newItems);
        return items;
    }

    /**
     * WARNING! This method is only for demo purposes!
     * Don‘t do anything like that in your regular project!
     */
    private void simulateLoading() {
        new AsyncTask<Void, Void, Void>() {
            @Override
            protected void onPreExecute() {
                progressBar.setVisibility(View.VISIBLE);
            }

            @Override
            protected Void doInBackground(Void... params) {
                try {
                    Thread.sleep(SIMULATED_LOADING_TIME_IN_MS);
                } catch (InterruptedException e) {
                    Log.e("MainActivity", e.getMessage());
                }
                return null;
            }

            @Override
            protected void onPostExecute(Void param) {
                progressBar.setVisibility(View.GONE);
            }
        }.execute();
    }
}

流程是这样的,一开始做了一个假数据,然后拉到底就刷新,然后拉到底就刷新然后刷新到最大值就不做增加的操作了,但是判断还是一直有的

上图是不刷新但还在判断的证据

那我们来大致看看这个下拉的判断是如何实现的

//继承于RecyclerView.OnScrollListener,也就有了一个很重要的方法
// onScrolled(RecyclerView recyclerView, int dx, int dy)
public abstract class InfiniteScrollListener extends RecyclerView.OnScrollListener
//构造函数分别传入2个参数,一个是要被加载的最大值,还有个是LinearLayoutManager对象,然后再是做异常处理,为空什么的
   public InfiniteScrollListener(int maxItemsPerRequest, LinearLayoutManager layoutManager) {
        Preconditions.checkIfPositive(maxItemsPerRequest, "maxItemsPerRequest <= 0");
        Preconditions.checkNotNull(layoutManager, "layoutManager == null");
        this.maxItemsPerRequest = maxItemsPerRequest;
        this.layoutManager = layoutManager;
    }
     //具体执行操作和回调做事的地方,返回的也就是那个可见第一个item的position
     @Override
    public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
        super.onScrolled(recyclerView, dx, dy);
        //这边就是判断是否能加在
        if (canLoadMoreItems()) {
            onScrolledToEnd(layoutManager.findFirstVisibleItemPosition());
        }
    }
//加载完刷新的操作,然后再移到那个标志位的位置上去,这也就是为什么每次我们刷新完没有跳到最上面的原因
protected void refreshView(RecyclerView view, RecyclerView.Adapter adapter, int position) {
        view.setAdapter(adapter);
        view.invalidate();
        view.scrollToPosition(position);
    }
  //抽象方法了,给我们实现用
  public abstract void onScrolledToEnd(final int firstVisibleItemPosition);

整体实现不太难,但是有很好的思路,所以给大家推荐下。

源码地址:https://github.com/ddwhan0123/BlogSample/blob/master/InfiniteScroll-master.zip

git地址:https://github.com/ddwhan0123/InfiniteScroll#download

时间: 2024-10-09 09:18:58

翻翻git之---实现下拉到底刷新RecycleView InfiniteScroll的相关文章

【原版的:参赛作品】窥秘懒---android打开下拉手势刷新时代

小飒的成长史原创作品:窥视懒人的秘密---android下拉刷新开启手势的新纪元转载请注明出处 *****************************************************************        前言:窥视懒人那些不为人知的秘密 ***************************************************************** 作为一个程序猿,哪有不勤奋的道理.当我们都在为技术奋不顾身的时候.偏偏懒人创造了世界. 有的

Js下拉无刷新

<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>iscroll.js</title> <script type="text/javascript" src="http://code.jquery.com/jquery-1.9.1.js"></script> <script

MUI实现上拉刷新和下拉加载

  前  言 ha ha 为实现下拉刷新功能,大多H5框架都是通过DIV模拟下拉回弹动画,在低端android手机上,DIV动画经常出现卡顿现象(特别是图文列表的情况): mui通过双webview解决这个DIV的拖动流畅度问题:拖动时,拖动的不是div,而是一个完整的webview(子webview),回弹动画使用原生动画. mui的上拉加载和下拉刷新类似,都属于pullRefresh插件. 上拉刷新 主页面内容比较简单,只需要创建子页面即可: mui.init({ subpages:[{ u

提升HTML5的性能体验系列之三 流畅下拉刷新和上拉

下拉刷新 为实现下拉刷新功能,大多H5框架都是通过DIV模拟下拉回弹动画,在低端android手机(Android4.4以下)上,DIV动画经常出现卡顿现象(特别是图文列表的情况).解决方案还是webview. 既然拉div卡,那就不拉div,改拉webview.webview的拉动是原生的,回弹效果也是原生的,体验与原生一致.思路是在父页面写titlebar,titlebar下面10像素左右写一个"下拉可刷新".然后append一个子webview,并设置为可下拉.那么在把子webv

Android 自定义ListView实现底部分页刷新与顶部下拉刷新

在项目开发中,由于数据过大时,需要进行分页加载或下拉刷新,来缓解一次性加载的过长等待.本篇博文实例讲解通过自定义的ListView实现底部分页加载和顶部下拉刷新的效果. 其效果图: 一.ListView 底部分页加载 整个底部分页加载,主要分一下几步: 1.加载底部自定义View; 2.响应OnScrollListener监听事件,onScroll方法记录最后可见的View Item以及整个totalItemCount.当onScrollStateChanged状态改变时, 当滑动到底端,并滑动

提升html5的性能体验系列之三流畅下拉刷新

下拉刷新 为实现下拉刷新功能,大多H5框架都是通过DIV模拟下拉回弹动画,在低端android手机(Android4.4以下)上,DIV动画经常出现卡顿现象(特别是图文列表的情况).解决方案还是webview. 既然拉div卡,那就不拉div,改拉webview.webview的拉动是原生的,回弹效果也是原生的,体验与原生一致.思路是在父页面写titlebar,titlebar下面10像素左右写一个“下拉可刷新”.然后append一个子webview,并设置为可下拉.那么在把子webview往下

Android ListView下拉/上拉刷新:设计原理与实现

 <Android ListView下拉/上拉刷新:设计原理与实现> Android上ListView的第三方开源的下拉刷新框架很多,应用场景很多很普遍,几乎成为现在APP的通用设计典范,甚至谷歌官方都索性在Android SDK层面支持下拉刷新,我之前写了一篇文章<Android SwipeRefreshLayout:谷歌官方SDK包中的下拉刷新>专门介绍过(链接地址:http://blog.csdn.net/zhangphil/article/details/4696537

Android SwipeRefreshLayout下拉刷新控件源码简单分析

咱们在做Android APP开发的时候经常碰到有下拉刷新和上拉加载跟多的需求,这篇文章咱们先说说下来刷新,咱们就以google的原生的下拉刷新控件SwipeRefreshLayout来看看大概的实现过程. SwipeRefreshLayout是google自己推出的下拉刷新控件.使用起来也非常的简单,在满足条件的情况下下拉的时候会显示一个圆形的loading的动画效果,然后回调到上层,上层自己做刷新的一系列的处理,处理结束后调用SwipeRefreshLayout的setRefreshing(

Android 自定义ListView实现底部分页刷新与顶部下拉刷新,androidlistview

在项目开发中,由于数据过大时,需要进行分页加载或下拉刷新,来缓解一次性加载的过长等待.本篇博文实例讲解通过自定义的ListView实现底部分页加载和顶部下拉刷新的效果. 其效果图: 一.ListView 底部分页加载 整个底部分页加载,主要分一下几步: 1.加载底部自定义View; 2.响应OnScrollListener监听事件,onScroll方法记录最后可见的View Item以及整个totalItemCount.当onScrollStateChanged状态改变时, 当滑动到底端,并滑动