Android 提供的Swiperefreshlayout 实现下拉刷新和RecyclerView上拉加载更多
一:简介
SwipeRefrshLayout是Google官网更新的一个控件,能够实现下拉刷新的成果
增加依赖首先在利用或模块的build.gradle文件中增加所需的工作依赖项:
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0"//增加依赖
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout android:id="@+id/swipe_refresh" android:layout_width="match_parent" android:layout_height="match_parent"> <androidx.recyclerview.widget.RecyclerView android:id="@+id/tv_recycler" android:layout_width="match_parent" android:layout_height="match_parent"/> </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
二:Swiperefreshlayout实现下拉加载更多
setColorSchemeResources(int... colorResIds):设置下拉进度条的色彩主题,参数为可变参数,并且是资源id,能够设置多种不同的色彩,每转一圈就显示一种色彩。
setOnRefreshListener(SwipeRefreshLayout.OnRefreshListener listener):设置监听,须要重写onRefresh()办法,顶部下拉时会调用这个办法,在外面实现申请数据的逻辑,设置下拉进度条隐没等等。
setProgressBackgroundColorSchemeResource(int colorRes):设置下拉进度条的背景色彩,默认红色。
setRefreshing(boolean refreshing):设置刷新状态,true示意正在刷新,false示意勾销刷新。
应用:
private SwipeRefreshLayout swipe_refresh;swipe_refresh=findViewById(R.id.swipe_refresh);swipe_refresh.setColorSchemeResources(new int[]{R.color.start,R.color.min,R.color.end});//设置下拉进度条色彩 swipe_refresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { @Override public void onRefresh() { //提早2秒设置不刷新,模仿耗时操作,须要放在子线程中 new Handler().postDelayed(new Runnable() { @Override public void run() { // myRecycleViewAdapter.addData(0); myRecycleViewAdapter.add(mInsertDatas);//增加一个数据汇合 // myRecycleViewAdapter.notifyDataSetChanged(); swipe_refresh.setRefreshing(false);//设置是否刷新 } },2000); } }); } 构建假的数据汇合 private List<String> mInsertDatas=new ArrayList<>(); for (int j=0;j<10;j++){ mInsertDatas.add("我是Insert Data"+j); } 调用适配器的add办法 /** * 增加数据汇合到数据汇合中 */ public void add(List<String> datas) { //mDatas.addAll(datas);//这个会把数据加载开端 mDatas.addAll(0,datas);//这个增加数据汇合到头 notifyDataSetChanged(); }
RecyclerView 的滑动状态有如下三种状态:
public static final int SCROLL_STATE_IDLE = 0;//手指来到屏幕
public static final int SCROLL_STATE_DRAGGING = 1;//手指触摸屏幕
public static final int SCROLL_STATE_SETTLING = 2;//手指减速滑动并放开,此时滑动状态随同SCROLL_STATE_IDLE
三:Swiperefreshlayout配合RecyclerView实现上拉加载更多
/**RecyclerView应用滚动监听*/ tv_recycler.addOnScrollListener(new RecyclerView.OnScrollListener() { /** * 当RecyclerView的滑动状态扭转时触发 */ @Override public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) { super.onScrollStateChanged(recyclerView, newState); Log.d("test", "StateChanged = " + newState); //如果想通过指尖滑动屏幕变动来判断是否触碰,实现当且仅当滑动到最初一项并且手指上拉抛出时才执行上拉加载更多成果的话,须要配合onScrollStateChanged(RecyclerView recyclerView, int newState的应用, //if (newState==RecyclerView.SCROLL_STATE_IDLE)来判断 } /** * 当RecyclerView滑动时触发 * 相似点击事件的MotionEvent.ACTION_MOVE */ @Override public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); int lastVisibleItemPosition = layoutManager.findLastVisibleItemPosition(); if (lastVisibleItemPosition+1==myRecycleViewAdapter.getItemCount()){ Log.d("test", "loading executed"); boolean isRefreshing=swipe_refresh.isRefreshing(); if (isRefreshing){ myRecycleViewAdapter.notifyItemRemoved(myRecycleViewAdapter.getItemCount()); return; } if (!isLoading){ isLoading=true; new Handler().postDelayed(new Runnable() { @Override public void run() { getData(); Log.d("test", "load more completed"); isLoading = false; } },1000); } } } }); } 获取假数据 /**获取测试数据*/ private void getData() { for (int i=0;i<6;i++){ mDatas.add("我是加载更多数据"+i); } myRecycleViewAdapter.notifyDataSetChanged(); swipe_refresh.setRefreshing(false); }
//对应的Adapter减少了脚布局ViewHolder实现加载最初显示叫布局
public class MyRecycleViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { private List<String> mDatas;//数据源 private Context context; private static final int TYPE_ITEM = 0;//定义非加载更多 private static final int TYPE_FOOTER = 1;//加载更多 private OnItemClickListener onItemClickListener; /** * 向内部提供调用设置监听 */ public void setOnItemClickListener(OnItemClickListener onItemClickListener) { this.onItemClickListener = onItemClickListener; } public MyRecycleViewAdapter(Context context, List<String> mDatas) { this.context = context; this.mDatas = mDatas; } @Override public int getItemViewType(int position) { if (position + 1 == getItemCount()) { return TYPE_FOOTER; } else { return TYPE_ITEM; } } /** * 创立ViewHolder并返回,后续item布局里控件都是从ViewHolder中取出 */ @NonNull @Override public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { if (viewType == TYPE_FOOTER) { //将咱们自定义的脚布局转成View View view_foot = LayoutInflater.from(context).inflate(R.layout.item_foot, parent, false); //将View传递给咱们自定义脚FootViewHolder return new FootViewHolder(view_foot); } else if (viewType == TYPE_ITEM) { //将咱们自定义的item布局转成View View view = LayoutInflater.from(context).inflate(R.layout.item_one, parent, false); //将View传递给咱们自定义ViewHolder return new MyHolder(view); } return null; } /** * 通过办法提供的ViewHolder,将数据绑定到的ViewHolder中 */ @Override public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { if (holder instanceof MyHolder){ ((MyHolder) holder).tv_content.setText(mDatas.get(position)); holder.itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (onItemClickListener != null) { onItemClickListener.onItemClick(v, holder.getAdapterPosition() + 1); } } }); } } /** * 增加一条数据到index 0数据 */ public void addData(int position) { mDatas.add(position, "Insert" + position); notifyItemInserted(position);////告诉插入的地位 if (position != getItemCount()) { notifyItemRangeChanged(position, getItemCount());//排序插入地位到开端 } } /** * 增加数据汇合到数据汇合中 */ public void add(List<String> datas) { //mDatas.addAll(datas); mDatas.addAll(0, datas); notifyDataSetChanged(); } /** * 获取数据源总的条目 */ @Override public int getItemCount() { return mDatas.size(); } static class MyHolder extends RecyclerView.ViewHolder { TextView tv_content; public MyHolder(@NonNull View itemView) { super(itemView); tv_content = itemView.findViewById(R.id.tv_content); } } /**脚布局的ViewHolder*/ static class FootViewHolder extends RecyclerView.ViewHolder { public FootViewHolder(@NonNull View itemView) { super(itemView); } } /** * 自定义的接口 */ public interface OnItemClickListener { void onItemClick(View view, int position); }}
对应的脚布局View,item_foot.xml
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="40dp" android:gravity="center" android:orientation="horizontal"> <ProgressBar android:layout_marginRight="6dp" android:id="@+id/progressBar" style="?android:attr/progressBarStyleSmall" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:text="加载更多" /></LinearLayout>
后果:
在Adapter中
对应想增加一条数据,或者删除一条数据 /**删除一条数据*/ public void removeData(int position){ mDatas.remove(position); notifyItemRemoved(position);//第position个被删除的时候刷新 //notifyItemRangeRemoved(1,10);//批量删除 if (position!=getItemCount()){ notifyItemRangeChanged(position,getItemCount());//能够刷新从positionStart开始itemCount数量的item了(这里的刷新指回调onBindViewHolder()办法)。 } } /** * 增加一条数据到index 0数据 */ public void addData(int position) { mDatas.add(position, "Insert" + position); notifyItemInserted(position);//告诉插入的地位 if (position != getItemCount()) { notifyItemRangeChanged(position, getItemCount());//排序插入地位到开端 } }
END:人后的苦尚且还能克服,人前的尊严确无比软弱。