【Android】给RecyclerView添加下拉刷新和加载更多(二)

大家都知道由于ListView的紧耦合问题,谷歌的改进就是RecyclerView本身不参与任何视图相关的问题。它不关心如何将子View放在合适的位置,也不关心如何分割这些子View,更不关心每个子View各自的外观。进一步来说,RecyclerView只负责回收和重用的工作,这就是它名字的由来。正是由于RecyclerView的插件化的特性,今天的目标是给RecyclerView加上下拉刷新和底部加载更多的功能。

下拉刷新使用到原生的SwipeRefreshLayout,当然大家也可以也可以使用开源项目来实现

加载更多在recyclerView的adapter中实现

还需要补充的是上一篇中没有实现的瀑布流效果


瀑布流的效果实现只需要更改两个位置①设置布局方式为StaggeredGridLayoutManager  ②在适配器中随机设置每一个Item项的高度即可

//为recyclerView设置布局方式
        recyclerView.setLayoutManager(new StaggeredGridLayoutManager(3,StaggeredGridLayoutManager.VERTICAL));

/**
 * Created by xiaoping on 2016/7/18.
 */
public class CaAdapter extends MyAdapter{

    private List<Integer> mHeights;

    public CaAdapter(Context context, List<String> list) {
        super(context, list);
        mHeights = new ArrayList<Integer>();
    }

    @Override
    public void onBindViewHolder(MyViewHolder holder, int pos) {
        super.onBindViewHolder(holder, pos);

        // 随机高度, 模拟瀑布效果.
        if (mHeights.size() <= pos) {
            mHeights.add((int) (100 + Math.random() * 300));
        }

        ViewGroup.LayoutParams lp = holder.itemView.getLayoutParams();
        lp.height = mHeights.get(pos);
        holder.itemView.setLayoutParams(lp);
    }
}


再来看下拉刷新

<android.support.v4.widget.SwipeRefreshLayout
        android:id="@+id/swipeRefreshLayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        >

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recylerview"
        android:layout_height="match_parent"
        android:layout_width="match_parent"/>
    </android.support.v4.widget.SwipeRefreshLayout>


swipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipeRefreshLayout);
        //设置进度条的颜色
        swipeRefreshLayout.setColorSchemeResources(android.R.color.holo_blue_light, android.R.color.holo_red_light, android.R.color.holo_orange_light, android.R.color.holo_green_light);
        swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                //设置4秒后停止动画效果,这里可以根据网络请求的时间来停止刷新
                Toast.makeText(MainActivity.this,"onRefresh there",Toast.LENGTH_SHORT).show();
                new Handler().postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        //模拟网络请求获取到数据
                        adapter.addItem(1, "onRefresh Item");
                        swipeRefreshLayout.setRefreshing(false);
                    }
                },4000);
            }
        });

加载更多是在我们的RecyclerView的适配器中实现的,即在我们正常的Item项的最下方加上一个FootView,也可以理解为一个特殊的Item项

private final static int TYPE_ITEM = 100;
    private final static int TYPE_FOOTER = 101;
    @Override
    public int getItemViewType(int position) {
        // 最后一个item设置为footerView
        if (position + 1 == getItemCount()) {
            return TYPE_FOOTER;
        } else {
            return TYPE_ITEM;
        }
    }

    //在整个View中添加一个footView
    @Override
    public int getItemCount() {
        return mList.size() + 1 ;
    }

    @Override
    public void onBindViewHolder(final MyViewHolder holder, final int pos) {
        if (pos + 1 == getItemCount()) {
            holder.tv.setText("点击加载更多...");
        }else{
            holder.tv.setText(mList.get(pos));
        }
        if(itemClickLister != null){
            holder.itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    //使用ViewHolder取到的postion可以避免positon的错乱
                    int layoutPostion = holder.getLayoutPosition();
                    //回调接口中的方法
                    itemClickLister.OnItemClickLister(holder.itemView,layoutPostion);
                }
            });
            holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
                @Override
                public boolean onLongClick(View v) {
                    int layoutPostion = holder.getLayoutPosition();
                    itemClickLister.OnItemLongClickLister(holder.itemView,layoutPostion);
                    return true;
                }
            });
        }
    }
因为我们加了一个FootView,我们需要对他负责,相信大家都是社会主义未来接班人,这点责任感还是有的,我们需要在适配器的getItemView(),getItemCount(),onBindViewHolder()中对这个特殊的家伙进行特殊的处理。当然不要忘记在Activity中也是一样的道理。

adapter.setOnItemClickLister(new MyAdapter.OnItemClickLister() {
            @Override
            public void OnItemClickLister(View view, int pos) {
                if (pos + 1 >= mList.size()) {
                    adapter.addItem(pos,"加载更多");
                    return;
                }else{
                    Toast.makeText(MainActivity.this,"CLick:" + mList.get(pos),Toast.LENGTH_SHORT).show();
                }
            }
            @Override
            public void OnItemLongClickLister(View view, int pos) {
                Toast.makeText(MainActivity.this,"LongCLick:" + mList.get(pos),Toast.LENGTH_SHORT).show();
            }
        });

点击下载源码



基于RecyclerView的优秀开源框架也不少,下面列举几个供大家参考


SwipeToLoadLayout  

https://github.com/Aspsine/SwipeToLoadLayout


UltimateRecyclerView  


IRecyclerView  


PullLoadMoreRecyclerView  


HeaderAndFooterRecyclerView  







评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值