package org.aisen.android.ui.fragment;
import android.app.Activity;
import android.app.Fragment;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import org.aisen.android.R;
import org.aisen.android.common.utils.Logger;
import org.aisen.android.common.utils.ViewUtils;
import org.aisen.android.component.bitmaploader.BitmapLoader;
import org.aisen.android.component.bitmaploader.core.BitmapOwner;
import org.aisen.android.network.biz.ABizLogic.CacheMode;
import org.aisen.android.network.biz.IResult;
import org.aisen.android.network.task.ITaskManager;
import org.aisen.android.network.task.TaskException;
import org.aisen.android.network.task.TaskManager;
import org.aisen.android.network.task.WorkTask;
import org.aisen.android.support.inject.InjectUtility;
import org.aisen.android.support.inject.ViewInject;
import org.aisen.android.ui.activity.basic.BaseActivity;
import java.text.SimpleDateFormat;
/**
* 基于ABaseFragment,维护与Activity之间的生命周期绑定,管理WorkTask线程,支持四种个基本视图之间的自动切换<br/>
*
* 1、处理缓存数据过期后,自动刷新页面<br/>
* 2、处理页面离开设定时间后,自动刷新页面<br/>
*
*/
public abstract class ABaseFragment extends Fragment implements ITaskManager, BitmapOwner {
static final String TAG = "AFragment-Base";
public enum ABaseTaskState {
none, prepare, falid, success, finished, canceled
}
private TaskManager taskManager;// 管理线程
ViewGroup rootView;// 根视图
@ViewInject(idStr = "layoutLoading")
View loadingLayout;// 加载中视图
@ViewInject(idStr = "layoutLoadFailed")
View loadFailureLayout;// 加载失败视图
@ViewInject(idStr = "layoutContent")
View contentLayout;// 内容视图
@ViewInject(idStr = "layoutEmpty")
View emptyLayout;// 空视图
// 标志是否ContentView是否为空
private boolean contentEmpty = true;
protected long lastResultGetTime = 0;// 最后一次非缓存数据获取时间
private boolean destory = false;
// UI线程的Handler
Handler mHandler = new Handler(Looper.getMainLooper()) {
};
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
if (activity instanceof BaseActivity)
((BaseActivity) activity).addFragment(toString(), this);
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
taskManager = new TaskManager();
if (savedInstanceState != null)
taskManager.restore(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
if (inflateContentView() > 0) {
ViewGroup contentView = (ViewGroup) inflater.inflate(inflateContentView(), null);
contentView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT));
setupContentView(inflater, contentView, savedInstanceState);
return getContentView();
}
return super.onCreateView(inflater, container, savedInstanceState);
}
/**
* 根据ContentView初始化视图
*
* @param inflater
* @param contentView
* @param savedInstanceState
*/
protected void setupContentView(LayoutInflater inflater, ViewGroup contentView, Bundle savedInstanceState) {
setContentView(contentView);
_layoutInit(inflater, savedInstanceState);
layoutInit(inflater, savedInstanceState);
}
public void setContentView(ViewGroup view) {
this.rootView = view;
}
/**
* 根视图
*
* @return
*/
public ViewGroup getContentView() {
return rootView;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if (savedInstanceState == null)
requestData();
}
/**
* Action的home被点击了
*
* @return
*/
public boolean onHomeClick() {
return onBackClick();
}
/**
* 返回按键被点击了
*
* @return
*/
public boolean onBackClick() {
return false;
}
/**
* 初次创建时默认会调用一次
*/
public void requestData() {
}
/**
* 延迟时间刷新
*
* @param delay
*/
public void requestDataDelay(long delay) {
Runnable requestDelayRunnable = new Runnable() {
@Override
public void run() {
Logger.d(TAG, "延迟刷新,开始刷新, " + toString());
requestData();
}
};
runUIRunnable(requestDelayRunnable, delay);
}
public void requestDataOutofdate() {
requestData();
}
/**
* A*Fragment重写这个方法
*
* @param inflater
* @param savedInstanceSate
*/
void _layoutInit(LayoutInflater inflater, Bundle savedInstanceSate) {
InjectUtility.initInjectedView(getActivity(), this, getContentView());
if (emptyLayout != null) {
View reloadView = emptyLayout.findViewById(R.id.layoutReload);
if (reloadView != null)
setViewOnClick(reloadView);
}
if (loadFailureLayout != null) {
View reloadView = loadFailureLayout.findViewById(R.id.layoutReload);
if (reloadView != null)
setViewOnClick(reloadView);
}
setViewVisiable(loadingLayout, View.GONE);
setViewVisiable(loadFailureLayout, View.GONE);
setViewVisiable(emptyLayout, View.GONE);
if (isContentEmpty()) {
// 如果视图为空,就开始加载数据
if (savedInstanceSate != null) {
requestData();
}
else {
setViewVisiable(emptyLayout, View.VISIBLE);
setViewVisiable(contentLayout, View.GONE);
}
}
else {
setViewVisiable(contentLayout, View.VISIBLE);
}
}
public View findViewById(int viewId) {
if (getContentView() == null)
return null;
return getContentView().findViewById(viewId);
}
public void setContentEmpty(boolean empty) {
this.contentEmpty = empty;
}
public boolean isContentEmpty() {
return contentEmpty;
}
/**
* 视图点击回调,子类重写
*
* @param view
*/
public void onViewClicked(View view) {
if (view.getId() == R.id.layoutReload)
requestData();
else if (view.getId() == R.id.layoutRefresh)
requestData();
}
protected void setViewVisiable(View v, int visibility) {
if (v != null && v.getVisibility() != visibility)
v.setVisibility(visibility);
}
/**
* 根据{@link ABaseTask} 的加载状态,刷新视图
*
* @param state
*
* @param exception
*/
protected void onTaskStateChanged(ABaseTaskState state, TaskException exception) {
// 开始Task
if (state == ABaseTaskState.prepare) {
if (isContentEmpty()) {
setViewVisiable(loadingLayout, View.VISIBLE);
setViewVisiable(contentLayout, View.GONE);
}
else {
setViewVisiable(loadingLayout, View.GONE);
setViewVisiable(contentLayout, View.VISIBLE);
}
setViewVisiable(emptyLayout, View.GONE);
if (isContentEmpty() && loadingLayout == null) {
setViewVisiable(contentLayout, View.VISIBLE);
}
setViewVisiable(loadFailureLayout, View.GONE);
}
// Task成功
else if (state == ABaseTaskState.success) {
setViewVisiable(loadingLayout, View.GONE);
if (isContentEmpty()) {
setViewVisiable(emptyLayout, View.VISIBLE);
setViewVisiable(contentLayout, View.GONE);
}
else {
setViewVisiable(contentLayout, View.VISIBLE);
setViewVisiable(emptyLayout, View.GONE);
}
}
// 取消Task
else if (state == ABaseTaskState.canceled) {
if (isContentEmpty()) {
setViewVisiable(loadingLayout, View.GONE);
setViewVisiable(emptyLayout, View.VISIBLE);
}
}
// Task失败
else if (state == ABaseTaskState.falid) {
if (isContentEmpty()) {
if (loadFailureLayout != null) {
setViewVisiable(loadFailureLayout, View.VISIBLE);
if (exception != null) {
TextView txtLoadFailed = (TextView) loadFailureLayout.findViewById(R.id.txtLoadFailed);
if (txtLoadFailed != null)
txtLoadFailed.setText(exception.getMessage());
}
setViewVisiable(emptyLayout, View.GONE);
} else {
setViewVisiable(emptyLayout, View.VISIBLE);
}
setViewVisiable(loadingLayout, View.GONE);
}
}
// Task结束
else if (state == ABaseTaskState.finished) {
}
}
public void showMessage(CharSequence msg) {
if (!TextUtils.isEmpty(msg) && getActivity() != null)
ViewUtils.showMessage(getActivity(), msg.toString());
}
public void showMessage(int msgId) {
if (getActivity() != null)
showMessage(getString(msgId));
}
/**
* Fragment主要的刷新任务线程,定义任务加载流程,耦合Fragment各个状态下的视图刷新方法
*
* @param <Params>
* @param <Progress>
* @param <Result>
*/
protected abstract class ABaseTask<Params, Progress, Result> extends WorkTask<Params, Progress, Result> {
public ABaseTask(String taskId) {
super(taskId, ABaseFragment.this);
}
@Override
protected void onPrepare() {
super.onPrepare();
onTaskStateChanged(ABaseTaskState.prepare, null);
}
@Override
protected void onSuccess(Result result) {
super.onSuccess(result);
// 默认加载数据成功,且ContentView有数据展示
ABaseFragment.this.setContentEmpty(resultIsEmpty(result));
onTaskStateChanged(ABaseTaskState.success, null);
if (Logger.DEBUG)
Logger.d(TAG, "Result获取时间:%s", new SimpleDateFormat("HH:mm:ss").format(lastResultGetTime));
if (result instanceof IResult) {
IResult iResult = (IResult) result;
// 数据是缓存数据
if (iResult.fromCache()) {
// 缓存过期刷新数据
if (iResult.outofdate()) {
runUIRunnable(new Runnable() {
@Override
public void run() {
Logger.d(TAG, "数据过期,开始刷新, " + toString());
requestDataOutofdate();
}
}, configRequestDelay());
}
} else {
lastResultGetTime = System.currentTimeMillis();
}
} else {
lastResultGetTime = System.currentTimeMillis();
}
}
@Override
protected void onFailure(TaskException exception) {
super.onFailure(exception);
onTaskStateChanged(ABaseTaskState.falid, exception);
}
@Override
protected void onCancelled() {
super.onCancelled();
onTaskStateChanged(ABaseTaskState.canceled, null);
}
@Override
protected void onFinished() {
super.onFinished();
onTaskStateChanged(ABaseTaskState.finished, null);
}
/**
* 返回数据是否空
*
* @param result
* @return
*/
protected boolean resultIsEmpty(Result result) {
return result == null ? true : false;
}
}
@Override
public void onDestroy() {
destory = true;
try {
// 4.1.1必报错,不知道为什么
super.onDestroy();
} catch (Exception e) {
Logger.printExc(getClass(), e);
}
removeAllTask(true);
if (BitmapLoader.getInstance() != null)
BitmapLoader.getInstance().cancelPotentialTask(this);
}
public boolean isDestory() {
return destory;
}
public boolean isActivityRunning() {
return getActivity() != null;
}
@Override
public void onDetach() {
super.onDetach();
if (getActivity() != null && getActivity() instanceof BaseActivity)
((BaseActivity) getActivity()).removeFragment(this.toString());
}
@Override
final public void addTask(@SuppressWarnings("rawtypes") WorkTask task) {
taskManager.addTask(task);
}
@Override
final public void removeTask(String taskId, boolean cancelIfRunning) {
taskManager.removeTask(taskId, cancelIfRunning);
}
@Override
final public void removeAllTask(boolean cancelIfRunning) {
taskManager.removeAllTask(cancelIfRunning);
}
@Override
final public int getTaskCount(String taskId) {
return taskManager.getTaskCount(taskId);
}
/**
* 初步定义,当Task执行BizLogic方法时,第一次创建时拉取缓存,其他都只拉取网络
*
* @param task
* @return
*/
final protected CacheMode getTaskCacheMode(WorkTask task) {
if (task == null || !TextUtils.isEmpty(task.getTaskId()))
return getTaskCount(task.getTaskId()) == 1 ? CacheMode.auto : CacheMode.disable;
return CacheMode.disable;
}
@Override
public void clearTaskCount(String taskId) {
taskManager.clearTaskCount(taskId);
}
protected void setViewOnClick(View v) {
if (v == null)
return;
v.setOnClickListener(innerOnClickListener);
}
View.OnClickListener innerOnClickListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
onViewClicked(v);
}
};
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
if (taskManager != null)
taskManager.save(outState);
}
protected ITaskManager getTaskManager() {
return taskManager;
}
public void runUIRunnable(Runnable runnable) {
runUIRunnable(runnable, 0);
}
public void runUIRunnable(Runnable runnable, long delay) {
if (delay > 0) {
mHandler.removeCallbacks(runnable);
mHandler.postDelayed(runnable, delay);
}
else {
mHandler.post(runnable);
}
}
/**
* 子类重写这个方法,初始化视图
*
* @param inflater
* @param savedInstanceSate
*/
protected void layoutInit(LayoutInflater inflater, Bundle savedInstanceSate) {
}
/**
* 是否显示图片接口实现
*/
@Override
public boolean canDisplay() {
return true;
}
/**
* 指定Fragment的LayoutID
*
* @return
*/
abstract public int inflateContentView();
/**
* 指定Activity的ContentViewID
*
* @return
*/
public int inflateActivityContentView() {
return -1;
}
/**
* 设置Activity的Theme
*
* @return
*/
public int setActivityTheme() {
return -1;
}
public int configRequestDelay() {
return 500;
}
public View getLoadingLayout() {
return loadingLayout;
}
public View getLoadFailureLayout() {
return loadFailureLayout;
}
public View getContentLayout() {
return contentLayout;
}
public View getEmptyLayout() {
return emptyLayout;
}
}