Android请求数据时,有时网络返回数据会是分页显示,所有就需要我们去分页显示,例如下面的例子,一个收支明细详情,网络端返回是每页20条数据。主要就是继承OnScrollListener方法,然后就会实现onScrollStateChanged、onScroll两种方法,在数据集最后一项的索引,再去加载数据。设置两个boolean变量,根据每页的条数去判断是否更新页码继续加载,要注意的是初始化时将footerView加上。
代码如下:
ListFooterView类:
public class ListFooterView {
public View v;
View layoutLoading;
RelativeLayout layoutAtBottom;
View layoutLoadFailed;
View btnReload;
TextView textAtBottom;
LoadingRetryCallback reloadCallback;
FrameLayout frla;
public ListFooterView(View _v){
v = _v;
layoutLoading =v.findViewById(R.id.layout_loading);
layoutAtBottom = (RelativeLayout)v.findViewById(R.id.layout_at_bottom);
frla = (FrameLayout)v.findViewById(R.id.frla);
layoutLoadFailed =v.findViewById(R.id.layout_load_failed);
btnReload = v.findViewById(R.id.btn_reload);
btnReload.setOnClickListener(reloadListener);
textAtBottom = (TextView)v.findViewById(R.id.text_at_bottom);
showLoading();
}
public void setReloadCallback(LoadingRetryCallback _callback){
reloadCallback = _callback;
}
View.OnClickListener reloadListener =new View.OnClickListener() {
@Override
public void onClick(View v) {
if (reloadCallback !=null){
reloadCallback.retry();
}
}
};
public void setAtBottomText(String t){
textAtBottom.setText(t);
}
public void showLoading(){
layoutLoading.setVisibility(View.VISIBLE);
layoutAtBottom.setVisibility(View.INVISIBLE);
layoutLoadFailed.setVisibility(View.INVISIBLE);
}
public void showAtBottom(){
layoutLoading.setVisibility(View.INVISIBLE);
layoutAtBottom.setVisibility(View.VISIBLE);
layoutLoadFailed.setVisibility(View.INVISIBLE);
}
public void showLoadFailed(){
layoutLoading.setVisibility(View.INVISIBLE);
layoutAtBottom.setVisibility(View.INVISIBLE);
layoutLoadFailed.setVisibility(View.VISIBLE);
}
}
footer_loadmore.xml布局文件:
<?xmlversion="1.0"encoding="utf-8"?>
<FrameLayoutxmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/frla"
>
<RelativeLayout
android:id="@+id/layout_loading"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<ProgressBar
android:id="@+id/progressBar1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"/>
</RelativeLayout>
<RelativeLayout
android:id="@+id/layout_at_bottom"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<TextView
android:clickable="true"
android:id="@+id/text_at_bottom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
/>
</RelativeLayout>
<RelativeLayout
android:id="@+id/layout_load_failed"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toLeftOf="@+id/btn_reload"
android:text="加载失败……"/>
<TextView
android:id="@+id/btn_reload"
android:layout_width="70dp"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_alignParentRight="true"
android:layout_marginRight="30dp"
android:layout_marginLeft="30dp"
android:text="重试"/>
</RelativeLayout>
</FrameLayout>
所用到下拉分页的fragment:
public class IncomeFragment extends Fragment implements OnScrollListener{
ListFooterView footerView;
String tagId;
String searchKeywords;
private View view;
private ListView income_listview;
private LayoutInflater inflater;
private OrderAdapter adapter;
private MyApp myApp;
private SharedPreferences sp;
private String agent_member_id;
private String check_code;
private int i;
int pageIndex = 1;
int pageNumber = 20;
int totalResult;
boolean isLoading = false;
boolean noMoreData = false;
private int visibleLastIndex = 0; // 最后的可视项索引
private int visibleItemCount; // 当前窗口可见项总数
private String token;
boolean isClear =false;
private List<NewAccountBean> list = new ArrayList<NewAccountBean>();
private List<NewAccountBean> templist = new ArrayList<NewAccountBean>();
NewAccountBean newAccountBean;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle args = getArguments();
i = (Integer) args.get("title");
adapter = new OrderAdapter();
inflater = LayoutInflater.from(getActivity());
View fv = inflater.inflate(R.layout.footer_loadmore, null);
footerView = new ListFooterView(fv);
}
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
view = inflater.inflate(R.layout.fragment_income_order, null);
initView();
return view;
}
private void initView() {
income_listview = (ListView) view
.findViewById(R.id.income_listview);
footerView.setReloadCallback(new LoadingRetryCallback() {
@Override
public void retry() {
loadingMore();
}
});
income_listview.addFooterView(footerView.v, null, false);
income_listview.setAdapter(adapter);
income_listview.setOnScrollListener(this);
income_listview.setFocusable(false);
myApp = (MyApp) getActivity().getApplicationContext();
sp = myApp.getMustElement();
token = myApp.getToken();
income_listview.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
}
});
loadingMore();
}
private void loadingMore() {
if (!isLoading && !noMoreData) {
isLoading = true;
if (i == 0) {
MyNet.Inst().accountInfo(getActivity(), token,"",callback);
isClear =true;
} else if (i == 1) {
MyNet.Inst().accountInfo(getActivity(), token,"1",callback);
isClear =true;
} else {
MyNet.Inst().accountInfo(getActivity(), token,"2",callback);
isClear =true;
}
}
}
ApiCallback callback = new ApiCallback() {
@Override
public void onDataSuccess(JSONObject data) {
if(isClear){
list.clear();
}
list.addAll(JSON.parseArray(data.getString("data"), NewAccountBean.class));
adapter.notifyDataSetChanged();
if ( (pageIndex == 1 && totalResult < pageNumber)|| (pageIndex == 1 && totalResult == pageNumber)) {
noMoreData = true;
if (adapter.getCount() == 0) {
if (i == 0) {
footerView.setAtBottomText("抱歉,您还没有收支明细!");
}else if (i == 1) {
footerView.setAtBottomText("抱歉,没有收入!");
}else {
footerView.setAtBottomText("抱歉,没有支出单!");
}
} else {
footerView.setAtBottomText("到底拉~");
}
footerView.showAtBottom();
}
pageIndex++;
isLoading = false;
}
@Override
public void onDataError(JSONObject data) {
isLoading = false;
footerView.showLoadFailed();
}
@Override
public void onNetError(String data) {
AlertHelper.createAlertConfirm(getActivity(), "提示",data).show();
}
};
public class OrderAdapter extends BaseAdapter {
@Override
public int getCount() {
return list.size();
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return list.get(position);
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
private void fillHolder(ViewHolder h, View v) {
h.update_date = (TextView) v.findViewById(R.id.update_date);
h.account = (TextView) v.findViewById(R.id.account);
h.allaccount = (TextView) v.findViewById(R.id.allaccount);
h.account_type = (TextView) v.findViewById(R.id.account_type);
}
@Override
public View getView(final int position, View convertView,
ViewGroup parent) {
// TODO Auto-generated method stub
ViewHolder holder;
if (convertView == null) {
if (i == 0) {
convertView = inflater.inflate(R.layout.fragment_incomeall_item,
null);
} else if (i == 1) {
convertView = inflater.inflate(R.layout.fragment_incomeincome_item,
null);
} else {
convertView = inflater.inflate(R.layout.fragment_incomedeposit_item,
null);
}
holder = new ViewHolder();
fillHolder(holder, convertView);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.account .setText(list.get(position).getAccount());
holder.account_type .setText(list.get(position).getAccount_type());
holder.update_date .setText(list.get(position).getOperation_date().substring(0, 10));
holder.allaccount .setText(list.get(position).getOperation_date().substring(11, 19));
return convertView;
}
protected void setResult(int resultOk, Intent intent) {
// TODO Auto-generated method stub
}
class ViewHolder {
TextView update_date;
TextView account,account_type;
TextView allaccount;
}
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
this.visibleItemCount = visibleItemCount;
visibleLastIndex = firstVisibleItem + visibleItemCount - 1;
}
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
int itemsLastIndex = adapter.getCount(); // 数据集最后一项的索引
if (scrollState == OnScrollListener.SCROLL_STATE_IDLE
&& visibleLastIndex == itemsLastIndex) {
// 如果是自动加载,可以在这里放置异步加载数据的代码
loadingMore();
}
}
}
效果图如下,下载分页的数据: