android自定义ListView加载更多与下拉刷新集成

项目中用到下拉刷新和加载更多的功能,试了很多都不是很满意。我记得有一个是下拉刷新和上拉加载更多都是一个箭头的那种,我觉得很不好,

不能做到滑到最后自动加载更多,非得用力往上拉。下拉刷新控件中android-Ultra-Pull-To-Refresh是一个比较好的(这里是几种开源下拉刷新控件的比较)

还有位大神自定义了一个ListView,可以实现下载更多,但没有下拉刷新。下面的例子中我将两者结合起来,实现了像大部分知名软件的下拉刷新和加载更多的效果。

1. 自定义ListView

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.ListView;

import com.centaline.framework.R;


public class LoadListView extends ListView implements OnScrollListener {
    View footer;
    int totalItemCount;
    int lastVisibleItem;
    boolean isLoading;
    ILoadListener iLoadListener;

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

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

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


    private void initView(Context context) {
        LayoutInflater inflater = LayoutInflater.from(context);
        footer = inflater.inflate(R.layout.footer_layout, null);
        footer.findViewById(R.id.load_layout).setVisibility(View.INVISIBLE);
        this.addFooterView(footer);
        this.setOnScrollListener(this);
    }

    @Override
    public void onScroll(AbsListView view, int firstVisibleItem,
                         int visibleItemCount, int totalItemCount) {
        // TODO Auto-generated method stub
        this.lastVisibleItem = firstVisibleItem + visibleItemCount;
        this.totalItemCount = totalItemCount;
    }

    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {

        Log.e("LoadListView","scrollState="+scrollState);
        // 滑到最后一条
        if (totalItemCount == lastVisibleItem && scrollState == SCROLL_STATE_IDLE) {
            if (!isLoading) {
                isLoading = true;
                footer.findViewById(R.id.load_layout).setVisibility(View.VISIBLE);
                if(iLoadListener!=null){
                    iLoadListener.onLoad();
                }
            }
        }
    }

    /*一次加载完成,不要把footer设置成GONE,不然下拉条会闪*/
    public void loadComplete() {
        isLoading = false;
        footer.findViewById(R.id.load_layout).setVisibility(View.INVISIBLE);
    }

    /*所有数据加载完成,才把footer设置成GONE*/
    public void loadOver(){
        isLoading = false;
        footer.findViewById(R.id.load_layout).setVisibility(View.GONE);
    }

    public void setInterface(ILoadListener iLoadListener) {
        this.iLoadListener = iLoadListener;
    }

    public interface ILoadListener {
        public void onLoad();
    }
}


加载更多footer的布局:

<?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"
    android:orientation="vertical" >

    <LinearLayout
        android:id="@+id/load_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:orientation="horizontal"
        android:paddingBottom="10dip"
        android:paddingTop="10dip" >

        <ProgressBar
            style="?android:attr/progressBarStyleSmall"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="10dip"
            android:text="正在加载..." />
    </LinearLayout>

</LinearLayout>



2.与ultra-pull-to-refresh集成使用

 布局:

  

    <in.srain.cube.views.ptr.PtrClassicFrameLayout xmlns:cube_ptr="http://schemas.android.com/apk/res-auto"
        android:id="@+id/rotate_header_list_view_frame"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#f1f1f1"
        cube_ptr:ptr_duration_to_close="200"
        cube_ptr:ptr_duration_to_close_header="1000"
        cube_ptr:ptr_keep_header_when_refresh="true"
        cube_ptr:ptr_pull_to_fresh="false"
        cube_ptr:ptr_ratio_of_header_height_to_refresh="1.2"
        cube_ptr:ptr_resistance="1.7">

        <com.chiang.framework.views.LoadListView
            android:id="@+id/lv_checkList"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:cacheColorHint="#00000000"
            android:divider="@null"
            android:listSelector="@null"
            android:scrollbars="none" />

    </in.srain.cube.views.ptr.PtrClassicFrameLayout>

Activity调用关键代码:(由于涉及到商业保密,只保留了与业务无关的关键代码,不能运行,但与下拉刷新和加载更多的逻辑已经表达出来了,请自行理解后再在自己的项目中参考使用)

public class YuYueCheckActivity extends Activity implements LoadListView.ILoadListener {

    private PtrClassicFrameLayout mPtrFrameLayout;
    private LoadListView listView;
    private ArrayList<ItemBean> mList = new ArrayList<ItemBean>();
    private int limit = 10;
    private int skip = 0;

    /**
     * 加载更多
     */
    private boolean isLoadMore = false;

    /**
     * 加载结束
     */
    private boolean isLoadOver = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        getData(siteId);
        initViews();
    }

    public void initViews() {
        mPtrFrameLayout = (PtrClassicFrameLayout) findViewById(R.id.rotate_header_list_view_frame);
        listView = (LoadListView) findViewById(R.id.lv_checkList);
 
        //下拉刷新
        mPtrFrameLayout.setPtrHandler(new PtrDefaultHandler() {
            @Override
            public void onRefreshBegin(PtrFrameLayout frame) {
                mList.clear();
                skip = 0;
                isLoadMore = false;
                if (siteId != null) {
                    skip = 0;
                    getCheckList(siteId);
                } else {
                    getCheckList(null);
                }
            }
        });

        mAdapter = new MyAdapter(this, mList);
        listView.setAdapter(mAdapter);
        listView.setInterface(this);
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                
            }
        });
    }

    private void getData(String siteId) {
            params.put("skip", skip * limit);
            params.put("limit", limit);
            。。。 请求数据。。。
           
    }


    public void success(JSONObject jsonObject) {
        super.success(bean, jsonObject);
        mPtrFrameLayout.setVisibility(View.VISIBLE);
        listView.loadComplete();
        JSONArray replys = null;
        try {

            if (jsonObject == null) {
                return;
            }
            replys = jsonObject.getJSONArray("list");
            ArrayList<ItemBean> list  = new Gson().fromJson(replys.toString(),
                    new TypeToken<ArrayList<ItemBean>>() {}.getType());

            if(list!=null){
                mList.addAll(list);
            }
            mAdapter.notifyDataSetChanged();

            if(!isLoadMore){
                mPtrFrameLayout.refreshComplete();
            }else{
                listView.loadComplete();
            }

            if(list == null || list.size() == 0){
                isLoadOver = true;
                Toast.makeText(YuYueCheckActivity.this,"没有更多数据",Toast.LENGTH_SHORT).show();
                listView.loadOver();
                skip--;
            }else{
                isLoadOver = false;
            }

        } catch (JSONException e) {
            e.printStackTrace();
        }
    }


//加载更多
Override public void onLoad() {
   skip++; 
   isLoadMore = true; 
   if(isLoadOver){ 
      listView.loadOver();//隐藏footer 
   }else{ 
      getData(); 
   } 
  }
}







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值