自定义ListView实现下拉刷新

作者: 麦兜叮叮当 | 来源:发表于2017-01-03 14:23 被阅读51次

    下拉加载更多在我们平常使用的APP中经常会见到,比如我们刷微博时下拉加载更多的新闻,空间动态下拉加载更多的消息等。Android是没有给我们提供这样的控件的,那今天我们就动手简单的实现一下这个功能。

    在这里我们重写ListView,利用 线程池+OnScrollListener+接口回调 配合来实现。

    简单说一下实现的逻辑:我们都知道ListView提供给我们一个方法addFooterView,我们就利用这个方法给我们的ListView添加脚布局,并通过setPadding方法控制脚布局的显示与隐藏,然后添加接口回调用于显示更多数据的加载,在回调方法外部包装一层线程池来控制数据加载的有序性,也许你会有个迷惑,我们什么时候开始加载数据呢,别忘了我们还用到了OnScrollListener接口呢,我们就在OnScrollListener接口的onScrollStateChanged方法中来判断ListView是否滑动到了底部。好,接下来我们看代码。

    
    public classXvListViewextendsListViewimplementsAbsListView.OnScrollListener{
    
    private intHIDE_HEIGHT;//脚布局的高
    
    private intmCount;//每次加载的个数
    
    privateContextmContext;
    
    privateViewmView;//脚布局
    
    privateHandlerUploadmHandlerUpload;//回调接口
    
    privateExecutorServicemEcecutorService;//线程池
    
    privateBaseAdapteradapter;
    
    /**
    
    * 得到主线程的looper
    
    */
    
    privateHandlermHandler=newHandler(Looper.getMainLooper()){
    
    @Override
    
    public voidhandleMessage(Message msg) {
    
    super.handleMessage(msg);
    
    switch(msg.what){
    
    case0:
    
    Toast.makeText(mContext,"没有更多内容了",Toast.LENGTH_SHORT).show();
    
    break;
    
    case1:
    
    showFooterView(false);
    
    adapter.notifyDataSetChanged();
    
    break;
    
    }
    
    }
    
    };
    
    publicXvListView(Context context,AttributeSet attrs) {
    
    super(context,attrs);
    
    mContext= context;
    
    init();
    
    setOnScrollListener(this);
    
    }
    
    /**
    
    * 线程池以及脚布局的初始化
    
    */
    
    private voidinit() {
    
    mEcecutorService= Executors.newFixedThreadPool(1);
    
    mView= LayoutInflater.from(mContext).inflate(R.layout.pull_to_refresh,null);
    
    HIDE_HEIGHT=mView.getMeasuredHeight();
    
    mView.setPadding(0,-HIDE_HEIGHT,0,0);
    
    this.addFooterView(mView);
    
    }
    
    /**
    
    * 这里实现OnScrollListener接口的onScrollStateChanged方法
    
    */
    
    @Override
    
    public voidonScrollStateChanged(AbsListView absListView, inti) {
    
    if((getAdapter().getCount()-1== getLastVisiblePosition()) &&
    
    ((i == OnScrollListener.SCROLL_STATE_IDLE) || (i == OnScrollListener.SCROLL_STATE_FLING))){
    
    executeUpload();
    
    }
    
    }
    
    /**
    
    * 控制脚布局的显示与隐藏
    
    */
    
    private voidshowFooterView(booleanisboolean){
    
    if(isboolean){
    
    mView.setPadding(0,0,0,0);
    
    }else{
    
    mView.setPadding(0,-HIDE_HEIGHT,0,0);
    
    }
    
    }
    
    /**
    
    * 利用线程池来控制有序加载
    
    */
    
    private voidexecuteUpload(){
    
    showFooterView(true);
    
    if(mHandlerUpload!=null){
    
    mEcecutorService.execute(newRunnable() {
    
    @Override
    
    public voidrun() {
    
    mCount=mHandlerUpload.upload();
    
    if(mCount==0) {
    
    mHandler.sendEmptyMessage(0);
    
    }
    
    mHandler.sendEmptyMessage(1);
    
    }
    
    });
    
    }
    
    }
    
    public voidsetHandlerUpload(HandlerUpload mHandlerUpload,BaseAdapter adapter){
    
    this.mHandlerUpload= mHandlerUpload;
    
    this.adapter= adapter;
    
    }
    
    @Override
    
    public voidonScroll(AbsListView absListView, inti, inti1, inti2) {
    
    }
    
    /**
    
    * 利用接口回调加载数据
    
    */
    
    public interfaceHandlerUpload{
    
    intupload();
    
    }
    
    }
    
    

    代码都有注释,很简单。

    XML布局

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    
    android:layout_height="match_parent"    
    tools:context=".MainActivity" >    <com.example.xvhuichuang.lianxi.com.lianxi.UI.XvListView        android:layout_width="match_parent"        
    android:layout_height="match_parent"        
    android:id="@+id/pullup"></com.example.xvhuichuang.lianxi.com.lianxi.UI.XvListView>
    </RelativeLayout>
    

    最后在Activity设置适配器并实现下拉加载功能

    public class Main extends AppCompatActivity{    
    private MyAdapter myAdapter;   
    private List<String> lists;    
    private int i = 0, j = 0 ;    
    XvListView pullUpLoadMoreListView ;    
    @Override    
    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        
    setContentView(R.layout.main2);        
    lists = new ArrayList<>();        
    for (;i<15;i++){            
    lists.add(i+"");       
    }        
    pullUpLoadMoreListView = (XvListView) findViewById(R.id.pullup);        
    myAdapter = new MyAdapter();        
    pullUpLoadMoreListView.setHandlerUpload(new XvListView.HandlerUpload() {            @Override            
    public int upload() {                
    j = i+15;               
     for (;i<j;i++){                    
    lists.add(""+i);               
     }                
    return 15;           
     }        
    },myAdapter);        
    pullUpLoadMoreListView.setAdapter(myAdapter);   
     }    
    class MyAdapter extends BaseAdapter{       
    @Override        
    public int getCount() {            
    return lists.size();       
     }        
    @Override        
    public Object getItem(int i) {            
    return lists.get(i);        
    }        
    @Override        
    public long getItemId(int i) {            
    return i;        
    }        
    @Override       
     public View getView(int i, View view, ViewGroup viewGroup) {            
    View view1 = LayoutInflater.from(Main.this).inflate(R.layout.qq,null);            
    TextView textView = (TextView) view1.findViewById(R.id.text);            textView.setText(lists.get(i));            
    return view1;        
    }    
    }
    }
    

    当然这里我没有对适配器的getView进行性能优化,在实际的运用中务必对其进行优化!

    相关文章

      网友评论

        本文标题:自定义ListView实现下拉刷新

        本文链接:https://www.haomeiwen.com/subject/bzxnvttx.html