优化了性能并修复了一些bug
This commit is contained in:
@@ -5,7 +5,7 @@ android {
|
||||
buildToolsVersion "23.0.3"
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion 15
|
||||
minSdkVersion 14
|
||||
targetSdkVersion 22
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
|
||||
@@ -32,7 +32,7 @@ public class FragmentTabAdapter implements OnCheckedChangeListener {
|
||||
// 默认显示第一页
|
||||
FragmentTransaction ft = fragmentActivity.getSupportFragmentManager()
|
||||
.beginTransaction();
|
||||
ft.add(fragmentContentId, fragments.get(currentTab));
|
||||
ft.add(fragmentContentId, fragments.get(currentTab),String.valueOf(currentTab));
|
||||
ft.commitAllowingStateLoss();
|
||||
if (rg != null) {
|
||||
rg.setOnCheckedChangeListener(this);
|
||||
@@ -74,7 +74,7 @@ public class FragmentTabAdapter implements OnCheckedChangeListener {
|
||||
fragment.onResume(); // 启动目标tab的onResume()
|
||||
}
|
||||
} else {
|
||||
ft.add(fragmentContentId, fragment);
|
||||
ft.add(fragmentContentId, fragment,String.valueOf(currentTab));
|
||||
}
|
||||
showTab(i); // 显示目标tab
|
||||
ft.commitAllowingStateLoss();
|
||||
|
||||
@@ -11,48 +11,50 @@ import com.kejiang.yuandl.adapter.common.ViewHolder;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public abstract class CommonAdapter<T> extends BaseAdapter
|
||||
{
|
||||
protected Context mContext;
|
||||
protected List<T> mDatas;
|
||||
protected LayoutInflater mInflater;
|
||||
private int layoutId;
|
||||
public abstract class CommonAdapter<T> extends BaseAdapter {
|
||||
protected Context mContext;
|
||||
protected List<T> mDatas;
|
||||
protected LayoutInflater mInflater;
|
||||
private int layoutId;
|
||||
|
||||
public CommonAdapter(Context context,int layoutId, List<T> datas )
|
||||
{
|
||||
this.mContext = context;
|
||||
mInflater = LayoutInflater.from(context);
|
||||
this.mDatas = datas;
|
||||
this.layoutId = layoutId;
|
||||
}
|
||||
public CommonAdapter(Context context, int layoutId, List<T> datas) {
|
||||
this.mContext = context;
|
||||
mInflater = LayoutInflater.from(context);
|
||||
this.mDatas = datas;
|
||||
this.layoutId = layoutId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount()
|
||||
{
|
||||
return mDatas.size();
|
||||
}
|
||||
public void notifyDataSetChanged(List<T> datas) {
|
||||
this.mDatas = datas;
|
||||
this.notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public T getItem(int position)
|
||||
{
|
||||
return mDatas.get(position);
|
||||
}
|
||||
@Override
|
||||
public int getCount() {
|
||||
return mDatas==null?0:mDatas.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getItemId(int position)
|
||||
{
|
||||
return position;
|
||||
}
|
||||
public List<T> getDatas() {
|
||||
return mDatas;
|
||||
}
|
||||
@Override
|
||||
public T getItem(int position) {
|
||||
return mDatas.get(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView(int position, View convertView, ViewGroup parent)
|
||||
{
|
||||
ViewHolder holder = ViewHolder.get(mContext, convertView, parent,
|
||||
layoutId, position);
|
||||
convert(holder, getItem(position));
|
||||
return holder.getConvertView();
|
||||
}
|
||||
@Override
|
||||
public long getItemId(int position) {
|
||||
return position;
|
||||
}
|
||||
|
||||
public abstract void convert(ViewHolder holder, T t);
|
||||
@Override
|
||||
public View getView(int position, View convertView, ViewGroup parent) {
|
||||
ViewHolder holder = ViewHolder.get(mContext, convertView, parent,
|
||||
layoutId, position);
|
||||
convert(holder, getItem(position));
|
||||
return holder.getConvertView();
|
||||
}
|
||||
|
||||
public abstract void convert(ViewHolder holder, T t);
|
||||
|
||||
}
|
||||
|
||||
@@ -53,7 +53,10 @@ public abstract class CommonAdapter<T> extends RecyclerView.Adapter<ViewHolder>
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public void notifyDataSetChanged(List<T> datas) {
|
||||
this.mDatas = datas;
|
||||
this.notifyDataSetChanged();
|
||||
}
|
||||
|
||||
protected void setListener(final ViewGroup parent, final ViewHolder viewHolder, int viewType)
|
||||
{
|
||||
@@ -99,7 +102,7 @@ public abstract class CommonAdapter<T> extends RecyclerView.Adapter<ViewHolder>
|
||||
@Override
|
||||
public int getItemCount()
|
||||
{
|
||||
return mDatas.size();
|
||||
return mDatas==null?0:mDatas.size();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,21 +1,30 @@
|
||||
package com.kejiang.yuandl.base;
|
||||
|
||||
import android.app.Dialog;
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.Activity;
|
||||
import android.app.Application;
|
||||
import android.content.Context;
|
||||
import android.content.ContextWrapper;
|
||||
import android.content.Intent;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.IBinder;
|
||||
import android.os.Looper;
|
||||
import android.os.MessageQueue;
|
||||
import android.support.v4.util.ArrayMap;
|
||||
import android.util.Log;
|
||||
import android.util.TypedValue;
|
||||
import android.view.Gravity;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.Window;
|
||||
import android.view.ViewTreeObserver;
|
||||
import android.view.WindowManager;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.widget.EditText;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.GridView;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.ListView;
|
||||
@@ -30,6 +39,8 @@ import com.kejiang.yuandl.R;
|
||||
import com.kejiang.yuandl.bean.JsonBean;
|
||||
import com.kejiang.yuandl.utils.AppManager;
|
||||
import com.kejiang.yuandl.utils.CheckNetwork;
|
||||
import com.kejiang.yuandl.utils.Reflector;
|
||||
import com.kejiang.yuandl.utils.SharedPreferencesUtils;
|
||||
import com.kejiang.yuandl.utils.Tools;
|
||||
import com.kejiang.yuandl.view.LoadingDialog;
|
||||
import com.orhanobut.logger.Logger;
|
||||
@@ -38,13 +49,17 @@ import com.zhy.autolayout.utils.AutoUtils;
|
||||
|
||||
import org.xutils.common.Callback;
|
||||
import org.xutils.common.util.KeyValue;
|
||||
import org.xutils.common.util.MD5;
|
||||
import org.xutils.ex.HttpException;
|
||||
import org.xutils.http.RequestParams;
|
||||
import org.xutils.x;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* com.bm.falvzixun.activities.BaseActivity;
|
||||
@@ -60,7 +75,6 @@ public abstract class BaseActivity extends AutoLayoutActivity implements View.On
|
||||
private LinearLayout llRoot;
|
||||
private LinearLayout layout_titlebar;
|
||||
protected Context context;
|
||||
Dialog dialog;
|
||||
/**
|
||||
* 加载数据对话框
|
||||
*/
|
||||
@@ -120,6 +134,10 @@ public abstract class BaseActivity extends AutoLayoutActivity implements View.On
|
||||
}
|
||||
}
|
||||
|
||||
protected FrameLayout getContentLayout() {
|
||||
return mContentLayout;
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载 activity_title 布局 ,并获取标题及两侧按钮
|
||||
*/
|
||||
@@ -373,216 +391,251 @@ public abstract class BaseActivity extends AutoLayoutActivity implements View.On
|
||||
protected void startActivity(Class c) {
|
||||
startActivity(new Intent(context, c));
|
||||
}
|
||||
//
|
||||
// /**
|
||||
// * 异步网络请求类
|
||||
// *
|
||||
// * @param requestParams
|
||||
// */
|
||||
// protected void ajax(RequestParams requestParams) {
|
||||
// if (!CheckNetwork.isNetworkAvailable(context)) {
|
||||
// showToast("网络不可用,请检查网络连接!");
|
||||
// return;
|
||||
// }
|
||||
// if (loadingDialog == null) {
|
||||
// loadingDialog = new LoadingDialog(context);
|
||||
// }
|
||||
// if (requestParams != null) {
|
||||
// String uri = requestParams.getUri();
|
||||
// if (!uri.isEmpty()) {
|
||||
// String[] split = uri.split("/");
|
||||
//// Logger.d("split=" + Arrays.toString(split));
|
||||
//
|
||||
// String method = null;
|
||||
// try {
|
||||
// method = split[split.length - 1].substring(0, split[split.length - 1].indexOf("."));
|
||||
// } catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
// Logger.d("请检查服务器地址后面是否含有.html");
|
||||
// }
|
||||
// String mode = split[split.length - 2];
|
||||
// String sign = MD5.md5(mode + method);
|
||||
// requestParams.addBodyParameter("sign", sign);
|
||||
// }
|
||||
//
|
||||
// }
|
||||
// Logger.d("url=" + requestParams.getUri() + "\nrequestParams=" + requestParams.getStringParams().toString());
|
||||
// List<KeyValue> params = requestParams.getStringParams();
|
||||
// for (KeyValue keyValue : params) {
|
||||
// if (keyValue.key.contains(":")) {
|
||||
// throw new RuntimeException("参数异常!");
|
||||
// }
|
||||
// }
|
||||
// // jsonBean = JSON.parseObject(result, JsonBean.class);
|
||||
// cancelable = x.http().post(requestParams, new Callback.ProgressCallback<String>() {
|
||||
//
|
||||
// @Override
|
||||
// public void onWaiting() {
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
//
|
||||
// public void onStarted() {
|
||||
// netOnStart();
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void onLoading(long total, long current, boolean isDownloading) {
|
||||
// netOnLoading(total, current, isDownloading);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void onSuccess(String result) {
|
||||
//
|
||||
// Logger.json(result);
|
||||
// JsonBean jsonBean = null;
|
||||
// try {
|
||||
//// jsonBean = JSON.parseObject(result, JsonBean.class);
|
||||
// jsonBean = jsonParse(result);
|
||||
// if (jsonBean.getMsg() != null && !jsonBean.getMsg().isEmpty()) {
|
||||
// showToast(jsonBean.getMsg());
|
||||
// }
|
||||
// if (jsonBean.getCode() == 200) {
|
||||
// Map<String, Object> data = new ArrayMap<String, Object>();
|
||||
// if (null != jsonBean.getData() && jsonBean.getData().size() > 0) {
|
||||
// data = jsonBean.getData();
|
||||
// }
|
||||
// netOnSuccess(data);
|
||||
// } else {
|
||||
//
|
||||
// netOnOtherStates(jsonBean.getCode(), jsonBean.getMsg());
|
||||
// }
|
||||
// } catch (Exception e) {
|
||||
// if (loadingDialog != null && loadingDialog.isShowing()) {
|
||||
// loadingDialog.dismiss();
|
||||
// }
|
||||
// Logger.d(result);
|
||||
// showToast("服务器异常!");
|
||||
// e.printStackTrace();
|
||||
// } finally {
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void onError(Throwable ex, boolean isOnCallback) {
|
||||
// netOnFailure(ex);
|
||||
//
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void onCancelled(CancelledException cex) {
|
||||
// Logger.d("用户取消了访问网络....");
|
||||
// netOnCancelled();
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void onFinished() {
|
||||
// netOnFinish();
|
||||
// }
|
||||
//
|
||||
// });
|
||||
// }
|
||||
//
|
||||
//
|
||||
// private JsonBean jsonParse(String json) throws JSONException {
|
||||
// ArrayMap<String,Object> arrayMap= JSON.parseObject(json,new TypeReference<ArrayMap<String,Object>>(){
|
||||
// }.getType());
|
||||
// JsonBean jsonBean = new JsonBean();
|
||||
// if (arrayMap.containsKey("data")) {
|
||||
// Object data = arrayMap.get("data");
|
||||
|
||||
/**
|
||||
* 异步网络请求类
|
||||
*
|
||||
* @param requestParams
|
||||
*/
|
||||
protected void ajax(RequestParams requestParams) {
|
||||
ajax(requestParams, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 异步网络请求类
|
||||
*
|
||||
* @param requestParams
|
||||
* @param requestCode 区分不同的网络请求
|
||||
*/
|
||||
protected void ajax(RequestParams requestParams, int requestCode) {
|
||||
if (!CheckNetwork.isNetworkAvailable(context)) {
|
||||
showToast("网络不可用,请检查网络连接!");
|
||||
netOnFailure(new Exception("网络不可用"), requestCode);
|
||||
return;
|
||||
}
|
||||
if (loadingDialog == null) {
|
||||
loadingDialog = new LoadingDialog(context);
|
||||
}
|
||||
SharedPreferencesUtils sp = new SharedPreferencesUtils(x.app());
|
||||
boolean isLogin = (boolean) sp.getParam("login", false);
|
||||
if (isLogin) {
|
||||
requestParams.addBodyParameter("mId", (String) sp.getParam("mId", ""));
|
||||
}
|
||||
boolean hasLocation = (boolean) sp.getParam("hasLocation", false);
|
||||
if (hasLocation) {
|
||||
requestParams.addBodyParameter("lng", (String) sp.getParam("lng", ""));
|
||||
requestParams.addBodyParameter("lat", (String) sp.getParam("lat", ""));
|
||||
}
|
||||
Logger.d("url=" + requestParams.getUri() + "\nrequestParams=" + requestParams.getStringParams().toString());
|
||||
List<KeyValue> params = requestParams.getStringParams();
|
||||
for (KeyValue keyValue : params) {
|
||||
if (keyValue.key.contains(":")) {
|
||||
throw new RuntimeException("参数异常!");
|
||||
}
|
||||
}
|
||||
cancelable = x.http().post(requestParams, new MyCallback(requestCode));
|
||||
}
|
||||
|
||||
private class MyCallback implements Callback.ProgressCallback<String> {
|
||||
private int requestCode = 0;
|
||||
|
||||
public MyCallback(int requestCode) {
|
||||
this.requestCode = requestCode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onWaiting() {
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
public void onStarted() {
|
||||
netOnStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoading(long total, long current, boolean isDownloading) {
|
||||
netOnLoading(total, current, isDownloading);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess(String result) {
|
||||
Logger.json(result);
|
||||
JsonBean jsonBean = null;
|
||||
try {
|
||||
jsonBean = jsonParse(result);
|
||||
if (jsonBean.getMsg() != null && !jsonBean.getMsg().isEmpty()) {
|
||||
showToast(jsonBean.getMsg());
|
||||
}
|
||||
if (jsonBean.getStatus() == 1) {
|
||||
Map<String, Object> data = new ArrayMap<String, Object>();
|
||||
if (null != jsonBean.getData() && jsonBean.getData().size() > 0) {
|
||||
data = jsonBean.getData();
|
||||
}
|
||||
netOnSuccess(data, requestCode);
|
||||
} else {
|
||||
netOnOtherStates(jsonBean.getStatus(), jsonBean.getMsg(), requestCode);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
if (loadingDialog != null && loadingDialog.isShowing()) {
|
||||
loadingDialog.dismiss();
|
||||
}
|
||||
Logger.d(result);
|
||||
showToast("服务器异常!");
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(Throwable ex, boolean isOnCallback) {
|
||||
netOnFailure(ex, requestCode);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCancelled(Callback.CancelledException cex) {
|
||||
Logger.d("用户取消了访问网络....");
|
||||
netOnCancelled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFinished() {
|
||||
netOnFinish(requestCode);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private JsonBean jsonParse(String json) throws JSONException {
|
||||
ArrayMap<String, Object> arrayMap = JSON.parseObject(json, new TypeReference<ArrayMap<String, Object>>() {
|
||||
}.getType());
|
||||
JsonBean jsonBean = new JsonBean();
|
||||
if (arrayMap.containsKey("data")) {
|
||||
Object data = arrayMap.get("data");
|
||||
// System.out.println("data.getClass().getName()=" + data.getClass().getName());
|
||||
// ArrayMap<String,Object> rrData = null;
|
||||
// if (data instanceof String) {
|
||||
ArrayMap<String, Object> rrData = null;
|
||||
if (data instanceof String) {
|
||||
// System.out.println("data instanceof String");
|
||||
// rrData = new ArrayMap<String,Object>();
|
||||
// rrData.put("data", data.toString());
|
||||
// } else if (data instanceof JSONArray) {
|
||||
rrData = new ArrayMap<String, Object>();
|
||||
rrData.put("data", data.toString());
|
||||
} else if (data instanceof JSONArray) {
|
||||
// System.out.println("data instanceof JSONArray");
|
||||
// rrData = new ArrayMap<String,Object>();
|
||||
// rrData.put("data", data);
|
||||
// } else if (data instanceof com.alibaba.fastjson.JSONObject) {
|
||||
rrData = new ArrayMap<String, Object>();
|
||||
rrData.put("data", data);
|
||||
} else if (data instanceof com.alibaba.fastjson.JSONObject) {
|
||||
// System.out.println("data instanceof JSONObject");
|
||||
// rrData = JSON.parseObject(data.toString(),new TypeReference<ArrayMap<String,Object>>(){
|
||||
// }.getType());
|
||||
// }
|
||||
// jsonBean.setData(rrData);
|
||||
// }
|
||||
// jsonBean.setCode(Integer.valueOf(arrayMap.get("code").toString()));
|
||||
// jsonBean.setMsg(Tools.getValue(arrayMap, "msg"));
|
||||
//
|
||||
// return jsonBean;
|
||||
// }
|
||||
//
|
||||
//
|
||||
// /**
|
||||
// * 开始访问网络
|
||||
// */
|
||||
// public void netOnStart() {
|
||||
// loadingDialog.show("正在获取数据...");
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 访问网络的进程
|
||||
// */
|
||||
// public void netOnLoading(long total, long current, boolean isUploading) {
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 访问网络成功
|
||||
// */
|
||||
// public void netOnSuccess(Map<String, Object> data) {
|
||||
// if (loadingDialog != null) {
|
||||
// loadingDialog.dismiss();
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 访问网络成功的其他状态
|
||||
// */
|
||||
// public void netOnOtherStates(int code, String msg) {
|
||||
// if (loadingDialog != null) {
|
||||
// loadingDialog.dismiss();
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 访问网络结束
|
||||
// */
|
||||
// public void netOnFinish() {
|
||||
// loadingDialog.dismiss();
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 访问网络失败
|
||||
// */
|
||||
// public void netOnFailure(Throwable ex) {
|
||||
// if (loadingDialog != null) {
|
||||
// loadingDialog.dismiss();
|
||||
// }
|
||||
// Logger.d(ex.getMessage());
|
||||
// if (ex instanceof HttpException) { // 网络错误
|
||||
// HttpException httpEx = (HttpException) ex;
|
||||
// int responseCode = httpEx.getCode();
|
||||
// String responseMsg = httpEx.getMessage();
|
||||
// String errorResult = httpEx.getResult();
|
||||
// Toast.makeText(x.app(), "网络错误:" + ex.getMessage(), Toast.LENGTH_LONG).show();
|
||||
// // ...
|
||||
// } else { // 其他错误
|
||||
// Toast.makeText(context, "连接服务器失败,请稍后再试!ex=" + ex.getMessage(), Toast.LENGTH_SHORT).show();
|
||||
// // ...
|
||||
// }
|
||||
//
|
||||
//
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 取消访问网络
|
||||
// */
|
||||
// public void netOnCancelled() {
|
||||
// if (loadingDialog != null) {
|
||||
// loadingDialog.dismiss();
|
||||
// }
|
||||
// }
|
||||
rrData = JSON.parseObject(data.toString(), new TypeReference<ArrayMap<String, Object>>() {
|
||||
}.getType());
|
||||
}
|
||||
jsonBean.setData(rrData);
|
||||
} else {
|
||||
Set<String> keys = arrayMap.keySet();
|
||||
ArrayMap<String, Object> rrData = new ArrayMap<>();
|
||||
for (String s : keys) {
|
||||
if (!s.equals("status")) {
|
||||
rrData.put(s, arrayMap.get(s));
|
||||
}
|
||||
}
|
||||
jsonBean.setData(rrData);
|
||||
}
|
||||
jsonBean.setStatus(Integer.valueOf(arrayMap.get("status").toString()));
|
||||
jsonBean.setMsg(Tools.getValue(arrayMap, "msg"));
|
||||
|
||||
return jsonBean;
|
||||
}
|
||||
|
||||
/**
|
||||
* 开始访问网络
|
||||
*/
|
||||
protected void netOnStart() {
|
||||
loadingDialog.show("Loading...");
|
||||
}
|
||||
|
||||
/**
|
||||
* 访问网络的进程
|
||||
*/
|
||||
protected void netOnLoading(long total, long current, boolean isUploading) {
|
||||
}
|
||||
|
||||
/**
|
||||
* 访问网络成功
|
||||
*/
|
||||
protected void netOnSuccess(Map<String, Object> data, int requestCode) {
|
||||
netOnSuccess(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 访问网络成功
|
||||
*/
|
||||
protected void netOnSuccess(Map<String, Object> data) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 访问网络成功的其他状态
|
||||
*/
|
||||
protected void netOnOtherStates(int status, String msg) {
|
||||
if (loadingDialog != null && loadingDialog.isShowing()) {
|
||||
loadingDialog.dismiss();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 访问网络成功的其他状态
|
||||
*/
|
||||
protected void netOnOtherStates(int status, String msg, int requestCode) {
|
||||
netOnOtherStates(status, msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* 访问网络结束
|
||||
*/
|
||||
protected void netOnFinish() {
|
||||
loadingDialog.dismiss();
|
||||
}
|
||||
|
||||
/**
|
||||
* 访问网络结束
|
||||
*/
|
||||
protected void netOnFinish(int requestCode) {
|
||||
loadingDialog.dismiss();
|
||||
netOnFinish();
|
||||
}
|
||||
|
||||
/**
|
||||
* 访问网络失败
|
||||
*/
|
||||
protected void netOnFailure(Throwable ex, int requestCode) {
|
||||
netOnFailure(ex);
|
||||
}
|
||||
|
||||
/**
|
||||
* 访问网络失败
|
||||
*/
|
||||
protected void netOnFailure(Throwable ex) {
|
||||
Logger.d(ex.getMessage());
|
||||
if (ex instanceof HttpException) { // 网络错误
|
||||
HttpException httpEx = (HttpException) ex;
|
||||
int responseCode = httpEx.getCode();
|
||||
String responseMsg = httpEx.getMessage();
|
||||
String errorResult = httpEx.getResult();
|
||||
Toast.makeText(x.app(), "网络错误:" + ex.getMessage(), Toast.LENGTH_LONG).show();
|
||||
// ...
|
||||
} else if (ex instanceof SocketTimeoutException) {
|
||||
Toast.makeText(x.app(), "连接服务器超时", Toast.LENGTH_LONG).show();
|
||||
} else if (ex != null && "网络不可用".equals(ex.getMessage())) {
|
||||
} else { // 其他错误
|
||||
Toast.makeText(x.app(), "连接服务器失败,请稍后再试!", Toast.LENGTH_SHORT).show();
|
||||
// ...
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消访问网络
|
||||
*/
|
||||
protected void netOnCancelled() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
@@ -599,7 +652,7 @@ public abstract class BaseActivity extends AutoLayoutActivity implements View.On
|
||||
|
||||
}
|
||||
|
||||
protected void setEmptyView(ListView listView) {
|
||||
protected <T extends View> T setEmptyView(ListView listView) {
|
||||
TextView emptyView = new TextView(context);
|
||||
emptyView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
|
||||
emptyView.setText("暂无数据!");
|
||||
@@ -608,9 +661,10 @@ public abstract class BaseActivity extends AutoLayoutActivity implements View.On
|
||||
emptyView.setVisibility(View.GONE);
|
||||
((ViewGroup) listView.getParent()).addView(emptyView);
|
||||
listView.setEmptyView(emptyView);
|
||||
return (T) emptyView;
|
||||
}
|
||||
|
||||
protected void setEmptyView(ListView listView, String text) {
|
||||
protected <T extends View> T setEmptyView(ListView listView, String text) {
|
||||
TextView emptyView = new TextView(context);
|
||||
emptyView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
|
||||
emptyView.setText(text);
|
||||
@@ -619,26 +673,121 @@ public abstract class BaseActivity extends AutoLayoutActivity implements View.On
|
||||
emptyView.setVisibility(View.GONE);
|
||||
((ViewGroup) listView.getParent()).addView(emptyView);
|
||||
listView.setEmptyView(emptyView);
|
||||
return (T) emptyView;
|
||||
}
|
||||
|
||||
protected <T extends View> T setEmptyView(GridView gridView) {
|
||||
TextView emptyView = new TextView(context);
|
||||
emptyView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
|
||||
emptyView.setText("暂无数据!");
|
||||
emptyView.setGravity(Gravity.CENTER);
|
||||
emptyView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 16);
|
||||
emptyView.setVisibility(View.GONE);
|
||||
((ViewGroup) gridView.getParent()).addView(emptyView);
|
||||
gridView.setEmptyView(emptyView);
|
||||
return (T) emptyView;
|
||||
}
|
||||
|
||||
protected <T extends View> T setEmptyView(GridView gridView, String text) {
|
||||
TextView emptyView = new TextView(context);
|
||||
emptyView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
|
||||
emptyView.setText(text);
|
||||
emptyView.setGravity(Gravity.CENTER);
|
||||
emptyView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 16);
|
||||
emptyView.setVisibility(View.GONE);
|
||||
((ViewGroup) gridView.getParent()).addView(emptyView);
|
||||
gridView.setEmptyView(emptyView);
|
||||
return (T) emptyView;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
// fixFocusedViewLeak(x.app());
|
||||
// fixInputMethodManager();
|
||||
mContentLayout.removeAllViews();
|
||||
mContentLayout = null;
|
||||
if (cancelable != null && !cancelable.isCancelled()) {
|
||||
cancelable.cancel();
|
||||
}
|
||||
AppManager.getAppManager().finishActivity(this);
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
if (null != this.getCurrentFocus()) {
|
||||
/**
|
||||
* 点击空白位置 隐藏软键盘
|
||||
*/
|
||||
InputMethodManager mInputMethodManager = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
|
||||
return mInputMethodManager.hideSoftInputFromWindow(this.getCurrentFocus().getWindowToken(), 0);
|
||||
public boolean dispatchTouchEvent(MotionEvent ev) {
|
||||
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
|
||||
View v = getCurrentFocus();
|
||||
if (isShouldHideKeyboard(v, ev)) {
|
||||
hideKeyboard(v.getWindowToken());
|
||||
}
|
||||
}
|
||||
return super.onTouchEvent(event);
|
||||
return super.dispatchTouchEvent(ev);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据EditText所在坐标和用户点击的坐标相对比,来判断是否隐藏键盘,因为当用户点击EditText时则不能隐藏
|
||||
*
|
||||
* @param v
|
||||
* @param event
|
||||
* @return
|
||||
*/
|
||||
private boolean isShouldHideKeyboard(View v, MotionEvent event) {
|
||||
if (v != null && (v instanceof EditText)) {
|
||||
int[] l = {0, 0};
|
||||
v.getLocationInWindow(l);
|
||||
int left = l[0],
|
||||
top = l[1],
|
||||
bottom = top + v.getHeight(),
|
||||
right = left + v.getWidth();
|
||||
if (event.getX() > left && event.getX() < right
|
||||
&& event.getY() > top && event.getY() < bottom) {
|
||||
// 点击EditText的事件,忽略它。
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// 如果焦点不是EditText则忽略,这个发生在视图刚绘制完,第一个焦点不在EditText上,和用户用轨迹球选择其他的焦点
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取InputMethodManager,隐藏软键盘
|
||||
*
|
||||
* @param token
|
||||
*/
|
||||
private void hideKeyboard(IBinder token) {
|
||||
if (token != null) {
|
||||
InputMethodManager im = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
im.hideSoftInputFromWindow(token, InputMethodManager.HIDE_NOT_ALWAYS);
|
||||
}
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public boolean onTouchEvent(MotionEvent event) {
|
||||
// if (null != this.getCurrentFocus()) {
|
||||
// /**
|
||||
// * 点击空白位置 隐藏软键盘
|
||||
// */
|
||||
// InputMethodManager mInputMethodManager = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
|
||||
// return mInputMethodManager.hideSoftInputFromWindow(this.getCurrentFocus().getWindowToken(), 0);
|
||||
// }
|
||||
// return super.onTouchEvent(event);
|
||||
// }
|
||||
private void fixInputMethodManager() {
|
||||
final Object imm = getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
|
||||
final Reflector.TypedObject windowToken
|
||||
= new Reflector.TypedObject(getWindow().getDecorView().getWindowToken(), IBinder.class);
|
||||
|
||||
Reflector.invokeMethodExceptionSafe(imm, "windowDismissed", windowToken);
|
||||
|
||||
final Reflector.TypedObject view
|
||||
= new Reflector.TypedObject(null, View.class);
|
||||
|
||||
Reflector.invokeMethodExceptionSafe(imm, "startGettingWindowFocus", view);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ import android.view.Gravity;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.GridView;
|
||||
import android.widget.ListView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
@@ -20,6 +21,7 @@ import com.alibaba.fastjson.TypeReference;
|
||||
import com.kejiang.yuandl.app.MyApplication;
|
||||
import com.kejiang.yuandl.bean.JsonBean;
|
||||
import com.kejiang.yuandl.utils.CheckNetwork;
|
||||
import com.kejiang.yuandl.utils.SharedPreferencesUtils;
|
||||
import com.kejiang.yuandl.utils.Tools;
|
||||
import com.kejiang.yuandl.view.LoadingDialog;
|
||||
import com.orhanobut.logger.Logger;
|
||||
@@ -35,6 +37,7 @@ import org.xutils.x;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* com.bm.falvzixun.fragment.BaseFragment
|
||||
@@ -50,7 +53,6 @@ public class BaseFragment extends Fragment {
|
||||
}
|
||||
|
||||
|
||||
|
||||
private Callback.Cancelable cancelable;
|
||||
/**
|
||||
* 加载数据对话框
|
||||
@@ -63,7 +65,7 @@ public class BaseFragment extends Fragment {
|
||||
*
|
||||
* @param requestParams
|
||||
*/
|
||||
private void ajax(RequestParams requestParams) {
|
||||
protected void ajax(RequestParams requestParams) {
|
||||
ajax(requestParams, 0);
|
||||
}
|
||||
|
||||
@@ -76,11 +78,24 @@ public class BaseFragment extends Fragment {
|
||||
protected void ajax(RequestParams requestParams, int requestCode) {
|
||||
if (!CheckNetwork.isNetworkAvailable(getContext())) {
|
||||
showToast("网络不可用,请检查网络连接!");
|
||||
netOnFailure(new Exception("网络不可用"));
|
||||
return;
|
||||
}
|
||||
if (loadingDialog == null) {
|
||||
loadingDialog = new LoadingDialog(getContext());
|
||||
}
|
||||
|
||||
SharedPreferencesUtils sp = new SharedPreferencesUtils(x.app());
|
||||
boolean isLogin = (boolean) sp.getParam("login", false);
|
||||
if (isLogin) {
|
||||
requestParams.addBodyParameter("mId", (String) sp.getParam("mId", ""));
|
||||
}
|
||||
boolean hasLocation = (boolean) sp.getParam("hasLocation", false);
|
||||
if (hasLocation) {
|
||||
requestParams.addBodyParameter("lng", (String) sp.getParam("lng", ""));
|
||||
requestParams.addBodyParameter("lat", (String) sp.getParam("lat", ""));
|
||||
}
|
||||
|
||||
Logger.d("url=" + requestParams.getUri() + "\nrequestParams=" + requestParams.getStringParams().toString());
|
||||
List<KeyValue> params = requestParams.getStringParams();
|
||||
for (KeyValue keyValue : params) {
|
||||
@@ -129,8 +144,7 @@ public class BaseFragment extends Fragment {
|
||||
}
|
||||
netOnSuccess(data, requestCode);
|
||||
} else {
|
||||
|
||||
netOnOtherStates(jsonBean.getStatus(), jsonBean.getMsg());
|
||||
netOnOtherStates(jsonBean.getStatus(), jsonBean.getMsg(), requestCode);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
if (loadingDialog != null && loadingDialog.isShowing()) {
|
||||
@@ -157,7 +171,7 @@ public class BaseFragment extends Fragment {
|
||||
|
||||
@Override
|
||||
public void onFinished() {
|
||||
netOnFinish();
|
||||
netOnFinish(requestCode);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -168,22 +182,31 @@ public class BaseFragment extends Fragment {
|
||||
JsonBean jsonBean = new JsonBean();
|
||||
if (arrayMap.containsKey("data")) {
|
||||
Object data = arrayMap.get("data");
|
||||
System.out.println("data.getClass().getName()=" + data.getClass().getName());
|
||||
// System.out.println("data.getClass().getName()=" + data.getClass().getName());
|
||||
ArrayMap<String, Object> rrData = null;
|
||||
if (data instanceof String) {
|
||||
System.out.println("data instanceof String");
|
||||
// System.out.println("data instanceof String");
|
||||
rrData = new ArrayMap<String, Object>();
|
||||
rrData.put("data", data.toString());
|
||||
} else if (data instanceof JSONArray) {
|
||||
System.out.println("data instanceof JSONArray");
|
||||
// System.out.println("data instanceof JSONArray");
|
||||
rrData = new ArrayMap<String, Object>();
|
||||
rrData.put("data", data);
|
||||
} else if (data instanceof com.alibaba.fastjson.JSONObject) {
|
||||
System.out.println("data instanceof JSONObject");
|
||||
// System.out.println("data instanceof JSONObject");
|
||||
rrData = JSON.parseObject(data.toString(), new TypeReference<ArrayMap<String, Object>>() {
|
||||
}.getType());
|
||||
}
|
||||
jsonBean.setData(rrData);
|
||||
} else {
|
||||
Set<String> keys = arrayMap.keySet();
|
||||
ArrayMap<String, Object> rrData = new ArrayMap<>();
|
||||
for (String s : keys) {
|
||||
if (!s.equals("status")) {
|
||||
rrData.put(s, arrayMap.get(s));
|
||||
}
|
||||
}
|
||||
jsonBean.setData(rrData);
|
||||
}
|
||||
jsonBean.setStatus(Integer.valueOf(arrayMap.get("status").toString()));
|
||||
jsonBean.setMsg(Tools.getValue(arrayMap, "msg"));
|
||||
@@ -194,50 +217,65 @@ public class BaseFragment extends Fragment {
|
||||
/**
|
||||
* 开始访问网络
|
||||
*/
|
||||
public void netOnStart() {
|
||||
protected void netOnStart() {
|
||||
loadingDialog.show("Loading...");
|
||||
}
|
||||
|
||||
/**
|
||||
* 访问网络的进程
|
||||
*/
|
||||
public void netOnLoading(long total, long current, boolean isUploading) {
|
||||
protected void netOnLoading(long total, long current, boolean isUploading) {
|
||||
}
|
||||
|
||||
/**
|
||||
* 访问网络成功
|
||||
*/
|
||||
public void netOnSuccess(Map<String, Object> data, int requestCode) {
|
||||
protected void netOnSuccess(Map<String, Object> data, int requestCode) {
|
||||
netOnSuccess(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 访问网络成功
|
||||
*/
|
||||
public void netOnSuccess(Map<String, Object> data) {
|
||||
protected void netOnSuccess(Map<String, Object> data) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 访问网络成功的其他状态
|
||||
*/
|
||||
public void netOnOtherStates(int status, String msg) {
|
||||
protected void netOnOtherStates(int status, String msg) {
|
||||
if (loadingDialog != null && loadingDialog.isShowing()) {
|
||||
loadingDialog.dismiss();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 访问网络成功的其他状态
|
||||
*/
|
||||
protected void netOnOtherStates(int status, String msg, int requestCode) {
|
||||
netOnOtherStates(status, msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* 访问网络结束
|
||||
*/
|
||||
public void netOnFinish() {
|
||||
protected void netOnFinish() {
|
||||
loadingDialog.dismiss();
|
||||
}
|
||||
|
||||
/**
|
||||
* 访问网络结束
|
||||
*/
|
||||
protected void netOnFinish(int requestCode) {
|
||||
loadingDialog.dismiss();
|
||||
netOnFinish();
|
||||
}
|
||||
|
||||
/**
|
||||
* 访问网络失败
|
||||
*/
|
||||
public void netOnFailure(Throwable ex) {
|
||||
protected void netOnFailure(Throwable ex) {
|
||||
Logger.d(ex.getMessage());
|
||||
if (ex instanceof HttpException) { // 网络错误
|
||||
HttpException httpEx = (HttpException) ex;
|
||||
@@ -248,8 +286,10 @@ public class BaseFragment extends Fragment {
|
||||
// ...
|
||||
} else if (ex instanceof SocketTimeoutException) {
|
||||
Toast.makeText(x.app(), "连接服务器超时", Toast.LENGTH_LONG).show();
|
||||
} else if (ex!= null && "网络不可用".equals(ex.getMessage())) {
|
||||
|
||||
} else { // 其他错误
|
||||
Toast.makeText(x.app(), "连接服务器失败,请稍后再试!ex=" + ex.getMessage(), Toast.LENGTH_SHORT).show();
|
||||
Toast.makeText(x.app(), "连接服务器失败,请稍后再试!", Toast.LENGTH_SHORT).show();
|
||||
// ...
|
||||
}
|
||||
|
||||
@@ -358,10 +398,36 @@ public class BaseFragment extends Fragment {
|
||||
listView.setEmptyView(emptyView);
|
||||
}
|
||||
|
||||
protected void setEmptyView(GridView gridView) {
|
||||
TextView emptyView = new TextView(getContext());
|
||||
emptyView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
|
||||
emptyView.setText("暂无数据!");
|
||||
emptyView.setGravity(Gravity.CENTER);
|
||||
emptyView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 16);
|
||||
emptyView.setVisibility(View.GONE);
|
||||
((ViewGroup) gridView.getParent()).addView(emptyView);
|
||||
gridView.setEmptyView(emptyView);
|
||||
}
|
||||
|
||||
protected void setEmptyView(GridView gridView, String text) {
|
||||
TextView emptyView = new TextView(getContext());
|
||||
emptyView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
|
||||
emptyView.setText(text);
|
||||
emptyView.setGravity(Gravity.CENTER);
|
||||
emptyView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 16);
|
||||
emptyView.setVisibility(View.GONE);
|
||||
((ViewGroup) gridView.getParent()).addView(emptyView);
|
||||
gridView.setEmptyView(emptyView);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
if (cancelable != null && !cancelable.isCancelled()) {
|
||||
cancelable.cancel();
|
||||
}
|
||||
RefWatcher refWatcher = MyApplication.getRefWatcher(getActivity());
|
||||
refWatcher.watch(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
package com.kejiang.yuandl.base;
|
||||
|
||||
import android.view.View;
|
||||
import android.view.ViewStub;
|
||||
|
||||
import com.kejiang.yuandl.R;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* com.bm.falvzixun.activities.BaseActivity;
|
||||
*
|
||||
* @author yuandl on 2015/12/17.
|
||||
* 所有页面的基类
|
||||
*/
|
||||
public abstract class BaseNetErrorActivity extends BaseActivity {
|
||||
private boolean isInflate = false;
|
||||
|
||||
@Override
|
||||
protected void netOnSuccess(Map<String, Object> data, int requestCode) {
|
||||
super.netOnSuccess(data, requestCode);
|
||||
(findViewById(R.id.vs)).setVisibility(View.GONE);
|
||||
getContentLayout().setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void netOnFailure(Throwable ex, int requestCode) {
|
||||
super.netOnFailure(ex, requestCode);
|
||||
getContentLayout().setVisibility(View.GONE);
|
||||
if (!isInflate) {
|
||||
((ViewStub) findViewById(R.id.vs)).inflate();
|
||||
isInflate = true;
|
||||
} else {
|
||||
(findViewById(R.id.vs)).setVisibility(View.VISIBLE);
|
||||
}
|
||||
findViewById(R.id.bt_reload).setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
reLoad();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 重新加载数据
|
||||
*/
|
||||
protected abstract void reLoad();
|
||||
}
|
||||
|
||||
@@ -90,7 +90,7 @@ public class ImageDispose {
|
||||
System.gc();
|
||||
BitmapFactory.Options options = new BitmapFactory.Options();
|
||||
options.inPurgeable = true;
|
||||
options.inSampleSize = 2;
|
||||
options.inSampleSize = inSampleSize;
|
||||
return options;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.kejiang.yuandl.utils;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Created by yuandl on 2016/6/27 0027.
|
||||
*/
|
||||
public interface MyHttpCallback {
|
||||
void netOnStart();
|
||||
|
||||
void netOnSuccess(Map<String, Object> data, int requestCode);
|
||||
|
||||
void netOnSuccess(Map<String, Object> data);
|
||||
|
||||
void netOnOtherStatus(int status, String msg, int requestCode);
|
||||
void netOnOtherStatus(int status, String msg);
|
||||
|
||||
void netOnFinish();
|
||||
|
||||
void netOnFailure(Throwable ex);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,304 @@
|
||||
package com.kejiang.yuandl.utils;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.v4.util.ArrayMap;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONException;
|
||||
import com.alibaba.fastjson.TypeReference;
|
||||
import com.kejiang.yuandl.bean.JsonBean;
|
||||
import com.kejiang.yuandl.view.LoadingDialog;
|
||||
import com.orhanobut.logger.Logger;
|
||||
|
||||
import org.xutils.common.Callback;
|
||||
import org.xutils.common.util.KeyValue;
|
||||
import org.xutils.ex.HttpException;
|
||||
import org.xutils.http.RequestParams;
|
||||
import org.xutils.x;
|
||||
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Created by yuandl on 2016/6/27 0027.
|
||||
*/
|
||||
public class MyHttpUtills {
|
||||
|
||||
private Callback.Cancelable cancelable;
|
||||
|
||||
private LoadingDialog loadingDialog;
|
||||
|
||||
private Toast toast;
|
||||
|
||||
private Context context;
|
||||
|
||||
private MyHttpCallback myHttpCallback;
|
||||
|
||||
public MyHttpUtills(Context context,MyHttpCallback myHttpCallback) {
|
||||
this.context = context;
|
||||
this.myHttpCallback = myHttpCallback;
|
||||
}
|
||||
|
||||
/**
|
||||
* 异步网络请求类
|
||||
*
|
||||
* @param requestParams
|
||||
*/
|
||||
public void ajax(RequestParams requestParams) {
|
||||
ajax(requestParams, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 异步网络请求类
|
||||
*
|
||||
* @param requestParams
|
||||
* @param requestCode 区分不同的网络请求
|
||||
*/
|
||||
public void ajax(RequestParams requestParams, int requestCode) {
|
||||
if (!CheckNetwork.isNetworkAvailable(context)) {
|
||||
showToast("网络不可用,请检查网络连接!");
|
||||
return;
|
||||
}
|
||||
if (loadingDialog == null) {
|
||||
loadingDialog = new LoadingDialog(context);
|
||||
}
|
||||
SharedPreferencesUtils sp = new SharedPreferencesUtils(x.app());
|
||||
boolean isLogin = (boolean) sp.getParam("login", false);
|
||||
if (isLogin) {
|
||||
requestParams.addBodyParameter("mId", (String) sp.getParam("mId", ""));
|
||||
}
|
||||
boolean hasLocation = (boolean) sp.getParam("hasLocation", false);
|
||||
if (hasLocation) {
|
||||
requestParams.addBodyParameter("lng", (String) sp.getParam("lng", ""));
|
||||
requestParams.addBodyParameter("lat", (String) sp.getParam("lat", ""));
|
||||
}
|
||||
Logger.d("url=" + requestParams.getUri() + "\nrequestParams=" + requestParams.getStringParams().toString());
|
||||
List<KeyValue> params = requestParams.getStringParams();
|
||||
for (KeyValue keyValue : params) {
|
||||
if (keyValue.key.contains(":")) {
|
||||
throw new RuntimeException("参数异常!");
|
||||
}
|
||||
}
|
||||
cancelable = x.http().post(requestParams, new MyCallback(requestCode));
|
||||
}
|
||||
|
||||
private class MyCallback implements Callback.ProgressCallback<String> {
|
||||
private int requestCode = 0;
|
||||
|
||||
public MyCallback(int requestCode) {
|
||||
this.requestCode = requestCode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onWaiting() {
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
public void onStarted() {
|
||||
netOnStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoading(long total, long current, boolean isDownloading) {
|
||||
netOnLoading(total, current, isDownloading);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess(String result) {
|
||||
Logger.json(result);
|
||||
JsonBean jsonBean = null;
|
||||
try {
|
||||
jsonBean = jsonParse(result);
|
||||
if (jsonBean.getMsg() != null && !jsonBean.getMsg().isEmpty()) {
|
||||
showToast(jsonBean.getMsg());
|
||||
}
|
||||
if (jsonBean.getStatus() == 1) {
|
||||
Map<String, Object> data = new ArrayMap<String, Object>();
|
||||
if (null != jsonBean.getData() && jsonBean.getData().size() > 0) {
|
||||
data = jsonBean.getData();
|
||||
}
|
||||
netOnSuccess(data, requestCode);
|
||||
} else {
|
||||
netOnOtherStates(jsonBean.getStatus(), jsonBean.getMsg(), requestCode);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
if (loadingDialog != null && loadingDialog.isShowing()) {
|
||||
loadingDialog.dismiss();
|
||||
}
|
||||
Logger.d(result);
|
||||
showToast("服务器异常!");
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(Throwable ex, boolean isOnCallback) {
|
||||
netOnFailure(ex);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCancelled(Callback.CancelledException cex) {
|
||||
Logger.d("用户取消了访问网络....");
|
||||
netOnCancelled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFinished() {
|
||||
netOnFinish(requestCode);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private JsonBean jsonParse(String json) throws JSONException {
|
||||
ArrayMap<String, Object> arrayMap = JSON.parseObject(json, new TypeReference<ArrayMap<String, Object>>() {
|
||||
}.getType());
|
||||
JsonBean jsonBean = new JsonBean();
|
||||
if (arrayMap.containsKey("data")) {
|
||||
Object data = arrayMap.get("data");
|
||||
System.out.println("data.getClass().getName()=" + data.getClass().getName());
|
||||
ArrayMap<String, Object> rrData = null;
|
||||
if (data instanceof String) {
|
||||
System.out.println("data instanceof String");
|
||||
rrData = new ArrayMap<String, Object>();
|
||||
rrData.put("data", data.toString());
|
||||
} else if (data instanceof JSONArray) {
|
||||
System.out.println("data instanceof JSONArray");
|
||||
rrData = new ArrayMap<String, Object>();
|
||||
rrData.put("data", data);
|
||||
} else if (data instanceof com.alibaba.fastjson.JSONObject) {
|
||||
System.out.println("data instanceof JSONObject");
|
||||
rrData = JSON.parseObject(data.toString(), new TypeReference<ArrayMap<String, Object>>() {
|
||||
}.getType());
|
||||
}
|
||||
jsonBean.setData(rrData);
|
||||
} else {
|
||||
Set<String> keys = arrayMap.keySet();
|
||||
ArrayMap<String, Object> rrData = new ArrayMap<>();
|
||||
for (String s : keys) {
|
||||
if (!s.equals("status") && !s.equals("msg")) {
|
||||
rrData.put(s, arrayMap.get(s));
|
||||
}
|
||||
}
|
||||
jsonBean.setData(rrData);
|
||||
}
|
||||
jsonBean.setStatus(Integer.valueOf(arrayMap.get("status").toString()));
|
||||
jsonBean.setMsg(Tools.getValue(arrayMap, "msg"));
|
||||
|
||||
return jsonBean;
|
||||
}
|
||||
|
||||
/**
|
||||
* 开始访问网络
|
||||
*/
|
||||
protected void netOnStart() {
|
||||
loadingDialog.show("Loading...");
|
||||
myHttpCallback.netOnStart();
|
||||
}
|
||||
|
||||
/**
|
||||
* 访问网络的进程
|
||||
*/
|
||||
protected void netOnLoading(long total, long current, boolean isUploading) {
|
||||
}
|
||||
|
||||
/**
|
||||
* 访问网络成功
|
||||
*/
|
||||
protected void netOnSuccess(Map<String, Object> data, int requestCode) {
|
||||
netOnSuccess(data);
|
||||
myHttpCallback.netOnSuccess(data,requestCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* 访问网络成功
|
||||
*/
|
||||
protected void netOnSuccess(Map<String, Object> data) {
|
||||
myHttpCallback.netOnSuccess(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 访问网络成功的其他状态
|
||||
*/
|
||||
protected void netOnOtherStates(int status, String msg) {
|
||||
myHttpCallback.netOnOtherStatus(status, msg);
|
||||
if (loadingDialog != null && loadingDialog.isShowing()) {
|
||||
loadingDialog.dismiss();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 访问网络成功的其他状态
|
||||
*/
|
||||
protected void netOnOtherStates(int status, String msg, int requestCode) {
|
||||
netOnOtherStates(status, msg);
|
||||
myHttpCallback.netOnOtherStatus(status, msg, requestCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* 访问网络结束
|
||||
*/
|
||||
protected void netOnFinish() {
|
||||
loadingDialog.dismiss();
|
||||
myHttpCallback.netOnFinish();
|
||||
}
|
||||
|
||||
/**
|
||||
* 访问网络结束
|
||||
*/
|
||||
protected void netOnFinish(int requestCode) {
|
||||
loadingDialog.dismiss();
|
||||
netOnFinish();
|
||||
}
|
||||
|
||||
/**
|
||||
* 访问网络失败
|
||||
*/
|
||||
protected void netOnFailure(Throwable ex) {
|
||||
Logger.d(ex.getMessage());
|
||||
if (ex instanceof HttpException) { // 网络错误
|
||||
HttpException httpEx = (HttpException) ex;
|
||||
int responseCode = httpEx.getCode();
|
||||
String responseMsg = httpEx.getMessage();
|
||||
String errorResult = httpEx.getResult();
|
||||
Toast.makeText(x.app(), "网络错误:" + ex.getMessage(), Toast.LENGTH_LONG).show();
|
||||
// ...
|
||||
} else if (ex instanceof SocketTimeoutException) {
|
||||
Toast.makeText(x.app(), "连接服务器超时", Toast.LENGTH_LONG).show();
|
||||
} else { // 其他错误
|
||||
Toast.makeText(x.app(), "连接服务器失败,请稍后再试!ex=" + ex.getMessage(), Toast.LENGTH_SHORT).show();
|
||||
// ...
|
||||
}
|
||||
myHttpCallback.netOnFailure(ex);
|
||||
myHttpCallback.netOnFinish();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消访问网络
|
||||
*/
|
||||
protected void netOnCancelled() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 弹出Toast便捷方法
|
||||
*
|
||||
* @param charSequence
|
||||
*/
|
||||
public void showToast(CharSequence charSequence) {
|
||||
if (null == toast) {
|
||||
toast = Toast.makeText(x.app(), charSequence, Toast.LENGTH_SHORT);
|
||||
} else {
|
||||
toast.setText(charSequence);
|
||||
}
|
||||
toast.show();
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package com.kejiang.yuandl.utils;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* Created by yuandl on 2016/7/19 0019.
|
||||
*/
|
||||
public class Reflector {
|
||||
public static final class TypedObject
|
||||
{
|
||||
private final Object object;
|
||||
private final Class type;
|
||||
|
||||
public TypedObject(final Object object, final Class type)
|
||||
{
|
||||
this.object = object;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
Object getObject()
|
||||
{
|
||||
return object;
|
||||
}
|
||||
|
||||
Class getType()
|
||||
{
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
||||
public static void invokeMethodExceptionSafe(final Object methodOwner, final String method, final TypedObject... arguments)
|
||||
{
|
||||
if (null == methodOwner)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
final Class<?>[] types = null == arguments ? new Class[0] : new Class[arguments.length];
|
||||
final Object[] objects = null == arguments ? new Object[0] : new Object[arguments.length];
|
||||
|
||||
if (null != arguments)
|
||||
{
|
||||
for (int i = 0, limit = types.length; i < limit; i++)
|
||||
{
|
||||
types[i] = arguments[i].getType();
|
||||
objects[i] = arguments[i].getObject();
|
||||
}
|
||||
}
|
||||
|
||||
final Method declaredMethod = methodOwner.getClass().getDeclaredMethod(method, types);
|
||||
|
||||
declaredMethod.setAccessible(true);
|
||||
declaredMethod.invoke(methodOwner, objects);
|
||||
}
|
||||
catch (final Throwable ignored)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.kejiang.yuandl.utils;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Map;
|
||||
|
||||
public class SeralizableMap implements Serializable {
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 1L;
|
||||
private Map<String, Object> map;
|
||||
|
||||
public Map<String, Object> getMap() {
|
||||
return map;
|
||||
}
|
||||
|
||||
public void setMap(Map<String, Object> map) {
|
||||
this.map = map;
|
||||
}
|
||||
}
|
||||
@@ -49,7 +49,7 @@ public class SharedPreferencesUtils {
|
||||
|
||||
String type = object.getClass().getSimpleName();
|
||||
SharedPreferences sp = context.getSharedPreferences(FILE_NAME,
|
||||
Context.MODE_PRIVATE);
|
||||
Context.MODE_MULTI_PROCESS);
|
||||
SharedPreferences.Editor editor = sp.edit();
|
||||
if ("String".equals(type)) {
|
||||
editor.putString(key, object.toString());
|
||||
|
||||
@@ -140,6 +140,7 @@ public class MyGallery extends Gallery implements OnItemSelectedListener {
|
||||
|
||||
public void destroy() {
|
||||
timer.cancel();
|
||||
mHandler.removeCallbacks(task);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -93,7 +93,7 @@ public class RatingBar extends LinearLayout {
|
||||
}
|
||||
|
||||
if (indexOfChild(v) > fint) {
|
||||
setStar(indexOfChild(v) + 0.5f);
|
||||
setStar(indexOfChild(v) + 1);
|
||||
} else if (indexOfChild(v) == fint) {
|
||||
if (imageView.getDrawable().getCurrent().getConstantState().equals(starHalfDrawable.getConstantState())) {
|
||||
setStar(indexOfChild(v) + 1);
|
||||
@@ -101,7 +101,7 @@ public class RatingBar extends LinearLayout {
|
||||
setStar(indexOfChild(v) + 0.5f);
|
||||
}
|
||||
} else {
|
||||
setStar(indexOfChild(v) + 1);
|
||||
setStar(indexOfChild(v) + 1f);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,632 @@
|
||||
package com.kejiang.yuandl.view;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.support.v4.view.MotionEventCompat;
|
||||
import android.support.v4.view.ViewCompat;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.VelocityTracker;
|
||||
import android.view.View;
|
||||
import android.view.ViewConfiguration;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.AbsListView;
|
||||
|
||||
import com.kejiang.yuandl.R;
|
||||
|
||||
|
||||
/**
|
||||
* <b>Project:</b> SlideDetailsLayout<br>
|
||||
* <b>Create Date:</b> 16/1/22<br>
|
||||
* <b>Author:</b> Gordon<br>
|
||||
* <b>Description:</b>
|
||||
* Pull up to open panel, pull down to close panel.
|
||||
* <br>
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public class SlideDetailsLayout extends ViewGroup {
|
||||
|
||||
/**
|
||||
* Callback for panel OPEN-CLOSE status changed.
|
||||
*/
|
||||
public interface OnSlideDetailsListener {
|
||||
/**
|
||||
* Called after status changed.
|
||||
*
|
||||
* @param status {@link Status}
|
||||
*/
|
||||
void onStatucChanged(Status status);
|
||||
}
|
||||
|
||||
public enum Status {
|
||||
/** Panel is closed */
|
||||
CLOSE,
|
||||
/** Panel is opened */
|
||||
OPEN;
|
||||
|
||||
public static Status valueOf(int stats) {
|
||||
if (0 == stats) {
|
||||
return CLOSE;
|
||||
} else if (1 == stats) {
|
||||
return OPEN;
|
||||
} else {
|
||||
return CLOSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static final float DEFAULT_PERCENT = 0.2f;
|
||||
private static final int DEFAULT_DURATION = 300;
|
||||
private static final float DEFAULT_MAX_VELOCITY = 2500f;
|
||||
|
||||
private View mFrontView;
|
||||
private View mBehindView;
|
||||
|
||||
private float mTouchSlop;
|
||||
private float mInitMotionY;
|
||||
private float mInitMotionX;
|
||||
|
||||
|
||||
private View mTarget;
|
||||
private float mSlideOffset;
|
||||
private Status mStatus = Status.CLOSE;
|
||||
private boolean isFirstShowBehindView = true;
|
||||
private float mPercent = DEFAULT_PERCENT;
|
||||
private long mDuration = DEFAULT_DURATION;
|
||||
private int mDefaultPanel = 0;
|
||||
private VelocityTracker mVelocityTracker;
|
||||
|
||||
private OnSlideDetailsListener mOnSlideDetailsListener;
|
||||
|
||||
public SlideDetailsLayout(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public SlideDetailsLayout(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public SlideDetailsLayout(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
|
||||
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SlideDetailsLayout, defStyleAttr, 0);
|
||||
mPercent = a.getFloat(R.styleable.SlideDetailsLayout_percent, DEFAULT_PERCENT);
|
||||
mDuration = a.getInt(R.styleable.SlideDetailsLayout_duration, DEFAULT_DURATION);
|
||||
mDefaultPanel = a.getInt(R.styleable.SlideDetailsLayout_default_panel, 0);
|
||||
a.recycle();
|
||||
|
||||
mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the callback of panel OPEN-CLOSE status.
|
||||
*
|
||||
* @param listener {@link OnSlideDetailsListener}
|
||||
*/
|
||||
public void setOnSlideDetailsListener(OnSlideDetailsListener listener) {
|
||||
this.mOnSlideDetailsListener = listener;
|
||||
}
|
||||
|
||||
/**
|
||||
* Open pannel smoothly.
|
||||
*
|
||||
* @param smooth true, smoothly. false otherwise.
|
||||
*/
|
||||
public void smoothOpen(boolean smooth) {
|
||||
if (mStatus != Status.OPEN) {
|
||||
mStatus = Status.OPEN;
|
||||
final float height = -getMeasuredHeight();
|
||||
animatorSwitch(0, height, true, smooth ? mDuration : 0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Close pannel smoothly.
|
||||
*
|
||||
* @param smooth true, smoothly. false otherwise.
|
||||
*/
|
||||
public void smoothClose(boolean smooth) {
|
||||
if (mStatus != Status.CLOSE) {
|
||||
mStatus = Status.OPEN;
|
||||
final float height = -getMeasuredHeight();
|
||||
animatorSwitch(height, 0, true, smooth ? mDuration : 0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the float value for indicate the moment of switch panel
|
||||
*
|
||||
* @param percent (0.0, 1.0)
|
||||
*/
|
||||
public void setPercent(float percent) {
|
||||
this.mPercent = percent;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected LayoutParams generateDefaultLayoutParams() {
|
||||
return new MarginLayoutParams(MarginLayoutParams.WRAP_CONTENT, MarginLayoutParams.WRAP_CONTENT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LayoutParams generateLayoutParams(AttributeSet attrs) {
|
||||
return new MarginLayoutParams(getContext(), attrs);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected LayoutParams generateLayoutParams(LayoutParams p) {
|
||||
return new MarginLayoutParams(p);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onFinishInflate() {
|
||||
super.onFinishInflate();
|
||||
|
||||
final int childCount = getChildCount();
|
||||
if (1 >= childCount) {
|
||||
throw new RuntimeException("SlideDetailsLayout only accept childs more than 1!!");
|
||||
}
|
||||
|
||||
mFrontView = getChildAt(0);
|
||||
mBehindView = getChildAt(1);
|
||||
|
||||
// set behindview's visibility to GONE before show.
|
||||
mBehindView.setVisibility(GONE);
|
||||
if (mDefaultPanel == 1) {
|
||||
post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
smoothOpen(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
final int pWidth = MeasureSpec.getSize(widthMeasureSpec);
|
||||
final int pHeight = MeasureSpec.getSize(heightMeasureSpec);
|
||||
|
||||
final int childWidthMeasureSpec =
|
||||
MeasureSpec.makeMeasureSpec(pWidth, MeasureSpec.EXACTLY);
|
||||
final int childHeightMeasureSpec =
|
||||
MeasureSpec.makeMeasureSpec(pHeight, MeasureSpec.EXACTLY);
|
||||
|
||||
View child;
|
||||
for (int i = 0; i < getChildCount(); i++) {
|
||||
child = getChildAt(i);
|
||||
// skip measure if gone
|
||||
if (child.getVisibility() == GONE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
measureChild(child, childWidthMeasureSpec, childHeightMeasureSpec);
|
||||
}
|
||||
|
||||
setMeasuredDimension(pWidth, pHeight);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onLayout(boolean changed, int l, int t, int r, int b) {
|
||||
final int left = l;
|
||||
final int right = r;
|
||||
int top;
|
||||
int bottom;
|
||||
|
||||
final int offset = (int) mSlideOffset;
|
||||
|
||||
View child;
|
||||
for (int i = 0; i < getChildCount(); i++) {
|
||||
child = getChildAt(i);
|
||||
|
||||
// skip layout
|
||||
if (child.getVisibility() == GONE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (child == mBehindView) {
|
||||
top = b + offset;
|
||||
bottom = top + b - t;
|
||||
} else {
|
||||
top = 0;
|
||||
bottom = b + offset;
|
||||
}
|
||||
|
||||
child.layout(left, top, right, bottom);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onInterceptTouchEvent(MotionEvent ev) {
|
||||
ensureTarget();
|
||||
if (null == mTarget) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!isEnabled()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final int aciton = MotionEventCompat.getActionMasked(ev);
|
||||
|
||||
boolean shouldIntercept = false;
|
||||
switch (aciton) {
|
||||
case MotionEvent.ACTION_DOWN: {
|
||||
if (null == mVelocityTracker) {
|
||||
mVelocityTracker = VelocityTracker.obtain();
|
||||
} else {
|
||||
mVelocityTracker.clear();
|
||||
}
|
||||
mVelocityTracker.addMovement(ev);
|
||||
|
||||
mInitMotionX = ev.getX();
|
||||
mInitMotionY = ev.getY();
|
||||
shouldIntercept = false;
|
||||
break;
|
||||
}
|
||||
case MotionEvent.ACTION_MOVE: {
|
||||
final float x = ev.getX();
|
||||
final float y = ev.getY();
|
||||
|
||||
final float xDiff = x - mInitMotionX;
|
||||
final float yDiff = y - mInitMotionY;
|
||||
|
||||
if (canChildScrollVertically((int) yDiff)) {
|
||||
shouldIntercept = false;
|
||||
// if (DEBUG) {
|
||||
// Log.d(TAG, "intercept, child can scroll vertically, do not intercept");
|
||||
// }
|
||||
} else {
|
||||
final float xDiffabs = Math.abs(xDiff);
|
||||
final float yDiffabs = Math.abs(yDiff);
|
||||
|
||||
// intercept rules:
|
||||
// 1. The vertical displacement is larger than the horizontal displacement;
|
||||
// 2. Panel stauts is CLOSE:slide up
|
||||
// 3. Panel status is OPEN:slide down
|
||||
if (yDiffabs > mTouchSlop && yDiffabs >= xDiffabs
|
||||
&& !(mStatus == Status.CLOSE && yDiff > 0
|
||||
|| mStatus == Status.OPEN && yDiff < 0)) {
|
||||
shouldIntercept = true;
|
||||
// if (DEBUG) {
|
||||
// Log.d(TAG, "intercept, intercept events");
|
||||
// }
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MotionEvent.ACTION_UP:
|
||||
case MotionEvent.ACTION_CANCEL: {
|
||||
shouldIntercept = false;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return shouldIntercept;
|
||||
}
|
||||
|
||||
private void recycleVelocityTracker(){
|
||||
if(null != mVelocityTracker){
|
||||
mVelocityTracker.recycle();
|
||||
mVelocityTracker = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent ev) {
|
||||
ensureTarget();
|
||||
if (null == mTarget) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!isEnabled()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
boolean wantTouch = true;
|
||||
final int action = MotionEventCompat.getActionMasked(ev);
|
||||
|
||||
switch (action) {
|
||||
case MotionEvent.ACTION_DOWN: {
|
||||
// if target is a view, we want the DOWN action.
|
||||
if (mTarget instanceof View) {
|
||||
wantTouch = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case MotionEvent.ACTION_MOVE: {
|
||||
mVelocityTracker.addMovement(ev);
|
||||
mVelocityTracker.computeCurrentVelocity(1000);
|
||||
final float y = ev.getY();
|
||||
final float yDiff = y - mInitMotionY;
|
||||
if (canChildScrollVertically(((int) yDiff))) {
|
||||
wantTouch = false;
|
||||
} else {
|
||||
processTouchEvent(yDiff);
|
||||
wantTouch = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case MotionEvent.ACTION_UP:
|
||||
case MotionEvent.ACTION_CANCEL: {
|
||||
finishTouchEvent();
|
||||
recycleVelocityTracker();
|
||||
wantTouch = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return wantTouch;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param offset Displacement in vertically.
|
||||
*/
|
||||
private void processTouchEvent(final float offset) {
|
||||
if (Math.abs(offset) < mTouchSlop) {
|
||||
return;
|
||||
}
|
||||
|
||||
final float oldOffset = mSlideOffset;
|
||||
// pull up to open
|
||||
if (mStatus == Status.CLOSE) {
|
||||
// reset if pull down
|
||||
if (offset >= 0) {
|
||||
mSlideOffset = 0;
|
||||
} else {
|
||||
mSlideOffset = offset;
|
||||
}
|
||||
|
||||
if (mSlideOffset == oldOffset) {
|
||||
return;
|
||||
}
|
||||
|
||||
// pull down to close
|
||||
} else if (mStatus == Status.OPEN) {
|
||||
final float pHeight = -getMeasuredHeight();
|
||||
// reset if pull up
|
||||
if (offset <= 0) {
|
||||
mSlideOffset = pHeight;
|
||||
} else {
|
||||
final float newOffset = pHeight + offset;
|
||||
mSlideOffset = newOffset;
|
||||
}
|
||||
|
||||
if (mSlideOffset == oldOffset) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// if (SlideDebug.DEBUG) {
|
||||
// Log.v("slide", "process, offset: " + mSlideOffset);
|
||||
// }
|
||||
// relayout
|
||||
requestLayout();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called after gesture is ending.
|
||||
*/
|
||||
private void finishTouchEvent() {
|
||||
final int pHeight = getMeasuredHeight();
|
||||
final int percent = (int) (pHeight * mPercent);
|
||||
final float offset = mSlideOffset;
|
||||
|
||||
boolean changed = false;
|
||||
final float yVelocity = mVelocityTracker.getYVelocity();
|
||||
|
||||
// if (DEBUG) {
|
||||
// Log.v(TAG, "finish, offset: " + offset + ", percent: " + percent + ", yVelocity: " + yVelocity);
|
||||
// }
|
||||
|
||||
if (Status.CLOSE == mStatus) {
|
||||
if (offset <= -percent || yVelocity <= -DEFAULT_MAX_VELOCITY) {
|
||||
mSlideOffset = -pHeight;
|
||||
mStatus = Status.OPEN;
|
||||
changed = true;
|
||||
} else {
|
||||
// keep panel closed
|
||||
mSlideOffset = 0;
|
||||
}
|
||||
} else if (Status.OPEN == mStatus) {
|
||||
if ((offset + pHeight) >= percent || yVelocity >= DEFAULT_MAX_VELOCITY) {
|
||||
mSlideOffset = 0;
|
||||
mStatus = Status.CLOSE;
|
||||
changed = true;
|
||||
} else {
|
||||
// keep panel opened
|
||||
mSlideOffset = -pHeight;
|
||||
}
|
||||
}
|
||||
|
||||
animatorSwitch(offset, mSlideOffset, changed);
|
||||
}
|
||||
|
||||
private void animatorSwitch(final float start, final float end) {
|
||||
animatorSwitch(start, end, true, mDuration);
|
||||
}
|
||||
|
||||
private void animatorSwitch(final float start, final float end, final long duration) {
|
||||
animatorSwitch(start, end, true, duration);
|
||||
}
|
||||
|
||||
private void animatorSwitch(final float start, final float end, final boolean changed) {
|
||||
animatorSwitch(start, end, changed, mDuration);
|
||||
}
|
||||
|
||||
private void animatorSwitch(final float start,
|
||||
final float end,
|
||||
final boolean changed,
|
||||
final long duration) {
|
||||
ValueAnimator animator = ValueAnimator.ofFloat(start, end);
|
||||
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
||||
@Override
|
||||
public void onAnimationUpdate(ValueAnimator animation) {
|
||||
mSlideOffset = (float) animation.getAnimatedValue();
|
||||
requestLayout();
|
||||
}
|
||||
});
|
||||
animator.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
super.onAnimationEnd(animation);
|
||||
if (changed) {
|
||||
if (mStatus == Status.OPEN) {
|
||||
checkAndFirstOpenPanel();
|
||||
}
|
||||
|
||||
if (null != mOnSlideDetailsListener) {
|
||||
mOnSlideDetailsListener.onStatucChanged(mStatus);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
animator.setDuration(duration);
|
||||
animator.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the closed pannel is opened at first time.
|
||||
* If open first, we should set the behind view's visibility as VISIBLE.
|
||||
*/
|
||||
private void checkAndFirstOpenPanel() {
|
||||
if (isFirstShowBehindView) {
|
||||
isFirstShowBehindView = false;
|
||||
mBehindView.setVisibility(VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* When pulling, target view changed by the panel status. If panel opened, the target is behind view.
|
||||
* Front view is for otherwise.
|
||||
*/
|
||||
private void ensureTarget() {
|
||||
if (mStatus == Status.CLOSE) {
|
||||
mTarget = mFrontView;
|
||||
} else {
|
||||
mTarget = mBehindView;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check child view can srcollable in vertical direction.
|
||||
*
|
||||
* @param direction Negative to check scrolling up, positive to check scrolling down.
|
||||
*
|
||||
* @return true if this view can be scrolled in the specified direction, false otherwise.
|
||||
*/
|
||||
protected boolean canChildScrollVertically(int direction) {
|
||||
return innerCanChildScrollVertically(mTarget, -direction);
|
||||
}
|
||||
|
||||
private boolean innerCanChildScrollVertically(View view, int direction) {
|
||||
if (view instanceof ViewGroup) {
|
||||
final ViewGroup vGroup = (ViewGroup) view;
|
||||
View child;
|
||||
boolean result;
|
||||
for (int i = 0; i < vGroup.getChildCount(); i++) {
|
||||
child = vGroup.getChildAt(i);
|
||||
if (child instanceof View) {
|
||||
result = ViewCompat.canScrollVertically(child, direction);
|
||||
} else {
|
||||
result = innerCanChildScrollVertically(child, direction);
|
||||
}
|
||||
|
||||
if (result) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ViewCompat.canScrollVertically(view, direction);
|
||||
}
|
||||
|
||||
protected boolean canListViewSroll(AbsListView absListView) {
|
||||
if (mStatus == Status.OPEN) {
|
||||
return absListView.getChildCount() > 0
|
||||
&& (absListView.getFirstVisiblePosition() > 0 || absListView.getChildAt(0)
|
||||
.getTop() <
|
||||
absListView.getPaddingTop());
|
||||
} else {
|
||||
final int count = absListView.getChildCount();
|
||||
return count > 0
|
||||
&& (absListView.getLastVisiblePosition() < count - 1
|
||||
|| absListView.getChildAt(count - 1)
|
||||
.getBottom() > absListView.getMeasuredHeight());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Parcelable onSaveInstanceState() {
|
||||
SavedState ss = new SavedState(super.onSaveInstanceState());
|
||||
ss.offset = mSlideOffset;
|
||||
ss.status = mStatus.ordinal();
|
||||
return ss;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onRestoreInstanceState(Parcelable state) {
|
||||
SavedState ss = (SavedState) state;
|
||||
super.onRestoreInstanceState(ss.getSuperState());
|
||||
mSlideOffset = ss.offset;
|
||||
mStatus = Status.valueOf(ss.status);
|
||||
|
||||
if (mStatus == Status.OPEN) {
|
||||
mBehindView.setVisibility(VISIBLE);
|
||||
}
|
||||
|
||||
requestLayout();
|
||||
}
|
||||
|
||||
static class SavedState extends BaseSavedState {
|
||||
|
||||
private float offset;
|
||||
private int status;
|
||||
|
||||
/**
|
||||
* Constructor used when reading from a parcel. Reads the state of the superclass.
|
||||
*
|
||||
* @param source
|
||||
*/
|
||||
public SavedState(Parcel source) {
|
||||
super(source);
|
||||
offset = source.readFloat();
|
||||
status = source.readInt();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor called by derived classes when creating their SavedState objects
|
||||
*
|
||||
* @param superState The state of the superclass of this view
|
||||
*/
|
||||
public SavedState(Parcelable superState) {
|
||||
super(superState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel out, int flags) {
|
||||
super.writeToParcel(out, flags);
|
||||
out.writeFloat(offset);
|
||||
out.writeInt(status);
|
||||
}
|
||||
|
||||
public static final Creator<SavedState> CREATOR =
|
||||
new Creator<SavedState>() {
|
||||
public SavedState createFromParcel(Parcel in) {
|
||||
return new SavedState(in);
|
||||
}
|
||||
|
||||
public SavedState[] newArray(int size) {
|
||||
return new SavedState[size];
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
BIN
libray_lxndroid/src/main/res/drawable/net_error.png
Normal file
BIN
libray_lxndroid/src/main/res/drawable/net_error.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 41 KiB |
BIN
libray_lxndroid/src/main/res/drawable/reload.png
Normal file
BIN
libray_lxndroid/src/main/res/drawable/reload.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.9 KiB |
@@ -17,5 +17,9 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
></FrameLayout>
|
||||
|
||||
<ViewStub
|
||||
android:id="@+id/vs"
|
||||
android:layout_width="match_parent"
|
||||
android:layout="@layout/pub_net_error"
|
||||
android:layout_height="match_parent" />
|
||||
</LinearLayout>
|
||||
15
libray_lxndroid/src/main/res/layout/pub_net_error.xml
Normal file
15
libray_lxndroid/src/main/res/layout/pub_net_error.xml
Normal file
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="vertical" android:layout_width="match_parent"
|
||||
android:background="@drawable/net_error"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<Button
|
||||
android:layout_width="270px"
|
||||
android:layout_height="118px"
|
||||
android:background="@drawable/reload"
|
||||
android:button="@null"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_marginTop="1160px"
|
||||
android:id="@+id/bt_reload" />
|
||||
</RelativeLayout>
|
||||
@@ -85,4 +85,17 @@
|
||||
<declare-styleable name="AutoTabLayout">
|
||||
<attr name="auto_textSize_base_width" format="boolean"></attr>
|
||||
</declare-styleable>
|
||||
|
||||
|
||||
<declare-styleable name="SlideDetailsLayout">
|
||||
<!-- float value for indicate the moment of switch panel-->
|
||||
<attr name="percent" format="float"/>
|
||||
<!-- how long the animation keep-->
|
||||
<attr name="duration" format="integer"/>
|
||||
<!-- default panel to show after init-->
|
||||
<attr name="default_panel" format="enum">
|
||||
<enum name="front" value="0"/>
|
||||
<enum name="behind" value="1"/>
|
||||
</attr>
|
||||
</declare-styleable>
|
||||
</resources>
|
||||
Reference in New Issue
Block a user