Android 自定义下拉刷新和上拉加载

视频教程传送门:http://www.imooc.com/learn/135

完整代码在最下面。。

头布局xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="50dp">

        <LinearLayout
            android:id="@+id/layout"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:gravity="center"
            android:orientation="vertical">

            <TextView
                android:id="@+id/txt_xia_la"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="下拉刷新"
                android:textSize="18sp" />

            <TextView
                android:id="@+id/txt_last_time"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textSize="18sp" />
        </LinearLayout>

        <ImageView
            android:id="@+id/jian_tou"
            android:layout_width="40dp"
            android:layout_height="40dp"
            android:layout_centerVertical="true"
            android:layout_marginEnd="16dp"
            android:layout_toLeftOf="@+id/layout"
            android:src="@mipmap/up" />

        <ProgressBar
            android:id="@+id/progress"
            android:layout_width="20dp"
            android:layout_height="20dp"
            android:layout_centerVertical="true"
            android:layout_marginEnd="16dp"
            android:layout_toLeftOf="@+id/layout"
            android:visibility="gone" />
    </RelativeLayout>
</LinearLayout>

添加头布局并隐藏

 private void initView(Context context) {
        header = LayoutInflater.from(context).inflate(R.layout.refresh_header, null);
        measureView(header);
        headerHeight = header.getMeasuredHeight();
        topPadding(-headerHeight);
        addHeaderView(header);
        setOnScrollListener(this);
    }

设置上边距

/**
     * 设置header上边距
     *
     * @param topPadding 上边距
     */

    private void topPadding(int topPadding) {
        header.setPadding(header.getPaddingLeft(), topPadding,
                header.getPaddingRight(), header.getPaddingBottom());
        header.invalidate();
    }

隐藏头布局得告诉父布局头布局占多大宽高

 /**
     * 通知父布局占多大宽高
     */
    private void measureView(View view) {
        ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
        if (layoutParams == null) {
            layoutParams = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                    ViewGroup.LayoutParams.WRAP_CONTENT);
        }
        int width = ViewGroup.getChildMeasureSpec(0, 0, layoutParams.width);
        int height;
        int tempHeight = layoutParams.height;
        if (tempHeight > 0) {
            // 高度不是0的时候,要填充
            height = MeasureSpec.makeMeasureSpec(tempHeight, MeasureSpec.EXACTLY);
        } else {
            // 高度是0的时候不要填充
            height = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
        }
        view.measure(width, height);
    }

给布局添加滚动事件

/**
     * 滚动事件
     *
     * @param view             当前可见的view
     * @param firstVisibleItem 当前界面第一个可见的item的位置
     * @param visibleItemCount
     * @param totalItemCount
     */
    @Override
    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
                         int totalItemCount) {
        this.firstVisibleItem = firstVisibleItem;
    }

    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
        this.scrollState = scrollState;
    }

按下时的三个事件

 /**
     * 触摸事件
     */
    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                // 判断界面是不是在最顶端
                if (firstVisibleItem == 0) {
                    isRemark = true;
                    startY = (int) ev.getY();
                }
                break;
            case MotionEvent.ACTION_MOVE:
                onMove(ev);
                break;
            case MotionEvent.ACTION_UP:
                if (state == RELESE) {
                    state = REFRESHING;
                    //加载最新数据
                    refreshViewByState();
                    mListener.onRefresh();
                } else if (state == PULL) {
                    state = NONE;
                    isRemark = false;
                    refreshViewByState();
                }
                break;
        }
        return super.onTouchEvent(ev);
    }

手指移动的操作

 /**
     * 判断移动过程中的操作
     */
    private void onMove(MotionEvent ev) {
        if (!isRemark) {
            return;
        }
        //当前已经移动到什么位置
        int tempY = (int) ev.getY();
        //手指移动的距离
        int space = tempY - startY;
        int topPadding = space - headerHeight;
        switch (state) {
            case NONE:
                if (space > 0) {
                    state = PULL;
                    refreshViewByState();
                }
                break;
            case PULL:
                topPadding(topPadding);
                if (space > headerHeight + 30 && scrollState == SCROLL_STATE_TOUCH_SCROLL) {
                    state = RELESE;
                    refreshViewByState();
                }
                break;
            case RELESE:
                topPadding(topPadding);
                if (space < headerHeight + 30) {
                    state = PULL;
                    refreshViewByState();
                } else if (space <= 0) {
                    state = NONE;
                    isRemark = false;
                    refreshViewByState();
                }
                break;
            case REFRESHING:

                break;
        }
    }

手指移动改变文本,这里用了两个不同的动画用于旋转下拉箭头

 /**
     * 根据当前状态改变界面显示
     */
    private void refreshViewByState() {
        TextView textView = header.findViewById(R.id.txt_xia_la);
        ImageView imageView = header.findViewById(R.id.jian_tou);
        ProgressBar progressBar = header.findViewById(R.id.progress);

//        RotateAnimation animation1 = new RotateAnimation(0, 180,
//                RotateAnimation.RELATIVE_TO_SELF, 0.5f,
//                RotateAnimation.RELATIVE_TO_SELF, 0.5f);
//        //设置时间间隔500ms
//        animation1.setDuration(500);
//        //当它完成时将会持续动画执行 转换
//        animation1.setFillAfter(true);
//        RotateAnimation animation2 = new RotateAnimation(180, 0,
//                RotateAnimation.RELATIVE_TO_SELF, 0.5f,
//                RotateAnimation.RELATIVE_TO_SELF, 0.5f);
//        animation2.setDuration(500);
//        animation2.setFillAfter(true);
        switch (state) {
            case NONE:
                topPadding(-headerHeight);
                imageView.clearAnimation();
                break;
            case PULL:
                imageView.setVisibility(VISIBLE);
                progressBar.setVisibility(GONE);
                textView.setText("下拉可以刷新");
                imageView.clearAnimation();
                break;
            case RELESE:
                imageView.setVisibility(VISIBLE);
                progressBar.setVisibility(GONE);
                textView.setText("松开可以刷新");
                imageView.clearAnimation();
//                imageView.setAnimation(animation1);
                ObjectAnimator.ofFloat(imageView, "rotation",
                        0, 180F).setDuration(500).start();
                break;
            case REFRESHING:
                topPadding(headerHeight);
                imageView.setVisibility(GONE);
                progressBar.setVisibility(VISIBLE);
                textView.setText("正在刷新");
                imageView.clearAnimation();
                break;
        }
    }

获取完数据

 /**
     * 获取完数据
     */
    public void refreshComplete() {
        state = NONE;
        isRemark = false;
        refreshViewByState();
        TextView textView = header.findViewById(R.id.txt_last_time);
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        Date date = new Date(System.currentTimeMillis());
        String time = format.format(date);
        textView.setText(time);
    }

设置接口给activity用于刷新后的操作

/**
     * 刷新数据接口
     */
    public interface RefreshListener {
        void onRefresh();
    }

    public void setInterface(RefreshListener listener) {
        this.mListener = listener;
    }

MainActivity.class

public class PullToRefreshActivity extends AppCompatActivity implements PullToRefresh.RefreshListener {

    private PullToRefresh pullToRefreshView;
    //    private PullLoadRefresh pullLoadRefresh;
    private ListView listView;
    private ArrayAdapter<String> adapter;
    String items[] = {"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M",
            "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"};

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_pull_to_refresh);

        pullToRefreshView = (PullToRefresh) findViewById(R.id.refresh_view);
//        listView = (ListView) findViewById(R.id.refresh_list);

        adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, items);
        pullToRefreshView.setAdapter(adapter);

        pullToRefreshView.setInterface(this);
    }

    @Override
    public void onRefresh() {
        //获取最新数据
        //显示数据
        //刷新数据
        Handler handler = new Handler();
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                if (!pullToRefreshView.isBottom) {
                    pullToRefreshView.refreshComplete();
                } else {
                    pullToRefreshView.refreshComplete2();
                }
                ToastUtil.showToast(PullToRefreshActivity.this, "sss");
            }
        }, 2000);
    }
}
activity_pull_to_refresh.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <com.example.xingzai.firstdemo.pullToRefresh.PullToRefresh
        android:id="@+id/refresh_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <!--<ListView-->
            <!--android:id="@+id/refresh_list"-->
            <!--android:layout_width="match_parent"-->
            <!--android:layout_height="match_parent" />-->
    </com.example.xingzai.firstdemo.pullToRefresh.PullToRefresh>
</LinearLayout>

至此下拉刷新结束。

上拉加载和下拉刷新原理都是一样的。

底部布局xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="50dp">

        <LinearLayout
            android:id="@+id/layout2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:gravity="center"
            android:orientation="vertical">

            <TextView
                android:id="@+id/txt_xia_la2"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="上拉加载"
                android:textSize="18sp" />

            <TextView
                android:id="@+id/txt_last_time2"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textSize="18sp" />
        </LinearLayout>

        <ImageView
            android:id="@+id/jian_tou2"
            android:layout_width="40dp"
            android:layout_height="40dp"
            android:layout_centerVertical="true"
            android:layout_marginEnd="16dp"
            android:layout_toLeftOf="@+id/layout2"
            android:src="@mipmap/down" />

        <ProgressBar
            android:id="@+id/progress2"
            android:layout_width="20dp"
            android:layout_height="20dp"
            android:layout_centerVertical="true"
            android:layout_marginEnd="16dp"
            android:layout_toLeftOf="@+id/layout"
            android:visibility="gone" />
    </RelativeLayout>
</LinearLayout>

添加底部据并隐藏

 /**
     * 底布局
     */
    private void initFootView(Context context) {
        footer = LayoutInflater.from(context).inflate(R.layout.activity_pull_loading, null);
        measureView(footer);
        footerHeight = footer.getMeasuredHeight();
        bottomPadding(-footerHeight);
        addFooterView(footer);
        setOnScrollListener(this);
    }

设置底部下边距

 /**
     * 设置footer下边距
     *
     * @param bottomPadding 下边距
     */
    private void bottomPadding(int bottomPadding) {
        footer.setPadding(footer.getPaddingLeft(), footer.getPaddingTop(),
                footer.getPaddingRight(), bottomPadding);
        footer.invalidate();
    }

在滚动事件里面判断是不是位于最底部

 /**
     * 滚动事件
     *
     * @param view             当前可见的view
     * @param firstVisibleItem 当前界面第一个可见的item的位置
     * @param visibleItemCount 可见item数量
     * @param totalItemCount   总item数量
     */
    @Override
    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
                         int totalItemCount) {
        this.firstVisibleItem = firstVisibleItem;
        if (firstVisibleItem + visibleItemCount == totalItemCount && totalItemCount > 0) {
            isBottom = true;
        } else {
            isBottom = false;
        }
    }

触摸事件

 /**
     * 触摸事件
     */
    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                // 判断界面是不是在最顶端
                if (firstVisibleItem == 0) {
                    isRemark = true;
                    startY = (int) ev.getY();
                }
                // 判断界面是不是在最底端
                if (isBottom) {
                    isRemark = true;
                    startY = (int) ev.getY();
                }
                break;
            case MotionEvent.ACTION_MOVE:
                if (!isBottom) {
                    onMove(ev);
                } else {
                    onMove2(ev);
                }
                break;
            case MotionEvent.ACTION_UP:
                if (state == RELEASE) {
                    state = REFRESHING;
                    //加载最新数据
                    refreshViewByState();
                    refreshViewByState2();
                    mListener.onRefresh();
                } else if (state == PULL) {
                    state = NONE;
                    isRemark = false;
                    refreshViewByState();
                    isBottom = false;
                    refreshViewByState2();
                }
                break;
        }
        return super.onTouchEvent(ev);
    }

上拉加载的移动事件

/**
     * 判断移动过程中的操作-上拉加载
     */
    private void onMove2(MotionEvent ev) {
        if (!isRemark) {
            return;
        }
        //当前已经移动到什么位置
        int tempY = (int) ev.getY();
        //手指移动的距离
        int space = startY - tempY;
        int bottomPadding = space - footerHeight;
        switch (state) {
            case NONE:
                if (space > 0) {
                    state = PULL;
                    refreshViewByState2();
                }
                break;
            case PULL:
                bottomPadding(bottomPadding);
                if (space > footerHeight + 30 && scrollState == SCROLL_STATE_TOUCH_SCROLL) {
                    state = RELEASE;
                    refreshViewByState2();
                }
                break;
            case RELEASE:
                bottomPadding(bottomPadding);
                if (space < footerHeight + 30) {
                    state = PULL;
                    refreshViewByState2();
                } else if (space <= 0) {
                    state = NONE;
                    isRemark = false;
                    refreshViewByState2();
                }
                break;
            case REFRESHING:
                break;
        }
    }

上拉加载的页面改变

 /**
     * 根据当前状态改变界面显示-下拉加载
     */
    private void refreshViewByState2() {
        TextView textView = footer.findViewById(R.id.txt_xia_la2);
        ImageView imageView = footer.findViewById(R.id.jian_tou2);
        ProgressBar progressBar = footer.findViewById(R.id.progress2);
        switch (state) {
            case NONE:
                bottomPadding(-footerHeight);
                imageView.clearAnimation();
                break;
            case PULL:
                imageView.setVisibility(VISIBLE);
                progressBar.setVisibility(GONE);
                textView.setText("上拉可以加载");
                imageView.clearAnimation();
                break;
            case RELEASE:
                imageView.setVisibility(VISIBLE);
                progressBar.setVisibility(GONE);
                textView.setText("松开可以刷新");
                imageView.clearAnimation();
//                imageView.setAnimation(animation1);
                ObjectAnimator.ofFloat(imageView, "rotation",
                        0, 180F).setDuration(500).start();
                break;
            case REFRESHING:
                bottomPadding(footerHeight);
                imageView.setVisibility(GONE);
                progressBar.setVisibility(VISIBLE);
                textView.setText("正在刷新");
                imageView.clearAnimation();
                break;
        }
    }

刷新结束的显示

/**
     * 获取完数据-上拉加载
     */
    public void refreshComplete2() {
        state = NONE;
        isRemark = false;
        isBottom = false;
        refreshViewByState2();
        TextView textView2 = footer.findViewById(R.id.txt_last_time2);
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        Date date = new Date(System.currentTimeMillis());
        String time = format.format(date);
        textView2.setText(time);
    }

pullToRefresh完整代码

import android.animation.ObjectAnimator;
import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.RotateAnimation;
import android.widget.AbsListView;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;

import com.example.xingzai.firstdemo.R;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * Created by wwx on 2018/9/6.
 * 下拉刷新
 */

public class PullToRefresh extends ListView implements AbsListView.OnScrollListener {

    /**
     * 顶部布局文件
     */
    private View header;

    /**
     * 底部据文件
     */
    private View footer;

    /**
     * 顶部布局文件高度
     */
    private int headerHeight;

    /**
     * 底部布局文件高度
     */
    private int footerHeight;

    /**
     * 标记是否在界面上按下
     */
    private boolean isRemark;

    /**
     * 是否在底部
     */
    public boolean isBottom;

    /**
     * 按下时的Y坐标值
     */
    private int startY;

    /**
     * 当前界面第一个可见的item的位置
     */
    private int firstVisibleItem;

    /**
     * 当前滚动状态
     */
    private int scrollState;

    /**
     * 当前状态
     */
    private int state;

    private final int NONE = 0;         //正常状态
    private final int PULL = 1;         //下拉刷新状态
    private final int RELEASE = 2;       //提示释放状态
    private final int REFRESHING = 3;   //正在刷新状态

    private RefreshListener mListener;  //刷新数据接口

    public PullToRefresh(Context context) {
        this(context, null);
    }

    public PullToRefresh(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public PullToRefresh(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        initHeaderView(context);
        initFootView(context);
    }

    /**
     * 头布局
     */
    private void initHeaderView(Context context) {
        header = LayoutInflater.from(context).inflate(R.layout.refresh_header, null);
        measureView(header);
        headerHeight = header.getMeasuredHeight();
        topPadding(-headerHeight);
        addHeaderView(header);
        setOnScrollListener(this);
    }

    /**
     * 底布局
     */
    private void initFootView(Context context) {
        footer = LayoutInflater.from(context).inflate(R.layout.activity_pull_loading, null);
        measureView(footer);
        footerHeight = footer.getMeasuredHeight();
        bottomPadding(-footerHeight);
        addFooterView(footer);
        setOnScrollListener(this);
    }

    /**
     * 设置header上边距
     *
     * @param topPadding 上边距
     */
    private void topPadding(int topPadding) {
        header.setPadding(header.getPaddingLeft(), topPadding,
                header.getPaddingRight(), header.getPaddingBottom());
        header.invalidate();
    }

    /**
     * 设置footer下边距
     *
     * @param bottomPadding 下边距
     */
    private void bottomPadding(int bottomPadding) {
        footer.setPadding(footer.getPaddingLeft(), footer.getPaddingTop(),
                footer.getPaddingRight(), bottomPadding);
        footer.invalidate();
    }

    /**
     * 通知父布局占多大宽高
     */
    private void measureView(View view) {
        ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
        if (layoutParams == null) {
            layoutParams = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                    ViewGroup.LayoutParams.WRAP_CONTENT);
        }
        int width = ViewGroup.getChildMeasureSpec(0, 0, layoutParams.width);
        int height;
        int tempHeight = layoutParams.height;
        if (tempHeight > 0) {
            // 高度不是0的时候,要填充
            height = MeasureSpec.makeMeasureSpec(tempHeight, MeasureSpec.EXACTLY);
        } else {
            // 高度是0的时候不要填充
            height = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
        }
        view.measure(width, height);
    }

    /**
     * 滚动事件
     *
     * @param view             当前可见的view
     * @param firstVisibleItem 当前界面第一个可见的item的位置
     * @param visibleItemCount 可见item数量
     * @param totalItemCount   总item数量
     */
    @Override
    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
                         int totalItemCount) {
        this.firstVisibleItem = firstVisibleItem;
        if (firstVisibleItem + visibleItemCount == totalItemCount && totalItemCount > 0) {
            isBottom = true;
        } else {
            isBottom = false;
        }
    }

    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
        this.scrollState = scrollState;
    }

    /**
     * 触摸事件
     */
    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                // 判断界面是不是在最顶端
                if (firstVisibleItem == 0) {
                    isRemark = true;
                    startY = (int) ev.getY();
                }
                // 判断界面是不是在最底端
                if (isBottom) {
                    isRemark = true;
                    startY = (int) ev.getY();
                }
                break;
            case MotionEvent.ACTION_MOVE:
                if (!isBottom) {
                    onMove(ev);
                } else {
                    onMove2(ev);
                }
                break;
            case MotionEvent.ACTION_UP:
                if (state == RELEASE) {
                    state = REFRESHING;
                    //加载最新数据
                    refreshViewByState();
                    refreshViewByState2();
                    mListener.onRefresh();
                } else if (state == PULL) {
                    state = NONE;
                    isRemark = false;
                    refreshViewByState();
                    isBottom = false;
                    refreshViewByState2();
                }
                break;
        }
        return super.onTouchEvent(ev);
    }

    /**
     * 判断移动过程中的操作-下拉刷新
     */
    private void onMove(MotionEvent ev) {
        if (!isRemark) {
            return;
        }
        //当前已经移动到什么位置
        int tempY = (int) ev.getY();
        //手指移动的距离
        int space = tempY - startY;
        int topPadding = space - headerHeight;
        switch (state) {
            case NONE:
                if (space > 0) {
                    state = PULL;
                    refreshViewByState();
                }
                break;
            case PULL:
                topPadding(topPadding);
                if (space > headerHeight + 30 && scrollState == SCROLL_STATE_TOUCH_SCROLL) {
                    state = RELEASE;
                    refreshViewByState();
                }
                break;
            case RELEASE:
                topPadding(topPadding);
                if (space < headerHeight + 30) {
                    state = PULL;
                    refreshViewByState();
                } else if (space <= 0) {
                    state = NONE;
                    isRemark = false;
                    refreshViewByState();
                }
                break;
            case REFRESHING:
                break;
        }
    }

    /**
     * 判断移动过程中的操作-上拉加载
     */
    private void onMove2(MotionEvent ev) {
        if (!isRemark) {
            return;
        }
        //当前已经移动到什么位置
        int tempY = (int) ev.getY();
        //手指移动的距离
        int space = startY - tempY;
        int bottomPadding = space - footerHeight;
        switch (state) {
            case NONE:
                if (space > 0) {
                    state = PULL;
                    refreshViewByState2();
                }
                break;
            case PULL:
                bottomPadding(bottomPadding);
                if (space > footerHeight + 30 && scrollState == SCROLL_STATE_TOUCH_SCROLL) {
                    state = RELEASE;
                    refreshViewByState2();
                }
                break;
            case RELEASE:
                bottomPadding(bottomPadding);
                if (space < footerHeight + 30) {
                    state = PULL;
                    refreshViewByState2();
                } else if (space <= 0) {
                    state = NONE;
                    isRemark = false;
                    refreshViewByState2();
                }
                break;
            case REFRESHING:
                break;
        }
    }

    /**
     * 根据当前状态改变界面显示-上拉刷新
     */
    private void refreshViewByState() {
        TextView textView = header.findViewById(R.id.txt_xia_la);
        ImageView imageView = header.findViewById(R.id.jian_tou);
        ProgressBar progressBar = header.findViewById(R.id.progress);

        RotateAnimation animation1 = new RotateAnimation(0, 180,
                RotateAnimation.RELATIVE_TO_SELF, 0.5f,
                RotateAnimation.RELATIVE_TO_SELF, 0.5f);
        //设置时间间隔500ms
        animation1.setDuration(500);
        //当它完成时将会持续动画执行 转换
        animation1.setFillAfter(true);
        RotateAnimation animation2 = new RotateAnimation(180, 0,
                RotateAnimation.RELATIVE_TO_SELF, 0.5f,
                RotateAnimation.RELATIVE_TO_SELF, 0.5f);
        animation2.setDuration(500);
        animation2.setFillAfter(true);
        switch (state) {
            case NONE:
                topPadding(-headerHeight);
                imageView.clearAnimation();
                break;
            case PULL:
                imageView.setVisibility(VISIBLE);
                progressBar.setVisibility(GONE);
                textView.setText("下拉可以刷新");
                imageView.clearAnimation();
                imageView.setAnimation(animation1);
                break;
            case RELEASE:
                imageView.setVisibility(VISIBLE);
                progressBar.setVisibility(GONE);
                textView.setText("松开可以刷新");
                imageView.clearAnimation();
                imageView.setAnimation(animation2);
//                ObjectAnimator.ofFloat(imageView, "rotation",
//                        0, 180F).setDuration(500).start();
                break;
            case REFRESHING:
                topPadding(headerHeight);
                imageView.setVisibility(GONE);
                progressBar.setVisibility(VISIBLE);
                textView.setText("正在刷新");
                imageView.clearAnimation();
                break;
        }
    }

    /**
     * 根据当前状态改变界面显示-下拉加载
     */
    private void refreshViewByState2() {
        TextView textView = footer.findViewById(R.id.txt_xia_la2);
        ImageView imageView = footer.findViewById(R.id.jian_tou2);
        ProgressBar progressBar = footer.findViewById(R.id.progress2);
        switch (state) {
            case NONE:
                bottomPadding(-footerHeight);
                imageView.clearAnimation();
                break;
            case PULL:
                imageView.setVisibility(VISIBLE);
                progressBar.setVisibility(GONE);
                textView.setText("上拉可以加载");
                imageView.clearAnimation();
                break;
            case RELEASE:
                imageView.setVisibility(VISIBLE);
                progressBar.setVisibility(GONE);
                textView.setText("松开可以刷新");
                imageView.clearAnimation();
//                imageView.setAnimation(animation1);
                ObjectAnimator.ofFloat(imageView, "rotation",
                        0, 180F).setDuration(500).start();
                break;
            case REFRESHING:
                bottomPadding(footerHeight);
                imageView.setVisibility(GONE);
                progressBar.setVisibility(VISIBLE);
                textView.setText("正在刷新");
                imageView.clearAnimation();
                break;
        }
    }

    /**
     * 获取完数据-下拉刷新
     */
    public void refreshComplete() {
        state = NONE;
        isRemark = false;
        refreshViewByState();
        TextView textView = header.findViewById(R.id.txt_last_time);
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        Date date = new Date(System.currentTimeMillis());
        String time = format.format(date);
        textView.setText(time);
    }

    /**
     * 获取完数据-上拉加载
     */
    public void refreshComplete2() {
        state = NONE;
        isRemark = false;
        isBottom = false;
        refreshViewByState2();
        TextView textView2 = footer.findViewById(R.id.txt_last_time2);
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        Date date = new Date(System.currentTimeMillis());
        String time = format.format(date);
        textView2.setText(time);
    }

    /**
     * 刷新数据接口
     */
    public interface RefreshListener {
        void onRefresh();
    }

    public void setInterface(RefreshListener listener) {
        this.mListener = listener;
    }
}

至此,下拉刷新和上拉加载全部完成。

猜你喜欢

转载自blog.csdn.net/qq_35820350/article/details/82491739