项目中用到下拉刷新和加载更多的功能,试了很多都不是很满意。我记得有一个是下拉刷新和上拉加载更多都是一个箭头的那种,我觉得很不好,
不能做到滑到最后自动加载更多,非得用力往上拉。下拉刷新控件中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();
}
}
}