大家可能有的没有swipeRefreshLayout这个类,简单说一下,这是v4包里面的,19.1版本的时候就有了,但是当时的样式还是几个横杠,大概在21.0后吧,已经是我这个demo这样了。。挺好看的。一个圆形进度条.所以大家在使用时,请先升级一下自己的v4包,另外大家可能android support library已经是19.1以上了,还是没有,大家要注意一下,上面的Android Support Repository。更新到最新版本
1,继承SwipeRefreshLayout,自定义一个view VRefresh
package demo.veidy.com.veidydemolist;import android.content.Context;import android.support.v4.widget.SwipeRefreshLayout;import android.support.v7.widget.RecyclerView;import android.util.AttributeSet;import android.util.Log;import android.view.LayoutInflater;import android.view.MotionEvent;import android.view.View;import android.view.ViewConfiguration;import android.widget.AbsListView;import android.widget.ListView; /** * Created by veidy on 2015/1/16. */public class VRefresh extends SwipeRefreshLayout implements AbsListView.OnScrollListener { /** * 滑动到最下面时的上拉操作 */ private int mTouchSlop; /** * listview实例 */ private ListView mListView; /** * RecyclerView 实例 */ private RecyclerView recyclerView; /** * 上拉监听器, 到了最底部的上拉加载操作 */ private OnLoadListener mOnLoadListener; /** * ListView的加载中footer */ private View mFooterView; /** * 按下时的y坐标 */ private int mYDown; /** * 抬起时的y坐标, 与mYDown一起用于滑动到底部时判断是上拉还是下拉 */// private int mLastY; /** * 是否在加载中 ( 上拉加载更多 ) */ private boolean isLoading = false; private float mLastY = -1; /** * 最后一行 */ boolean isLastRow = false; /** * 是否还有数据可以加载 */ private boolean moreData = true; public VRefresh(Context context) { super(context); } public VRefresh(Context context, AttributeSet attrs) { super(context, attrs); mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop(); mFooterView = LayoutInflater.from(context).inflate(R.layout.vrefresh_footer, null, false); } /** * 设置默认的childview-必须要设置 * * @param context * @param childView */ public void setView(Context context, View childView) { if (childView instanceof ListView) { mListView = (ListView) childView; // 设置滚动监听器给ListView, 使得滚动的情况下也可以自动加载 mListView.setOnScrollListener(this); mListView.setFooterDividersEnabled(false); Log.d("VRefresh", "获取到listview"); } else if (childView instanceof RecyclerView) { recyclerView = (RecyclerView) childView; // 设置滚动监听器给ListView, 使得滚动的情况下也可以自动加载 recyclerView.setOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { super.onScrollStateChanged(recyclerView, newState); } @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); Log.d("VRefresh", "dx=" + dx + "---dy=" + dy); } }); Log.d("VRefresh", "获取到recyclerView"); } initWithContext(context); } private void initWithContext(Context context) { if (mListView != null) mListView.addFooterView(mFooterView, null, false);//设置footview不可点击// if (recyclerView!=null){// Log.d("VRefresh","快去自定义recyclerView 加footview吧");// return;// } mFooterView.setVisibility(View.GONE);//默认先隐藏 } @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); } /** * 是否可以加载更多, listview不在加载中, 且为上拉操作. * * @param canload 是否还有可以加载的数据 * @return */ private boolean canLoad(boolean canload) { return canload && !isLoading && isPullUp(); } /** * 判断是否到了最底部 */ private boolean isBottom() { if (mListView != null && mListView.getAdapter() != null) { return mListView.getLastVisiblePosition() == (mListView.getAdapter().getCount() - 1); } return false; } /** * 是否是上拉操作 * * @return */ private boolean isPullUp() { Log.d("VRefresh", "isPullUp--->"); return (mYDown - mLastY) >= mTouchSlop; } /** * 如果到了最底部,而且是上拉操作.onLoadMore */ private void loadData() { Log.d("VRefresh", "loadData--->"); if (mOnLoadListener != null) { // 设置状态 setLoading(true); mOnLoadListener.onLoadMore(); } } /** * @param loading */ public void setLoading(boolean loading) { isLoading = loading; if (isLoading) {// mListView.addFooterView(mFooterView); mFooterView.setVisibility(View.VISIBLE); } else {// mListView.removeFooterView(mFooterView); mFooterView.setVisibility(View.GONE); mYDown = 0; mLastY = 0; } } /* * (non-Javadoc) * @see android.view.ViewGroup#dispatchTouchEvent(android.view.MotionEvent) */ @Override public boolean dispatchTouchEvent(MotionEvent event) { final int action = event.getAction(); if (mLastY == -1) { mLastY = (int) event.getRawY(); } switch (action) { case MotionEvent.ACTION_DOWN: // 按下 mYDown = (int) event.getRawY(); Log.d("VRefresh", "按下"); break; case MotionEvent.ACTION_MOVE: // 移动 mLastY = (int) event.getRawY(); final float deltaY = event.getRawY() - mLastY; Log.d("VRefresh", "移动");// if (null != mListView && isPullUp()) {// if (mListView.getLastVisiblePosition() == mTotalItemCount - 1 || deltaY < 0) {// mListView.setSelection(mTotalItemCount - 1);// }// } break; default:// if (isLastRow && canLoad(moreData)) {// Log.d("VRefresh", "能加载...");// loadData();// } else {// Log.d("VRefresh", "不能加载...");// } break; } return super.dispatchTouchEvent(event); } @Override public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); } /** * @param loadListener */ public void setOnLoadListener(OnLoadListener loadListener) { mOnLoadListener = loadListener; } @Override public void onScrollStateChanged(AbsListView absListView, int i) { } @Override public void onScroll(AbsListView absListView, int firstVisibleItem, int visibleItemCount, int totalItemCount) { //判断是否滚到最后一行 if (firstVisibleItem + visibleItemCount == totalItemCount && totalItemCount > 0) { //双重判断,应该没有必要 if (absListView.getLastVisiblePosition() == (absListView.getAdapter().getCount() - 1)) { isLastRow = true;// mFooterView.setVisibility(View.VISIBLE); if (canLoad(moreData)) { Log.d("VRefresh", "滚动到最后一行,加载数据,显示footview"); loadData(); } } Log.d("VRefresh", "滚动到最后一行"); } else { Log.d("VRefresh", "没有滚动到最后一行"); isLastRow = false; } } public static interface OnLoadListener { public void onLoadMore(); } public boolean isMoreData() { return moreData; } public void setMoreData(boolean moreData) { this.moreData = moreData; }}
2.创建一个activity--SwipeRefreshDemo,创建activity之前,创建一个xml布局,直接引用自定义控制
3,在activity里面进行设置-核心代码
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_swipe_refresh_layout_view); initialize(); for (int i = 0; i < 2; i++) { A a = new A(); a.setDescribe("----" + i); bean.add(a); } //进度条颜色 swiperefreshlayou.setColorSchemeResources(android.R.color.holo_red_light,android.R.color.holo_green_light, android.R.color.holo_blue_bright, android.R.color.holo_orange_light);// swiperefreshlayou.setProgressBackgroundColor(getResources().getColor(android.R.color.holo_red_light)); swiperefreshlayou.setSize(0);//0和1 圆形进度条两种不同效果 0刚开始有渲染效果 myAdapter = new MyAdapter(bean, this);//listview adapter swiperefreshlayou.setView(this, lv);//设置嵌套的子view -listview swiperefreshlayou.setMoreData(false);//设置是否还有数据可加载(一般根据服务器反回来决定) lv.setAdapter(myAdapter); swiperefreshlayou.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { @Override public void onRefresh() { Message msg = mhandler.obtainMessage(); msg.what = REFRESH_COMPLETE; mhandler.sendMessageDelayed(msg, 3000);//3秒后通知停止刷新 } }); swiperefreshlayou.setOnLoadListener(new VRefresh.OnLoadListener() { @Override public void onLoadMore() { Message msg = mhandler.obtainMessage(); msg.what = LOADMORE_COMPLETE; mhandler.sendMessageDelayed(msg, 3000);//3秒后通知停止加载更多 } }); }
加载完成后去handle更新
private static final int REFRESH_COMPLETE = 0;//刷新完成标识 private static final int LOADMORE_COMPLETE = 1;//加载更多完成标识 Handler mhandler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what) { case LOADMORE_COMPLETE: for (int i = 0; i < 5; i++) { A a = new A(); a.setDescribe("----" + i); bean.add(a); } myAdapter.notifyDataSetChanged(); swiperefreshlayou.setMoreData(true);//设置还有数据可以加载 swiperefreshlayou.setLoading(false);//停止加载更多 break; case REFRESH_COMPLETE: bean.clear(); for (int i = 0; i < 5; i++) { A a = new A(); a.setDescribe("----" + i); bean.add(a); } swiperefreshlayou.setMoreData(true);//设置还有数据可以加载 myAdapter.notifyDataSetChanged(); swiperefreshlayou.setRefreshing(false);//停止刷新 break; } } };