RecyclerView简单案例&添加下拉刷新(SwipeRefreshLayout)、上拉加载(lastVisibleItem)
来源:互联网 发布:波士顿矩阵的特点 编辑:程序博客网 时间:2024/05/17 01:05
效果图如下
一、先看各个布局
activity_main
使用SwipeRefreshLayout包裹RecyclerView<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <android.support.v4.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/srl" android:layout_width="match_parent" android:layout_height="match_parent"> <android.support.v7.widget.RecyclerView android:id="@+id/rv" android:layout_width="match_parent" android:layout_height="match_parent"/> </android.support.v4.widget.SwipeRefreshLayout></LinearLayout>
list_item
只显示一个一个字符串<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" > <TextView android:id="@+id/tv_text" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:padding="15dp" android:textSize="18sp" /> <View android:layout_width="match_parent" android:layout_height="1dp" android:background="#fcc" /></LinearLayout>
list_foot
最后一个条目可见时加载更多数据(一个loading和文字提示)<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center_vertical" android:orientation="horizontal" android:padding="10dp"> <ProgressBar android:id="@+id/pb_loading" style="@android:style/Widget.ProgressBar.Inverse" android:layout_width="26dp" android:layout_height="26dp" android:layout_marginLeft="130dp"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="20dp" android:text="松开加载" android:textColor="#c0f0" android:textSize="20sp"/></LinearLayout>
二、适配器的实现(★)
RecyclerView的适配器(要熟练掌握哦)
分析数据应该如何展示,完整代码紧跟在分析之后怎么区分当前位置要展示的具体布局类型
ListView中我们很熟悉了,通过getViewTypeCount(): Int
获取需要展示的布局数目(如2),然后通过getItemViewType(): Int
获取当前位置需要展示的具体布局类型
↑ VS ↓
RecyclerView中仅使用getItemViewType(): Int
即可获得当前位置对应的布局类型,用法和ListView的getItemViewType(): Int
别无它异,具体参考下面的完整代码ViewHolder如何创建
ListView中需要手动创建静态Holder,并在getView(): View
中先后手动setTag()
和getTag()
来获取holder,然后进行控件内容的填充
↑ VS ↓
RecyclerView已帮我们集成进了ViewHolder(这也是Recycler的核心),只要继承RecyclerView.Adapter
时添加泛型RecyclerView.ViewHolder
,然后分别添加各布局对应的Holder类(类中初始化控件),最后在onCreateViewHolder: RecyclerView.ViewHolder
中通过各布局类型创建对应的Holder实例即可如何通过ViewHolder填充数据
ListView中在getView(): View
的缓存复用、holder的setTag()
完成后直接进行控件内容的填充
↑ VS ↓
RecyclerView中,我们单独在onBindViewHolder(holder): void
方法中通过转换holder类型后进行控件内容的填充
public class SampleAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { // 要展示的数据集合 private List<String> mDatas; // 判断布局类型 private static final int TYPE_ITEM = 0; private static final int TYPE_FOOT = 1; /** * 初始化工作(在这里是获得了数据集合) */ public SampleAdapter(List<String> datas) { mDatas = datas; } /** * 当前位置应该展示的条目布局的类型 */ @Override public int getItemViewType(int position) { // 数据集合最后一行数据之后的那一行就应该加载脚布局 if (position + 1 == getItemCount()) { return TYPE_FOOT; } else { return TYPE_ITEM; } } /** * 设置各布局,并返回与其对应的ViewHolder实例 */ @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = null; RecyclerView.ViewHolder holder = null; if (viewType == TYPE_ITEM) { view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item, null); holder = new ItemHolder(view); } else if (viewType == TYPE_FOOT) { view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_foot, null); holder = new FootHolder(view); } else { // 默认的布局及其对应的ViewHolder实例,防止发生意外 // default view = ... // default holder = ... } return holder; } /** * 填充各布局的控件内容 */ @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) { if (holder instanceof ItemHolder) { ((ItemHolder) holder).tvText.setText(String.valueOf(mDatas.get(position))); } } /** * 要展示的条目总数(包括所有数据集合和额外添加的头、身、脚条目数量) */ @Override public int getItemCount() { return mDatas.size() + 1; } /**************************************** * 各布局类型的ViewHolder */ class FootHolder extends RecyclerView.ViewHolder { public FootHolder(View view) { super(view); } } class ItemHolder extends RecyclerView.ViewHolder { // 展示一行字符串 @BindView(R.id.tv_text) TextView tvText; public ItemHolder(View view) { super(view); ButterKnife.bind(this, view); } }}
三、Activity中如何展示并添加刷新和加载逻辑
注意数据集合发生变化,需要使用
mAdapter.notifyItemRemoved(position)
来告知适配器以进行界面刷新
public class MainActivity extends BaseActivity { @BindView(R.id.srl) SwipeRefreshLayout srl; @BindView(R.id.rv) RecyclerView rv; /** * 布局管理器 * 1. LinearLayoutManager:支持横向、纵向 * 2. GridLayoutManager:网格 * 3. StaggeredGridLayoutManager:瀑布流 */ private LinearLayoutManager mLayoutManager; private List<String> mDatas; private SampleAdapter mAdapter; // 记录最后可见条目 private int lastVisible; // 分别记录刷新和加载次数 int refreshTimes = 0; int addmoreTimes = 0; @Override int layoutId() { return R.layout.activity_main; } /** * 初始化数据 */ @Override void initData() { mDatas = new ArrayList<String>(); for (int i = 0; i < 15; i++) { mDatas.add("数据== " + (i + 1) + " =="); } } @Override void initView() { srl.setColorSchemeResources(R.color.color1, R.color.color2, R.color.color3, R.color.color4); srl.setOnRefreshListener(this); rv.setOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { super.onScrollStateChanged(recyclerView, newState); // 不在滑动和最后可见条目是脚布局时加载更多 if (newState == RecyclerView.SCROLL_STATE_IDLE && lastVisible + 1 == mAdapter.getItemCount()) { addmore(); } } @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); lastVisible = mLayoutManager.findLastVisibleItemPosition(); } }); rv.setHasFixedSize(true); mLayoutManager = new LinearLayoutManager(this); rv.setLayoutManager(mLayoutManager); rv.setItemAnimator(new DefaultItemAnimator()); mAdapter = new SampleAdapter(mDatas); rv.setAdapter(mAdapter); } /** * 模仿下拉刷新 */ @Override void srlRefresh() { mDatas.add(0, "刷新 " + ++refreshTimes + "次"); new Timer().schedule(new TimerTask() { @Override public void run() { runOnUiThread(new Runnable() { @Override public void run() { Toast.makeText(MainActivity.this, "刷新" + refreshTimes, Toast.LENGTH_SHORT).show(); srl.setRefreshing(false); mAdapter.notifyDataSetChanged(); } }); } }, 1000); } /** * 模仿上拉加载 */ void addmore() { new Timer().schedule(new TimerTask() { @Override public void run() { runOnUiThread(new Runnable() { @Override public void run() { mDatas.add("数据增加" + ++addmoreTimes); Toast.makeText(MainActivity.this, "加载" + addmoreTimes, Toast.LENGTH_SHORT).show(); mAdapter.notifyItemInserted(mDatas.size()); } }); } }, 1000); }}
- RecyclerView简单案例&添加下拉刷新(SwipeRefreshLayout)、上拉加载(lastVisibleItem)
- RecyclerView和SwipeRefreshLayout下拉刷新和上拉加载
- SwipeRefreshLayout+RecyclerView实现下拉刷新上拉自动加载
- SwipeRefreshLayout + RecyclerView实现上拉加载和下拉刷新
- recyclerview+swiperefreshlayout实现GridView下拉刷新,上拉加载更多
- SwipeRefreshLayout+RecyclerView实现下拉刷新上拉自动加载
- Android SwipeRefreshLayout+RecyclerView下拉刷新与上拉加载
- SwipeRefreshLayout配合RecyclerView实现上拉加载更多下拉刷新
- SwipeRefreshLayout + RecyclerView下拉刷新,上拉加载更多
- SwipeRefreshLayout+RecyclerView实现下拉刷新上拉加载功能
- 自定义下拉刷新上拉加载控件(SwipeRefreshLayout + recyclerView)
- SwipeRefreshLayout + RecyclerView 实现 上拉刷新 和 下拉加载更多
- Swiperefreshlayout与Recyclerview下拉刷新和上拉加载
- SwipeRefreshLayout + RecyclerView 实现上拉加载下拉刷新
- retrofit+RecyclerView+SwipeRefreshLayout下拉刷新上拉加载+item点击
- SwipeRefreshLayout和RecyclerView实现下拉刷新和上拉加载
- Kotlin中SwipeRefreshLayout结合RecyclerView下拉刷新上拉加载
- RecyclerView+SwipeRefreshLayout+ViewPager实现上拉加载更多下拉刷新和添加Banner(附源码)
- js中的"!!"是什么意思?boolean强制类型转换
- 4泰坦尼克号问题
- Ibatis后台打印sql语句
- 巧用margin/padding的百分比值实现高度自适应(多用于占位,避免闪烁)
- 第一天实训
- RecyclerView简单案例&添加下拉刷新(SwipeRefreshLayout)、上拉加载(lastVisibleItem)
- SSM初始环境搭建
- VS2015 EF中 Orcale 通信:无法连接到服务器,或者无法对连接字符串进行语法分析
- 元素居中
- webstorm简单介绍,webstrom基本使用
- HTTP详解
- 传感器
- C#-面向对象
- spring boot集成shiro与缓存ehcache