PulltoRefresh实现上下拉刷新

首先看运行效果:实现的是上,下拉刷新的效果。

这里写图片描述

本文主要介绍使用android开源项目PullToRefresh-master,实现上下拉刷新。

首先下载library,将library添加到项目依赖中,项目的主要目录结构如下:
这里写图片描述
主要的知识都在代码中注释,首先activity.xml中是这样配置:

<?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="fill_parent"
    android:orientation="vertical">
    <com.handmark.pulltorefresh.library.PullToRefreshListView
        android:id="@+id/pull_refresh_list"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:cacheColorHint="#00000000"
        android:divider="#19000000"
        android:dividerHeight="4dp"
        android:fadingEdge="none"
        android:fastScrollEnabled="false"
        android:footerDividersEnabled="false"
        android:headerDividersEnabled="false"
        android:smoothScrollbar="true" />
</LinearLayout>

还有item.xml的文件,显示的是每个listview中显示的内容

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView
        android:id="@+id/textview"
        android:layout_width="fill_parent"
        android:layout_height="30dp"
        android:gravity="center_vertical"
        android:paddingLeft="10dp"
        android:text="123" />
</LinearLayout>

MainActivity中的代码如下:

package app.myapplication;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.text.format.DateUtils;
import android.widget.ListView;

import com.handmark.pulltorefresh.library.PullToRefreshBase;
import com.handmark.pulltorefresh.library.PullToRefreshListView;
import java.util.ArrayList;
public class MainActivity extends ActionBarActivity {
    //设置集合
    private ArrayList list;
    //设置适配器
    private MyAdapter adapter;
    PullToRefreshListView pull_refresh_list;
    //设置一个标记,判断是下拉还是上拉;
    private Boolean isPullDown = false;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        list = new ArrayList();
        pull_refresh_list = (PullToRefreshListView) findViewById(R.id.pull_refresh_list);
        //初始化集合
        initData();
        adapter = new MyAdapter(MainActivity.this, list);
        pull_refresh_list.setAdapter(adapter);
        //设置拉伸的模式,both代表上,下都能拉伸,默认的是只能下拉刷新;
        pull_refresh_list.setMode(PullToRefreshBase.Mode.BOTH);
        pull_refresh_list.setOnRefreshListener(new PullToRefreshBase.OnRefreshListener2<ListView>() {
            //下拉的时候执行
            @Override
            public void onPullDownToRefresh(PullToRefreshBase<ListView> refreshView) {
                //label主要 设置下拉刷新时候显示的内容;
                String label = DateUtils.formatDateTime(getApplicationContext(),
                        System.currentTimeMillis(),
                        DateUtils.FORMAT_SHOW_TIME
                                | DateUtils.FORMAT_SHOW_DATE
                                | DateUtils.FORMAT_ABBREV_ALL);
                //把显示的内容设置到控件中
                refreshView.getLoadingLayoutProxy().setLastUpdatedLabel(label);
                isPullDown = true;
                //异步任务,主要作耗时操作,实际开发中是应该联网,从服务器或者数据库中获取数据;
                new LoadData().execute();
            }
            //上拉的时候执行
            @Override
            public void onPullUpToRefresh(PullToRefreshBase<ListView> refreshView) {
                isPullDown = false;
                //在下拉的时候同样执行操作,由isPullDown标识是下拉,或者下拉
                new LoadData().execute();
            }
        });
    }
    public class LoadData extends AsyncTask<Integer, Integer, String> {
        //在doInBackground中作主要的耗时操作,比如连网,查询。在这只让休眠1秒中;
        @Override
        protected String doInBackground(Integer... params) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return null;
        }
        //在doInBackground方法执行后执行此方法,主要负责更新UI界面和数据;
        @Override
        protected void onPostExecute(String s) {
            super.onPostExecute(s);
            if (isPullDown) {
                //在下拉时给集合中添加元素;
                list.add(0, "我是下拉出来的数据");
            } else {
                //在上拉时给集合中添加元素;
                list.add(list.size(), "我是上拉出来的数据");
            }
            //能过nofifyDataSetChanged()方法,不用刷新Activity,只刷新listview;
            adapter.notifyDataSetChanged();
            //下拉刷新结束后,把拉出来的布局隐藏;
            pull_refresh_list.onRefreshComplete();
        }
    }
    private void initData() {
        for (int i = 0; i < 10; i++) {
            list.add(" 我是item " + i);
        }
    }
}

最后适配器中的代码也比较简单:

package app.myapplication;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

import java.util.ArrayList;

/**
 * Created by Administrator on 2015/9/8.
 */
public class MyAdapter extends BaseAdapter {
    ArrayList arraylist;
    Context context;

    public MyAdapter(Context context, ArrayList arraylist) {
        this.context = context;
        this.arraylist = arraylist;
    }

    @Override
    public int getCount() {
        return arraylist.size();
    }

    @Override
    public Object getItem(int position) {
        return position;
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder vh;
        if (convertView == null) {
            vh = new ViewHolder();
            convertView = LayoutInflater.from(context).inflate(R.layout.item, null);
            vh.textview = (TextView) convertView.findViewById(R.id.textview);
            convertView.setTag(vh);
        } else {
            vh = (ViewHolder) convertView.getTag();
        }
        vh.textview.setText(arraylist.get(position) + "");
        return convertView;
    }
    static class ViewHolder {
        TextView textview;
    }
}

在PullToRrefresh中如果要设置进入到页面(比如聊天页面,显示最后一条消息)要设置这样的属性

pullToRefresh.getRefreshableView().setSelection(
                            arrayList.size() - 1);

2、AsyncTask总结

1、AsyncTask的内部原理:

在以前代码中

private static final int CORE_POOL_SIZE =5;//5个核心工作线程
private static final int MAXIMUM_POOL_SIZE = 128;//最多128个排队线程
private static final int KEEP_ALIVE = 1;//空闲线程的超时时间为1秒

private static final BlockingQueue<Runnable> sWorkQueue =
           new LinkedBlockingQueue<Runnable>(10);//等待队列

private static final ThreadPoolExecutorsExecutor = new ThreadPoolExecutor(CORE_POOL_SIZE,
           MAXIMUM_POOL_SIZE, KEEP_ALIVE, TimeUnit.SECONDS, sWorkQueue,sThreadFactory);//线程池是静态变量,所有的异步任务都会放到这个线程池的工作线程内执行。

但是从6.0sdk中面

private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
    private static final int CORE_POOL_SIZE = CPU_COUNT + 1;//为cup的核心+1
    private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1;
    private static final int KEEP_ALIVE = 1;

    private static final ThreadFactory sThreadFactory = new ThreadFactory() {
        private final AtomicInteger mCount = new AtomicInteger(1);

        public Thread newThread(Runnable r) {
            return new Thread(r, "AsyncTask #" + mCount.getAndIncrement());
        }
    };

    private static final BlockingQueue<Runnable> sPoolWorkQueue =
            new LinkedBlockingQueue<Runnable>(128);//依然是128个最多排队线程

2、AsyncTask中的实现原理

(1)、AsyncTask的底层是线程池+UI线程,比起Thread+Handler的方式,AsyncTask在操作UI线程上更方便,因为onPreExecute()、onPostExecute()及更新UI方法onProgressUpdate()均运行在主线程中UI线程中执行,这样就不用Handler发消息处理了;
(2)、AsyncTask实际工作的也就是5个线程,也就是说,一个APP如果运用AsyncTask技术来执行线程,那么同一时间最多只能有5个线程同时运行,其他线程将被所以AsyncTask不要用于多线程取网络数据,因为很可能这样会产生阻塞,从而降低效率。
(3)、AsyncTask用的是线程池机制,容量是128等线程,最多同时运行5个core线程,剩下的排队。线程池中如果已经有128个线程,缓冲队列已满,如果此时向线程提交任务,将会抛出RejectedExecutionException

3、AsyncTask中的常见问题

在Activity中创建的AsyncTask并不会随着Activity的销毁而结束任务,因此在Activity销毁前的时候我们必须取消任务请求。

4、AsyncTask的重要参数和方法

三个参数:

1、Params 在执行AsyncTask时需要传入的参数,可用于在后台任务中使用。

2、Progress后台任何执行时,如果需要在界面上显示当前的进度,则使用这里指定的泛型作为进度单位。

3、Result 当任务执行完毕后,如果需要对结果进行返回,则使用这里指定的泛型作为返回值类型。

四个方法:
1、onPreExecute()
这个方法会在后台任务开始执行之间调用,用于进行一些界面上的初始化操作,比如显示一个进度条对话框等。

2、doInBackground(Params…)
做耗时操作,比如从服务器获取数据。

3、onProgressUpdate(Progress…)
比如更新进度条,显示进度值。

4、onPostExecute(Result)
获取数对话据,关闭框。


示例代码

 private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
     protected Long doInBackground(URL... urls) {
         int count = urls.length;
         long totalSize = 0;
         for (int i = 0; i < count; i++) {
             totalSize += Downloader.downloadFile(urls[i]);
             publishProgress((int) ((i / (float) count) * 100));
             // Escape early if cancel() is called
             if (isCancelled()) break;
         }
         return totalSize;
     }

     protected void onProgressUpdate(Integer... progress) {
         setProgressPercent(progress[0]);
     }

     protected void onPostExecute(Long result) {
         showDialog("Downloaded " + result + " bytes");
     }
 }
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值