RecycleView作为Android5.0谷歌对ListView的升级版,其强大之处是:比ListView更为轻量,使用得当的话,完全可以替代ListView/GridView。本节主要说明添加刷新头的原理。首先我们先来熟悉一下RecycleView的简单使用吧。
recycleView的用法:
1.因为RecycleView在V7包里面有引入,所以我们要导入正确的v7包(后缀带有recycle的v7包);
//设置布局管理器
rvMain.setLayoutManager(new LinearLayoutManager(this));
//设置adapter
rvMain.setAdapter(new HomeAdapter());
//设置Item增加、移除动画
rvMain.setItemAnimator(new DefaultItemAnimator());
//添加分割线
rvMain.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL));
2.该分割线是系统默认的,你可以在theme.xml中找到该属性的使用情况
注意:这里的布局管理器有三种,
rvMain.setLayoutManager(new LinearLayoutManager(this)); //rvMain.setLayoutManager(new GridLayoutManager(this,4)); //rvMain.setLayoutManager(new StaggeredGridLayoutManager(3,StaggeredGridLayoutManager.VERTICAL));
大家可以分别设置一下看看效果,自己去尝试一下总比我在这里演示要我,问题也不难。简单繁琐的事情我这里就略过了。
但是我要告诉大家的是如果你仅仅是改变布局管理器而不去改写分割线的话效果是明显不美观的。大家可以参考鸿洋大神重写分割线
的博文,很详细。
recycleViewAdapter的方法概要:
玩过Android开发的小伙伴都应该知道ListView这玩意吧,但是到了RecyclerView这里好像就不像ListView一样提供一个
addHeaderView的方法。那么我们如何实现这个效果呢?
@Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { if (TYPE_REFRESH_HEADER==viewType){ return new LViewHolder(mRefreshHeader.getHeaderView()); }else{ return new MyViewHolder(LayoutInflater.from(mContext).inflate(R.layout.item_rvmain, parent, false)); } } @Override public void onBindViewHolder( RecyclerView.ViewHolder holder,int position) { if (!isRefreshHeader(position)){ ((MyViewHolder)holder).tv.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(mContext, String.valueOf("aa"),Toast.LENGTH_SHORT).show(); Intent intent = new Intent(mContext ,CoordinatorActivity.class); mContext.startActivity(intent); } }); ((MyViewHolder)holder).tv.setOnLongClickListener(new View.OnLongClickListener() { @Override public boolean onLongClick(View v) { Toast.makeText(mContext, String.valueOf("aa")+"---LONG",Toast.LENGTH_SHORT).show(); return true; } }); } } @Override public int getItemCount() { return 20; } @Override public int getItemViewType(int position) { if (isRefreshHeader(position)) { return TYPE_REFRESH_HEADER; } return TYPE_NORMAL; }
public interface IRefreshHeader { int STATE_NORMAL = 0; int STATE_RELEASE_TO_REFRESH = 1; int STATE_REFRESHING = 2; int STATE_DONE = 3; void onReset(); /** * 下拉移动 */ void onMove(float offSet, float sumOffSet); /** * 处于可以刷新的状态,已经过了指定距离 */ void onPrepare(); /** * 下拉松开 */ boolean onRelease(); /** * 正在刷新 */ void onRefreshing(); /** * 下拉刷新完成 */ void refreshComplete(); /** * 获取HeaderView */ View getHeaderView(); /** * 获取Header的显示高度 */ int getVisibleHeight(); }
@Override public boolean onTouchEvent(MotionEvent e) { if (mLastY == -1) { mLastY = e.getRawY(); } int action =e.getAction(); switch (action){ case MotionEvent.ACTION_DOWN: mLastY = e.getRawY(); sumOffSet = 0; break; case MotionEvent.ACTION_MOVE: final float deltaY = (e.getRawY() - mLastY) / DRAG_RATE; mLastY = e.getRawY(); sumOffSet += deltaY;
//动态设置第一个Item的高度,即刷新头 mRefreshHeader.onMove(deltaY, sumOffSet); Log.v("ACTION_MOVE","-------------------"+deltaY); if (mRefreshHeader.getVisibleHeight() > 0 && mRefreshing) { return false; } break; // case MotionEvent.ACTION_UP: // break; // case MotionEvent.ACTION_CANCEL: // break; default://当滑动松开时,刷新头滑动到刷新状态 if (mRefreshHeader.onRelease()) { if (mRefreshListener != null) { mFootView.setVisibility(GONE); mRefreshing = true;
//刷新状态的回调,加载数据的过程
mRefreshListener.onRefresh(); } } } return super.onTouchEvent(e); }3.主页面主要逻辑
public void BasicUse(){ //设置布局管理器 rvMain.setLayoutManager(new LinearLayoutManager(this)); //rvMain.setLayoutManager(new GridLayoutManager(this,4)); //rvMain.setLayoutManager(new StaggeredGridLayoutManager(3,StaggeredGridLayoutManager.VERTICAL)); //设置adapter rvMain.setAdapter(new LRecyclerViewAdapter(MainActivity.this)); //设置Item增加、移除动画 rvMain.setItemAnimator(new DefaultItemAnimator()); //添加分割线 // rvMain.addItemDecoration(new DividerItemDecoration( // this, DividerItemDecoration.VERTICAL)); rvMain.addItemDecoration(new DividerGridItemDecoration( MainActivity.this)); rvMain.setOnRefreshListener(new OnRefreshListener() { @Override public void onRefresh() { new Handler().postDelayed(new Runnable(){ public void run() { //这里作网络数据请求提供的方法,但我没有处理 //当数据刷新后我们调用下面的方法把正在刷新状态下的刷新头的高度和状态改变 rvMain.refreshComplete(10); } }, 1200); } }); }上拉加载更多原理:
@Override public void onScrollStateChanged(int state) { super.onScrollStateChanged(state); currentScrollState = state; Log.d("------------", "onScrollStateChanged: onScrollStateChanged--------------"+state); if (mLScrollListener != null) { mLScrollListener.onScrollStateChanged(state); } if (mLoadMoreListener != null && mLoadMoreEnabled) { if (currentScrollState == RecyclerView.SCROLL_STATE_IDLE) { RecyclerView.LayoutManager layoutManager = getLayoutManager(); int visibleItemCount = layoutManager.getChildCount(); int totalItemCount = layoutManager.getItemCount(); if (visibleItemCount > 0 && lastVisibleItemPosition == totalItemCount - 1 && totalItemCount > visibleItemCount && !mRefreshing) { mFootView.setVisibility(View.VISIBLE); if (mLoadingData) { return; } else { mLoadingData = true; mLoadMoreFooter.onLoading(); mLoadMoreListener.onLoadMore(); }3.dapter的改写
@Override public int getItemViewType(int position) { // if (isRefreshHeader(position)) { // return TYPE_REFRESH_HEADER; // } // return TYPE_NORMAL; // int adjPosition = position - (getHeaderViewsCount() + 1); if (isRefreshHeader(position)) { return TYPE_REFRESH_HEADER; } // if (isHeader(position)) { // position = position - 1; // return mHeaderTypes.get(position); // } if (isFooter(position)) { return TYPE_FOOTER_VIEW; } // int adapterCount; // if (mInnerAdapter != null) { // adapterCount = mInnerAdapter.getItemCount(); // if (adjPosition < adapterCount) { // return mInnerAdapter.getItemViewType(adjPosition); // } // } return TYPE_NORMAL; }
@Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { if (TYPE_REFRESH_HEADER==viewType){ return new LViewHolder(mRefreshHeader.getHeaderView()); } else if (viewType == TYPE_FOOTER_VIEW) { return new LViewHolder(mFooterViews.get(0)); } else { return new MyViewHolder(LayoutInflater.from(mContext).inflate(R.layout.item_rvmain, parent, false)); }3.主页面逻辑
rvMain.setOnLoadMoreListener(new OnLoadMoreListener() { @Override public void onLoadMore() { new Handler().postDelayed(new Runnable() { public void run() { //这里作网络数据请求提供的方法,但我没有处理 //当数据刷新后我们调用下面的方法把正在刷新状态下的刷新头的高度和状态改变 rvMain.setNoMore(true); } }, 1200); } });这里只是简单的介绍了RecycleView下拉刷新和上拉加载的基本原理,离真实项目开发用到还有很长一段距离要走呢。接下来我会整理一下这个Demo