diff --git a/.idea/.name b/.idea/.name
deleted file mode 100644
index bb17c9a..0000000
--- a/.idea/.name
+++ /dev/null
@@ -1 +0,0 @@
-AndroidFrame
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
index 1a3eaff..f0ee888 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -27,20 +27,5 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/ac_main.xml b/app/src/main/res/layout/ac_main.xml
index 890c422..74a2518 100644
--- a/app/src/main/res/layout/ac_main.xml
+++ b/app/src/main/res/layout/ac_main.xml
@@ -19,7 +19,7 @@
app:starEmpty="@mipmap/star_grey"
app:starFill="@mipmap/star_yellow"
app:starHalf="@mipmap/star_half_yellow"
- app:starImageSize="20dp"
+ app:starImageSize="30dp"
app:starStep="4.5">
extends BaseAdapter
-{
- protected Context mContext;
- protected List mDatas;
- protected LayoutInflater mInflater;
- private int layoutId;
+public abstract class CommonAdapter extends BaseAdapter {
+ protected Context mContext;
+ protected List mDatas;
+ protected LayoutInflater mInflater;
+ private int layoutId;
- public CommonAdapter(Context context,int layoutId, List datas )
- {
- this.mContext = context;
- mInflater = LayoutInflater.from(context);
- this.mDatas = datas;
- this.layoutId = layoutId;
- }
+ public CommonAdapter(Context context, int layoutId, List 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 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 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);
}
diff --git a/libray_lxndroid/src/main/java/com/kejiang/yuandl/adapter/common/recyclerview/CommonAdapter.java b/libray_lxndroid/src/main/java/com/kejiang/yuandl/adapter/common/recyclerview/CommonAdapter.java
index dada422..420eac3 100644
--- a/libray_lxndroid/src/main/java/com/kejiang/yuandl/adapter/common/recyclerview/CommonAdapter.java
+++ b/libray_lxndroid/src/main/java/com/kejiang/yuandl/adapter/common/recyclerview/CommonAdapter.java
@@ -53,7 +53,10 @@ public abstract class CommonAdapter extends RecyclerView.Adapter
{
return true;
}
-
+ public void notifyDataSetChanged(List 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 extends RecyclerView.Adapter
@Override
public int getItemCount()
{
- return mDatas.size();
+ return mDatas==null?0:mDatas.size();
}
diff --git a/libray_lxndroid/src/main/java/com/kejiang/yuandl/base/BaseActivity.java b/libray_lxndroid/src/main/java/com/kejiang/yuandl/base/BaseActivity.java
index 79834d6..ec4459b 100644
--- a/libray_lxndroid/src/main/java/com/kejiang/yuandl/base/BaseActivity.java
+++ b/libray_lxndroid/src/main/java/com/kejiang/yuandl/base/BaseActivity.java
@@ -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 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() {
-//
-// @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 data = new ArrayMap();
-// 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 arrayMap= JSON.parseObject(json,new TypeReference>(){
-// }.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 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 {
+ 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 data = new ArrayMap();
+ 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 arrayMap = JSON.parseObject(json, new TypeReference>() {
+ }.getType());
+ JsonBean jsonBean = new JsonBean();
+ if (arrayMap.containsKey("data")) {
+ Object data = arrayMap.get("data");
// System.out.println("data.getClass().getName()=" + data.getClass().getName());
-// ArrayMap rrData = null;
-// if (data instanceof String) {
+ ArrayMap rrData = null;
+ if (data instanceof String) {
// System.out.println("data instanceof String");
-// rrData = new ArrayMap();
-// rrData.put("data", data.toString());
-// } else if (data instanceof JSONArray) {
+ rrData = new ArrayMap();
+ rrData.put("data", data.toString());
+ } else if (data instanceof JSONArray) {
// System.out.println("data instanceof JSONArray");
-// rrData = new ArrayMap();
-// rrData.put("data", data);
-// } else if (data instanceof com.alibaba.fastjson.JSONObject) {
+ rrData = new ArrayMap();
+ 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>(){
-// }.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 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>() {
+ }.getType());
+ }
+ jsonBean.setData(rrData);
+ } else {
+ Set keys = arrayMap.keySet();
+ ArrayMap 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 data, int requestCode) {
+ netOnSuccess(data);
+ }
+
+ /**
+ * 访问网络成功
+ */
+ protected void netOnSuccess(Map 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 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 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 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 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);
+ }
+
+
}
diff --git a/libray_lxndroid/src/main/java/com/kejiang/yuandl/base/BaseFragment.java b/libray_lxndroid/src/main/java/com/kejiang/yuandl/base/BaseFragment.java
index 3b16f29..ca10fa8 100644
--- a/libray_lxndroid/src/main/java/com/kejiang/yuandl/base/BaseFragment.java
+++ b/libray_lxndroid/src/main/java/com/kejiang/yuandl/base/BaseFragment.java
@@ -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 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 rrData = null;
if (data instanceof String) {
- System.out.println("data instanceof String");
+// System.out.println("data instanceof String");
rrData = new ArrayMap();
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();
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>() {
}.getType());
}
jsonBean.setData(rrData);
+ } else {
+ Set keys = arrayMap.keySet();
+ ArrayMap 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 data, int requestCode) {
+ protected void netOnSuccess(Map data, int requestCode) {
netOnSuccess(data);
}
/**
* 访问网络成功
*/
- public void netOnSuccess(Map data) {
+ protected void netOnSuccess(Map 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);
}
+
}
diff --git a/libray_lxndroid/src/main/java/com/kejiang/yuandl/base/BaseNetErrorActivity.java b/libray_lxndroid/src/main/java/com/kejiang/yuandl/base/BaseNetErrorActivity.java
new file mode 100644
index 0000000..d41df92
--- /dev/null
+++ b/libray_lxndroid/src/main/java/com/kejiang/yuandl/base/BaseNetErrorActivity.java
@@ -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 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();
+}
+
diff --git a/libray_lxndroid/src/main/java/com/kejiang/yuandl/utils/ImageDispose.java b/libray_lxndroid/src/main/java/com/kejiang/yuandl/utils/ImageDispose.java
index e87b99f..5ead3f5 100644
--- a/libray_lxndroid/src/main/java/com/kejiang/yuandl/utils/ImageDispose.java
+++ b/libray_lxndroid/src/main/java/com/kejiang/yuandl/utils/ImageDispose.java
@@ -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;
}
diff --git a/libray_lxndroid/src/main/java/com/kejiang/yuandl/utils/MyHttpCallback.java b/libray_lxndroid/src/main/java/com/kejiang/yuandl/utils/MyHttpCallback.java
new file mode 100644
index 0000000..755dd45
--- /dev/null
+++ b/libray_lxndroid/src/main/java/com/kejiang/yuandl/utils/MyHttpCallback.java
@@ -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 data, int requestCode);
+
+ void netOnSuccess(Map data);
+
+ void netOnOtherStatus(int status, String msg, int requestCode);
+ void netOnOtherStatus(int status, String msg);
+
+ void netOnFinish();
+
+ void netOnFailure(Throwable ex);
+
+}
diff --git a/libray_lxndroid/src/main/java/com/kejiang/yuandl/utils/MyHttpUtills.java b/libray_lxndroid/src/main/java/com/kejiang/yuandl/utils/MyHttpUtills.java
new file mode 100644
index 0000000..17c43e6
--- /dev/null
+++ b/libray_lxndroid/src/main/java/com/kejiang/yuandl/utils/MyHttpUtills.java
@@ -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 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 {
+ 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 data = new ArrayMap();
+ 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 arrayMap = JSON.parseObject(json, new TypeReference>() {
+ }.getType());
+ JsonBean jsonBean = new JsonBean();
+ if (arrayMap.containsKey("data")) {
+ Object data = arrayMap.get("data");
+ System.out.println("data.getClass().getName()=" + data.getClass().getName());
+ ArrayMap rrData = null;
+ if (data instanceof String) {
+ System.out.println("data instanceof String");
+ rrData = new ArrayMap();
+ rrData.put("data", data.toString());
+ } else if (data instanceof JSONArray) {
+ System.out.println("data instanceof JSONArray");
+ rrData = new ArrayMap();
+ 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>() {
+ }.getType());
+ }
+ jsonBean.setData(rrData);
+ } else {
+ Set keys = arrayMap.keySet();
+ ArrayMap 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 data, int requestCode) {
+ netOnSuccess(data);
+ myHttpCallback.netOnSuccess(data,requestCode);
+ }
+
+ /**
+ * 访问网络成功
+ */
+ protected void netOnSuccess(Map 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();
+
+ }
+}
diff --git a/libray_lxndroid/src/main/java/com/kejiang/yuandl/utils/Reflector.java b/libray_lxndroid/src/main/java/com/kejiang/yuandl/utils/Reflector.java
new file mode 100644
index 0000000..554547c
--- /dev/null
+++ b/libray_lxndroid/src/main/java/com/kejiang/yuandl/utils/Reflector.java
@@ -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)
+ {
+ }
+ }
+}
diff --git a/libray_lxndroid/src/main/java/com/kejiang/yuandl/utils/SeralizableMap.java b/libray_lxndroid/src/main/java/com/kejiang/yuandl/utils/SeralizableMap.java
new file mode 100644
index 0000000..59f6b33
--- /dev/null
+++ b/libray_lxndroid/src/main/java/com/kejiang/yuandl/utils/SeralizableMap.java
@@ -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 map;
+
+ public Map getMap() {
+ return map;
+ }
+
+ public void setMap(Map map) {
+ this.map = map;
+ }
+}
diff --git a/libray_lxndroid/src/main/java/com/kejiang/yuandl/utils/SharedPreferencesUtils.java b/libray_lxndroid/src/main/java/com/kejiang/yuandl/utils/SharedPreferencesUtils.java
index 3184510..70a52c1 100644
--- a/libray_lxndroid/src/main/java/com/kejiang/yuandl/utils/SharedPreferencesUtils.java
+++ b/libray_lxndroid/src/main/java/com/kejiang/yuandl/utils/SharedPreferencesUtils.java
@@ -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());
diff --git a/libray_lxndroid/src/main/java/com/kejiang/yuandl/view/MyGallery.java b/libray_lxndroid/src/main/java/com/kejiang/yuandl/view/MyGallery.java
index 6e0a75a..a99ffe8 100644
--- a/libray_lxndroid/src/main/java/com/kejiang/yuandl/view/MyGallery.java
+++ b/libray_lxndroid/src/main/java/com/kejiang/yuandl/view/MyGallery.java
@@ -140,6 +140,7 @@ public class MyGallery extends Gallery implements OnItemSelectedListener {
public void destroy() {
timer.cancel();
+ mHandler.removeCallbacks(task);
}
@Override
diff --git a/libray_lxndroid/src/main/java/com/kejiang/yuandl/view/RatingBar.java b/libray_lxndroid/src/main/java/com/kejiang/yuandl/view/RatingBar.java
index 79036fa..4fdb9ca 100644
--- a/libray_lxndroid/src/main/java/com/kejiang/yuandl/view/RatingBar.java
+++ b/libray_lxndroid/src/main/java/com/kejiang/yuandl/view/RatingBar.java
@@ -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);
}
}
diff --git a/libray_lxndroid/src/main/java/com/kejiang/yuandl/view/SlideDetailsLayout.java b/libray_lxndroid/src/main/java/com/kejiang/yuandl/view/SlideDetailsLayout.java
new file mode 100644
index 0000000..7ec4c56
--- /dev/null
+++ b/libray_lxndroid/src/main/java/com/kejiang/yuandl/view/SlideDetailsLayout.java
@@ -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;
+
+
+/**
+ * Project: SlideDetailsLayout
+ * Create Date: 16/1/22
+ * Author: Gordon
+ * Description:
+ * Pull up to open panel, pull down to close panel.
+ *
+ */
+@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 CREATOR =
+ new Creator() {
+ public SavedState createFromParcel(Parcel in) {
+ return new SavedState(in);
+ }
+
+ public SavedState[] newArray(int size) {
+ return new SavedState[size];
+ }
+ };
+ }
+}
diff --git a/libray_lxndroid/src/main/res/drawable/net_error.png b/libray_lxndroid/src/main/res/drawable/net_error.png
new file mode 100644
index 0000000..a30a416
Binary files /dev/null and b/libray_lxndroid/src/main/res/drawable/net_error.png differ
diff --git a/libray_lxndroid/src/main/res/drawable/reload.png b/libray_lxndroid/src/main/res/drawable/reload.png
new file mode 100644
index 0000000..3cf03f0
Binary files /dev/null and b/libray_lxndroid/src/main/res/drawable/reload.png differ
diff --git a/libray_lxndroid/src/main/res/layout/ac_title.xml b/libray_lxndroid/src/main/res/layout/ac_title.xml
index 1455f20..61ab346 100644
--- a/libray_lxndroid/src/main/res/layout/ac_title.xml
+++ b/libray_lxndroid/src/main/res/layout/ac_title.xml
@@ -17,5 +17,9 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
>
-
+
\ No newline at end of file
diff --git a/libray_lxndroid/src/main/res/layout/pub_net_error.xml b/libray_lxndroid/src/main/res/layout/pub_net_error.xml
new file mode 100644
index 0000000..4b9980b
--- /dev/null
+++ b/libray_lxndroid/src/main/res/layout/pub_net_error.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/libray_lxndroid/src/main/res/values/attrs.xml b/libray_lxndroid/src/main/res/values/attrs.xml
index 8ddde25..b9b8ab1 100644
--- a/libray_lxndroid/src/main/res/values/attrs.xml
+++ b/libray_lxndroid/src/main/res/values/attrs.xml
@@ -85,4 +85,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file