package com.dh.foundation.widget.netlistview;
import android.accounts.NetworkErrorException;
import android.content.Context;
import android.view.View;
import android.widget.AbsListView;
import android.widget.ListView;
import com.dh.foundation.adapter.NetListViewBaseAdapter;
import com.dh.foundation.exception.DhRequestError;
import com.dh.foundation.utils.AutoPrintHttpNetUtils;
import com.dh.foundation.utils.DLoggerUtils;
import com.dh.foundation.utils.HttpNetUtils;
import com.dh.foundation.utils.NetWorkDetector;
import com.dh.foundation.utils.NumUtils;
import com.dh.foundation.utils.ProgressDialogUtil;
import com.dh.foundation.utils.ReflectUtils;
import com.dh.foundation.utils.RequestParams;
import com.dh.foundation.utils.ToastUtils;
import com.google.gson.internal.$Gson$Types;
import java.lang.ref.WeakReference;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
/**
* 网络请求列表委托者
* Created by Seal.Wu
* On :2015.09.28
*/
class NetListViewDelegate implements NLVCommonInterface {
private final ListView listView;
private final Context context;
private List<Object> list;//数据列表
private NetListViewBaseAdapter adapter;//专用适配器
private RequestParams params;//参数
private boolean loadMoreAble;
private View loadMoreView;//加载更多提示控件
private String pageName;//分页名称
private String baseAddress;
private int pageNo = 0;//请求服务器数据的页码
private int startPageNo;//分页功能起始页码
private NLVCommonInterface.LoadMoreAbleListener<Object> loadMoreAbleListener;//扩展接口,是否可加载更多自定义使能
private NLVCommonInterface.OnLoadFinishListener<Object> onLoadFinishListener;
private NLVCommonInterface.OnLoadStartListener onLoadStartListener;//刚开始加载监听器
private boolean isLoadOkToast = true;//加载全部是否进行提示
private boolean isNetErrorToast = true;//是否出错提示
private boolean isShowProgressDialog = true;
private boolean refreshing = true;//是否正在刷新,第一次加载默认当刷新
/**
* 数据为空指示view
*/
private int emptyViewId;
private View emptyView;
private View netErrorView;
/**
* 网络请求出错提示viewId
*/
private int netErrorViewId;
private AbsListView.OnScrollListener onScrollListener;
/**
* 妥协处理,泛型仅用于交互
*/
private HttpNetUtils.RequestListener<Object> listener;
private static class RequestListener extends HttpNetUtils.RequestListener<Object> {
private boolean isLoadSuccess = true;
private Throwable error;
private Object returnData;
private WeakReference<NetListViewDelegate> weakReference;
public RequestListener(NetListViewDelegate netListViewDelegate) {
this.weakReference = new WeakReference<NetListViewDelegate>(netListViewDelegate);
}
@Override
public void onSuccess(Object t) {
isLoadSuccess = true;
returnData = t;
final NetListViewDelegate netListViewDelegate = weakReference.get();
if (netListViewDelegate == null) {
return;
}
if (netListViewDelegate.loadMoreAbleListener == null) {
return;
}
if (netListViewDelegate.netErrorView != null) {
netListViewDelegate.netErrorView.setVisibility(View.GONE);
}
final List<?> fetchedData = netListViewDelegate.loadMoreAbleListener.getLoadedData(t);
if (netListViewDelegate.refreshing) {
netListViewDelegate.list.clear();//如果此次请求是刷新动作,则先清空数据
}
if (fetchedData != null) {
netListViewDelegate.list.addAll(fetchedData);
}
netListViewDelegate.setLoadMoreAble(t, fetchedData);
if (!netListViewDelegate.loadMoreAble && netListViewDelegate.isLoadOkToast) {
ToastUtils.toast("已全部加载");
}
}
@Override
public void onFailed(Throwable throwable) {
isLoadSuccess = false;
this.error = throwable;
final NetListViewDelegate netListViewDelegate = weakReference.get();
if (netListViewDelegate != null) {
netListViewDelegate.loadMoreFailedReset();
if (netListViewDelegate.netErrorView != null && netListViewDelegate.list.isEmpty()) {
netListViewDelegate.netErrorView.setVisibility(View.VISIBLE);
if (netListViewDelegate.listView.getEmptyView() != null) {
netListViewDelegate.listView.getEmptyView().setVisibility(View.GONE);
}
}
if (netListViewDelegate.isNetErrorToast) {
final String message = throwable.getCause().getMessage();
ToastUtils.toast(message);
}
}
}
@Override
public void onFinished() {
final NetListViewDelegate netListViewDelegate = weakReference.get();
if (netListViewDelegate != null) {
if (netListViewDelegate.onLoadFinishListener != null) {
netListViewDelegate.onLoadFinishListener.onLoadFinished(netListViewDelegate.refreshing, isLoadSuccess, returnData, error);
}
netListViewDelegate.listView.removeFooterView(netListViewDelegate.loadMoreView);
if (isLoadSuccess) {
netListViewDelegate.adapter.notifyDataSetChanged();
}
netListViewDelegate.refreshing = false;
}
ProgressDialogUtil.dismissProgressDialog();
}
}
public NetListViewDelegate(ListView listView) {
this.listView = listView;
this.context = listView.getContext();
this.listener = new RequestListener(this);
}
public void setLoadMoreView(View loadMoreView) {
this.loadMoreView = loadMoreView;
}
@Override
public void setEmptyViewId(int emptyViewId) {
this.emptyViewId = emptyViewId;
if (this.emptyViewId != 0) {
final View emptyView = listView.getRootView().findViewById(emptyViewId);
this.emptyView = emptyView;
if (emptyView != null) {
emptyView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
emptyView.setVisibility(View.GONE);
refreshData();
}
});
listView.setEmptyView(emptyView);
emptyView.setVisibility(View.GONE);
}
}
}
@Override
public void setNetErrorViewId(int netErrorViewId) {
this.netErrorViewId = netErrorViewId;
if (this.netErrorViewId != 0) {
final View netErrorView = listView.getRootView().findViewById(netErrorViewId);
this.netErrorView = listView.getRootView().findViewById(netErrorViewId);
if (netErrorView != null) {
netErrorView.setVisibility(View.GONE);
netErrorView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
netErrorView.setVisibility(View.GONE);
refreshData();
}
});
}
}
}
@Override
public View getNetErrorView() {
return netErrorView;
}
/**
* 加载全部是否进行提示
*/
public void setLoadOkToast(boolean isLoadOkToast) {
this.isLoadOkToast = isLoadOkToast;
}
@Override
public void setNetErrorToast(boolean isNetErrorToast) {
this.isNetErrorToast = isNetErrorToast;
}
/**
* 设置是否展示等待对话框
*/
public void setIsShowProgressDialog(boolean isShowProgressDialog) {
this.isShowProgressDialog = isShowProgressDialog;
}
public boolean isShowProgressDialog() {
return isShowProgressDialog;
}
/**
* 设置自定义加载更多使能
*/
public void setLoadMoreAbleListener(NLVCommonInterface.LoadMoreAbleListener loadMoreAbleListener) {
this.loadMoreAbleListener = loadMoreAbleListener;
}
/**
* 设置自加载完成监听器
*/
public void setOnLoadFinishListener(NLVCommonInterface.OnLoadFinishListener onLoadFinishListener) {
this.onLoadFinishListener = onLoadFinishListener;
}
@Override
public void setOnLoadStartListener(OnLoadStartListener onLoadStartListener) {
this.onLoadStartListener = onLoadStartListener;
}
public void setOnScrollListener(AbsListView.OnScrollListener onScrollListener) {
this.onScrollListener = onScrollListener;
}
/**
* 获取当前分页页码
*/
public int getPageNo() {
return pageNo;
}
/**
* 初始化网络处理功能ListView
*
* @param params 参数
* @param adapter 专用适配器
* @param pageName 页码名称
*/
public void initNetListView(String baseAddress, RequestParams params, final NetListViewBaseAdapter adapter, String pageName) {
View emptyView = null;
if (emptyViewId != 0) {
emptyView = listView.getRootView().findViewById(emptyViewId);
}
initNetListView(baseAddress, params, adapter, pageName, emptyView);
}
/**
* 初始化网络处理功能ListView
*
* @param params 参数
* @param adapter 专用适配器
* @param pageName 页码名称
* @param emptyView 当无数据时指定显示的view
*/
public void initNetListView(String baseAddress, RequestParams params, final NetListViewBaseAdapter adapter, String pageName, final View emptyView) {
this.baseAddress = baseAddress;
this.params = params == null ? new RequestParams() : params;
this.adapter = adapter;
this.list = new ArrayList<>();
this.pageName = pageName == null ? "" : pageName;
if (params != null) {
if (params.isRestStyle()) {
Object paramObj = params.getParamsObj();
Field field = ReflectUtils.getDeclaredField(paramObj.getClass(), pageName);
if (field != null) {
field.setAccessible(true);
try {
startPageNo = pageNo = field.getInt(paramObj);
} catch (IllegalAccessException e) {
DLoggerUtils.e(e);
}
}
} else {
String page = (String) this.params.getParams().get(pageName);
if (NumUtils.isInteger(page)) {
startPageNo = pageNo = Integer.valueOf(page);
}
}
}
this.adapter.setList(list);
listView.addFooterView(loadMoreView);
listView.setAdapter(adapter);
listView.removeFooterView(loadMoreView);
if (listView instanceof SuperScrollListenerSetter) {
((SuperScrollListenerSetter) listView).setSuperOnScrollListener(new AbsListView.OnScrollListener() {
private int lastVisibleItem;
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
if (scrollState == SCROLL_STATE_IDLE && lastVisibleItem == adapter.getCount() + listView.getHeaderViewsCount() + listView.getFooterViewsCount() - 1 && loadMoreAble) {
loadMore();
}
if (onScrollListener != null) {
onScrollListener.onScrollStateChanged(view, scrollState);
}
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
lastVisibleItem = firstVisibleItem + visibleItemCount - 1;
if (onScrollListener != null) {
onScrollListener.onScroll(view, firstVisibleItem, visibleItemCount, totalItemCount);
}
}
});
}
if (emptyView != null) {
emptyView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
emptyView.setVisibility(View.GONE);
refreshData();
}
});
listView.setEmptyView(emptyView);
emptyView.setVisibility(View.GONE);
}
getData();
}
/**
* 刷新数据
*/
public void refreshData() {
refreshing = true;
pageNo = startPageNo;
getData();
}
/**
* 请求网络数据
*/
public void getData() {
if (onLoadStartListener != null) {
onLoadStartListener.onLoadStart(refreshing);
}
if (isNetStateUnavailable(listener)) {
return;
}
ProgressDialogUtil.showProgressDialog(context);
if (params.isRestStyle()) {
Object paramObj = params.getParamsObj();
Field field = ReflectUtils.getDeclaredField(paramObj.getClass(), pageName);
if (field != null) {
field.setAccessible(true);
try {
field.setInt(paramObj, pageNo);
} catch (IllegalAccessException e) {
DLoggerUtils.e(e);
}
}
} else {
params.setParams(pageName, pageNo + "");
}
if (params.isRestStyle()) {
AutoPrintHttpNetUtils.postData(baseAddress, params, getSuperclassTypeParameter(adapter.getClass()), listener).setTag(listView.hashCode());
} else {
AutoPrintHttpNetUtils.getData(baseAddress, params, getSuperclassTypeParameter(adapter.getClass()), listener).setTag(listView.hashCode());
}
if (pageNo != startPageNo || !isShowProgressDialog()) {//代表在刷新,仅仅刷新的时候显示等待进度条
ProgressDialogUtil.dismissProgressDialog();
}
}
/**
* 加载更多
*/
public void loadMore() {
loadMoreAble = false;//不能重复加载直到此次加载完毕
pageNo++;
listView.addFooterView(loadMoreView);
listView.setSelection(listView.getBottom());
getData();
}
/**
* 加载更多失败时恢复加载更多之前参数值配置
*/
public void loadMoreFailedReset() {
if (pageNo != startPageNo) {
pageNo--;
loadMoreAble = true;
}
}
/**
* 设置是否可以加载更多
*
* @param t 网络请求返回对象
* @param invoke 数据列表
*/
private void setLoadMoreAble(Object t, List<?> invoke) {
loadMoreAble = loadMoreAbleListener.isLoadMoreAble(t, invoke);
}
/**
* Returns the type from super class's type parameter in {@link $Gson$Types#canonicalize
* canonical form}.
*/
private Type getSuperclassTypeParameter(Class<?> subclass) {
Type superclass = subclass.getGenericSuperclass();
if (superclass instanceof Class) {
throw new RuntimeException("Missing type parameter.");
}
ParameterizedType parameterized = (ParameterizedType) superclass;
return $Gson$Types.canonicalize(parameterized.getActualTypeArguments()[0]);
}
/**
* 网络状态是否不可用
*/
private <T> boolean isNetStateUnavailable(final HttpNetUtils.RequestListener<T> requestListener) {
if (!NetWorkDetector.isNetConnected()) {
listView.post(new Runnable() {
@Override
public void run() {
if (requestListener != null) {
requestListener.onFailed(new DhRequestError(new NetworkErrorException("无可用网络请检查网络设置")));
requestListener.onFinished();
}
}
});
return true;
}
return false;
}
}