本身實現一個下拉刷新的ListView
效果
:html

實現一個下拉刷新的ListView
1.肯定狀態
下拉刷新的ListView一共有四種狀態,分別是
- 常態(刷新完成或者是正常展現的時候)
- 正在下拉可是下拉的距離沒有達到咱們定義的能夠刷新的距離(下拉能夠刷新)
- 下拉的距離達到了能夠刷新的距離(釋放當即刷新)
- 正在刷新
2.肯定實現方案
- 咱們用一個FrameLayout包裹一個下拉刷新的頭佈局和一個ListView,最開始的時候使下拉刷新的頭佈局Margin爲賦值,看不到
- 觸摸事件攔截,當ListView的第一個Item可見而且咱們向下拉的時候,攔截觸摸事件
- 在觸摸事件處理的時候,使下拉刷新的頭佈局和ListView的Margin變化,從而達到隨手指下拉移動的效果,最開始顯示的狀態是「下拉能夠刷新」
- 當下拉的距離達到能夠刷新的距離的時候,咱們改變狀態爲「釋放當即刷新」
- 釋放的時候,若是狀態是「下拉能夠刷新」,則直接回到初始狀態,不掉用刷新的接口;若是狀態是「釋放當即刷新」,則調用刷新的接口,當回調刷新完成時,回到初始狀態
3.代碼實現
- package com.example.myapp.view;
-
- import android.content.Context;
- import android.util.AttributeSet;
- import android.view.LayoutInflater;
- import android.view.MotionEvent;
- import android.view.View;
- import android.widget.AdapterView;
- import android.widget.FrameLayout;
- import android.widget.ListAdapter;
- import android.widget.ListView;
- import android.widget.TextView;
-
- import com.example.myapp.R;
-
- /**
- * Created by zyr
- * DATE: 16-3-16
- * Time: 下午4:12
- * Email: yanru.zhang@renren-inc.com
- * 關於下拉刷新,我目前看到的辦法是將刷新的部分和ListView包含在LinearlyLayout中,滑動的時候改變LinearlyLayout的padding
- * 感受用header,改變ListView的header的高度應該也可行把,沒有試過
- *
- *
- *
- * 下拉刷新
- * 1.往下拉,並且已經拉到最頂部
- * 2.超過必定的距離
- * 3.
- */
- public class CustomPullToRefreshListView extends FrameLayout{
- private Context mContext;
- private View refreshView;
- private ListView listView;
- private TextView textView;
- private int mWidth,mHeight,mRefreshWidth,mRefreshHeight;
- private FrameLayout.LayoutParams refreshViewLayoutParams,listViewLayoutParams;
- private int downX,downY,touchX,touchY,deltaX,deltaY,startX,startY,headMoveX,headMoveY;
- private boolean isScrollDown = false;
- private int currentStatus = STATUS_REFRESH_FINISHED;
- /**
- * 下拉狀態
- */
- public static final int STATUS_PULL_TO_REFRESH = 0;
- /**
- * 釋放當即刷新狀態
- */
- public static final int STATUS_RELEASE_TO_REFRESH = 1;
- /**
- * 正在刷新狀態
- */
- public static final int STATUS_REFRESHING = 2;
- /**
- * 刷新完成或未刷新狀態
- */
- public static final int STATUS_REFRESH_FINISHED = 3;
- /**
- * 下拉超過這個高度釋放就能夠刷新
- */
- public static final int REFRESH_HEIGHT = 200;
- /*************************** OnRefreshListener *************************/
- public void setOnRefreshListener(OnRefreshListener onRefreshListener) {
- this.onRefreshListener = onRefreshListener;
- }
-
- private OnRefreshListener onRefreshListener;
- public interface OnRefreshListener{
- void onRefresh();
- }
-
- public CustomPullToRefreshListView(Context context) {
- this(context, null);
- }
-
- public CustomPullToRefreshListView(Context context, AttributeSet attrs) {
- this(context, attrs, 0);
- }
-
- public CustomPullToRefreshListView(Context context, AttributeSet attrs, int defStyleAttr) {
- super(context, attrs, defStyleAttr);
- mContext = context;
- init();
- }
-
- private void init() {
- LayoutInflater.from(mContext).inflate(R.layout.layout_custom_pull_to_refresh_listview, this);
- refreshView = findViewById(R.id.refresh_view);
- refreshViewLayoutParams = (FrameLayout.LayoutParams)refreshView.getLayoutParams();
- textView = (TextView)refreshView.findViewById(R.id.text_view);
- listView = (ListView)findViewById(R.id.list_view);
- listViewLayoutParams = (FrameLayout.LayoutParams)listView.getLayoutParams();
- }
-
- @Override
- protected void onSizeChanged(int w, int h, int oldw, int oldh) {
- super.onSizeChanged(w, h, oldw, oldh);
- if(w!=oldw || h!=oldh){
- mWidth = w;
- mHeight = h;
- mRefreshWidth = refreshView.getMeasuredWidth();
- mRefreshHeight = refreshView.getMeasuredHeight();
- if(mRefreshHeight!=0){
- refreshViewLayoutParams.setMargins(0,-mRefreshHeight,0,0);
- refreshView.setLayoutParams(refreshViewLayoutParams);
- }
- }
- }
-
- /************************** ListView ************************/
- public void setAdapter(ListAdapter adapter){
- listView.setAdapter(adapter);
- }
-
- public void setOnItemClickListener(AdapterView.OnItemClickListener onItemClickListener){
- listView.setOnItemClickListener(onItemClickListener);
- }
-
- public void setSelection(int position){
- listView.setSelection(position);
- }
-
- /************************** Touch ************************/
- /**
- * 若是dispatchTouchEvent返回true ,則交給這個view的onTouchEvent處理,
- * 若是dispatchTouchEvent返回 false ,則交給這個 view 的 interceptTouchEvent 方法來決定是否要攔截這個事件
- * @param ev
- * @return
- */
- @Override
- public boolean dispatchTouchEvent(MotionEvent ev) {
- switch (ev.getAction()){
- case MotionEvent.ACTION_DOWN:
- downX =(int) ev.getX();
- downY =(int) ev.getY();
- break;
- case MotionEvent.ACTION_MOVE:
- touchX =(int) ev.getX();
- touchY =(int) ev.getY();
- deltaX = touchX-downX;
- deltaY = touchY-downY;
- if(deltaY>=0){
- isScrollDown = true;
- }else{
- isScrollDown = false;
- }
- break;
- case MotionEvent.ACTION_CANCEL:
- case MotionEvent.ACTION_UP:
- downX = 0;
- downY = 0;
- touchX = 0;
- touchY = 0;
- deltaX = 0;
- deltaY = 0;
- startX = 0;
- startY = 0;
- break;
- }
- return super.dispatchTouchEvent(ev);
- }
-
- @Override
- public boolean onInterceptTouchEvent(MotionEvent ev) {
- switch (ev.getAction()){
- case MotionEvent.ACTION_MOVE:
- if(isScrollDown && listView.getFirstVisiblePosition() ==0 && listView.getScrollY() == 0){
- currentStatus = STATUS_PULL_TO_REFRESH;
- textView.setText("下拉能夠刷新");
- startX =(int) ev.getX();
- startY =(int) ev.getY();
- return true;
- }
- break;
- }
- return super.onInterceptTouchEvent(ev);
- }
-
- @Override
- public boolean onTouchEvent(MotionEvent event) {
- switch (event.getAction()){
- case MotionEvent.ACTION_DOWN:
- break;
- case MotionEvent.ACTION_MOVE:
- headMoveY = (int) event.getY() - startY - mRefreshHeight;
- refreshViewLayoutParams.setMargins(0, headMoveY, 0, 0);
- refreshView.setLayoutParams(refreshViewLayoutParams);
- listViewLayoutParams.setMargins(0, headMoveY + mRefreshHeight, 0, 0);
- listView.setLayoutParams(listViewLayoutParams);
- if(headMoveY > REFRESH_HEIGHT){
- currentStatus = STATUS_RELEASE_TO_REFRESH;
- textView.setText("釋放當即刷新");
- }
- break;
- case MotionEvent.ACTION_UP:
- case MotionEvent.ACTION_CANCEL:
- if(currentStatus == STATUS_RELEASE_TO_REFRESH){
- currentStatus = STATUS_REFRESHING;
- textView.setText("正在刷新。。。");
- onRefreshListener.onRefresh();
- }else{
- refreshViewLayoutParams.setMargins(0, -mRefreshHeight, 0, 0);
- refreshView.setLayoutParams(refreshViewLayoutParams);
- listViewLayoutParams.setMargins(0,0 , 0,0);
- listView.setLayoutParams(listViewLayoutParams);
- }
- break;
- }
- return super.onTouchEvent(event);
- }
-
- public void onRefreshComplete(){
- if(currentStatus == STATUS_REFRESHING){
- currentStatus = STATUS_REFRESH_FINISHED;
- textView.setText("刷新成功!");
- }
- refreshViewLayoutParams.setMargins(0, -mRefreshHeight, 0, 0);
- refreshView.setLayoutParams(refreshViewLayoutParams);
- listViewLayoutParams.setMargins(0,0 , 0,0);
- listView.setLayoutParams(listViewLayoutParams);
- }
- }
- <?xml version="1.0" encoding="utf-8"?>
- <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
- <ListView android:id="@+id/list_view"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="@color/primary_light">
- </ListView>
- <LinearLayout android:id="@+id/refresh_view"
- android:layout_width="match_parent"
- android:layout_height="50dp"
- android:orientation="horizontal"
- android:background="@color/gray">
- <TextView android:id="@+id/text_view"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:gravity="center"
- android:text="Refresh"
- android:textColor="@color/white"
- android:textSize="20sp"/>
- </LinearLayout>
- </FrameLayout>
歡迎關注本站公眾號,獲取更多信息