最近忙完了公司项目,花点时间来写写博客,跟大家分享一下android开发中必不可少的下拉刷新、上拉加载功能。很多APP都有这样的效果:列表向上滚动一定条目的数据时,在右下角出现一个返回顶部的图片,点击可置顶,在数据量大的时候就不用做死地滚回去了,这样的体验是不是很人性化呢,在本列中我也顺便实现了这个功能,从头到尾都是自己敲的代码哦,没有用到第三房依赖库,关键是代码简洁,有利于修改和维护。哈哈,不多说了,直接上代码吧!
一、首先是下拉刷新的实现:列表采用recycleView,外面套一层SwipeRefreshLayout。右下角可以放个image view或button之类的,xml根部局建议使用FrameLayout,不然可能会显示不出来。
swipelayout=(SwipeRefreshLayout)findViewById(R.id.swipelayout); testRecycleView=(RecyclerView)findViewById(R.id.testRecycleView);
//设置图标的颜色数组
swipelayout.setColorSchemeResources(R.color.colorPrimary, R.color.colorPrimaryDark);//下拉刷新 swipelayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { @Override public void onRefresh() {//自己写更新适配器的方法 refreshData(adapter); } });
二、先在来看看上拉加载和滚动10条数据后显示置顶按钮的实现。
final LinearLayoutManager manager=(LinearLayoutManager)testRecycleView.getLayoutManager(); testRecycleView.addOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); int lastItemIndex=manager.findLastVisibleItemPosition(); int firstItemIndex=manager.findFirstVisibleItemPosition(); Log.i("aa","进了onScrolled:"+lastItemIndex+":"+list.size()); //滑动到最后一个并且状态不是加载中,执行加载更多,isLoading默认值false if(lastItemIndex>=list.size()-1&&!isLoading){ loadMore(); } if(firstItemIndex>10){ iv.setVisibility(View.VISIBLE); }else{ iv.setVisibility(View.GONE); } } });
public void loadMore(){ list.add(null);//显示加载中的布局,对应MyAdapter的getItemViewType()方法 adapter.notifyItemInserted(list.size() - 1); isLoading=true; new Thread(){ @Override public void run() { try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } runOnUiThread(new Runnable() { @Override public void run() {//加载成功后移除null,并且修改状态isLoading为false list.remove(list.size() - 1); adapter.notifyItemRemoved(list.size()); for (int i=0;i<10;i++){ list.add("loading"+i); } adapter.notifyDataSetChanged(); isLoading=false; } }); } }.start(); }最后贴上实现此效果的recycleView的适配器的源码:
public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{ private List<String> mlist; private Context mContext; private int loading=-1; public MyAdapter(List<String> list,Context context){ mlist=list; mContext=context; } @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { if(holder instanceof ViewHolder){ ((ViewHolder)holder).item.setText(mlist.get(position)); }else{ ((LoadingViewHolder)holder).progressBar.setIndeterminate(true); } } @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { if(viewType!=loading){ View view= LayoutInflater.from(mContext).inflate(R.layout.item_list,parent,false); return new ViewHolder(view); }else{ View view=LayoutInflater.from(mContext).inflate(R.layout.loading,parent,false); return new LoadingViewHolder(view); } } @Override public int getItemCount() { return mlist.size(); } @Override public int getItemViewType(int position) { if(mlist.get(position)==null){ Log.i("aa", position + "\\"); } if(mlist.get(position)!=null){ return super.getItemViewType(position); }else{ return loading; } } public class ViewHolder extends RecyclerView.ViewHolder{ public TextView item; public ViewHolder(View view){ super(view); item=(TextView)view.findViewById(R.id.item); } } public class LoadingViewHolder extends RecyclerView.ViewHolder{ public ProgressBar progressBar; public TextView textView; public LoadingViewHolder(View view){ super(view); progressBar=(ProgressBar)view.findViewById(R.id.progressBar); textView=(TextView)view.findViewById(R.id.textView); } }至此,关键的代码都已经奉上了,需要demo源码的加1050637333,尽量还是自己一步步地实现哦。