Android ListView 实现上拉加载的示例代码
在开发中,常用到的列表控件是ListView,但在处理大量数据时,仅使用ListView可能无法满足需求,因为初始状态下列表只会显示一定数量的数据,需要滑动到底部才会加载更多数据。于是,很多开发者会尝试实现上拉加载功能。下面,我将为大家介绍一种实现上拉加载的示例代码,希望对大家有所帮助。
先看一下实现效果:

下拉刷新的代码不再详细讲述,主要介绍如何实现上拉加载。
1、在布局文件中添加LoadMoreView
<?xml version="1.0" encoding="utf-8"?>
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/srl_refresh"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:id="@+id/lv_list"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<include
android:id="@+id/loadMoreView"
layout="@layout/load_more_view" />
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
其中,layout="@layout/load_more_view"即为加载更多的布局文件。
2、编写LoadMoreView
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/ll_load_more"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical"
android:padding="10dp"
android:visibility="gone">
<ProgressBar
android:id="@+id/pb_loading"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:indeterminate="true" />
<TextView
android:id="@+id/tv_load_hint"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="正在加载中..."
android:textColor="#999999"
android:textSize="14sp" />
</LinearLayout>
其中,ProgressBar和TextView用于显示正在加载中的提示信息。
3、编写LoadMoreAdapter
/**
* 上拉加载的适配器
*/
public abstract class LoadMoreAdapter extends BaseAdapter {
/**
* ListView 对象
*/
private ListView mListView;
/**
* LoadMoreView 布局
*/
private View mLoadMoreView;
/**
* ProgressBar
*/
private ProgressBar mLoadingView;
/**
* TextView
*/
private TextView mLoadText;
/**
* 加载状态
*/
private int mLoadState = STATE_NONE;
/**
* 数据加载状态
*/
public static final int STATE_NONE = 0; // 隐藏
public static final int STATE_LOADING = 1; // 正在加载
public static final int STATE_FAILED = 2; // 加载失败
public static final int STATE_NO_MORE = 3; // 没有更多数据了
public LoadMoreAdapter(ListView listView) {
mListView = listView;
mLoadMoreView = LayoutInflater.from(listView.getContext()).inflate(R.layout.load_more_view, null);
mLoadingView = mLoadMoreView.findViewById(R.id.pb_loading);
mLoadText = mLoadMoreView.findViewById(R.id.tv_load_hint);
mLoadMoreView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mLoadState == STATE_FAILED) {
mLoadState = STATE_LOADING;
updateLoadState();
onLoadMore();
}
}
});
updateLoadState();
mListView.addFooterView(mLoadMoreView);
}
/**
* 更新加载状态
*/
public void updateLoadState() {
switch (mLoadState) {
case STATE_NONE:
mLoadMoreView.setVisibility(View.GONE);
break;
case STATE_LOADING:
mLoadingView.setVisibility(View.VISIBLE);
mLoadText.setText(R.string.loading);
mLoadMoreView.setVisibility(View.VISIBLE);
break;
case STATE_FAILED:
mLoadingView.setVisibility(View.GONE);
mLoadText.setText(R.string.load_failed);
mLoadMoreView.setVisibility(View.VISIBLE);
break;
case STATE_NO_MORE:
mLoadingView.setVisibility(View.GONE);
mLoadText.setText(R.string.no_more_data);
mLoadMoreView.setVisibility(View.VISIBLE);
break;
}
}
/**
* 设置加载状态
* @param loadState 加载状态
*/
public void setLoadState(int loadState) {
mLoadState = loadState;
updateLoadState();
}
/**
* 获取加载状态
* @return 加载状态
*/
public int getLoadState() {
return mLoadState;
}
/**
* 加载更多数据
*/
public abstract void onLoadMore();
}
其中,主要实现了updateLoadState()方法,用于更新加载状态;setLoadState()方法,用于设置加载状态;getLoadState()方法,用于获取加载状态;onLoadMore()方法,用于加载更多数据。
4、编写LoadMoreListView
public class LoadMoreListView extends ListView {
/**
* 加载状态
*/
private int mLoadState = STATE_NONE;
/**
* 数据加载状态
*/
public static final int STATE_NONE = 0; // 隐藏
public static final int STATE_LOADING = 1; // 正在加载
public static final int STATE_FAILED = 2; // 加载失败
public static final int STATE_NO_MORE = 3; // 没有更多数据了
/**
* 适配器
*/
private LoadMoreAdapter mAdapter;
/**
* 是否正在加载中
*/
private boolean mIsLoading = false;
public LoadMoreListView(Context context) {
super(context);
}
public LoadMoreListView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public LoadMoreListView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
/**
* 设置适配器
* @param adapter 适配器对象
* @param listener 加载完成监听器
*/
public void setLoadMoreAdapter(final LoadMoreAdapter adapter, final OnLoadMoreListener listener) {
mAdapter = adapter;
super.setAdapter(adapter);
// 添加滚动事件监听
super.setOnScrollListener(new OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
// 滚动停止时的监听事件
if (scrollState == SCROLL_STATE_IDLE) {
if (getLastVisiblePosition() == getAdapter().getCount() - 1) { // 已经滑到底部了
if (mAdapter.getLoadState() == LoadMoreAdapter.STATE_NONE && !mIsLoading) { // 如果当前不在加载中,开始加载更多数据
mIsLoading = true;
mAdapter.setLoadState(LoadMoreAdapter.STATE_LOADING);
listener.onLoadMore();
}
}
}
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
}
});
}
/**
* 加载数据完成
*/
public void onLoadMoreCompleted() {
mIsLoading = false;
}
}
其中,onLoadMoreCompleted()方法,用于通知上拉加载完成。
5、编写OnLoadMoreListener
/**
* 加载更多监听器
*/
public interface OnLoadMoreListener {
/**
* 加载更多数据
*/
void onLoadMore();
}
6、在Activity中使用
`
public class MainActivity extends AppCompatActivity {
/**
* 数据列表
*/
private List<String> mDataList;
/**
* 数据适配器
*/
private ArrayAdapter<String> mAdapter;
/**
* ListView 对象
*/
private LoadMoreListView mListView;
/**
* 下拉刷新控件
*/
private SwipeRefreshLayout mRefreshLayout;
/**
* 加载完成监听器
*/
private LoadMoreListView.OnLoadMoreListener mLoadMoreListener = new LoadMoreListView.OnLoadMoreListener() {
@Override
public void onLoadMore() {
// 模拟网络请求
new Handler().postDelayed(new Runnable() {
@Override
public void run()
