ListView结合PullToRefreshScrollView 下拉刷新

public class MainActivity extends Activity implements OnPullEventListener,
        OnRefreshListener {

    // 测试的ListView
    private ListView mListView;
    // ListView的headerView
    private View mListHeaderView;
    // 下拉刷新控件
    private PullToRefreshScrollView mPullRefreshScrollView;
    // ListView的测试数据
    private ArrayList<String> mData;
    // 获取数据的刷新任务
    private LoadDataTask mLoadDataTask;

    private View mTopItem;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initData();
        initViews();
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
                android.R.layout.simple_list_item_1, mData);
        mListView.setAdapter(adapter);
        initEvents();
    }

    private void initEvents() {

        // ListView 的滑动事件
        mListView.setOnScrollListener(new OnScrollListener() {
            @Override
            public void onScrollStateChanged(AbsListView view, int scrollState) {

            }
            @Override
            public void onScroll(AbsListView view, int firstVisibleItem,
                    int visibleItemCount, int totalItemCount) {

//              Log.i("TAG", "headerView.getTop :" + mListHeaderView.getTop());

                //测试看看mListHeaderView 算不算第一个列表项
                //测试下来, mListHeaderView 就是第0个元素, 第一个列表项, 
                //ListHeaderView 主要是为了添加一个和列表项区别很大的列表元素, 但还是列表项的首项
                if(mTopItem != null) {
                    String info = (mTopItem == mListHeaderView) ?  "mListHeaderView is first item." : "mListHeaderView is not first item.";
//                  Toast.makeText(getApplicationContext(), info, Toast.LENGTH_SHORT).show();
                }
                if (firstVisibleItem == 0) {
                    mPullRefreshScrollView.setMode(Mode.PULL_FROM_START);// 如果是listview的首项则下拉刷新
                    if(mTopItem == null) {
                        mTopItem = view.getChildAt(0);
                    }
                } else {
                    // 这里如果简单把RefreshScrollView设置为disabled的话,
                    // 在一些时候比如下拉然后突然向上,此时scrollview会卡住不上不下
                    if (mPullRefreshScrollView.getState() == State.RESET) {
                         mPullRefreshScrollView.setMode(Mode.DISABLED);
                    }else if(firstVisibleItem > 3 || 0 - mListHeaderView.getTop() > 100){ 
                        //刷新过程中判断上滑超过3个时还没有刷新完毕,则取消刷新, 同时取消异步任务,  
                        //但是如果列表项每一个都很高的话, 比如添加一个ListHeaderView可能高度比较高用上滑动项个数判断就不合理了,
                        //那应该判断上滑距离, 观察getTop 上滑是负数, 比如上滑超过100像素,则取消
                        mPullRefreshScrollView.onRefreshComplete();
                        if(mLoadDataTask != null) {
                            mLoadDataTask.cancel(true);
                        }
                        Toast.makeText(getApplicationContext(), "刷新取消", Toast.LENGTH_SHORT).show();

                    }

                }
            }
        });

        //不要忘记绑定下拉刷新控件的两个事件监听器
        //下拉时候的显示setOnPullEventListener
        mPullRefreshScrollView.setOnPullEventListener(this);
        //刷新时具体需要完成的任务
        mPullRefreshScrollView.setOnRefreshListener(this);
    }

    private void initData() {
        mData = new ArrayList<String>();
        for (int i = 'a'; i < 'z'; i++) {
            mData.add((char) i + "-- 测试Item");
        }
    }

    private void initViews() {
        mListView = (ListView) findViewById(R.id.drag_list);

        mListHeaderView = LayoutInflater.from(this).inflate(R.layout.header_listview, null);
        mListView.addHeaderView(mListHeaderView, null, true);
        mPullRefreshScrollView = (PullToRefreshScrollView) findViewById(R.id.pull_refresh_scrollview);
        mListView.setSelection(0);
    }


    // OnPullEventListener 下拉事件需要复写的方法, 下拉时显示上次刷新时间
    @Override
    public void onPullEvent(PullToRefreshBase refreshView, State state,
            Mode direction) {
        //下拉的时候需要显示上次刷新的时间的话需要在数据库中记录上次刷新时间, 这里是测试生成的时间
        long time = 30 * 1000L;
        String label = String.format("上次刷新:%s", "从未");
        if (time > 0)
            label = String.format("上次刷新:%s",
                    TimeUtils.getListTime(this.getResources(), System.currentTimeMillis() - time));
        mPullRefreshScrollView.getLoadingLayoutProxy().setLastUpdatedLabel(
                label);

    }

    /**
     * 刷新事件 , 执行任务, 已经在跑则返回
     */

    @Override
    public void onRefresh(PullToRefreshBase refreshView) {

        if (mLoadDataTask != null && mLoadDataTask.getStatus() == Status.RUNNING) {
            return;
        }
        mLoadDataTask = new LoadDataTask();
        mLoadDataTask.execute();
    }

    private class LoadDataTask extends AsyncTask<Void, Void, Void> {

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            // Call setRefreshing when the list begin to refresh.
            mPullRefreshScrollView.setRefreshing(true);
        }

        @Override
        protected Void doInBackground(Void... params) {
            // 一些耗时的数据操作, 这里测试休眠2秒
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onPostExecute(Void result) {
            super.onPostExecute(result);
            // Call onRefreshComplete when the list has been .
            mPullRefreshScrollView.onRefreshComplete();

            // 刷新任务异步完成后, 判断刷新是否成功 ,分别给予提示
            if (!mData.isEmpty()) {
                Toast.makeText(getApplicationContext(), "刷新成功", Toast.LENGTH_SHORT)
                        .show();
            } else {
                Toast.makeText(getApplicationContext(), "刷新失败", Toast.LENGTH_SHORT)
                        .show();
            }
        }

    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值