Android编程至高武学之《如来神掌》第五式~迎佛西天
来源:互联网 发布:淘宝首页海报怎么做 编辑:程序博客网 时间:2024/04/30 21:45
上回书Android编程至高武学之《如来神掌》第四式~佛问迦蓝,为众卿家分析了寡人小小框架中最重要的一环,网络请求。这次朕将挥泪告别大家了,临走前,孤还是要请尔等搓一顿的。言归正传,废话少说,出来混迟早要还的,我还是老老实实地讲我的框架中的最后一点,也是最大的一点,xrecylerview,带有刷新和加载更多哦!详情如下:
package com.jcodecraeer.xrecyclerview;import android.content.Context;import android.support.v7.widget.GridLayoutManager;import android.support.v7.widget.RecyclerView;import android.support.v7.widget.StaggeredGridLayoutManager;import android.util.AttributeSet;import android.util.Log;import android.view.MotionEvent;import android.view.View;import android.view.ViewGroup;import java.util.ArrayList;import java.util.List;public class XRecyclerView extends RecyclerView { private Context mContext; private boolean isLoadingData = false; private boolean isnomore = false; private int mRefreshProgressStyle = ProgressStyle.SysProgress; private int mLoadingMoreProgressStyle = ProgressStyle.SysProgress; private ArrayList<View> mHeaderViews = new ArrayList<>(); private ArrayList<View> mFootViews = new ArrayList<>(); private Adapter mAdapter; private Adapter mWrapAdapter; private float mLastY = -1; private static final float DRAG_RATE = 3; private LoadingListener mLoadingListener; private ArrowRefreshHeader mRefreshHeader; private boolean pullRefreshEnabled = true; private boolean loadingMoreEnabled = true; private static final int TYPE_REFRESH_HEADER = -5; private static final int TYPE_HEADER = -4; private static final int TYPE_NORMAL = 0; private static final int TYPE_FOOTER = -3; private int previousTotal = 0; private int mPageCount = 0; public XRecyclerView(Context context) { this(context, null); } public XRecyclerView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public XRecyclerView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(context); } private void init(Context context) { mContext = context; if(pullRefreshEnabled) { ArrowRefreshHeader refreshHeader = new ArrowRefreshHeader(mContext); mHeaderViews.add(0, refreshHeader); mRefreshHeader = refreshHeader; mRefreshHeader.setProgressStyle(mRefreshProgressStyle); } LoadingMoreFooter footView = new LoadingMoreFooter(mContext); footView.setProgressStyle(mLoadingMoreProgressStyle); addFootView(footView); mFootViews.get(0).setVisibility(GONE); } public void addHeaderView(View view) { if (pullRefreshEnabled && !(mHeaderViews.get(0) instanceof ArrowRefreshHeader)) { ArrowRefreshHeader refreshHeader = new ArrowRefreshHeader(mContext); mHeaderViews.add(0, refreshHeader); mRefreshHeader = refreshHeader; mRefreshHeader.setProgressStyle(mRefreshProgressStyle); } mHeaderViews.add(view); } public void addFootView(final View view) { mFootViews.clear(); mFootViews.add(view); } public void loadMoreComplete() { isLoadingData = false; View footView = mFootViews.get(0); if(footView instanceof LoadingMoreFooter) { ( (LoadingMoreFooter) footView ).setState(LoadingMoreFooter.STATE_NORMAL); }else{ footView.setVisibility(View.GONE); } } public void noMoreLoading() { isLoadingData = false; View footView = mFootViews.get(0); isnomore = true; if(footView instanceof LoadingMoreFooter) { ( (LoadingMoreFooter) footView ).setState(LoadingMoreFooter.STATE_NOMORE); }else{ footView.setVisibility(View.GONE); } } public void refreshComplete() { mRefreshHeader.refreshComplate(); isLoadingData = false; } public void setRefreshHeader(ArrowRefreshHeader refreshHeader){ mRefreshHeader = refreshHeader; } public void setPullRefreshEnabled(boolean enabled){ pullRefreshEnabled = enabled; } /** * 是否可以加载更多 */ public boolean setLoadingMoreEnabled(List list, int pageSize){ loadMoreComplete(); if (list==null || list.size()==0){ setLoadingMoreEnabled(false); return false; }else { setLoadingMoreEnabled(list.size()>=pageSize); return list.size()>=pageSize; } } /** * 是否可以加载更多 * @param enabled */ public void setLoadingMoreEnabled(boolean enabled){ loadingMoreEnabled = enabled; View footView = mFootViews.get(0); if(enabled){ footView.setVisibility(View.VISIBLE); if(footView instanceof LoadingMoreFooter) { ( (LoadingMoreFooter) footView ).setState(LoadingMoreFooter.STATE_NORMAL); } }else{ footView.setVisibility(View.VISIBLE); if(footView instanceof LoadingMoreFooter) { ( (LoadingMoreFooter) footView ).setState(LoadingMoreFooter.STATE_NOMORE); } } } public void setRefreshProgressStyle(int style) { mRefreshProgressStyle = style; if (mRefreshHeader != null){ mRefreshHeader.setProgressStyle(style); } } public void setLoadingMoreProgressStyle(int style) { mLoadingMoreProgressStyle = style; if(mFootViews.size() > 0 && mFootViews.get(0) instanceof LoadingMoreFooter){ ((LoadingMoreFooter) mFootViews.get(0)).setProgressStyle(style); } } public void setArrowImageView(int resid) { if (mRefreshHeader != null){ mRefreshHeader.setArrowImageView(resid); } } @Override public void setAdapter(Adapter adapter) { mAdapter = adapter; mWrapAdapter = new WrapAdapter(mHeaderViews, mFootViews, adapter); super.setAdapter(mWrapAdapter); mAdapter.registerAdapterDataObserver(mDataObserver); } @Override public void onScrollStateChanged(int state) { super.onScrollStateChanged(state); //isLoadingData =false; if (state == RecyclerView.SCROLL_STATE_IDLE && mLoadingListener != null && !isLoadingData && loadingMoreEnabled) { if (mRefreshHeader.getState() < ArrowRefreshHeader.STATE_REFRESHING) { View footView = mFootViews.get(0); if(footView instanceof LoadingMoreFooter) { ( (LoadingMoreFooter) footView ).setState(LoadingMoreFooter.STATE_LAODING); } else{ footView.setVisibility(View.VISIBLE); } isLoadingData = true; mLoadingListener.onLoadMore(); } } } @Override public boolean onTouchEvent(MotionEvent ev) { if (mLastY == -1) { mLastY = ev.getRawY(); } switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: mLastY = ev.getRawY(); break; case MotionEvent.ACTION_MOVE: final float deltaY = ev.getRawY() - mLastY; mLastY = ev.getRawY(); if ( isOnTop() && pullRefreshEnabled) { mRefreshHeader.onMove(deltaY / DRAG_RATE); if(mRefreshHeader.getVisiableHeight() > 0 && mRefreshHeader.getState() < ArrowRefreshHeader.STATE_REFRESHING ) { Log.i("getVisiableHeight", "getVisiableHeight = " + mRefreshHeader.getVisiableHeight()); Log.i("getVisiableHeight", " mRefreshHeader.getState() = " + mRefreshHeader.getState()); return false; } } break; default: mLastY = -1; // reset if ( isOnTop() && pullRefreshEnabled) { if( mRefreshHeader.releaseAction()) { if (mLoadingListener != null) { mLoadingListener.onRefresh(); isLoadingData=true; isnomore = false; previousTotal = 0; } } } break; } return super.onTouchEvent(ev); } private int findMax(int[] lastPositions) { int max = lastPositions[0]; for (int value : lastPositions) { if (value > max) { max = value; } } return max; } private int findMin(int[] firstPositions) { int min = firstPositions[0]; for (int value : firstPositions) { if (value < min) { min = value; } } return min; } private boolean isOnTop() { if (mHeaderViews == null || mHeaderViews.isEmpty()) { return false; } View view = mHeaderViews.get(0); if (view.getParent() != null) { return true; } else { return false; }// LayoutManager layoutManager = getLayoutManager();// int firstVisibleItemPosition;// if (layoutManager instanceof GridLayoutManager) {// firstVisibleItemPosition = ((GridLayoutManager) layoutManager).findFirstVisibleItemPosition();// } else if ( layoutManager instanceof StaggeredGridLayoutManager ) {// int[] into = new int[((StaggeredGridLayoutManager) layoutManager).getSpanCount()];// ((StaggeredGridLayoutManager) layoutManager).findFirstVisibleItemPositions(into);// firstVisibleItemPosition = findMin(into);// } else {// firstVisibleItemPosition = ((LinearLayoutManager) layoutManager).findFirstVisibleItemPosition();// }// if ( firstVisibleItemPosition <= 1 ) {// return true;// }// return false; } private final RecyclerView.AdapterDataObserver mDataObserver = new RecyclerView.AdapterDataObserver() { @Override public void onChanged() { mWrapAdapter.notifyDataSetChanged(); } @Override public void onItemRangeInserted(int positionStart, int itemCount) { mWrapAdapter.notifyItemRangeInserted(positionStart, itemCount); } @Override public void onItemRangeChanged(int positionStart, int itemCount) { mWrapAdapter.notifyItemRangeChanged(positionStart, itemCount); } @Override public void onItemRangeChanged(int positionStart, int itemCount, Object payload) { mWrapAdapter.notifyItemRangeChanged(positionStart, itemCount, payload); } @Override public void onItemRangeRemoved(int positionStart, int itemCount) { mWrapAdapter.notifyItemRangeRemoved(positionStart, itemCount); } @Override public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) { mWrapAdapter.notifyItemMoved(fromPosition, toPosition); } }; private class WrapAdapter extends RecyclerView.Adapter<ViewHolder> { private RecyclerView.Adapter adapter; private ArrayList<View> mHeaderViews; private ArrayList<View> mFootViews; private int headerPosition = 1; public WrapAdapter(ArrayList<View> headerViews, ArrayList<View> footViews, RecyclerView.Adapter adapter) { this.adapter = adapter; this.mHeaderViews = headerViews; this.mFootViews = footViews; } @Override public void onAttachedToRecyclerView(RecyclerView recyclerView) { super.onAttachedToRecyclerView(recyclerView); RecyclerView.LayoutManager manager = recyclerView.getLayoutManager(); if(manager instanceof GridLayoutManager) { final GridLayoutManager gridManager = ((GridLayoutManager) manager); gridManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() { @Override public int getSpanSize(int position) { return (isHeader(position)|| isFooter(position)) ? gridManager.getSpanCount() : 1; } }); } } @Override public void onViewAttachedToWindow(RecyclerView.ViewHolder holder) { super.onViewAttachedToWindow(holder); ViewGroup.LayoutParams lp = holder.itemView.getLayoutParams(); if(lp != null && lp instanceof StaggeredGridLayoutManager.LayoutParams && (isHeader( holder.getLayoutPosition()) || isFooter( holder.getLayoutPosition())) ) { StaggeredGridLayoutManager.LayoutParams p = (StaggeredGridLayoutManager.LayoutParams) lp; p.setFullSpan(true); } } public boolean isHeader(int position) { return position >= 0 && position < mHeaderViews.size(); } public boolean isFooter(int position) { return position < getItemCount() && position >= getItemCount() - mFootViews.size(); } public boolean isRefreshHeader(int position) { return position == 0 ; } public int getHeadersCount() { return mHeaderViews.size(); } public int getFootersCount() { return mFootViews.size(); } @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { if (viewType == TYPE_REFRESH_HEADER) { return new SimpleViewHolder(mHeaderViews.get(0)); } else if (viewType == TYPE_HEADER) { return new SimpleViewHolder(mHeaderViews.get(headerPosition++ )); } else if (viewType == TYPE_FOOTER) { return new SimpleViewHolder(mFootViews.get(0)); } return adapter.onCreateViewHolder(parent, viewType); } @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { if (isHeader(position)) { return; } int adjPosition = position - getHeadersCount(); int adapterCount; if (adapter != null) { adapterCount = adapter.getItemCount(); if (adjPosition < adapterCount) { adapter.onBindViewHolder(holder, adjPosition); return; } } } @Override public int getItemCount() { if (adapter != null) { return getHeadersCount() + getFootersCount() + adapter.getItemCount(); } else { return getHeadersCount() + getFootersCount(); } } @Override public int getItemViewType(int position) { if(isRefreshHeader(position)){ return TYPE_REFRESH_HEADER; } if (isHeader(position)) { return TYPE_HEADER; } if(isFooter(position)){ return TYPE_FOOTER; } int adjPosition = position - getHeadersCount();; int adapterCount; if (adapter != null) { adapterCount = adapter.getItemCount(); if (adjPosition < adapterCount) { return adapter.getItemViewType(adjPosition); } } return TYPE_NORMAL; } @Override public long getItemId(int position) { if (adapter != null && position >= getHeadersCount()) { int adjPosition = position - getHeadersCount(); int adapterCount = adapter.getItemCount(); if (adjPosition < adapterCount) { return adapter.getItemId(adjPosition); } } return -1; } @Override public void unregisterAdapterDataObserver(AdapterDataObserver observer) { if (adapter != null) { adapter.unregisterAdapterDataObserver(observer); } } @Override public void registerAdapterDataObserver(AdapterDataObserver observer) { if (adapter != null) { adapter.registerAdapterDataObserver(observer); } } private class SimpleViewHolder extends RecyclerView.ViewHolder { public SimpleViewHolder(View itemView) { super(itemView); } } } public void setLoadingListener(LoadingListener listener) { mLoadingListener = listener; } public interface LoadingListener { void onRefresh(); void onLoadMore(); }}
recylerview就不用多说了,大家应该都懂的,不懂的,度娘懂。xrecylerview里面最主要的还是其刷新、加载。主要是有一个自定义的布局,用于展示刷新时间、图标和刷新的提示语的。然后就是通过xrecylerview的手势来判断处理一些刷新时的变化展示了;加载类似的,就几再说了。其实挺简单的,就是代码量有点点多。这时就有人要反驳了,既然这么简单,你倒是写一个啊。惭愧啊!我这个人比较懒,现在开源代码这么多,我倒是喜欢二次封装一下下,毕竟自己写的不知道会出啥bug。其实开发中,很多东西能二次封装的就二次封装,毕竟人家有实践经验的,站在巨人的肩上,你将看得更远。
至于用法呢,很简单,先设置一下:
mRecyclerview.setAdapter(new ConcernFansAdapter(getActivity(), null)); StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(1, StaggeredGridLayoutManager.VERTICAL); layoutManager.setOrientation(StaggeredGridLayoutManager.VERTICAL); mRecyclerview.setRefreshProgressStyle(ProgressStyle.BallSpinFadeLoader); mRecyclerview.setLoadingMoreProgressStyle(ProgressStyle.BallRotate); mRecyclerview.setArrowImageView(R.mipmap.iconfont_downgrey); mRecyclerview.setHasFixedSize(true); mRecyclerview.setLayoutManager(layoutManager); mRefeshLy.setRetryListener(this); mRecyclerview.setLoadingListener(this); mRecyclerview.setLoadingMoreEnabled(false); mRecyclerview.setPullRefreshEnabled(true);
然后,再实现一下接口中的两个方法就行了: @Override public void onRefresh() { } @Override public void onLoadMore() { }
是不是很简单,两步就搞定!当然,如果您实在是不太理解,或者不怎么会用,那么请观看俺的上一篇博客Android编程至高武学之《如来神掌》第二式~金顶佛灯 。或者直接去下载demo,https://Git.oschina.NET/bjnq/NeiquanDemo,运行后里面直接有用法。本回书完,下回寡人将要标新立异,去研究研究新的框架,毕竟人总是要成长的,敬请期待.....
阅读全文
0 0
- Android编程至高武学之《如来神掌》第五式~迎佛西天
- Android编程至高武学之《如来神掌》第三式~佛动山河
- Android编程至高武学之《如来神掌》第二式~金顶佛灯
- Android编程至高武学之《如来神掌》第一式~佛光初现
- Android编程至高武学之《如来神掌》第四式~佛问迦蓝
- 《如来神掌》详细攻略
- 唐僧在如来面前吐真言 解析西天取经团队
- 《如来神掌》详细攻略2
- 《如来神掌》详细攻略3
- 编程的至高境界是什么?
- 如来
- 趣学Python-教孩子学编程--第五章
- 野人学Android基础篇之初探UI控件第五课--RadioGroup
- 西天取经真相之二(悟空采访实录)
- 西天取经真相之二(悟空采访…
- 学编程学IT教程之ArrayList
- [百合原帖]由“如来神掌”想到“金镖黄天霸”……《功夫》
- 神是什么?神即道 道法自然 如来
- Spring3 注解说明
- 设计模式入门之鸭子问题
- 习题8-14 商队抢劫者(Caravan Robbers ACMICPC NEERC 2012 UVa1616)
- [leetcode: Python]404. Sum of Left Leaves
- Android开源库V
- Android编程至高武学之《如来神掌》第五式~迎佛西天
- Android 自定义View(二)函数分析
- 单选按钮技术演示---调查问卷为例
- SLAM常用术语及翻译
- HDU-1789
- 手机移动端web 禁止手机返回功能
- springside3
- oracle中级部分选择题
- CSS使元素水平垂直居中的方法