加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

Android系统上拉刷新功能的实现

发布时间:2020-12-14 23:30:56 所属栏目:Java 来源:网络整理
导读:今天PHP站长网 52php.cn把收集自互联网的代码分享给大家,仅供参考。 自定义ListView: public class MyListView extends ListView implements OnScrollListener { public final int RATIO = 5;// 手拖动时,手指拖动距离

以下代码由PHP站长网 52php.cn收集自互联网

现在PHP站长网小编把它分享给大家,仅供参考

自定义ListView:
public class MyListView extends ListView implements OnScrollListener {
  
    public final int RATIO = 5;// 手拖动时,手指拖动距离与header下移的倍数
    private final int LOADING = 0;// 正在加载
    private final int RELEASE_To_REFRESH = 2;// 正在下拉状态,即将松手进行刷新
    private final int DONE = 3;// 完成
    private final int HIDE_To_REFRESH = 1;// 未下拉或已完成状态,设置padding为负值把header挡住
  
    private int refreshStatus;// 下拉刷新过程状态变量
  
    private LinearLayout hearderLayout;
    private ImageView arrowImageView;
    private ProgressBar progressBar;
    private TextView tipsTextview;
    private TextView lastUpdatedTime;
    private int headContentHeight;
    private int headContentWidth;
    private RotateAnimation animation;
    private RotateAnimation reverseAnimation;
    private boolean isStartRefreshEvent = false;// 下拉刷新事件是否已经开始
    private boolean isRefreshable = false;// 是否设置下拉刷新监听
    private int firstItemIndex;
  
    private OnRefreshListener refreshListener;
  
    public MyListView (Context context) {
        super(context);
        init(context);
    }
  
    public MyListView (Context context,AttributeSet attrs) {
        super(context,attrs);
        init(context);
    }
  
    private void init(Context context) {
  
        LayoutInflater inflater = LayoutInflater.from(context);
        hearderLayout = (LinearLayout) inflater.inflate(R.layout.list_view_header,null);
        // 下拉箭头
        arrowImageView = (ImageView) hearderLayout.findViewById(R.id.head_arrowImageView);
        // 进度条
        progressBar = (ProgressBar) hearderLayout.findViewById(R.id.head_progressBar);
        // 下拉提示 刷新
        tipsTextview = (TextView) hearderLayout.findViewById(R.id.head_tipsTextView);
        // 最新一次刷新时间
        lastUpdatedTime = (TextView) hearderLayout.findViewById(R.id.head_lastUpdatedTextView);
        // 计算head的高宽
        this.measureView(hearderLayout);
        headContentHeight = hearderLayout.getMeasuredHeight();
        headContentWidth = hearderLayout.getMeasuredWidth();
  
        // 初始状态是 隐藏掉head 布局
        hearderLayout.setPadding(0,-1 * headContentHeight,0);
        hearderLayout.invalidate();
  
        Log.e("sys","width:" + headContentWidth + " height:" + headContentHeight);
        // list添加头文件
        addHeaderView(hearderLayout,null,false);
        setOnScrollListener(this);// TODO
        // 下拉以及恢复动画
        animation = new RotateAnimation(0,-180,RotateAnimation.RELATIVE_TO_SELF,0.5f,0.5f);
        animation.setInterpolator(new LinearInterpolator());
        animation.setDuration(250);
        animation.setFillAfter(true);
        reverseAnimation = new RotateAnimation(-180,0.5f);
        reverseAnimation.setInterpolator(new LinearInterpolator());
        reverseAnimation.setDuration(200);
        reverseAnimation.setFillAfter(true);
        refreshStatus = DONE;
    }
  
    @Override
    public void onScroll(AbsListView arg0,int firstVisiableItem,int arg2,int arg3) {
        firstItemIndex = firstVisiableItem;
    }
  
    @Override
    public void onScrollStateChanged(AbsListView arg0,int arg1) {
    }
  
    private int startY = 0;
    @Override
    public boolean onTouchEvent(MotionEvent event) {
  
        if (firstItemIndex == 0 && isRefreshable) {
            switch (event.getAction()) {
            // 在down时候记录当前Y的位置
            case MotionEvent.ACTION_DOWN:
                if (!isStartRefreshEvent) {
                    isStartRefreshEvent = true;
                    startY = (int) event.getY();
                }
                break;
  
            case MotionEvent.ACTION_MOVE:
  
                int tempY = (int) event.getY();
                int scrollY = (tempY - startY) / RATIO;
  
                Log.i("sys","拉开方向 " + scrollY);
  
                if (!isStartRefreshEvent) {
                    isStartRefreshEvent = true;
                    startY = tempY;
                } else if (isStartRefreshEvent && refreshStatus != LOADING) {
                    // 可以松手去刷新了
                    if (refreshStatus == RELEASE_To_REFRESH) {
                        setSelection(0);
                        // header被用户拉下来后,又往上推了,推到了已经小于header高度时,则推回去,并取消刷新
                        if (scrollY < headContentHeight && scrollY > 0) {
                            refreshStatus = HIDE_To_REFRESH;
                            this.changeHeaderView();
                        }
                        // 一下子推到顶了
                        else if (scrollY <= 0) {
                            refreshStatus = DONE;
                            this.changeHeaderView();
                        }
                    }
                    // 还没有到达显示松开刷新的时候,DONE或者是HIDE_To_REFRESH状态
                    if (refreshStatus == HIDE_To_REFRESH) {
                        setSelection(0);
                        // 下拉至超过header本身高度后,可以进入RELEASE_TO_REFRESH的状态
                        if (scrollY > headContentHeight) {
                            refreshStatus = RELEASE_To_REFRESH;
                            this.changeHeaderView();
                        }
                        // 上推到顶了
                        else if (scrollY <= 0) {
                            refreshStatus = DONE;
                            this.changeHeaderView();
                        }
                    }
                    // done状态下
                    if (refreshStatus == DONE) {
                        if (scrollY > 0) {
                            refreshStatus = HIDE_To_REFRESH;
                            this.changeHeaderView();
                        }
                    }
                    // 更新headView的size
                    if (refreshStatus == HIDE_To_REFRESH) {
                        hearderLayout.setPadding(0,-1 * headContentHeight + scrollY,0);
                    }
                    // 更新headView的paddingTop
                    if (refreshStatus == RELEASE_To_REFRESH) {
                        hearderLayout.setPadding(0,scrollY - headContentHeight,0);
                    }
                }
                break;
  
            case MotionEvent.ACTION_UP:
                if (refreshStatus != LOADING) {
                    if (refreshStatus == DONE) {
                        // 什么都不做
                    }
                    // 由下拉刷新状态,到done状态
                    if (refreshStatus == HIDE_To_REFRESH) {
                        refreshStatus = DONE;
                        this.changeHeaderView();
                    }
  
                    if (refreshStatus == RELEASE_To_REFRESH) {
                        refreshStatus = LOADING;
                        this.changeHeaderView();
                        onRefresh();
                    }
                }
                isStartRefreshEvent = false;
                break;
  
            }
        }
        return super.onTouchEvent(event);
    }
  
    private void changeHeaderView() {
        switch (refreshStatus) {
        // 松开刷新状态
        case RELEASE_To_REFRESH:
            arrowImageView.setVisibility(View.VISIBLE);
            progressBar.setVisibility(View.GONE);
            tipsTextview.setVisibility(View.VISIBLE);
            lastUpdatedTime.setVisibility(View.VISIBLE);
            arrowImageView.clearAnimation();
            arrowImageView.startAnimation(animation);
            tipsTextview.setText("松开刷新");
            break;
        // 下拉刷新
        case HIDE_To_REFRESH:
            progressBar.setVisibility(View.GONE);
            tipsTextview.setVisibility(View.VISIBLE);
            lastUpdatedTime.setVisibility(View.VISIBLE);
            arrowImageView.setVisibility(View.VISIBLE);
            // 是由RELEASE_To_REFRESH状态转变来的
            arrowImageView.clearAnimation();
            arrowImageView.startAnimation(reverseAnimation);
            tipsTextview.setText("下拉刷新");
            break;
        // 刷新中 状态
        case LOADING:
            hearderLayout.setPadding(0,0);
            progressBar.setVisibility(View.VISIBLE);
            arrowImageView.clearAnimation();
            arrowImageView.setVisibility(View.GONE);
            tipsTextview.setText("正在刷新...");
            lastUpdatedTime.setVisibility(View.VISIBLE);
            break;
        // 刷新完毕
        case DONE:
            hearderLayout.setPadding(0,0);
            progressBar.setVisibility(View.GONE);
            arrowImageView.clearAnimation();
            // arrowImageView.setImageResource(R.drawable.goicon);
            tipsTextview.setText("下拉刷新");
            lastUpdatedTime.setVisibility(View.VISIBLE);
            break;
        }
    }
  
    public void setonRefreshListener(OnRefreshListener refreshListener) {
        this.refreshListener = refreshListener;
        isRefreshable = true;
    }
  
    public interface OnRefreshListener {
        public void onRefresh();
    }
  
    public void onRefreshFinished() {
        refreshStatus = DONE;
        DateFormat format = new SimpleDateFormat("yyyy年MM月dd日  HH:mm");
        String date = format.format(new Date());
        lastUpdatedTime.setText("最近更新:" + date);
        changeHeaderView();
    }
  
    private void onRefresh() {
        if (refreshListener != null) {
            refreshListener.onRefresh();
        }
    }
  
    // 此方法计算高度
    private void measureView(View child) {
        ViewGroup.LayoutParams p = child.getLayoutParams();
        if (p == null) {
            p = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,ViewGroup.LayoutParams.WRAP_CONTENT);
        }
        int childWidthSpec = ViewGroup.getChildMeasureSpec(0,0 + 0,p.width);
        int lpHeight = p.height;
        int childHeightSpec;
        if (lpHeight > 0) {
            childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight,MeasureSpec.EXACTLY);
        } else {
            childHeightSpec = MeasureSpec.makeMeasureSpec(0,MeasureSpec.UNSPECIFIED);
        }
        child.measure(childWidthSpec,childHeightSpec);
    }
  
    public void setAdapter(BaseAdapter adapter) {
        DateFormat format = new SimpleDateFormat("yyyy年MM月dd日  HH:mm");
        String date = format.format(new Date());
        lastUpdatedTime.setText("最近更新:" + date);
        super.setAdapter(adapter);
    }
}
  

layout:
<?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"
    android:background="#ffffff" >
  
    <!-- 内容 -->
  
    <RelativeLayout
        android:id="@+id/head_contentLayout"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:paddingLeft="30dip" >
  
        <!-- 箭头图像、进度条 -->
        <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:src="@drawable/arrow"
                android:layout_gravity="center" />
              
            <!-- 进度条,style集合了一个anim -->
            <ProgressBar
                android:id="@+id/head_progressBar"
                style="@style/wait_anim"
                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:textSize="15dp" />
              
            <!-- 最近更新 -->
            <TextView
                android:id="@+id/head_lastUpdatedTextView"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="上次更新"
                android:textSize="12dp" />
        </LinearLayout>
    </RelativeLayout>
  
</LinearLayout>
  
  
Activity中关键代码:
  
mListView.setonRefreshListener(new OnRefreshListener() {
            public void onRefresh() {
                new AsyncTask<Void,Void,Void>() {
                    protected Void doInBackground(Void... params) {
                        try {
                            Thread.sleep(3000);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
//                      dates.addFirst(new AttachmentModule(new Date(),WorkLogContentType.WORKLOG_ATTACHMENT,AttachmentType.Attachment_Nomal));
                        return null;
                    }
  
                    @Override
                    protected void onPostExecute(Void result) {
                        adapter.notifyDataSetChanged();
                        mListView.onRefreshFinished();
                    }
                }.execute(null);
            }
        });

以上内容由PHP站长网【52php.cn】收集整理供大家参考研究

如果以上内容对您有帮助,欢迎收藏、点赞、推荐、分享。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读