其实实现的原理很简单,显示在listView的headerView中添加一个要刷新的进度条显示设置这个view影藏,在你拖动listView的时候当你托到最上面的时候,进行判断显示,影藏进度条,在显示进度条后你松开手势的时候根据不同的状态实现页面的操作。不多说了,实现的代码如下:
显示声明一个显示进度条的view的布局文件:head.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/head_rootLayout" android:layout_width="fill_parent" android:layout_height="wrap_content" > <!-- 内容 --> <RelativeLayout android:id="@+id/head_contentLayout" android:layout_width="fill_parent" android:layout_height="wrap_content" android:paddingLeft="30dp" > <!-- 箭头图像、进度条 --> <FrameLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_centerVertical="true" > <!-- 箭头 --> <ImageView android:id="@+id/head_arrowImageView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:background="@drawable/arrow" /> <!-- 进度条 --> <ProgressBar android:id="@+id/head_progressBar" style="?android:attr/progressBarStyleSmall" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:visibility="gone" /> </FrameLayout> <!-- 提示、最近更新 --> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:gravity="center_horizontal" android:orientation="vertical" > <!-- 提示 --> <TextView android:id="@+id/head_tipsTextView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="下拉刷新" android:textColor="#ffffff" android:textSize="20sp" /> <!-- 最近更新 --> <TextView android:id="@+id/head_lastUpdatedTextView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="最近更新" android:textColor="#cc6600" android:textSize="10sp" /> </LinearLayout> </RelativeLayout> </LinearLayout>
在重写listView实现onScrollListener
public class MyListView extends ListView implements OnScrollListener { /** * 下拉现实的headView */ private View headView; /** * 刷新的箭头的view */ private ImageView arrowImageView; /** * 显示刷新的进度条 */ private ProgressBar progressBar = null; /** * 显示提示刷新的提示语句 */ private TextView tipsTextView; /** * 显示的第一个Item的view */ private int fistVisibleItem = -1; /** * headView的宽度 */ private int headContextWidth=0; /** * 向下箭头的样式 */ private Animation todownAnimation; /** * 向上箭头的样式 */ private Animation toupAnimation; /** * headView的高度 */ private int headContextHeight = 0; /** * 定义当前滑动的状态 */ private int state = DONE; /** * 未执行的状态 */ private static final int DONE = 0; /** * 即将松开去刷新界面,箭头变为向上 */ private static final int RELEATSE_TO_FRESH = 1; /** * 正在加载数据 */ private static final int LOADING = 2; /** * 拉动去刷新,调整箭头的位置,箭头向下 */ private static final int PULL_TO_REFRESH = 3; /** * 确定当前只有一个开始的位置被记录 */ private boolean isRecorded = false; /** * 设置滑动的比例 */ private static final int FLING_V = 3; /** * 开始的位置 */ private int starty =0; private boolean isback = false; /** * 刷新界面的回调接口 */ private OnRefreshListener onRefreshListener; public interface OnRefreshListener { public void onRefresh(); } public MyListView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); initView(); } public MyListView(Context context, AttributeSet attrs) { super(context, attrs); initView(); } public MyListView(Context context) { super(context); initView(); } /** * 初始化要显示的headview * * @see intView */ private void initView() { headView = ((LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.head, null); arrowImageView = (ImageView)headView.findViewById(R.id.head_arrowImageView); progressBar = (ProgressBar)headView.findViewById(R.id.head_progressBar); tipsTextView = (TextView)headView.findViewById(R.id.head_tipsTextView); //重新设置headView的大小 resetHeadView(); headContextWidth = headView.getMeasuredWidth(); headContextHeight = headView.getMeasuredHeight(); //设置headView的padding headView.setPadding(0, -headContextHeight, 0, 0); headView.invalidate(); //添加headView到listView的第一个item中去 addHeaderView(headView,null,false); setOnScrollListener(this); todownAnimation = new RotateAnimation(-180, 0, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); todownAnimation.setInterpolator(new LinearInterpolator()); todownAnimation.setDuration(250); todownAnimation.setFillAfter(true); toupAnimation = new RotateAnimation(0, -180, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); toupAnimation.setInterpolator(new LinearInterpolator()); toupAnimation.setDuration(250); toupAnimation.setFillAfter(true); state = DONE; isRecorded = false; } /** * 实现listView的触摸的事件 * * @param ev * * 点击的事件 * * @see onTouchEvent */ @Override public boolean onTouchEvent(MotionEvent ev) { int tempy = 0; switch(ev.getAction()) { //点击的事件 case MotionEvent.ACTION_DOWN: if(fistVisibleItem ==0 && !isRecorded) { isRecorded = true; starty = (int)ev.getY(); } break; //移动的事件 case MotionEvent.ACTION_MOVE: tempy = (int)ev.getY(); if(fistVisibleItem ==0 && !isRecorded) { isRecorded = true; starty = (int)ev.getY(); } //当前的用户不在加载数据,并且不在刷新界面的时候 if(state != LOADING && isRecorded) { //可以松开去刷新界面了 if(state == RELEATSE_TO_FRESH) { setSelection(0); //用户在向上推的时候 if((tempy-starty)/FLING_V0) { state = PULL_TO_REFRESH; changeHeadViewState(); } //用户快速向上推 else if(tempy-startyheadContextHeight) { isback = true; state = RELEATSE_TO_FRESH; changeHeadViewState(); } //上推到顶了 else if((tempy-starty)/FLING_V0) { state = PULL_TO_REFRESH; changeHeadViewState(); } } //修改显示view的大小 if(state == PULL_TO_REFRESH||state == RELEATSE_TO_FRESH) { headView.setPadding(0, -headContextHeight+(tempy-starty)/FLING_V, 0, 0); } } break; //手势离开控件 case MotionEvent.ACTION_UP: if(state != LOADING) { if(state == PULL_TO_REFRESH) { state = DONE; changeHeadViewState(); } else if(state == DONE) { } else if(state == RELEATSE_TO_FRESH) { state = LOADING; changeHeadViewState(); //刷新界面 onRefresh(); } } isRecorded = false; break; } return super.onTouchEvent(ev); } /** * 刷新界面的数据 * * @see onRefresh */ private void onRefresh() { if(null != onRefreshListener) { onRefreshListener.onRefresh(); } } /** * 界面刷新结束 * * @see complete */ public void complete() { state = DONE; changeHeadViewState(); } /** * 根据状态修改headView * * @see changeHeadViewState */ private void changeHeadViewState() { switch(state) { //箭头向上 case RELEATSE_TO_FRESH: arrowImageView.setVisibility(View.VISIBLE); progressBar.setVisibility(View.GONE); tipsTextView.setVisibility(View.VISIBLE); arrowImageView.clearAnimation(); arrowImageView.startAnimation(toupAnimation); Log.e(VIEW_LOG_TAG, "RELEATSE_TO_FRESH"); tipsTextView.setText("松开刷新"); break; //箭头向下 case PULL_TO_REFRESH: arrowImageView.setVisibility(View.VISIBLE); progressBar.setVisibility(View.GONE); tipsTextView.setVisibility(View.VISIBLE); if(isback) { Log.e(VIEW_LOG_TAG, "PULL_TO_REFRESH"); arrowImageView.clearAnimation(); arrowImageView.startAnimation(todownAnimation); isback = false; } tipsTextView.setText("下拉刷新"); break; case DONE: headView.setPadding(0, -headContextHeight, 0, 0); arrowImageView.setVisibility(View.VISIBLE); progressBar.setVisibility(View.GONE); tipsTextView.setVisibility(View.VISIBLE); arrowImageView.clearAnimation(); tipsTextView.setText("下拉刷新"); break; //正在现在插件 case LOADING: headView.setPadding(0,0, 0, 0); arrowImageView.setVisibility(View.GONE); progressBar.setVisibility(View.VISIBLE); tipsTextView.setVisibility(View.VISIBLE); arrowImageView.clearAnimation(); tipsTextView.setText("正在刷新"); break; default: break; } } /** * 重新设置headView的大小 * * @see resetHeadView */ private void resetHeadView() { ViewGroup.LayoutParams layoutParams = headView.getLayoutParams(); if(null == layoutParams) { layoutParams = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,ViewGroup.LayoutParams.WRAP_CONTENT); } int childWidthSpec = ViewGroup.getChildMeasureSpec(0, 0, layoutParams.width); int tempHeight = layoutParams.height; int childHeightSpec=0; if(tempHeight>0) { childHeightSpec=MeasureSpec.makeMeasureSpec(tempHeight, MeasureSpec.EXACTLY); } else { childHeightSpec=MeasureSpec.makeMeasureSpec(tempHeight, MeasureSpec.UNSPECIFIED); } headView.measure(childWidthSpec, childHeightSpec); } @Override public void onScrollStateChanged(AbsListView view, int scrollState) { } /** * listView滑动的时候获取第一个显示的item */ @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { fistVisibleItem = firstVisibleItem; } public void setOnRefreshListener(OnRefreshListener onRefreshListener) { this.onRefreshListener = onRefreshListener; } }
上传一张显示的箭头的图片,这是重其它地方搞来的