1:android的下拉刷新操做是須要一個ListView,經過onTouchEvent來判斷用戶的手勢操做,用戶觸摸屏幕而且下拉時,當下拉超過指定的設定高度時就提示用戶進行刷新。android
2:當進行刷新時,header顯示加載條,並提示用戶上次更新的時間。佈局
3:數據加載結束後,經過handle刷新界面,並隱藏header,至此下拉刷新結束。spa
android onTouchEvent事件代碼:code
public boolean onTouchEvent(MotionEvent event) { if (isRefreshable) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: if (firstItemIndex == 0 && !isRecored) { isRecored = true; startY = (int) event.getY();//獲取用戶觸摸位置 } break; case MotionEvent.ACTION_UP: if (state != REFRESHING && state != LOADING) { if (state == DONE) { } if (state == PULL_To_REFRESH) { state = DONE; changeHeaderViewByState(); Log.v(TAG, "由下拉刷新狀態,到done狀態"); } if (state == RELEASE_To_REFRESH) { state = REFRESHING; changeHeaderViewByState(); onRefresh(); Log.v(TAG, "由鬆開刷新狀態,到done狀態"); } } isRecored = false; isBack = false; break; case MotionEvent.ACTION_MOVE: int tempY = (int) event.getY(); if (!isRecored && firstItemIndex == 0) { Log.v(TAG, "在move時候記錄下位置"); isRecored = true; startY = tempY; } if (state != REFRESHING && isRecored && state != LOADING) { // 保證在設置padding的過程當中,當前的位置一直是在head,不然若是當列表超出屏幕的話,當在上推的時候,列表會同時進行滾動 // 能夠鬆手去刷新了 if (state == RELEASE_To_REFRESH) { setSelection(0); // 往上推了,推到了屏幕足夠掩蓋head的程度,可是尚未推到所有掩蓋的地步 if (((tempY - startY) / RATIO < headContentHeight) && (tempY - startY) > 0) { state = PULL_To_REFRESH; changeHeaderViewByState(); Log.v(TAG, "由鬆開刷新狀態轉變到下拉刷新狀態"); } // 一會兒推到頂了 else if (tempY - startY <= 0) { state = DONE; changeHeaderViewByState(); Log.v(TAG, "由鬆開刷新狀態轉變到done狀態"); } // 往下拉了,或者尚未上推到屏幕頂部掩蓋head的地步 else { // 不用進行特別的操做,只用更新paddingTop的值就好了 } } // 尚未到達顯示鬆開刷新的時候,DONE或者是PULL_To_REFRESH狀態 if (state == PULL_To_REFRESH) { setSelection(0); // 下拉到能夠進入RELEASE_TO_REFRESH的狀態 if ((tempY - startY) / RATIO >= headContentHeight) { state = RELEASE_To_REFRESH; isBack = true; changeHeaderViewByState(); Log.v(TAG, "由done或者下拉刷新狀態轉變到鬆開刷新"); } // 上推到頂了 else if (tempY - startY <= 0) { state = DONE; changeHeaderViewByState(); Log.v(TAG, "由DOne或者下拉刷新狀態轉變到done狀態"); } } // done狀態下 if (state == DONE) { if (tempY - startY > 0) { state = PULL_To_REFRESH; changeHeaderViewByState(); } } // 更新headView的size if (state == PULL_To_REFRESH) { headView.setPadding(0, -1 * headContentHeight + (tempY - startY) / RATIO, 0, 0); } // 更新headView的paddingTop if (state == RELEASE_To_REFRESH) { headView.setPadding(0, (tempY - startY) / RATIO - headContentHeight, 0, 0); } } break; } } return super.onTouchEvent(event); }
// 當狀態改變時候,調用該方法,以更新界面 private void changeHeaderViewByState() { switch (state) { case RELEASE_To_REFRESH: arrowImageView.setVisibility(View.VISIBLE); progressBar.setVisibility(View.GONE); tipsTextview.setVisibility(View.VISIBLE); lastUpdatedTextView.setVisibility(View.VISIBLE); arrowImageView.clearAnimation(); arrowImageView.startAnimation(animation); tipsTextview.setText("鬆開刷新"); Log.v(TAG, "當前狀態,鬆開刷新"); date = new Date().toLocaleString();//記錄上次更新的時間 break; case PULL_To_REFRESH: progressBar.setVisibility(View.GONE); tipsTextview.setVisibility(View.VISIBLE); lastUpdatedTextView.setVisibility(View.VISIBLE); arrowImageView.clearAnimation(); arrowImageView.setVisibility(View.VISIBLE); // 是由RELEASE_To_REFRESH狀態轉變來的 if (isBack) { isBack = false; arrowImageView.clearAnimation(); arrowImageView.startAnimation(reverseAnimation); tipsTextview.setText("下拉刷新"); } else { tipsTextview.setText("下拉刷新"); } Log.v(TAG, "當前狀態,下拉刷新"); break; case REFRESHING: headView.setPadding(0, 0, 0, 0); progressBar.setVisibility(View.VISIBLE); arrowImageView.clearAnimation(); arrowImageView.setVisibility(View.GONE); tipsTextview.setText("正在刷新..."); lastUpdatedTextView.setVisibility(View.VISIBLE); Log.v(TAG, "當前狀態,正在刷新..."); break; case DONE: headView.setPadding(0, -1 * headContentHeight, 0, 0); progressBar.setVisibility(View.GONE); arrowImageView.clearAnimation(); arrowImageView.setImageResource(R.drawable.arrow); tipsTextview.setText("下拉刷新"); lastUpdatedTextView.setVisibility(View.VISIBLE); Log.v(TAG, "當前狀態,done"); break; } }
佈局文件:xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content"> <RelativeLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:id="@+id/head_contentLayout" android:paddingLeft="30dp"> <!-- 箭頭圖像、進度條 --> <FrameLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_centerVertical="true"> <!-- 箭頭 --> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:src="@drawable/arrow" android:id="@+id/head_arrowImageView"/> <!-- 進度條 --> <ProgressBar android:layout_width="wrap_content" android:layout_height="wrap_content" style="?android:attr/progressBarStyleSmall" android:layout_gravity="center" android:id="@+id/head_progressBar" android:visibility="gone"/> </FrameLayout> <!-- 提示、最近更新 --> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:orientation="vertical" android:gravity="center_horizontal"> <!-- 提示 --> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="下拉刷新" android:textColor="@color/white" android:textSize="20dip" android:id="@+id/head_tipsTextView"/> <!-- 最近更新 --> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/head_lastUpdatedTextView" android:text="上次更新" android:textColor="@color/white" android:textSize="12dip"/> </LinearLayout> </RelativeLayout> </LinearLayout>
效果圖:blog