android ListView下拉刷新之功能实现

首先要知道刷新有三个状态,

1是下拉中

2是松开刷新

3是正在刷新

还有一个非常重要的是回调接口,这个接口是正在刷新的时候外界需要做的事。

然后外界再把状态重置。

回调接口需要三个属性,

private OnRefLisner listener;

public void setOnRefLisner(OnRefLisner listener){
        this.listener = listener;
    }

//回调接口
    public interface OnRefLisner{
        void setPullRfe();
    }

package com.example.listviewf5;

import java.text.SimpleDateFormat;

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

public class MyListView extends ListView {
    private View v;
    private int headHeight;// 头部的高度
    private int downY;// 按下时候Y坐标

    private final int PULL_REF = 0;// 下拉
    private final int REL_REF = 1;// 松开刷新
    private final int REFING = 2;// 刷新中
    private int currentState = PULL_REF;

    private TextView tv;
    private TextView tvtiem;
    private ImageView img;
    private ProgressBar pb;
    //旋转动画
    private RotateAnimation upAnimation,downAnimation;

    public MyListView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        // TODO Auto-generated constructor stub
        initView(context);
    }

    public MyListView(Context context, AttributeSet attrs) {
        super(context, attrs);
        // TODO Auto-generated constructor stub
        initView(context);
    }

    public MyListView(Context context) {
        super(context);
        // TODO Auto-generated constructor stub
        initView(context);
    }

    /**
     * 加载顶部布局文件
     *
     * @param context
     */
    private void initView(Context context) {
        // LayoutInflater in =LayoutInflater.from(context);
        // v = in.inflate(R.layout.head,null);
        v = View.inflate(context, R.layout.head, null);
        this.addHeaderView(v);
        v.measure(0, 0);// 通知系统测量宽高
        headHeight = v.getMeasuredHeight();// 得到测量后的高度
        v.setPadding(0, -headHeight, 0, 0);// 进行隐藏head,就是把paddingtop设置成负高度

        tv = (TextView) v.findViewById(R.id.head_tv);
        tvtiem = (TextView) v.findViewById(R.id.head_tvtime);
        img = (ImageView) v.findViewById(R.id.head_img);
        pb = (ProgressBar) v.findViewById(R.id.pb);
        initHeadRotateAnimation();

    }

    private void initHeadRotateAnimation() {
        upAnimation = new RotateAnimation(0, -180,
                RotateAnimation.RELATIVE_TO_SELF, 0.5f,
                RotateAnimation.RELATIVE_TO_SELF, 0.5f);
        upAnimation.setDuration(300);
        upAnimation.setFillAfter(true);
        downAnimation = new RotateAnimation(-180, -360,
                RotateAnimation.RELATIVE_TO_SELF, 0.5f,
                RotateAnimation.RELATIVE_TO_SELF, 0.5f);
        downAnimation.setDuration(300);
        downAnimation.setFillAfter(true);

    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        switch (ev.getAction()) {
        case MotionEvent.ACTION_DOWN:
            downY = (int) ev.getY();
            break;
        case MotionEvent.ACTION_MOVE:
            //如果是正在刷新状态滑动没有
            if(currentState==REFING){
                break;
            }

            int deltaY = (int) (ev.getY() - downY);// 得到移动的距离
            int currentHeight = -headHeight + deltaY;
            // 判断当前的距离是不是大于headHeight 并且显示的是第一个位置
            if (currentHeight > -headHeight && getFirstVisiblePosition() == 0) {
                v.setPadding(0, currentHeight, 0, 0);// 展现头部
                if (currentHeight >= 0 && currentState == PULL_REF) {
                    currentState = REL_REF;
                    refHeadView();
                } else if (currentHeight < 0 && currentState == REL_REF) {
                    currentState = PULL_REF;
                    refHeadView();
                }
                return true;// 拦截事件不让listview处理
            }
            break;
        case MotionEvent.ACTION_UP:
            //判断当前是不是要刷新状态
            if(currentState==PULL_REF){
                v.setPadding(0, -headHeight, 0, 0);
            }else if(currentState==REL_REF){
                currentState=REFING;
                v.setPadding(0,0, 0, 0);
                refHeadView();
                if(listener!=null){
                    listener.setPullRfe();
                }
            }
            break;
        }
        return super.onTouchEvent(ev);
    }

    private void refHeadView() {
        switch (currentState) {
        case PULL_REF:
            tv.setText("下拉刷新");
            img.startAnimation(downAnimation);
            break;
        case REL_REF:
            tv.setText("松开刷新");
            img.startAnimation(upAnimation);
            break;
        case REFING:
            tv.setText("正在刷新……");
            img.setVisibility(View.GONE);
            img.clearAnimation();
            pb.setVisibility(View.VISIBLE);
            break;

        default:
            break;
        }

    }
    //刷新完成要把控件和状态重置
    public void completeRef(){
        v.setPadding(0, -headHeight, 0, 0);// 展现头部
        currentState=PULL_REF;
        tv.setText("下拉刷新");
        img.setVisibility(View.VISIBLE);
        pb.setVisibility(View.GONE);
        SimpleDateFormat sDateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        String date = sDateFormat.format(new java.util.Date());
        tvtiem.setText("最后刷新:"+date);

    }
    private OnRefLisner listener;
    public void setOnRefLisner(OnRefLisner listener){
        this.listener = listener;
    }
    //回调接口
    public interface OnRefLisner{
        void setPullRfe();
    }

}
package com.example.listviewf5;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.example.listviewf5.MyListView.OnRefLisner;

import android.os.Bundle;
import android.os.Handler;
import android.app.Activity;
import android.view.Menu;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.Toast;

public class MainActivity extends Activity {
    private MyListView lv;
    private List<Map<String, Object>> list;
    private SimpleAdapter sa;
    private Handler handler = new Handler(){
        public void handleMessage(android.os.Message msg) {
            sa.notifyDataSetChanged();
            lv.completeRef();

        };
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        lv = (MyListView) findViewById(R.id.lv);
        list = new ArrayList<Map<String,Object>>();
        for (int i = 0; i <20; i++) {
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("key1","神马都是浮云");
            map.put("key2","heheda");
            list.add(map);
        }
        sa = new SimpleAdapter(this, list,R.layout.item_lv, new String[]{"key1","key2"},new int[]{R.id.tv,R.id.tv2});
        lv.setAdapter(sa);
        lv.setOnRefLisner(new OnRefLisner() {

            @Override
            public void setPullRfe() {
                Map<String, Object> map = new HashMap<String, Object>();
                map.put("key1","下拉更新的数据");
                map.put("key2","hehedaheheda");
                list.add(0, map);
                handler.sendEmptyMessageDelayed(0,3000);
            }
        });
    }
}
时间: 2024-10-26 16:14:27

android ListView下拉刷新之功能实现的相关文章

Android ListView 下拉刷新 点击加载更多

最近项目中用到了ListView的下拉刷新的功能,总结了一下前辈们的代码,单独抽取出来写了一个demo作为示例. 效果图 下拉刷新: 加载更多: CustomListView.java [java] view plaincopy package com.example.uitest.view; import java.util.Date; import com.example.uitest.R; import android.content.Context; import android.uti

Android listview下拉刷新 上拉加载

转载自:http://blog.csdn.net/bboyfeiyu Android下拉刷新完全解析,教你如何一分钟实现下拉刷新功能 http://blog.csdn.net/guolin_blog/article/details/9255575 打造通用的Android下拉刷新组件(适用于ListView.GridView等各类View)  http://blog.csdn.net/bboyfeiyu/article/details/39718861 Android打造(ListView.Gr

最新Android ListView 下拉刷新 上滑加载

开发项目过程中基本都会用到listView的下拉刷新和上滑加载更多,之前大家最常用的应该是pull to refresh或它的变种版吧,google官方在最新的android.support.v4包中增加了一个新类SwipeRefreshLayout,地址 这个类的作用就是提供官方的下拉刷新,并且效果相当不错,而上拉加载更多则用我们自定义的listview,也是相当简单. 下拉刷新 简单的介绍下: 首先它是一个viewgroup,但是它只允许有一个子控件,子控件能是任何view,使用的时候,所在

Android—自定义控件实现ListView下拉刷新

这篇博客为大家介绍一个android常见的功能——ListView下拉刷新(参考自他人博客,网址忘记了,阅读他的代码自己理解注释的,希望能帮助到大家): 首先下拉未松手时候手机显示这样的界面: 下面的代码是自定的扎样的控件: package com.dhsr.smartID.view; import android.content.Context; import android.util.AttributeSet; import android.view.Gravity; import andr

Xamarin. Android实现下拉刷新功能

下拉刷新功能在安卓和iOS中非常常见,一般实现这样的功能都是直接使用第三方的库,网上能找到很多这样的开源库.然而在Xamarin. Android中要实现一个好用的下拉刷新功能却不是很容易,在网上找了几个Xamarin.Android的下拉刷新控件,都不是很满意,所以想重新绑定一个java写的下拉刷新控件.在网上找了几个这样的开源库,通过对比发现android-pull-to-refresh实现的功能比较多,实现的效果也比较满意. Android-Pull-To-Refresh项目地址:http

基于Android的计步器(Pedometer)的讲解(六)——ListView下拉刷新页面

计步器(Pedometer)整个项目的源代码,最近做了比较大的修改,可能以前下载的不能运行,感兴趣的朋友可以下载来看看(记得帮小弟在github打个星~) https://github.com/296777513/pedometer 今天实现实现的下拉刷新的功能,先上几张效果图: 如图所示,今天就是要实现的这个效果 首先,分析ListView下拉刷新实现方式 1.需要添加顶部下拉加载页面 2.需要监听onScrollListener来判断当前是否显示在listview的最顶部 3.因为顶部下拉加

Android ListView下拉/上拉刷新:设计原理与实现

 <Android ListView下拉/上拉刷新:设计原理与实现> Android上ListView的第三方开源的下拉刷新框架很多,应用场景很多很普遍,几乎成为现在APP的通用设计典范,甚至谷歌官方都索性在Android SDK层面支持下拉刷新,我之前写了一篇文章<Android SwipeRefreshLayout:谷歌官方SDK包中的下拉刷新>专门介绍过(链接地址:http://blog.csdn.net/zhangphil/article/details/4696537

Android中ListView下拉刷新的实现

ListView中的下拉刷新是非常常见的,也是经常使用的,看到有很多同学想要,那我就整理一下,供大家参考.那我就不解释,直接上代码了. 这里需要自己重写一下ListView,重写代码如下: [java] view plain copy package net.loonggg.listview; import java.util.Date; import android.content.Context; import android.util.AttributeSet; import androi

Android PullToRefresh 下拉刷新,上拉更多,支持ScrollView,ListView,可方便拓展GridView,WebView等

在写着东西之前,从网上找到很多这方面的源码,但是基本没有找到满意的,包括在GitHub上的比较有名的Android-PullToRefresh-master,思来想去还是自己写吧,当然其中借鉴了一些别的开源代码! 废话不多说,直接上代码,注释很全乎,应该不难理解,Demo下载地址在最后: package com.zs.pulltorefreshtest; import android.content.Context; import android.util.AttributeSet; impor