taskList = am.getRunningTasks(1);
if (taskList != null && !taskList.isEmpty()) {
- ComponentName topActivity = taskList.get(0).topActivity;
+ ComponentName topActivity = taskList.get(0).topActivity;
if (topActivity != null && !topActivity.getPackageName().equals(context.getPackageName())) {
return true;
}
@@ -1011,7 +1014,7 @@ public static long getFirstOfMonth(long mills) {
}
-
+ @SuppressLint("MissingPermission")
public static class NetWork {
public static final String NETWORK_TYPE_WIFI = "wifi";
public static final String NETWORK_TYPE_3G = "eg";
diff --git a/mvp/src/main/java/cn/droidlover/xdroidmvp/mvp/LazyFragment.java b/mvp/src/main/java/cn/droidlover/xdroidmvp/mvp/LazyFragment.java
index f3c371b..bb09e92 100644
--- a/mvp/src/main/java/cn/droidlover/xdroidmvp/mvp/LazyFragment.java
+++ b/mvp/src/main/java/cn/droidlover/xdroidmvp/mvp/LazyFragment.java
@@ -3,7 +3,7 @@
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
-import android.support.annotation.Nullable;
+import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
diff --git a/mvp/src/main/java/cn/droidlover/xdroidmvp/mvp/XActivity.java b/mvp/src/main/java/cn/droidlover/xdroidmvp/mvp/XActivity.java
index cc3242a..5c58977 100644
--- a/mvp/src/main/java/cn/droidlover/xdroidmvp/mvp/XActivity.java
+++ b/mvp/src/main/java/cn/droidlover/xdroidmvp/mvp/XActivity.java
@@ -2,7 +2,7 @@
import android.app.Activity;
import android.os.Bundle;
-import android.support.annotation.Nullable;
+import androidx.annotation.Nullable;
import android.view.Menu;
import android.view.View;
diff --git a/mvp/src/main/java/cn/droidlover/xdroidmvp/mvp/XFragment.java b/mvp/src/main/java/cn/droidlover/xdroidmvp/mvp/XFragment.java
index d737450..97e40f0 100644
--- a/mvp/src/main/java/cn/droidlover/xdroidmvp/mvp/XFragment.java
+++ b/mvp/src/main/java/cn/droidlover/xdroidmvp/mvp/XFragment.java
@@ -3,7 +3,7 @@
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
-import android.support.annotation.Nullable;
+import androidx.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
diff --git a/mvp/src/main/java/cn/droidlover/xdroidmvp/router/Router.java b/mvp/src/main/java/cn/droidlover/xdroidmvp/router/Router.java
index 7fb53cb..d6e2c50 100644
--- a/mvp/src/main/java/cn/droidlover/xdroidmvp/router/Router.java
+++ b/mvp/src/main/java/cn/droidlover/xdroidmvp/router/Router.java
@@ -4,11 +4,11 @@
import android.content.Intent;
import android.os.Bundle;
import android.os.Parcelable;
-import android.support.annotation.Nullable;
import java.io.Serializable;
import java.util.ArrayList;
+import androidx.annotation.Nullable;
import androidx.core.app.ActivityCompat;
import androidx.core.app.ActivityOptionsCompat;
import cn.droidlover.xdroidmvp.XDroidConf;
diff --git a/xrecycler/build.gradle b/xrecycler/build.gradle
index 54aae9c..45fc6e5 100644
--- a/xrecycler/build.gradle
+++ b/xrecycler/build.gradle
@@ -1,7 +1,18 @@
apply plugin: 'com.android.library'
apply plugin: 'com.github.dcendents.android-maven'
-
-group = 'com.github.limedroid'
+//apply plugin: 'com.novoda.bintray-release'
+//
+//publish {
+// artifactId = 'xrecycler' // artifactId
+// uploadName = 'XRecycler' // 展示名字
+// publishVersion = '1.0.0' // 版本
+// userOrg = rootProject.userOrg
+// groupId = rootProject.groupId
+// repoName = rootProject.repoName
+// desc = ''
+// website = rootProject.website
+// licences = rootProject.licences
+//}
android {
compileSdkVersion rootProject.ext.android.compileSdkVersion
@@ -18,6 +29,10 @@ android {
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
+ lintOptions {
+ abortOnError false
+ }
+
}
dependencies {
From 43a337bfce0f8e28866b135a6f9e70dda09676e0 Mon Sep 17 00:00:00 2001
From: Edit <20336448+lennon19940306@users.noreply.github.com>
Date: Thu, 28 Nov 2019 11:11:22 +0800
Subject: [PATCH 04/24] Set theme jekyll-theme-hacker
---
_config.yml | 1 +
1 file changed, 1 insertion(+)
create mode 100644 _config.yml
diff --git a/_config.yml b/_config.yml
new file mode 100644
index 0000000..fc24e7a
--- /dev/null
+++ b/_config.yml
@@ -0,0 +1 @@
+theme: jekyll-theme-hacker
\ No newline at end of file
From 47cccc8a0fb08cb30360bef6f7e34d615619b7d9 Mon Sep 17 00:00:00 2001
From: Edit <20336448+lennon19940306@users.noreply.github.com>
Date: Thu, 28 Nov 2019 11:11:34 +0800
Subject: [PATCH 05/24] Set theme jekyll-theme-hacker
From a42763bccabca9a8ed9280100308a96b03a60f9b Mon Sep 17 00:00:00 2001
From: Lennon <1136160757@qq.com>
Date: Wed, 11 Dec 2019 16:27:52 +0800
Subject: [PATCH 06/24] =?UTF-8?q?=E4=BF=AE=E5=A4=8Drecyclerview=20remove?=
=?UTF-8?q?=E6=9C=80=E5=90=8E=E4=B8=80=E9=A1=B9=E5=88=97=E8=A1=A8=E9=A1=B9?=
=?UTF-8?q?=E6=97=B6=EF=BC=8C=E4=BC=9A=E5=AF=BC=E8=87=B4=E5=B4=A9=E6=BA=83?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
app/build.gradle | 2 +-
app/src/main/res/layout/view_toolbar.xml | 4 +--
build.gradle | 6 +++--
conf.gradle | 4 ++-
mvp/build.gradle | 25 ++++++++---------
xrecycler/build.gradle | 27 ++++++++++---------
.../xrecyclerview/RecyclerAdapter.java | 8 ++++--
.../xrecyclerview/XRecyclerView.java | 3 ++-
8 files changed, 45 insertions(+), 34 deletions(-)
diff --git a/app/build.gradle b/app/build.gradle
index d650e23..953bfff 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -32,5 +32,5 @@ dependencies {
api fileTree(dir: 'libs', include: ['*.jar'])
annotationProcessor rootProject.ext.dependencies["butterknife-apt"]
api rootProject.ext.dependencies["avi-loading"]
- api project(":mvp")
+ api rootProject.ext.dependencies["xdroid-mvp"]
}
diff --git a/app/src/main/res/layout/view_toolbar.xml b/app/src/main/res/layout/view_toolbar.xml
index e343e70..c04fd66 100644
--- a/app/src/main/res/layout/view_toolbar.xml
+++ b/app/src/main/res/layout/view_toolbar.xml
@@ -1,5 +1,5 @@
-
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
index 842d554..d7740f0 100644
--- a/build.gradle
+++ b/build.gradle
@@ -3,9 +3,10 @@ apply from: "conf.gradle"
buildscript {
repositories {
+ maven {url 'https://dl.bintray.com/lennon-xia/lennon/'}
jcenter() { url 'https://maven.aliyun.com/repository/jcenter' }
jcenter()
- maven {url 'https://dl.bintray.com/lennon-xia/lennon/'}
+
maven {
url 'https://maven.google.com/'
name 'Google'
@@ -32,9 +33,10 @@ ext{
allprojects {
repositories {
+ maven {url 'https://dl.bintray.com/lennon-xia/lennon/'}
jcenter() { url 'https://maven.aliyun.com/repository/jcenter' }
mavenCentral()
- maven {url 'https://dl.bintray.com/lennon-xia/lennon/'}
+
maven {
url 'https://maven.google.com/'
name 'Google'
diff --git a/conf.gradle b/conf.gradle
index 78864a7..f44bab4 100644
--- a/conf.gradle
+++ b/conf.gradle
@@ -18,6 +18,7 @@ ext {
]
dependencies = [
+
"appcompat-v7" : "androidx.appcompat:appcompat:${android["latest_integration"]}",
"support-v4" : "androidx.legacy:legacy-support-v4:${android["latest_integration"]}",
@@ -36,7 +37,8 @@ ext {
"glide-compiler" : "com.github.bumptech.glide:compiler:4.9.0",
"picasso" : "com.squareup.picasso:picasso:2.5.2",
- "xrecyclerview" : "com.lennon.utill:xrecycler:1.0.0",
+ "xrecyclerview" : "com.lennon.utill:xrecycler:1.0.2",
+ "xdroid-mvp" : "com.lennon.utill:xdroid-mvp:1.0.0",
"avi-loading" : "com.wang.avi:library:1.0.2",
"rxbus" : "com.blankj:rxbus:1.2",
diff --git a/mvp/build.gradle b/mvp/build.gradle
index a3642a5..38589a7 100644
--- a/mvp/build.gradle
+++ b/mvp/build.gradle
@@ -1,18 +1,19 @@
apply plugin: 'com.android.library'
apply plugin: 'com.github.dcendents.android-maven'
-apply plugin: 'com.novoda.bintray-release'
-publish {
- artifactId = 'xdroid-mvp' // artifactId
- uploadName = 'XDroidMvp' // 展示名字
- publishVersion = '1.0.0' // 版本
- userOrg = rootProject.userOrg
- groupId = rootProject.groupId
- repoName = rootProject.repoName
- desc = ''
- website = rootProject.website
- licences = rootProject.licences
-}
+//apply plugin: 'com.novoda.bintray-release'
+//
+//publish {
+// artifactId = 'xdroid-mvp' // artifactId
+// uploadName = 'XDroidMvp' // 展示名字
+// publishVersion = '1.0.0' // 版本
+// userOrg = rootProject.userOrg
+// groupId = rootProject.groupId
+// repoName = rootProject.repoName
+// desc = ''
+// website = rootProject.website
+// licences = rootProject.licences
+//}
android {
compileSdkVersion rootProject.ext.android.compileSdkVersion
diff --git a/xrecycler/build.gradle b/xrecycler/build.gradle
index 45fc6e5..4a6acca 100644
--- a/xrecycler/build.gradle
+++ b/xrecycler/build.gradle
@@ -1,18 +1,19 @@
apply plugin: 'com.android.library'
apply plugin: 'com.github.dcendents.android-maven'
-//apply plugin: 'com.novoda.bintray-release'
-//
-//publish {
-// artifactId = 'xrecycler' // artifactId
-// uploadName = 'XRecycler' // 展示名字
-// publishVersion = '1.0.0' // 版本
-// userOrg = rootProject.userOrg
-// groupId = rootProject.groupId
-// repoName = rootProject.repoName
-// desc = ''
-// website = rootProject.website
-// licences = rootProject.licences
-//}
+
+apply plugin: 'com.novoda.bintray-release'
+
+publish {
+ artifactId = 'xrecycler' // artifactId
+ uploadName = 'XRecycler' // 展示名字
+ publishVersion = '1.0.2' // 版本
+ userOrg = rootProject.userOrg
+ groupId = rootProject.groupId
+ repoName = rootProject.repoName
+ desc = ''
+ website = rootProject.website
+ licences = rootProject.licences
+}
android {
compileSdkVersion rootProject.ext.android.compileSdkVersion
diff --git a/xrecycler/src/main/java/cn/droidlover/xrecyclerview/RecyclerAdapter.java b/xrecycler/src/main/java/cn/droidlover/xrecyclerview/RecyclerAdapter.java
index e89c2e0..8408b26 100644
--- a/xrecycler/src/main/java/cn/droidlover/xrecyclerview/RecyclerAdapter.java
+++ b/xrecycler/src/main/java/cn/droidlover/xrecyclerview/RecyclerAdapter.java
@@ -85,7 +85,9 @@ public void removeElement(T element) {
int position = data.indexOf(element);
data.remove(element);
notifyItemRemoved(position);
- notifyItemChanged(position);
+ if (position < data.size()) {
+ notifyItemChanged(position);
+ }
}
}
@@ -98,7 +100,9 @@ public void removeElement(int position) {
if (data != null && data.size() > position) {
data.remove(position);
notifyItemRemoved(position);
- notifyItemChanged(position);
+ if (position < data.size()) {
+ notifyItemChanged(position);
+ }
}
}
diff --git a/xrecycler/src/main/java/cn/droidlover/xrecyclerview/XRecyclerView.java b/xrecycler/src/main/java/cn/droidlover/xrecyclerview/XRecyclerView.java
index fa5944b..109ab3d 100644
--- a/xrecycler/src/main/java/cn/droidlover/xrecyclerview/XRecyclerView.java
+++ b/xrecycler/src/main/java/cn/droidlover/xrecyclerview/XRecyclerView.java
@@ -7,6 +7,7 @@
import java.util.Collections;
import java.util.List;
+import android.widget.Adapter;
import androidx.annotation.ColorRes;
import androidx.annotation.DimenRes;
import androidx.annotation.Nullable;
@@ -232,7 +233,7 @@ public XRecyclerView verticalStaggeredLayoutManager(int spanCount) {
}
public XRecyclerView horizontalStaggeredLayoutManager(int spanCount) {
- StaggeredGridLayoutManager manager = new StaggeredGridLayoutManager(spanCount, StaggeredGridLayoutManager.VERTICAL);
+ StaggeredGridLayoutManager manager = new StaggeredGridLayoutManager(spanCount, StaggeredGridLayoutManager.HORIZONTAL);
setLayoutManager(manager);
return this;
}
From 475058821d00b3045be1b31ae11621a68f88f59b Mon Sep 17 00:00:00 2001
From: Lennon <1136160757@qq.com>
Date: Wed, 11 Dec 2019 16:53:59 +0800
Subject: [PATCH 07/24] =?UTF-8?q?=E4=BF=AE=E5=A4=8Drecyclerview=20remove?=
=?UTF-8?q?=E6=9C=80=E5=90=8E=E4=B8=80=E9=A1=B9=E5=88=97=E8=A1=A8=E9=A1=B9?=
=?UTF-8?q?=E6=97=B6=EF=BC=8C=E4=BC=9A=E5=AF=BC=E8=87=B4=E5=B4=A9=E6=BA=83?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../java/cn/droidlover/xrecyclerview/RecyclerAdapter.java | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/xrecycler/src/main/java/cn/droidlover/xrecyclerview/RecyclerAdapter.java b/xrecycler/src/main/java/cn/droidlover/xrecyclerview/RecyclerAdapter.java
index 8408b26..0ed585c 100644
--- a/xrecycler/src/main/java/cn/droidlover/xrecyclerview/RecyclerAdapter.java
+++ b/xrecycler/src/main/java/cn/droidlover/xrecyclerview/RecyclerAdapter.java
@@ -86,7 +86,7 @@ public void removeElement(T element) {
data.remove(element);
notifyItemRemoved(position);
if (position < data.size()) {
- notifyItemChanged(position);
+ notifyItemChanged(position,data.size()-position);
}
}
}
@@ -101,7 +101,7 @@ public void removeElement(int position) {
data.remove(position);
notifyItemRemoved(position);
if (position < data.size()) {
- notifyItemChanged(position);
+ notifyItemChanged(position,data.size()-position);
}
}
}
From 5aefd7a5ec1d34da7e73486cd83ead57137419dc Mon Sep 17 00:00:00 2001
From: Lennon <1136160757@qq.com>
Date: Wed, 11 Dec 2019 16:57:37 +0800
Subject: [PATCH 08/24] =?UTF-8?q?=E4=BF=AE=E5=A4=8Drecyclerview=20remove?=
=?UTF-8?q?=E6=9C=80=E5=90=8E=E4=B8=80=E9=A1=B9=E5=88=97=E8=A1=A8=E9=A1=B9?=
=?UTF-8?q?=E6=97=B6=EF=BC=8C=E4=BC=9A=E5=AF=BC=E8=87=B4=E5=B4=A9=E6=BA=83?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
conf.gradle | 2 +-
xrecycler/build.gradle | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/conf.gradle b/conf.gradle
index f44bab4..98e9366 100644
--- a/conf.gradle
+++ b/conf.gradle
@@ -37,7 +37,7 @@ ext {
"glide-compiler" : "com.github.bumptech.glide:compiler:4.9.0",
"picasso" : "com.squareup.picasso:picasso:2.5.2",
- "xrecyclerview" : "com.lennon.utill:xrecycler:1.0.2",
+ "xrecyclerview" : "com.lennon.utill:xrecycler:1.0.3",
"xdroid-mvp" : "com.lennon.utill:xdroid-mvp:1.0.0",
"avi-loading" : "com.wang.avi:library:1.0.2",
diff --git a/xrecycler/build.gradle b/xrecycler/build.gradle
index 4a6acca..bcb4e31 100644
--- a/xrecycler/build.gradle
+++ b/xrecycler/build.gradle
@@ -6,7 +6,7 @@ apply plugin: 'com.novoda.bintray-release'
publish {
artifactId = 'xrecycler' // artifactId
uploadName = 'XRecycler' // 展示名字
- publishVersion = '1.0.2' // 版本
+ publishVersion = '1.0.3' // 版本
userOrg = rootProject.userOrg
groupId = rootProject.groupId
repoName = rootProject.repoName
From 78d10cd865868af7dd43ee3e7a761c7d90c49fbc Mon Sep 17 00:00:00 2001
From: lennon <1136160757@qq.com>
Date: Wed, 25 Dec 2019 17:31:29 +0800
Subject: [PATCH 09/24] =?UTF-8?q?=E6=9B=B4=E6=96=B0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
app/build.gradle | 3 +-
build.gradle | 5 +-
conf.gradle | 21 +-
mvp/build.gradle | 10 +-
.../cn/droidlover/xdroidmvp/kit/KnifeKit.java | 45 -
.../cn/droidlover/xdroidmvp/mvp/IView.java | 1 -
.../xdroidmvp/mvp/LazyFragment.java | 4 +-
.../droidlover/xdroidmvp/mvp/XActivity.java | 10 -
.../droidlover/xdroidmvp/mvp/XFragment.java | 10 -
.../xdroidmvp/mvp/XLazyFragment.java | 9 -
settings.gradle | 2 +-
test/build.gradle | 3 +-
utill/build.gradle | 47 +
utill/consumer-rules.pro | 0
utill/proguard-rules.pro | 21 +
utill/src/main/AndroidManifest.xml | 12 +
.../cn/utill/adapter/BaseViewAdapter.kt | 32 +
.../cn/utill/adapter/StringItemAdapter.kt | 81 ++
.../com/lennon/cn/utill/base/BaseActivity.kt | 212 ++++
.../com/lennon/cn/utill/base/BaseApi.java | 50 +
.../lennon/cn/utill/base/BaseApplication.kt | 382 ++++++++
.../com/lennon/cn/utill/base/BaseFragment.kt | 145 +++
.../com/lennon/cn/utill/base/BasePresent.java | 13 +
.../java/com/lennon/cn/utill/base/BaseView.kt | 19 +
.../lennon/cn/utill/bean/BaseViewBean.java | 14 +
.../com/lennon/cn/utill/bean/Download.java | 73 ++
.../com/lennon/cn/utill/bean/HttpEntity.java | 67 ++
.../com/lennon/cn/utill/bean/StringBean.java | 9 +
.../com/lennon/cn/utill/cache/ACache.java | 72 ++
.../com/lennon/cn/utill/cache/DataCache.java | 138 +++
.../lennon/cn/utill/cache/DataListCache.java | 163 ++++
.../java/com/lennon/cn/utill/conf/Lennon.kt | 106 ++
.../lennon/cn/utill/conf/LennonProvider.kt | 27 +
.../dialog/BottomSearchSelectDialog.java | 257 +++++
.../cn/utill/dialog/BottomSelectDialog.java | 223 +++++
.../cn/utill/dialog/CommonAlertDialog.java | 169 ++++
.../cn/utill/dialog/CustomProgressDialog.java | 112 +++
.../utill/dialog/OnAlertDialogListener.java | 12 +
.../com/lennon/cn/utill/utill/AmtUtils.java | 250 +++++
.../lennon/cn/utill/utill/AnimationUtil.java | 307 ++++++
.../cn/utill/utill/AppStatusManager.java | 48 +
.../cn/utill/utill/AudioPlayerUtil.java | 86 ++
.../cn/utill/utill/AudioRecorderUtil.java | 196 ++++
.../lennon/cn/utill/utill/BitmapOperations.kt | 109 +++
.../lennon/cn/utill/utill/CountdownUtill.java | 57 ++
.../com/lennon/cn/utill/utill/DensityUtils.kt | 148 +++
.../com/lennon/cn/utill/utill/FileUtil.java | 859 +++++++++++++++++
.../lennon/cn/utill/utill/GetDeviceId.java | 271 ++++++
.../com/lennon/cn/utill/utill/IDCard.java | 196 ++++
.../com/lennon/cn/utill/utill/JsonUtils.java | 136 +++
.../java/com/lennon/cn/utill/utill/NetUtil.kt | 43 +
.../com/lennon/cn/utill/utill/OSUtils.java | 352 +++++++
.../lennon/cn/utill/utill/PictureUtil.java | 189 ++++
.../lennon/cn/utill/utill/RandomUntil.java | 149 +++
.../lennon/cn/utill/utill/StatusBarUtil.java | 864 +++++++++++++++++
.../lennon/cn/utill/utill/StringUtils.java | 904 ++++++++++++++++++
.../cn/utill/utill/SystemBarTintManager.java | 97 ++
.../lennon/cn/utill/utill/TeminalDevice.java | 346 +++++++
.../lennon/cn/utill/utill/TimeCountUtil.java | 45 +
.../com/lennon/cn/utill/utill/TimeUtill.kt | 34 +
.../java/com/lennon/cn/utill/utill/Utill.kt | 317 ++++++
.../lennon/cn/utill/utill/UtillString.java | 9 +
.../lennon/cn/utill/utill/VersionUtill.java | 131 +++
.../com/lennon/cn/utill/utill/ZipUtil.java | 166 ++++
.../cn/utill/utill/photo/PhotoString.java | 20 +
.../cn/utill/utill/photo/SelectPicUtil.java | 254 +++++
.../lennon/cn/utill/utill/rsa/RSACoder.java | 258 +++++
.../lennon/cn/utill/utill/rsa/RSAKeyUtil.java | 92 ++
.../lennon/cn/utill/utill/rsa/RSAUtils.java | 373 ++++++++
.../com/lennon/cn/utill/utill/rx/RxTool.java | 68 ++
.../lennon/cn/utill/utill/time/DateStyle.java | 57 ++
.../lennon/cn/utill/utill/time/DateUtil.java | 771 +++++++++++++++
.../com/lennon/cn/utill/utill/time/Week.java | 43 +
.../com/lennon/cn/utill/version/DownLoad.java | 109 +++
.../lennon/cn/utill/version/DownloadAPI.java | 76 ++
.../cn/utill/version/DownloadService.java | 18 +
.../download/DownloadProgressInterceptor.java | 28 +
.../download/DownloadProgressListener.java | 9 +
.../DownloadProgressResponseBody.java | 61 ++
.../version/exception/CustomizeException.java | 11 +
.../widget/AutoLineFeedLayoutManager.java | 53 +
.../utill/widget/ClearWithSpaceEditText.java | 234 +++++
.../utill/widget/ContainsEmojiEditText.java | 155 +++
.../cn/utill/widget/DrawableTextView.java | 89 ++
.../cn/utill/widget/FlowLayoutManager.java | 157 +++
.../com/lennon/cn/utill/widget/HeadBar.java | 175 ++++
.../lennon/cn/utill/widget/MyRatingBar.java | 244 +++++
.../cn/utill/widget/SearchScanView.java | 224 +++++
.../lennon/cn/utill/widget/SearchView.java | 217 +++++
.../java/com/lennon/cn/utill/widget/Star.java | 178 ++++
.../widget/interf/OnHeadBarListener.java | 12 +
utill/src/main/res/anim/pull_in_left.xml | 11 +
utill/src/main/res/anim/pull_in_right.xml | 10 +
utill/src/main/res/anim/push_out_left.xml | 10 +
utill/src/main/res/anim/push_out_right.xml | 11 +
utill/src/main/res/anim/pw_push_bottom_in.xml | 8 +
.../src/main/res/anim/pw_push_bottom_out.xml | 8 +
utill/src/main/res/anim/scale_in.xml | 15 +
utill/src/main/res/anim/scale_out.xml | 15 +
utill/src/main/res/drawable/btn_ac5454.xml | 5 +
utill/src/main/res/drawable/btn_ac5454_f.xml | 7 +
.../main/res/drawable/btn_bfbfbf_frame.xml | 17 +
utill/src/main/res/drawable/common_button.xml | 5 +
.../res/drawable/common_button_bfbfbf.xml | 5 +
.../main/res/drawable/common_button_fffff.xml | 8 +
.../main/res/drawable/common_dialog_frame.xml | 15 +
utill/src/main/res/drawable/conner_f2f2f2.xml | 6 +
utill/src/main/res/drawable/conner_fd0202.xml | 5 +
utill/src/main/res/drawable/conner_ffffff.xml | 8 +
.../main/res/drawable/conner_right_fd0202.xml | 7 +
.../res/drawable/linearlayout_fffff_frame.xml | 15 +
.../src/main/res/drawable/price_selector.xml | 7 +
utill/src/main/res/drawable/table_line.xml | 7 +
utill/src/main/res/drawable/table_radio.xml | 7 +
utill/src/main/res/drawable/table_select.xml | 5 +
.../src/main/res/drawable/table_unselect.xml | 5 +
utill/src/main/res/drawable/web_progress.xml | 26 +
.../main/res/layout/common_alert_dialog.xml | 130 +++
.../main/res/layout/customprogressdialog.xml | 24 +
.../layout/dialog_bottom_search_select.xml | 51 +
.../main/res/layout/dialog_bottom_select.xml | 44 +
utill/src/main/res/layout/headbar.xml | 57 ++
utill/src/main/res/layout/item_base_view.xml | 21 +
.../src/main/res/layout/item_string_item.xml | 20 +
.../res/layout/search_scan_view_layout.xml | 70 ++
.../src/main/res/layout/searchview_layout.xml | 64 ++
.../res/mipmap-hdpi/ic_rating_bar_hollow.png | Bin 0 -> 3162 bytes
.../res/mipmap-hdpi/ic_rating_bar_solid.png | Bin 0 -> 3166 bytes
utill/src/main/res/mipmap-xhdpi/back.png | Bin 0 -> 1186 bytes
utill/src/main/res/mipmap-xxhdpi/cha2.png | Bin 0 -> 2129 bytes
utill/src/main/res/mipmap-xxhdpi/scan.png | Bin 0 -> 1919 bytes
utill/src/main/res/raw/beep.ogg | Bin 0 -> 10185 bytes
utill/src/main/res/values/attrs.xml | 50 +
utill/src/main/res/values/color.xml | 43 +
utill/src/main/res/values/dimens.xml | 73 ++
utill/src/main/res/values/strings.xml | 7 +
utill/src/main/res/values/style.xml | 67 ++
utill/src/main/res/values/values.xml | 5 +
xrecycler/build.gradle | 26 +-
139 files changed, 13772 insertions(+), 102 deletions(-)
delete mode 100644 mvp/src/main/java/cn/droidlover/xdroidmvp/kit/KnifeKit.java
create mode 100644 utill/build.gradle
create mode 100644 utill/consumer-rules.pro
create mode 100644 utill/proguard-rules.pro
create mode 100644 utill/src/main/AndroidManifest.xml
create mode 100644 utill/src/main/java/com/lennon/cn/utill/adapter/BaseViewAdapter.kt
create mode 100644 utill/src/main/java/com/lennon/cn/utill/adapter/StringItemAdapter.kt
create mode 100644 utill/src/main/java/com/lennon/cn/utill/base/BaseActivity.kt
create mode 100644 utill/src/main/java/com/lennon/cn/utill/base/BaseApi.java
create mode 100644 utill/src/main/java/com/lennon/cn/utill/base/BaseApplication.kt
create mode 100644 utill/src/main/java/com/lennon/cn/utill/base/BaseFragment.kt
create mode 100644 utill/src/main/java/com/lennon/cn/utill/base/BasePresent.java
create mode 100644 utill/src/main/java/com/lennon/cn/utill/base/BaseView.kt
create mode 100644 utill/src/main/java/com/lennon/cn/utill/bean/BaseViewBean.java
create mode 100644 utill/src/main/java/com/lennon/cn/utill/bean/Download.java
create mode 100644 utill/src/main/java/com/lennon/cn/utill/bean/HttpEntity.java
create mode 100644 utill/src/main/java/com/lennon/cn/utill/bean/StringBean.java
create mode 100644 utill/src/main/java/com/lennon/cn/utill/cache/ACache.java
create mode 100644 utill/src/main/java/com/lennon/cn/utill/cache/DataCache.java
create mode 100644 utill/src/main/java/com/lennon/cn/utill/cache/DataListCache.java
create mode 100644 utill/src/main/java/com/lennon/cn/utill/conf/Lennon.kt
create mode 100644 utill/src/main/java/com/lennon/cn/utill/conf/LennonProvider.kt
create mode 100644 utill/src/main/java/com/lennon/cn/utill/dialog/BottomSearchSelectDialog.java
create mode 100644 utill/src/main/java/com/lennon/cn/utill/dialog/BottomSelectDialog.java
create mode 100644 utill/src/main/java/com/lennon/cn/utill/dialog/CommonAlertDialog.java
create mode 100644 utill/src/main/java/com/lennon/cn/utill/dialog/CustomProgressDialog.java
create mode 100644 utill/src/main/java/com/lennon/cn/utill/dialog/OnAlertDialogListener.java
create mode 100644 utill/src/main/java/com/lennon/cn/utill/utill/AmtUtils.java
create mode 100644 utill/src/main/java/com/lennon/cn/utill/utill/AnimationUtil.java
create mode 100644 utill/src/main/java/com/lennon/cn/utill/utill/AppStatusManager.java
create mode 100644 utill/src/main/java/com/lennon/cn/utill/utill/AudioPlayerUtil.java
create mode 100644 utill/src/main/java/com/lennon/cn/utill/utill/AudioRecorderUtil.java
create mode 100644 utill/src/main/java/com/lennon/cn/utill/utill/BitmapOperations.kt
create mode 100644 utill/src/main/java/com/lennon/cn/utill/utill/CountdownUtill.java
create mode 100644 utill/src/main/java/com/lennon/cn/utill/utill/DensityUtils.kt
create mode 100644 utill/src/main/java/com/lennon/cn/utill/utill/FileUtil.java
create mode 100644 utill/src/main/java/com/lennon/cn/utill/utill/GetDeviceId.java
create mode 100644 utill/src/main/java/com/lennon/cn/utill/utill/IDCard.java
create mode 100644 utill/src/main/java/com/lennon/cn/utill/utill/JsonUtils.java
create mode 100644 utill/src/main/java/com/lennon/cn/utill/utill/NetUtil.kt
create mode 100644 utill/src/main/java/com/lennon/cn/utill/utill/OSUtils.java
create mode 100644 utill/src/main/java/com/lennon/cn/utill/utill/PictureUtil.java
create mode 100644 utill/src/main/java/com/lennon/cn/utill/utill/RandomUntil.java
create mode 100644 utill/src/main/java/com/lennon/cn/utill/utill/StatusBarUtil.java
create mode 100644 utill/src/main/java/com/lennon/cn/utill/utill/StringUtils.java
create mode 100644 utill/src/main/java/com/lennon/cn/utill/utill/SystemBarTintManager.java
create mode 100644 utill/src/main/java/com/lennon/cn/utill/utill/TeminalDevice.java
create mode 100644 utill/src/main/java/com/lennon/cn/utill/utill/TimeCountUtil.java
create mode 100644 utill/src/main/java/com/lennon/cn/utill/utill/TimeUtill.kt
create mode 100644 utill/src/main/java/com/lennon/cn/utill/utill/Utill.kt
create mode 100644 utill/src/main/java/com/lennon/cn/utill/utill/UtillString.java
create mode 100644 utill/src/main/java/com/lennon/cn/utill/utill/VersionUtill.java
create mode 100644 utill/src/main/java/com/lennon/cn/utill/utill/ZipUtil.java
create mode 100644 utill/src/main/java/com/lennon/cn/utill/utill/photo/PhotoString.java
create mode 100644 utill/src/main/java/com/lennon/cn/utill/utill/photo/SelectPicUtil.java
create mode 100644 utill/src/main/java/com/lennon/cn/utill/utill/rsa/RSACoder.java
create mode 100644 utill/src/main/java/com/lennon/cn/utill/utill/rsa/RSAKeyUtil.java
create mode 100644 utill/src/main/java/com/lennon/cn/utill/utill/rsa/RSAUtils.java
create mode 100644 utill/src/main/java/com/lennon/cn/utill/utill/rx/RxTool.java
create mode 100644 utill/src/main/java/com/lennon/cn/utill/utill/time/DateStyle.java
create mode 100644 utill/src/main/java/com/lennon/cn/utill/utill/time/DateUtil.java
create mode 100644 utill/src/main/java/com/lennon/cn/utill/utill/time/Week.java
create mode 100644 utill/src/main/java/com/lennon/cn/utill/version/DownLoad.java
create mode 100644 utill/src/main/java/com/lennon/cn/utill/version/DownloadAPI.java
create mode 100644 utill/src/main/java/com/lennon/cn/utill/version/DownloadService.java
create mode 100644 utill/src/main/java/com/lennon/cn/utill/version/download/DownloadProgressInterceptor.java
create mode 100644 utill/src/main/java/com/lennon/cn/utill/version/download/DownloadProgressListener.java
create mode 100644 utill/src/main/java/com/lennon/cn/utill/version/download/DownloadProgressResponseBody.java
create mode 100644 utill/src/main/java/com/lennon/cn/utill/version/exception/CustomizeException.java
create mode 100644 utill/src/main/java/com/lennon/cn/utill/widget/AutoLineFeedLayoutManager.java
create mode 100644 utill/src/main/java/com/lennon/cn/utill/widget/ClearWithSpaceEditText.java
create mode 100644 utill/src/main/java/com/lennon/cn/utill/widget/ContainsEmojiEditText.java
create mode 100644 utill/src/main/java/com/lennon/cn/utill/widget/DrawableTextView.java
create mode 100644 utill/src/main/java/com/lennon/cn/utill/widget/FlowLayoutManager.java
create mode 100644 utill/src/main/java/com/lennon/cn/utill/widget/HeadBar.java
create mode 100644 utill/src/main/java/com/lennon/cn/utill/widget/MyRatingBar.java
create mode 100644 utill/src/main/java/com/lennon/cn/utill/widget/SearchScanView.java
create mode 100644 utill/src/main/java/com/lennon/cn/utill/widget/SearchView.java
create mode 100644 utill/src/main/java/com/lennon/cn/utill/widget/Star.java
create mode 100644 utill/src/main/java/com/lennon/cn/utill/widget/interf/OnHeadBarListener.java
create mode 100644 utill/src/main/res/anim/pull_in_left.xml
create mode 100644 utill/src/main/res/anim/pull_in_right.xml
create mode 100644 utill/src/main/res/anim/push_out_left.xml
create mode 100644 utill/src/main/res/anim/push_out_right.xml
create mode 100644 utill/src/main/res/anim/pw_push_bottom_in.xml
create mode 100644 utill/src/main/res/anim/pw_push_bottom_out.xml
create mode 100644 utill/src/main/res/anim/scale_in.xml
create mode 100644 utill/src/main/res/anim/scale_out.xml
create mode 100644 utill/src/main/res/drawable/btn_ac5454.xml
create mode 100644 utill/src/main/res/drawable/btn_ac5454_f.xml
create mode 100644 utill/src/main/res/drawable/btn_bfbfbf_frame.xml
create mode 100644 utill/src/main/res/drawable/common_button.xml
create mode 100644 utill/src/main/res/drawable/common_button_bfbfbf.xml
create mode 100644 utill/src/main/res/drawable/common_button_fffff.xml
create mode 100644 utill/src/main/res/drawable/common_dialog_frame.xml
create mode 100644 utill/src/main/res/drawable/conner_f2f2f2.xml
create mode 100644 utill/src/main/res/drawable/conner_fd0202.xml
create mode 100644 utill/src/main/res/drawable/conner_ffffff.xml
create mode 100644 utill/src/main/res/drawable/conner_right_fd0202.xml
create mode 100644 utill/src/main/res/drawable/linearlayout_fffff_frame.xml
create mode 100644 utill/src/main/res/drawable/price_selector.xml
create mode 100644 utill/src/main/res/drawable/table_line.xml
create mode 100644 utill/src/main/res/drawable/table_radio.xml
create mode 100644 utill/src/main/res/drawable/table_select.xml
create mode 100644 utill/src/main/res/drawable/table_unselect.xml
create mode 100644 utill/src/main/res/drawable/web_progress.xml
create mode 100644 utill/src/main/res/layout/common_alert_dialog.xml
create mode 100644 utill/src/main/res/layout/customprogressdialog.xml
create mode 100644 utill/src/main/res/layout/dialog_bottom_search_select.xml
create mode 100644 utill/src/main/res/layout/dialog_bottom_select.xml
create mode 100644 utill/src/main/res/layout/headbar.xml
create mode 100644 utill/src/main/res/layout/item_base_view.xml
create mode 100644 utill/src/main/res/layout/item_string_item.xml
create mode 100644 utill/src/main/res/layout/search_scan_view_layout.xml
create mode 100644 utill/src/main/res/layout/searchview_layout.xml
create mode 100644 utill/src/main/res/mipmap-hdpi/ic_rating_bar_hollow.png
create mode 100644 utill/src/main/res/mipmap-hdpi/ic_rating_bar_solid.png
create mode 100644 utill/src/main/res/mipmap-xhdpi/back.png
create mode 100644 utill/src/main/res/mipmap-xxhdpi/cha2.png
create mode 100644 utill/src/main/res/mipmap-xxhdpi/scan.png
create mode 100644 utill/src/main/res/raw/beep.ogg
create mode 100644 utill/src/main/res/values/attrs.xml
create mode 100644 utill/src/main/res/values/color.xml
create mode 100644 utill/src/main/res/values/dimens.xml
create mode 100644 utill/src/main/res/values/strings.xml
create mode 100644 utill/src/main/res/values/style.xml
create mode 100644 utill/src/main/res/values/values.xml
diff --git a/app/build.gradle b/app/build.gradle
index 953bfff..3365b95 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -30,7 +30,6 @@ android {
dependencies {
api fileTree(dir: 'libs', include: ['*.jar'])
- annotationProcessor rootProject.ext.dependencies["butterknife-apt"]
api rootProject.ext.dependencies["avi-loading"]
- api rootProject.ext.dependencies["xdroid-mvp"]
+ api "com.lennon.utill:xdroid-mvp:1.0.1"
}
diff --git a/build.gradle b/build.gradle
index d7740f0..03cdf7a 100644
--- a/build.gradle
+++ b/build.gradle
@@ -2,6 +2,7 @@
apply from: "conf.gradle"
buildscript {
+ ext.kotlin_version = '1.3.61'
repositories {
maven {url 'https://dl.bintray.com/lennon-xia/lennon/'}
jcenter() { url 'https://maven.aliyun.com/repository/jcenter' }
@@ -13,10 +14,10 @@ buildscript {
}
}
dependencies {
- classpath 'com.android.tools.build:gradle:3.5.2'
+ classpath 'com.android.tools.build:gradle:3.5.3'
+ classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5'
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
- classpath 'com.jakewharton:butterknife-gradle-plugin:10.2.0'
classpath 'com.novoda:bintray-release:0.9.1'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
diff --git a/conf.gradle b/conf.gradle
index 98e9366..bf80f20 100644
--- a/conf.gradle
+++ b/conf.gradle
@@ -17,7 +17,23 @@ ext {
latest_integration: "latest.integration",
]
dependencies = [
+ "navigation-fragment-ktx" : "androidx.navigation:navigation-fragment-ktx:2.1.0",
+ "navigation-ui-ktx" : "androidx.navigation:navigation-ui-ktx:2.1.0",
+ "navigation-ui" : "androidx.navigation:navigation-ui:2.1.0",
+ "navigation-fragment" : "androidx.navigation:navigation-fragment:2.1.0",
+
+ "constraintlayout" : "androidx.constraintlayout:constraintlayout:${android["latest_integration"]}",
+
+ "exifinterface" : "androidx.exifinterface:exifinterface:${android["latest_integration"]}",
+
+ "multidex" : "androidx.multidex:multidex:${android["latest_integration"]}",
+
+ "kotlin" : "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version",
+
+ "PersistentCookieJar" : "com.github.franmontiel:PersistentCookieJar:${android["latest_integration"]}",
+
+ "qiujuer-ui" : "net.qiujuer.genius:ui:${android["latest_integration"]}",
"appcompat-v7" : "androidx.appcompat:appcompat:${android["latest_integration"]}",
@@ -29,16 +45,13 @@ ext {
"recyclerview-v7" : "androidx.recyclerview:recyclerview:${android["latest_integration"]}",
- "butterknife" : "com.jakewharton:butterknife:10.2.0",
- "butterknife-apt" : "com.jakewharton:butterknife-compiler:10.2.0",
-
"eventbus" : "org.greenrobot:eventbus:3.0.0",
"glide" : "com.github.bumptech.glide:glide:4.9.0",
"glide-compiler" : "com.github.bumptech.glide:compiler:4.9.0",
"picasso" : "com.squareup.picasso:picasso:2.5.2",
"xrecyclerview" : "com.lennon.utill:xrecycler:1.0.3",
- "xdroid-mvp" : "com.lennon.utill:xdroid-mvp:1.0.0",
+ "xdroid-mvp" : "com.lennon.utill:xdroid-mvp:1.0.3",
"avi-loading" : "com.wang.avi:library:1.0.2",
"rxbus" : "com.blankj:rxbus:1.2",
diff --git a/mvp/build.gradle b/mvp/build.gradle
index 38589a7..410aa86 100644
--- a/mvp/build.gradle
+++ b/mvp/build.gradle
@@ -1,12 +1,16 @@
apply plugin: 'com.android.library'
apply plugin: 'com.github.dcendents.android-maven'
+apply plugin: 'kotlin-android'
+
+apply plugin: 'kotlin-kapt'
+apply plugin: 'kotlin-android-extensions'
//apply plugin: 'com.novoda.bintray-release'
//
//publish {
// artifactId = 'xdroid-mvp' // artifactId
// uploadName = 'XDroidMvp' // 展示名字
-// publishVersion = '1.0.0' // 版本
+// publishVersion = '1.0.3' // 版本
// userOrg = rootProject.userOrg
// groupId = rootProject.groupId
// repoName = rootProject.repoName
@@ -41,9 +45,9 @@ dependencies {
api rootProject.ext.dependencies["xrecyclerview"]
- api rootProject.ext.dependencies["butterknife"]
api rootProject.ext.dependencies["glide"]
annotationProcessor rootProject.ext.dependencies["glide-compiler"]
+ kapt rootProject.ext.dependencies["glide-compiler"]
api rootProject.ext.dependencies["gson"]
api rootProject.ext.dependencies["rxandroid"]
@@ -58,6 +62,8 @@ dependencies {
api rootProject.ext.dependencies["rxlifecycle-android"]
api rootProject.ext.dependencies["rxlifecycle-components"]
api rootProject.ext.dependencies["rxpermissions"]
+
+ api rootProject.ext.dependencies["kotlin"]
}
tasks.withType(JavaCompile) {
diff --git a/mvp/src/main/java/cn/droidlover/xdroidmvp/kit/KnifeKit.java b/mvp/src/main/java/cn/droidlover/xdroidmvp/kit/KnifeKit.java
deleted file mode 100644
index 9b08959..0000000
--- a/mvp/src/main/java/cn/droidlover/xdroidmvp/kit/KnifeKit.java
+++ /dev/null
@@ -1,45 +0,0 @@
-package cn.droidlover.xdroidmvp.kit;
-
-import android.app.Activity;
-import android.app.Dialog;
-import android.view.View;
-
-import butterknife.ButterKnife;
-import butterknife.Unbinder;
-
-/**
- * Created by wanglei on 2016/11/27.
- */
-
-public class KnifeKit {
-
- public static Unbinder bind(Object target) {
- if (target instanceof Activity) {
- return ButterKnife.bind((Activity) target);
- } else if (target instanceof Dialog) {
- return ButterKnife.bind((Dialog) target);
- } else if (target instanceof View) {
- return ButterKnife.bind((View) target);
- }
- return Unbinder.EMPTY;
- }
-
-
- public static Unbinder bind(Object target, Object source) {
- if (source instanceof Activity) {
- return ButterKnife.bind(target, (Activity) source);
- } else if (source instanceof Dialog) {
- return ButterKnife.bind(target, (Dialog) source);
- } else if (source instanceof View) {
- return ButterKnife.bind(target, (View) source);
- }
- return Unbinder.EMPTY;
- }
-
-
- public static void unbind(Unbinder unbinder) {
- if (unbinder != Unbinder.EMPTY) {
- unbinder.unbind();
- }
- }
-}
diff --git a/mvp/src/main/java/cn/droidlover/xdroidmvp/mvp/IView.java b/mvp/src/main/java/cn/droidlover/xdroidmvp/mvp/IView.java
index 56c3224..7c1d76e 100644
--- a/mvp/src/main/java/cn/droidlover/xdroidmvp/mvp/IView.java
+++ b/mvp/src/main/java/cn/droidlover/xdroidmvp/mvp/IView.java
@@ -8,7 +8,6 @@
*/
public interface IView {
- void bindUI(View rootView);
void bindEvent();
diff --git a/mvp/src/main/java/cn/droidlover/xdroidmvp/mvp/LazyFragment.java b/mvp/src/main/java/cn/droidlover/xdroidmvp/mvp/LazyFragment.java
index bb09e92..d5a5320 100644
--- a/mvp/src/main/java/cn/droidlover/xdroidmvp/mvp/LazyFragment.java
+++ b/mvp/src/main/java/cn/droidlover/xdroidmvp/mvp/LazyFragment.java
@@ -220,7 +220,9 @@ public void onDestroyView() {
rootView = null;
container = null;
layoutInflater = null;
- if (isInitReady) onDestoryLazy();
+ if (isInitReady) {
+ onDestoryLazy();
+ }
isInitReady = false;
}
diff --git a/mvp/src/main/java/cn/droidlover/xdroidmvp/mvp/XActivity.java b/mvp/src/main/java/cn/droidlover/xdroidmvp/mvp/XActivity.java
index 5c58977..ba1e88f 100644
--- a/mvp/src/main/java/cn/droidlover/xdroidmvp/mvp/XActivity.java
+++ b/mvp/src/main/java/cn/droidlover/xdroidmvp/mvp/XActivity.java
@@ -4,14 +4,11 @@
import android.os.Bundle;
import androidx.annotation.Nullable;
import android.view.Menu;
-import android.view.View;
import com.tbruyelle.rxpermissions2.RxPermissions;
-import butterknife.Unbinder;
import cn.droidlover.xdroidmvp.XDroidConf;
import cn.droidlover.xdroidmvp.event.BusProvider;
-import cn.droidlover.xdroidmvp.kit.KnifeKit;
import com.trello.rxlifecycle3.components.support.RxAppCompatActivity;
/**
@@ -26,7 +23,6 @@ public abstract class XActivity
extends RxAppCompatActivity
private RxPermissions rxPermissions;
- private Unbinder unbinder;
@Override
@@ -38,18 +34,12 @@ protected void onCreate(@Nullable Bundle savedInstanceState) {
if (getLayoutId() > 0) {
setContentView(getLayoutId());
- bindUI(null);
bindEvent();
}
initData(savedInstanceState);
}
- @Override
- public void bindUI(View rootView) {
- unbinder = KnifeKit.bind(this);
- }
-
protected VDelegate getvDelegate() {
if (vDelegate == null) {
vDelegate = VDelegateBase.create(context);
diff --git a/mvp/src/main/java/cn/droidlover/xdroidmvp/mvp/XFragment.java b/mvp/src/main/java/cn/droidlover/xdroidmvp/mvp/XFragment.java
index 97e40f0..5d0dee2 100644
--- a/mvp/src/main/java/cn/droidlover/xdroidmvp/mvp/XFragment.java
+++ b/mvp/src/main/java/cn/droidlover/xdroidmvp/mvp/XFragment.java
@@ -10,10 +10,8 @@
import com.tbruyelle.rxpermissions2.RxPermissions;
-import butterknife.Unbinder;
import cn.droidlover.xdroidmvp.XDroidConf;
import cn.droidlover.xdroidmvp.event.BusProvider;
-import cn.droidlover.xdroidmvp.kit.KnifeKit;
import com.trello.rxlifecycle3.components.support.RxFragment;
/**
@@ -30,8 +28,6 @@ public abstract class XFragment
extends RxFragment implement
private RxPermissions rxPermissions;
- private Unbinder unbinder;
-
@Nullable
@Override
@@ -39,7 +35,6 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle sa
layoutInflater = inflater;
if (rootView == null && getLayoutId() > 0) {
rootView = inflater.inflate(getLayoutId(), null);
- bindUI(rootView);
} else {
ViewGroup viewGroup = (ViewGroup) rootView.getParent();
if (viewGroup != null) {
@@ -63,11 +58,6 @@ public void onActivityCreated(@Nullable Bundle savedInstanceState) {
initData(savedInstanceState);
}
- @Override
- public void bindUI(View rootView) {
- unbinder = KnifeKit.bind(this, rootView);
- }
-
protected VDelegate getvDelegate() {
if (vDelegate == null) {
vDelegate = VDelegateBase.create(context);
diff --git a/mvp/src/main/java/cn/droidlover/xdroidmvp/mvp/XLazyFragment.java b/mvp/src/main/java/cn/droidlover/xdroidmvp/mvp/XLazyFragment.java
index 1482a54..e442fe6 100644
--- a/mvp/src/main/java/cn/droidlover/xdroidmvp/mvp/XLazyFragment.java
+++ b/mvp/src/main/java/cn/droidlover/xdroidmvp/mvp/XLazyFragment.java
@@ -5,10 +5,8 @@
import com.tbruyelle.rxpermissions2.RxPermissions;
-import butterknife.Unbinder;
import cn.droidlover.xdroidmvp.XDroidConf;
import cn.droidlover.xdroidmvp.event.BusProvider;
-import cn.droidlover.xdroidmvp.kit.KnifeKit;
/**
* Created by wanglei on 2017/1/26.
@@ -21,7 +19,6 @@ public abstract class XLazyFragment
private P p;
private RxPermissions rxPermissions;
- private Unbinder unbinder;
@Override
protected void onCreateViewLazy(Bundle savedInstanceState) {
@@ -31,7 +28,6 @@ protected void onCreateViewLazy(Bundle savedInstanceState) {
if (getLayoutId() > 0) {
setContentView(getLayoutId());
- bindUI(getRealRootView());
}
if (useEventBus()) {
BusProvider.getBus().register(this);
@@ -40,11 +36,6 @@ protected void onCreateViewLazy(Bundle savedInstanceState) {
initData(savedInstanceState);
}
- @Override
- public void bindUI(View rootView) {
- unbinder = KnifeKit.bind(this, rootView);
- }
-
@Override
public void bindEvent() {
diff --git a/settings.gradle b/settings.gradle
index ace07e0..ad346bd 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -1 +1 @@
-include ':app', ':mvp', ':test',':xrecycler'
+include ':app', ':mvp', ':test',':xrecycler',':utill'
diff --git a/test/build.gradle b/test/build.gradle
index 4383c2e..956030e 100644
--- a/test/build.gradle
+++ b/test/build.gradle
@@ -20,7 +20,6 @@ android {
dependencies {
api fileTree(dir: 'libs', include: ['*.jar'])
- annotationProcessor rootProject.ext.dependencies["butterknife-apt"]
- api project(":mvp")
+ api "com.lennon.utill:xdroid-mvp:1.0.1"
}
diff --git a/utill/build.gradle b/utill/build.gradle
new file mode 100644
index 0000000..0723a40
--- /dev/null
+++ b/utill/build.gradle
@@ -0,0 +1,47 @@
+apply plugin: 'com.android.library'
+apply plugin: 'com.github.dcendents.android-maven'
+
+apply plugin: 'kotlin-android'
+apply plugin: 'kotlin-android-extensions'
+
+apply plugin: 'com.novoda.bintray-release'
+publish {
+ artifactId = 'lennon-utill' // artifactId
+ uploadName = 'LennonUtill' // 展示名字
+ publishVersion = '1.0.3' // 版本
+ userOrg = rootProject.userOrg
+ groupId = rootProject.groupId
+ repoName = rootProject.repoName
+ desc = ''
+ website = rootProject.website
+ licences = rootProject.licences
+}
+android {
+ compileSdkVersion rootProject.ext.android.compileSdkVersion
+
+ defaultConfig {
+ minSdkVersion rootProject.ext.android.minSdkVersion
+ targetSdkVersion rootProject.ext.android.targetSdkVersion
+ versionCode rootProject.ext.android.versionCode
+ versionName rootProject.ext.android.versionName
+ }
+
+ lintOptions {
+ abortOnError false
+ }
+}
+dependencies {
+ api fileTree(include: ['*.jar'], dir: 'libs')
+ api rootProject.ext.dependencies["xdroid-mvp"]
+
+ api rootProject.ext.dependencies["PersistentCookieJar"]
+ api rootProject.ext.dependencies["qiujuer-ui"]
+ api rootProject.ext.dependencies["multidex"]
+ api rootProject.ext.dependencies["exifinterface"]
+ api rootProject.ext.dependencies["constraintlayout"]
+
+ api rootProject.ext.dependencies["navigation-fragment-ktx"]
+ api rootProject.ext.dependencies["navigation-ui-ktx"]
+ api rootProject.ext.dependencies["navigation-ui"]
+ api rootProject.ext.dependencies["navigation-fragment"]
+}
diff --git a/utill/consumer-rules.pro b/utill/consumer-rules.pro
new file mode 100644
index 0000000..e69de29
diff --git a/utill/proguard-rules.pro b/utill/proguard-rules.pro
new file mode 100644
index 0000000..f1b4245
--- /dev/null
+++ b/utill/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
diff --git a/utill/src/main/AndroidManifest.xml b/utill/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..d4ae61b
--- /dev/null
+++ b/utill/src/main/AndroidManifest.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/utill/src/main/java/com/lennon/cn/utill/adapter/BaseViewAdapter.kt b/utill/src/main/java/com/lennon/cn/utill/adapter/BaseViewAdapter.kt
new file mode 100644
index 0000000..4a7ed3c
--- /dev/null
+++ b/utill/src/main/java/com/lennon/cn/utill/adapter/BaseViewAdapter.kt
@@ -0,0 +1,32 @@
+package com.lennon.cn.utill.adapter
+
+import android.content.Context
+import android.view.View
+import android.widget.ImageView
+import android.widget.TextView
+import androidx.recyclerview.widget.RecyclerView
+import cn.droidlover.xdroidmvp.base.SimpleRecAdapter
+import com.lennon.cn.utill.bean.BaseViewBean
+import lennon.com.utill.R
+
+class BaseViewAdapter(context: Context) : SimpleRecAdapter(context) {
+ override fun newViewHolder(itemView: View): ViewHolder {
+ return ViewHolder(itemView)
+ }
+
+ override fun getLayoutId(): Int {
+ return R.layout.item_base_view
+ }
+
+ override fun onBindViewHolder(holder: ViewHolder, position: Int) {
+// super.onBindViewHolder(holder, position)
+ val d = data[position]
+ d.loadIcon(holder.icon)
+ d.loadName(holder.name)
+ }
+
+ class ViewHolder(v: View) : RecyclerView.ViewHolder(v) {
+ val icon = v.findViewById(R.id.icon)
+ val name = v.findViewById(R.id.name)
+ }
+}
\ No newline at end of file
diff --git a/utill/src/main/java/com/lennon/cn/utill/adapter/StringItemAdapter.kt b/utill/src/main/java/com/lennon/cn/utill/adapter/StringItemAdapter.kt
new file mode 100644
index 0000000..4bde0db
--- /dev/null
+++ b/utill/src/main/java/com/lennon/cn/utill/adapter/StringItemAdapter.kt
@@ -0,0 +1,81 @@
+package com.lennon.cn.utill.adapter
+
+import android.content.Context
+import android.graphics.Typeface
+import android.util.TypedValue
+import android.view.View
+import android.widget.TextView
+import androidx.recyclerview.widget.RecyclerView
+import cn.droidlover.xdroidmvp.base.SimpleRecAdapter
+import com.lennon.cn.utill.bean.StringBean
+import com.lennon.cn.utill.utill.TeminalDevice
+import com.lennon.cn.utill.utill.Utill
+import lennon.com.utill.R
+
+/**
+ * Created by lennon on 2017/9/20.
+ */
+
+open class StringItemAdapter(context: Context) :
+ SimpleRecAdapter.ViewHolder>(context) {
+
+ private var textSize: List? = null
+ private var typefaces: List? = null
+ private var colors: List? = null
+ fun setTypefaces(typefaces: List) {
+ this.typefaces = typefaces
+ }
+
+ fun setColors(colors: List) {
+ this.colors = colors
+ }
+
+ fun setTextSize(textSize: List) {
+ this.textSize = textSize
+ }
+
+ override fun newViewHolder(itemView: View): ViewHolder {
+ return ViewHolder(itemView)
+ }
+
+ override fun getLayoutId(): Int {
+ return R.layout.item_string_item
+ }
+
+ override fun onBindViewHolder(holder: ViewHolder, position: Int) {
+// super.onBindViewHolder(holder, position)
+ holder.name.text = data[position].itemString
+ holder.name.setBackgroundResource(R.color.color_ffffff)
+ holder.name.setTextColor(Utill.getColor(context.resources, R.color.color_0F83F0))
+ if (typefaces != null && typefaces!!.isNotEmpty()) {
+ holder.name.typeface = typefaces!![position % typefaces!!.size]
+ }
+ if (colors != null && colors!!.isNotEmpty()) {
+ holder.name.setBackgroundColor(Utill.getColor(context.resources, colors!![position % colors!!.size]))
+ }
+ if (textSize != null && textSize!!.isNotEmpty()) {
+ holder.name.textSize = TeminalDevice.dip2px(
+ context,
+ textSize!![position % textSize!!.size].toFloat()
+ ).toFloat()
+ }
+ }
+
+
+ inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
+ internal var name = itemView.findViewById(R.id.name) as TextView
+
+ fun upBack(resource: Int, textColor: Int) {
+ name.setBackgroundResource(resource)
+ name.setTextColor(Utill.getColor(context.resources, textColor))
+ }
+
+ fun unselect() {
+ upBack(R.drawable.conner_f2f2f2, R.color.color_333333)
+ }
+
+ fun select() {
+ upBack(R.drawable.conner_fd0202, R.color.color_ffffff)
+ }
+ }
+}
diff --git a/utill/src/main/java/com/lennon/cn/utill/base/BaseActivity.kt b/utill/src/main/java/com/lennon/cn/utill/base/BaseActivity.kt
new file mode 100644
index 0000000..d6eaa52
--- /dev/null
+++ b/utill/src/main/java/com/lennon/cn/utill/base/BaseActivity.kt
@@ -0,0 +1,212 @@
+package com.lennon.cn.utill.base
+
+import android.app.Activity
+import android.content.Context
+import android.content.Intent
+import android.os.Bundle
+import android.view.View
+import android.view.ViewGroup
+import android.widget.Toast
+import cn.droidlover.xdroidmvp.log.XLog
+import cn.droidlover.xdroidmvp.mvp.XActivity
+import cn.droidlover.xdroidmvp.net.NetError
+
+import com.lennon.cn.utill.conf.Lennon
+import com.lennon.cn.utill.dialog.CommonAlertDialog
+import com.lennon.cn.utill.dialog.CustomProgressDialog
+import com.lennon.cn.utill.dialog.OnAlertDialogListener
+import com.lennon.cn.utill.utill.AppStatusManager
+import com.lennon.cn.utill.utill.StatusBarUtil
+import com.lennon.cn.utill.utill.Utill
+import java.lang.Exception
+
+
+abstract class BaseActivity> : XActivity
(), BaseView
{
+ private var TAG = javaClass.simpleName
+ private var dialog: CustomProgressDialog? = null
+
+ /** * 设置当前窗口亮度 * @param brightness */
+ fun setWindowBrightness(brightness: Float) {
+ val window = window
+ val lp = window.attributes
+ lp.screenBrightness = brightness
+ window.attributes = lp
+ }
+
+ /**
+ * 获取当前屏幕亮度
+ */
+ fun getBrightness(): Int {
+ val lp = window?.attributes
+ if (lp != null) {
+ //screenBrightness 默认为-1
+ if (lp.screenBrightness < 0) return 0
+ return (lp.screenBrightness * 255).toInt()
+ }
+ return 0
+ }
+
+ override fun showProgressDialog(msg: String) {
+ if (dialog != null) dialog!!.dismiss()
+ dialog = CustomProgressDialog(getContext())
+ dialog!!.setMessage(msg)
+ dialog!!.show()
+ }
+
+ override fun useEventBus(): Boolean {
+ return true
+ }
+
+ override fun closeProgressDialog() {
+ if (null != dialog) dialog!!.dismiss()
+ }
+
+ override fun toast(msg: String, second: Int) {
+ val dialog = CommonAlertDialog(this)
+ dialog.setMsg(msg)
+ dialog.disableCancle()
+ dialog.show()
+ dialog.setDialogListener(object : OnAlertDialogListener() {
+ override fun onSure() {
+ super.onSure()
+ dialog.dismiss()
+ }
+ })
+ Toast.makeText(getContext(), msg, second)
+ .show()
+ }
+
+ override fun toast(msg: String) {
+ toast(msg, true)
+ }
+
+ override fun toast(msg: String, runnable: Runnable) {
+ val dialog = CommonAlertDialog(getContext())
+ dialog.setMsg(msg)
+ dialog.disableCancle()
+ dialog.show()
+ dialog.setDialogListener(object : OnAlertDialogListener() {
+ override fun onSure() {
+ super.onSure()
+ dialog.dismiss()
+ runnable.run()
+ }
+ })
+ Toast.makeText(getContext(), msg, Toast.LENGTH_SHORT)
+ .show()
+ }
+
+ override fun toast(msg: String, flag: Boolean) {
+ if (flag) {
+ val dialog = CommonAlertDialog(this)
+ dialog.setMsg(msg)
+ dialog.disableCancle()
+ dialog.show()
+ dialog.setDialogListener(object : OnAlertDialogListener() {
+ override fun onSure() {
+ super.onSure()
+ dialog.dismiss()
+ }
+ })
+ }
+ Toast.makeText(getContext(), msg, Toast.LENGTH_SHORT)
+ .show()
+ }
+
+ override fun showLoading(visibility: Int) {
+ }
+
+ override fun showLoadingError(errorType: NetError) {
+
+ }
+
+ override fun getContext(): Context {
+ return this
+ }
+
+ override fun onRefresh(bRefresh: Boolean) {
+ XLog.e("$TAG:onRefresh()")
+ }
+
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ XLog.e("$TAG:onCreate")
+// Thread.setDefaultUncaughtExceptionHandler(CrashHandler(this))
+ Lennon.useDensity(this)
+// window.addFlags(WindowManager.LayoutParams.FLAG_SECURE)
+ super.onCreate(savedInstanceState)
+ if (checkAppStatus()) {
+ BaseApplication.restart(this)
+ finish()
+ } else {
+ BaseApplication.addActivity(this)
+ try {
+ if ((this.findViewById(android.R.id.content) as ViewGroup).getChildAt(0) != null) {
+ StatusBarUtil.setColorNoTranslucent(
+ this,
+ Utill.getColor(resources, getMTitleColor())
+ )
+ // StatusBarUtil.setImmersiveStatusBar(this, false)
+ }
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ }
+ }
+
+ open fun getMTitleColor(): Int {
+ return Lennon.getTitleColor()
+ }
+
+ override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
+ XLog.e("$TAG:onActivityResult($requestCode,$resultCode)")
+ super.onActivityResult(requestCode, resultCode, data)
+ }
+
+
+ override fun onStart() {
+ super.onStart()
+ XLog.e("$TAG:onStart()")
+ }
+
+ override fun onDestroy() {
+ BaseApplication.exitActivity(this)
+ XLog.e("$TAG:onDestroy()")
+ super.onDestroy()
+ }
+
+ override fun onPause() {
+ XLog.e("$TAG:onPause()")
+ super.onPause()
+ }
+
+ override fun onResume() {
+ XLog.e("$TAG:onResume()")
+ super.onResume()
+ }
+
+ override fun onBackPressed() {
+ XLog.e("$TAG:onBackPressed()")
+ super.onBackPressed()
+ }
+
+ override fun onPostResume() {
+ XLog.e("$TAG:onPostResume()")
+ super.onPostResume()
+ }
+
+ override fun onStop() {
+ XLog.e("$TAG:onStop()")
+ super.onStop()
+ }
+
+ private fun checkAppStatus(): Boolean {
+ XLog.e(TAG + ":" + AppStatusManager.getInstance().appStatus)
+ return AppStatusManager.getInstance().appStatus == AppStatusManager.AppStatusConstant.APP_FORCE_KILLED
+ }
+
+ override fun getActivity(): Activity {
+ return this
+ }
+
+}
diff --git a/utill/src/main/java/com/lennon/cn/utill/base/BaseApi.java b/utill/src/main/java/com/lennon/cn/utill/base/BaseApi.java
new file mode 100644
index 0000000..538cded
--- /dev/null
+++ b/utill/src/main/java/com/lennon/cn/utill/base/BaseApi.java
@@ -0,0 +1,50 @@
+package com.lennon.cn.utill.base;
+
+
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+
+import cn.droidlover.xdroidmvp.net.IModel;
+import cn.droidlover.xdroidmvp.net.XApi;
+import io.reactivex.Flowable;
+
+/**
+ * Created by lennon on 2017/8/10.
+ */
+
+public abstract class BaseApi {
+ public T service;
+ protected Class tClass;
+
+ public BaseApi(String url) {
+ tClass = (Class) getModelClass(0);
+ try {
+ service = XApi.getInstance().getRetrofit(url, true).create(tClass);
+ } catch (Exception e) {
+ e.printStackTrace();
+ BaseApplication.Companion.registerProvider();
+ service = XApi.getInstance().getRetrofit(url, true).create(tClass);
+ }
+ }
+
+ public final Flowable compose(Flowable flowable) {
+ return flowable.compose(XApi.getApiTransformer())
+ .compose(XApi.getScheduler());
+ }
+
+ //泛型类作为父类,可以获取子类的所有实际参数的类型
+ @SuppressWarnings("unchecked")
+ public Class> getModelClass(int index) {
+ Class modelClass;
+ // 得到泛型父类
+ Type genType = this.getClass().getGenericSuperclass();
+ //一个泛型类可能有多个泛型形参,比如ClassName 这里有两个泛型形参T和K,Class Name 这里只有1个泛型形参T
+ Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
+ if (params.length - 1 < index) {
+ modelClass = null;
+ } else {
+ modelClass = (Class) params[index];
+ }
+ return modelClass;
+ }
+}
diff --git a/utill/src/main/java/com/lennon/cn/utill/base/BaseApplication.kt b/utill/src/main/java/com/lennon/cn/utill/base/BaseApplication.kt
new file mode 100644
index 0000000..6f3df81
--- /dev/null
+++ b/utill/src/main/java/com/lennon/cn/utill/base/BaseApplication.kt
@@ -0,0 +1,382 @@
+package com.lennon.cn.utill.base
+
+import android.app.Activity
+import android.content.Context
+import android.content.res.Configuration
+import android.content.res.Resources
+import android.text.TextUtils
+import androidx.multidex.MultiDex
+import androidx.multidex.MultiDexApplication
+import cn.droidlover.xdroidmvp.cache.SharedPref
+import cn.droidlover.xdroidmvp.log.XLog
+import cn.droidlover.xdroidmvp.net.NetError
+import cn.droidlover.xdroidmvp.net.NetProvider
+import cn.droidlover.xdroidmvp.net.RequestHandler
+import cn.droidlover.xdroidmvp.net.XApi
+import com.franmontiel.persistentcookiejar.PersistentCookieJar
+import com.franmontiel.persistentcookiejar.cache.SetCookieCache
+import com.franmontiel.persistentcookiejar.persistence.SharedPrefsCookiePersistor
+import com.lennon.cn.utill.conf.Lennon
+import com.lennon.cn.utill.utill.DensityUtils
+import com.lennon.cn.utill.utill.TimeUtill
+import com.lennon.cn.utill.utill.Utill
+import lennon.com.utill.BuildConfig
+import okhttp3.*
+import java.io.BufferedReader
+import java.io.FileReader
+import java.util.*
+
+/**
+ * Created by lennon on 2017/7/26.
+ */
+open class BaseApplication : MultiDexApplication() {
+
+ override fun attachBaseContext(base: Context) {
+ super.attachBaseContext(base)
+ MultiDex.install(base)
+ }
+
+ override fun onConfigurationChanged(newConfig: Configuration) {
+ if (newConfig.fontScale != 1f)
+ //非默认值
+ resources
+ super.onConfigurationChanged(newConfig)
+ }
+
+ override fun getResources(): Resources {
+ val res = super.getResources()
+ if (res.configuration.fontScale != 1f) {//非默认值
+ val newConfig = Configuration()
+ newConfig.setToDefaults()//设置默认
+ res.updateConfiguration(newConfig, res.displayMetrics)
+ }
+ return res
+ }
+
+ open fun init() {
+ registerProvider()
+// val context = applicationContext
+ // 获取当前包名
+// val packageName = context.packageName
+ // 获取当前进程名
+// val processName = getProcessName(android.os.Process.myPid())
+ // 设置是否为上报进程
+// val strategy = CrashReport.UserStrategy(context)
+// strategy.isUploadProcess = processName == null || processName == packageName
+ // 初始化Bugly
+// CrashReport.initCrashReport(context, Lennon.getCrashID(), Lennon.isTest())
+// NLoggerConfig.getInstance()
+// .builder()
+// .tag("APP")
+// .loggerLevel(LoggerLevel.INFO)
+// .fileLogger(true)
+// .fileDirectory(getDataFile() + "/logs")
+// .fileFormatter(SimpleFormatter())
+// .expiredPeriod(7)
+// .catchException(true) { _, throwable ->
+// getCuttureActivity()?.finish()
+// val t = if (throwable != null) {
+// throwable
+// } else {
+// Throwable("未知异常")
+// }
+// t.printStackTrace()
+// getCuttureActivity()!!.runOnUiThread {
+// // 使用Toast来显示异常信息
+// object : Thread() {
+// override fun run() {
+// Looper.prepare()
+// Toast.makeText(
+// getCuttureActivity(),
+// "很抱歉,程序出现异常,即将退出,请前往 我的 上传日志并联系客服:" + t.message,
+// Toast.LENGTH_LONG
+// ).show()
+// Looper.loop()
+// }
+// }.start()
+//
+// Toast.makeText(
+// getCuttureActivity(),
+// "非常抱歉,程序出错了,请前往 我的 上传日志并联系客服:" + t.message,
+// Toast.LENGTH_SHORT
+// ).show()
+// XLog.e("uncaughtException", t.message)
+// Lennon.restartApp()
+// AppExit()
+// }
+// }.build()
+ }
+
+ override fun onCreate() {
+ DensityUtils.setDensity(this)
+ appliction = this
+ super.onCreate()
+
+ }
+
+ companion object {
+ private var list: ArrayList? = null
+ private val loger = true
+ private var appliction: BaseApplication? = null
+ private var cookiePersistor: SharedPrefsCookiePersistor? = null
+ private var cookieJar: PersistentCookieJar? = null
+ private var test = true
+ /**
+ * 获取进程号对应的进程名
+ *
+ * @param pid 进程号
+ * @return 进程名
+ */
+ fun getProcessName(pid: Int): String? {
+ var reader: BufferedReader? = null
+ try {
+ reader = BufferedReader(FileReader("/proc/" + pid + "/cmdline"))
+ var processName = reader.readLine()
+ if (!TextUtils.isEmpty(processName)) {
+ processName = processName.trim()
+ }
+ return processName
+ } catch (throwable: Throwable) {
+ throwable.printStackTrace()
+ } finally {
+ try {
+ if (reader != null) {
+ reader.close()
+ }
+ } catch (exception: Exception) {
+ exception.printStackTrace()
+ }
+ }
+ return null
+ }
+
+// fun init() {
+// NLoggerConfig.getInstance()
+// .builder()
+// .tag("APP")
+// .loggerLevel(LoggerLevel.INFO)
+// .fileLogger(true)
+// .fileDirectory(getDataFile() + "/logs")
+// .fileFormatter(SimpleFormatter())
+// .expiredPeriod(7)
+// .catchException(true) { _, throwable ->
+// getCuttureActivity()?.finish()
+// val t = if (throwable != null) {
+// throwable
+// } else {
+// Throwable("未知异常")
+// }
+// t.printStackTrace()
+//// if (getCuttureActivity() != null) {
+// getCuttureActivity()!!.runOnUiThread {
+// // 使用Toast来显示异常信息
+// object : Thread() {
+// override fun run() {
+// Looper.prepare()
+// Toast.makeText(
+// getCuttureActivity(),
+// "很抱歉,程序出现异常,即将退出,请联系客服:" + t.message,
+// Toast.LENGTH_LONG
+// ).show()
+// Looper.loop()
+// }
+// }.start()
+// // val dialog = CommonAlertDialog(getCuttureActivity())
+//// dialog.setTitle("非常抱歉")
+//// dialog.setCancelable(false)
+//// dialog.setCanceledOnTouchOutside(false)
+//// dialog.setMsg("程序出错了,请联系客服:" + t.message)
+//// dialog.setDialogListener(object : OnAlertDialogListener() {
+//// override fun onSure() {
+//// super.onSure()
+//// dialog.dismiss()
+//// XLog.e("uncaughtException", throwable!!)
+//// Lennon.restartApp()
+//// AppExit()
+//// }
+//// })
+//// dialog.show()
+//// }
+//// } else {
+// Toast.makeText(
+// getCuttureActivity(),
+// "非常抱歉,程序出错了,请联系客服:" + t.message,
+// Toast.LENGTH_SHORT
+// ).show()
+// XLog.e("uncaughtException", t.message)
+// Lennon.restartApp()
+// AppExit()
+// }
+//// android.os.Process.killProcess(android.os.Process.myPid())
+// }.build()
+//
+// }
+
+ fun isLoger(): Boolean {
+ return loger
+ }
+
+ fun context(): Context? {
+ return appliction
+ }
+
+ fun registerProvider() {
+ if (cookieJar == null) {
+ cookiePersistor = SharedPrefsCookiePersistor(appliction!!)
+ cookieJar = PersistentCookieJar(SetCookieCache(), cookiePersistor!!)
+ }
+ XApi.registerProvider(object : NetProvider {
+
+ override fun configInterceptors(): Array {
+ return arrayOfNulls(0)
+ }
+
+ override fun configHttps(builder: OkHttpClient.Builder) {
+
+ }
+
+ override fun configCookie(): CookieJar? {
+ return cookieJar
+ }
+
+ override fun configHandler(): RequestHandler {
+ return object : RequestHandler {
+ private var sendTime = 0L
+ private var url = ""
+ override fun onBeforeRequest(
+ request: Request,
+ chain: Interceptor.Chain
+ ): Request? {
+ val builder = chain.request().newBuilder()
+ builder.addHeader("Content-Type", "application/json;charset=utf-8")
+ builder.addHeader("Accept", "application/json;charset=utf-8")
+ sendTime = System.currentTimeMillis()
+ url = request.url().toString()
+ try {
+ return builder.build()
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ return null
+ }
+
+ override fun onAfterRequest(
+ response: Response,
+ chain: Interceptor.Chain
+ ): Response {
+ if (getCuttureActivity() != null) {
+ val end = System.currentTimeMillis()
+ val mss = end - sendTime
+ XLog.e("请求" + url + "耗时" + TimeUtill.formatDuring(mss))
+ }
+ return response
+ }
+ }
+ }
+
+ override fun configConnectTimeoutMills(): Long {
+ return 60000
+ }
+
+ override fun configReadTimeoutMills(): Long {
+ return 60000
+ }
+
+ override fun configLogEnable(): Boolean {
+ return BaseApplication.isLoger()
+ }
+
+ override fun handleError(error: NetError): Boolean {
+ return Lennon.handleNetError(error)
+ }
+
+ override fun dispatchProgressEnable(): Boolean {
+ return false
+ }
+ })
+ }
+
+ fun getDataFile(): String {
+ Utill.makeDir(Lennon.getFilePathName())
+ return Lennon.getFilePathName()
+ }
+
+ val cookie: List
+ get() = cookiePersistor!!.loadAll()
+
+ fun clearCookies() {
+ cookieJar!!.clear()
+ }
+
+ fun setCookies(cookie: List) {}
+ fun addActivity(activity: Activity) {
+ if (list == null)
+ list = ArrayList()
+ list!!.add(activity)
+ }
+
+ fun exitActivity(activity: Activity?) {
+ if (list != null) {
+// list!!.remove(activity)
+ list!!.remove(activity)
+ }
+ }
+
+
+ fun getCuttureActivity(): Activity? {
+ return if (list == null || list!!.size == 0) null else list!![list!!.size - 1]
+ }
+
+
+ fun AppExit() {
+ Lennon.appExit()
+ for (activity in list!!) {
+ activity?.finish()
+ }
+ System.exit(0)
+ }
+
+ fun clean() {
+ Lennon.clean()
+ SharedPref.getInstance(context()).clear()
+ }
+
+
+ fun resources(): Resources {
+ return context()!!.resources
+ }
+
+
+ fun finshActivity() {
+ for (activity in list!!) {
+ activity.finish()
+ }
+ }
+
+ fun restart(context: Context) {
+ if (list != null)
+ list!!.clear()
+ getAppliction()?.restart(context)
+ }
+
+ fun getAppliction(): BaseApplication? {
+ return appliction
+ }
+
+ fun isTest(): Boolean {
+ return test && BuildConfig.DEBUG
+ }
+
+ fun addCookie(cookie: Cookie) {
+ val l = cookiePersistor!!.loadAll()
+ l.add(cookie)
+ cookiePersistor!!.saveAll(l)
+ }
+ }
+
+ open fun restart(context: Context) {
+
+ }
+
+
+}
diff --git a/utill/src/main/java/com/lennon/cn/utill/base/BaseFragment.kt b/utill/src/main/java/com/lennon/cn/utill/base/BaseFragment.kt
new file mode 100644
index 0000000..990c16c
--- /dev/null
+++ b/utill/src/main/java/com/lennon/cn/utill/base/BaseFragment.kt
@@ -0,0 +1,145 @@
+package com.lennon.cn.utill.base
+
+import android.app.Activity
+import android.content.Context
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.Toast
+import cn.droidlover.xdroidmvp.log.XLog
+
+import cn.droidlover.xdroidmvp.mvp.XFragment
+import com.lennon.cn.utill.dialog.CommonAlertDialog
+import com.lennon.cn.utill.dialog.CustomProgressDialog
+import com.lennon.cn.utill.dialog.OnAlertDialogListener
+
+abstract class BaseFragment> : XFragment
(), BaseView
{
+ private var rootView: View? = null
+ private var dialog: CustomProgressDialog? = null
+ private var mActivity: Activity? = null
+ override fun showLoading(visibility: Int) {
+ }
+
+ override fun useEventBus(): Boolean {
+ return true
+ }
+
+ private var isFirst = true
+ private var stop = false
+
+
+ override fun onRefresh(bRefresh: Boolean) {
+ }
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ XLog.e(getName() + " onCreateView")
+ rootView = super.onCreateView(inflater, container, savedInstanceState)
+ return rootView
+ }
+
+
+ override fun showProgressDialog(msg: String) {
+ if (dialog != null)
+ dialog!!.dismiss()
+ dialog = CustomProgressDialog(getContext())
+ dialog!!.setMessage(msg)
+ dialog!!.show()
+ }
+
+
+ override fun onResume() {
+ super.onResume()
+ XLog.e(getName() + " onResume")
+ }
+
+
+ protected fun getName(): String {
+ return javaClass.simpleName
+ }
+
+ override fun closeProgressDialog() {
+ if (null != dialog)
+ dialog!!.dismiss()
+ }
+
+ override fun toast(msg: String) {
+ toast(msg, true)
+ }
+
+ override fun toast(msg: String, runnable: Runnable) {
+ val dialog = CommonAlertDialog(getContext())
+ dialog.setMsg(msg)
+ dialog.disableCancle()
+ dialog.show()
+ dialog.setDialogListener(object : OnAlertDialogListener() {
+ override fun onSure() {
+ super.onSure()
+ dialog.dismiss()
+ runnable.run()
+ }
+ })
+ Toast.makeText(getContext(), msg, Toast.LENGTH_SHORT)
+ .show()
+ }
+
+ override fun toast(msg: String, flag: Boolean) {
+ if (flag) {
+ val dialog = CommonAlertDialog(getContext())
+ dialog.setMsg(msg)
+ dialog.disableCancle()
+ dialog.show()
+ dialog.setDialogListener(object : OnAlertDialogListener() {
+ override fun onSure() {
+ super.onSure()
+ dialog.dismiss()
+ }
+ })
+ }
+ Toast.makeText(getContext(), msg, Toast.LENGTH_SHORT)
+ .show()
+ }
+
+ override fun toast(msg: String, second: Int) {
+ val dialog = CommonAlertDialog(getContext())
+ dialog.setMsg(msg)
+ dialog.disableCancle()
+ dialog.show()
+ dialog.setDialogListener(object : OnAlertDialogListener() {
+ override fun onSure() {
+ super.onSure()
+ dialog.dismiss()
+ }
+ })
+ Toast.makeText(getContext(), msg, second).show()
+ }
+
+ override fun onStop() {
+ XLog.e(getName() + " onStop")
+ stop = true
+ super.onStop()
+ }
+
+ override fun onAttach(activity: Activity) {
+ XLog.e(getName() + " onAttach")
+ super.onAttach(activity)
+ mActivity = activity
+ }
+
+ override fun onPause() {
+ XLog.e(getName() + " onPause")
+ super.onPause()
+ }
+
+ override fun getContext(): Context? {
+ return if (mActivity != null) {
+ mActivity
+ } else {
+ BaseApplication.getCuttureActivity()
+ }
+ }
+}
diff --git a/utill/src/main/java/com/lennon/cn/utill/base/BasePresent.java b/utill/src/main/java/com/lennon/cn/utill/base/BasePresent.java
new file mode 100644
index 0000000..fca5aac
--- /dev/null
+++ b/utill/src/main/java/com/lennon/cn/utill/base/BasePresent.java
@@ -0,0 +1,13 @@
+package com.lennon.cn.utill.base;
+
+import cn.droidlover.xdroidmvp.mvp.IView;
+import cn.droidlover.xdroidmvp.mvp.XPresent;
+import org.jetbrains.annotations.Nullable;
+
+public abstract class BasePresent extends XPresent {
+
+ public BasePresent(V v){
+ attachV(v);
+ }
+
+}
diff --git a/utill/src/main/java/com/lennon/cn/utill/base/BaseView.kt b/utill/src/main/java/com/lennon/cn/utill/base/BaseView.kt
new file mode 100644
index 0000000..288f5c8
--- /dev/null
+++ b/utill/src/main/java/com/lennon/cn/utill/base/BaseView.kt
@@ -0,0 +1,19 @@
+package com.lennon.cn.utill.base
+
+import android.app.Activity
+import android.content.Context
+import cn.droidlover.xdroidmvp.net.NetError
+
+interface BaseView?> {
+ fun showProgressDialog(msg: String)
+ fun closeProgressDialog()
+ fun toast(msg: String, second: Int)
+ fun toast(msg: String)
+ fun toast(msg: String, runnable: Runnable)
+ fun toast(msg: String, flag: Boolean)
+ fun showLoading(visibility: Int)
+ fun showLoadingError(errorType: NetError)
+ fun getContext(): Context?
+ fun onRefresh(bRefresh: Boolean)
+ fun getActivity(): Activity?
+}
\ No newline at end of file
diff --git a/utill/src/main/java/com/lennon/cn/utill/bean/BaseViewBean.java b/utill/src/main/java/com/lennon/cn/utill/bean/BaseViewBean.java
new file mode 100644
index 0000000..d36d0ff
--- /dev/null
+++ b/utill/src/main/java/com/lennon/cn/utill/bean/BaseViewBean.java
@@ -0,0 +1,14 @@
+package com.lennon.cn.utill.bean;
+
+import android.widget.ImageView;
+import android.widget.TextView;
+
+public interface BaseViewBean {
+ public void onClick();
+
+ public void onLongClick();
+
+ public void loadIcon(ImageView icon);
+
+ public void loadName(TextView name);
+}
diff --git a/utill/src/main/java/com/lennon/cn/utill/bean/Download.java b/utill/src/main/java/com/lennon/cn/utill/bean/Download.java
new file mode 100644
index 0000000..83b908f
--- /dev/null
+++ b/utill/src/main/java/com/lennon/cn/utill/bean/Download.java
@@ -0,0 +1,73 @@
+package com.lennon.cn.utill.bean;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.io.Serializable;
+
+/**
+ * Created by JokAr on 16/7/5.
+ */
+public class Download implements Parcelable,Serializable {
+
+ private int progress;
+ private long currentFileSize;
+ private long totalFileSize;
+
+ public int getProgress() {
+ return progress;
+ }
+
+ public void setProgress(int progress) {
+ this.progress = progress;
+ }
+
+ public long getCurrentFileSize() {
+ return currentFileSize;
+ }
+
+ public void setCurrentFileSize(long currentFileSize) {
+ this.currentFileSize = currentFileSize;
+ }
+
+ public long getTotalFileSize() {
+ return totalFileSize;
+ }
+
+ public void setTotalFileSize(long totalFileSize) {
+ this.totalFileSize = totalFileSize;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(this.progress);
+ dest.writeLong(this.currentFileSize);
+ dest.writeLong(this.totalFileSize);
+ }
+
+ public Download() {
+ }
+
+ protected Download(Parcel in) {
+ this.progress = in.readInt();
+ this.currentFileSize = in.readLong();
+ this.totalFileSize = in.readLong();
+ }
+
+ public static final Creator CREATOR = new Creator() {
+ @Override
+ public Download createFromParcel(Parcel source) {
+ return new Download(source);
+ }
+
+ @Override
+ public Download[] newArray(int size) {
+ return new Download[size];
+ }
+ };
+}
diff --git a/utill/src/main/java/com/lennon/cn/utill/bean/HttpEntity.java b/utill/src/main/java/com/lennon/cn/utill/bean/HttpEntity.java
new file mode 100644
index 0000000..7aa1b84
--- /dev/null
+++ b/utill/src/main/java/com/lennon/cn/utill/bean/HttpEntity.java
@@ -0,0 +1,67 @@
+package com.lennon.cn.utill.bean;
+
+import java.io.Serializable;
+import java.util.Collection;
+
+import cn.droidlover.xdroidmvp.net.IModel;
+
+/**
+ * Created by dingyi on 2016/11/30.
+ */
+
+public class HttpEntity implements IModel, Serializable {
+ private String msg;
+ private String code;
+ private T data;
+
+ public String getMsg() {
+ return msg;
+ }
+
+ public void setMsg(String msg) {
+ this.msg = msg;
+ }
+
+ public String getCode() {
+ return code;
+ }
+
+ public void setCode(String code) {
+ this.code = code;
+ }
+
+ public T getData() {
+ return data;
+ }
+
+ public void setData(T data) {
+ this.data = data;
+ }
+
+ public boolean isSuccess() {
+ return "0000".equals(code);
+ }
+
+ @Override
+ public boolean isNull() {
+ if (!"0000".equals(code)) {
+ return data == null && !"1000".equals(code);
+ }
+ return false;
+ }
+
+ @Override
+ public boolean isAuthError() {
+ return "1000".equals(code);
+ }
+
+ @Override
+ public boolean isBizError() {
+ return !"0000".equals(code);
+ }
+
+ @Override
+ public String getErrorMsg() {
+ return msg;
+ }
+}
diff --git a/utill/src/main/java/com/lennon/cn/utill/bean/StringBean.java b/utill/src/main/java/com/lennon/cn/utill/bean/StringBean.java
new file mode 100644
index 0000000..41520f1
--- /dev/null
+++ b/utill/src/main/java/com/lennon/cn/utill/bean/StringBean.java
@@ -0,0 +1,9 @@
+package com.lennon.cn.utill.bean;
+
+/**
+ * Created by lennon on 2018/5/7.
+ */
+
+public interface StringBean {
+ String getItemString();
+}
diff --git a/utill/src/main/java/com/lennon/cn/utill/cache/ACache.java b/utill/src/main/java/com/lennon/cn/utill/cache/ACache.java
new file mode 100644
index 0000000..caaed21
--- /dev/null
+++ b/utill/src/main/java/com/lennon/cn/utill/cache/ACache.java
@@ -0,0 +1,72 @@
+package com.lennon.cn.utill.cache;
+
+import android.content.Context;
+
+import cn.droidlover.xdroidmvp.cache.DiskCache;
+import cn.droidlover.xdroidmvp.cache.ICache;
+import cn.droidlover.xdroidmvp.cache.MemoryCache;
+
+public class ACache implements ICache {
+ DiskCache diskCache;
+ MemoryCache memoryCache;
+ private static ACache aCache;
+
+ private ACache(Context context) {
+ diskCache = DiskCache.getInstance(context);
+ memoryCache = MemoryCache.getInstance();
+ }
+
+ public static ACache getInstance(Context context) {
+ if (aCache == null) {
+ aCache = new ACache(context);
+ }
+ return aCache;
+
+ }
+
+// @Override
+// public synchronized void put(String key, String value) {
+// memoryCache.put(key, value);
+// diskCache.put(key, value);
+// }
+
+ @Override
+ public void put(String key, Object value) {
+ memoryCache.put(key, value);
+ diskCache.put(key, value);
+ }
+
+ @Override
+ public String get(String key) {
+ try {
+ if (memoryCache.contains(key)) {
+ return memoryCache.get(key).toString();
+ } else if (diskCache.contains(key)) {
+ String s = diskCache.get(key);
+ memoryCache.put(key, s);
+ return s;
+ }
+ return "";
+ } catch (Exception e) {
+ e.printStackTrace();
+ return "";
+ }
+ }
+
+ @Override
+ public void remove(String key) {
+ memoryCache.remove(key);
+ diskCache.remove(key);
+ }
+
+ @Override
+ public boolean contains(String key) {
+ return memoryCache.contains(key) || diskCache.contains(key);
+ }
+
+ @Override
+ public void clear() {
+ memoryCache.clear();
+ diskCache.clear();
+ }
+}
diff --git a/utill/src/main/java/com/lennon/cn/utill/cache/DataCache.java b/utill/src/main/java/com/lennon/cn/utill/cache/DataCache.java
new file mode 100644
index 0000000..695fdb6
--- /dev/null
+++ b/utill/src/main/java/com/lennon/cn/utill/cache/DataCache.java
@@ -0,0 +1,138 @@
+package com.lennon.cn.utill.cache;
+
+import android.text.TextUtils;
+
+import com.google.gson.Gson;
+import com.lennon.cn.utill.base.BaseApplication;
+import com.lennon.cn.utill.base.BaseView;
+import com.lennon.cn.utill.bean.HttpEntity;
+import com.lennon.cn.utill.conf.Lennon;
+import com.trello.rxlifecycle3.LifecycleProvider;
+
+import java.lang.reflect.Type;
+
+import androidx.annotation.NonNull;
+import cn.droidlover.xdroidmvp.cache.SharedPref;
+import cn.droidlover.xdroidmvp.mvp.IView;
+import cn.droidlover.xdroidmvp.net.ApiSubscriber;
+import cn.droidlover.xdroidmvp.net.NetError;
+import cn.droidlover.xdroidmvp.net.XApi;
+import io.reactivex.Flowable;
+
+/**
+ * Created by lennon on 2017/10/18.
+ */
+
+public class DataCache {
+ BaseView activity;
+ String dataKey;
+ Flowable flowable;
+ LifecycleProvider lifecycleProvider;
+ DataCallBack dataCallBack;
+ ACache maCache;
+ protected Type tClass;
+ private boolean refresh = false;
+
+ public static void initDataCache(String DataCacheKey) {
+ SharedPref.getInstance(BaseApplication.Companion.context()).putString("DataCacheKey", DataCacheKey);
+ }
+
+ public DataCache(BaseView activity, String dataKey, Flowable flowable,
+ LifecycleProvider lifecycleProvider, DataCallBack dataCallBack, Type tClass) {
+ this.tClass = tClass;
+ this.activity = activity;
+ this.dataKey = dataKey;
+ this.flowable = flowable;
+ this.lifecycleProvider = lifecycleProvider;
+ this.dataCallBack = dataCallBack;
+ this.maCache = ACache.getInstance(BaseApplication.Companion.context());
+ }
+
+ public void getData() {
+ T t = getLocalData();
+ if (t == null) {
+ activity.showProgressDialog("加载中……");
+ } else {
+ if (dataCallBack != null) {
+ dataCallBack.upView(t);
+ }
+ }
+ getDataFromNet();
+ }
+
+ public void refresh() {
+ refresh = true;
+ getDataFromNet();
+ }
+
+ String getKey(String a) {
+ return a + SharedPref.getInstance(BaseApplication.Companion.context()).getString("DataCacheKey", "");
+ }
+
+ void saveData(T t) {
+ maCache.put(getKey(dataKey), new Gson().toJson(t));
+ }
+
+ T getLocalData() {
+ if (TextUtils.isEmpty(maCache.get(getKey(dataKey)))) {
+ return null;
+ }
+
+ T t = new Gson().fromJson(maCache.get(getKey(dataKey)), tClass);
+ return t;
+ }
+
+ void getDataFromNet() {
+ flowable.compose(XApi.getApiTransformer())
+ .compose(XApi.getScheduler())
+ .compose(lifecycleProvider.bindToLifecycle())
+ .subscribe(new ApiSubscriber() {
+ @Override
+ protected void onFail(NetError error) {
+ if (getLocalData() != null) {
+ dataCallBack.netError(error);
+ } else {
+ dataCallBack.netErrorForNoData(error);
+ }
+ activity.closeProgressDialog();
+ if (error.getType() == NetError.AuthError) {
+ activity.toast("登陆失效", new Runnable() {
+ @Override
+ public void run() {
+ Lennon.Companion.requserLogin();
+ }
+ });
+ return;
+ }
+ }
+
+ @Override
+ public void onNext(T o) {
+ if (getLocalData() != null) {
+ String a = new Gson().toJson(getLocalData());
+ String b = new Gson().toJson(o);
+ if (a.equals(b) && refresh) {
+ dataCallBack.upView(o);
+ } else if (a.equals(b) && !refresh) {
+
+ } else {
+ dataCallBack.upView(o);
+ saveData(o);
+ }
+ } else {
+ dataCallBack.upView(o);
+ saveData(o);
+ }
+ activity.closeProgressDialog();
+ }
+ });
+ }
+
+ public interface DataCallBack {
+ void upView(@NonNull T t);
+
+ void netErrorForNoData(@NonNull NetError error);
+
+ void netError(@NonNull NetError error);
+ }
+}
diff --git a/utill/src/main/java/com/lennon/cn/utill/cache/DataListCache.java b/utill/src/main/java/com/lennon/cn/utill/cache/DataListCache.java
new file mode 100644
index 0000000..6f14ec9
--- /dev/null
+++ b/utill/src/main/java/com/lennon/cn/utill/cache/DataListCache.java
@@ -0,0 +1,163 @@
+package com.lennon.cn.utill.cache;
+
+import android.text.TextUtils;
+
+import cn.droidlover.xdroidmvp.net.NetError;
+import com.google.gson.Gson;
+import com.lennon.cn.utill.base.BaseApplication;
+import com.lennon.cn.utill.base.BaseView;
+import com.lennon.cn.utill.bean.HttpEntity;
+import com.lennon.cn.utill.conf.Lennon;
+import com.trello.rxlifecycle3.LifecycleProvider;
+
+import java.lang.reflect.Type;
+
+import androidx.annotation.NonNull;
+import cn.droidlover.xdroidmvp.cache.SharedPref;
+import cn.droidlover.xdroidmvp.net.ApiSubscriber;
+import cn.droidlover.xdroidmvp.net.XApi;
+import io.reactivex.Flowable;
+
+/**
+ * @author lennon
+ * @date 2017/10/18
+ */
+
+public class DataListCache {
+ BaseView activity;
+ String dataKey;
+ LifecycleProvider lifecycleProvider;
+ DataCallBack dataCallBack;
+ ACache maCache;
+ int startPage = 1;
+ int page = 0;
+ protected Type tClass;
+ private boolean refresh = false;
+
+ public static void initDataCache(String DataCacheKey) {
+ SharedPref.getInstance(BaseApplication.Companion.context()).putString("DataCacheKey", DataCacheKey);
+ }
+
+ public DataListCache(BaseView activity, String dataKey, int startPage,
+ LifecycleProvider lifecycleProvider, DataCallBack dataCallBack, Type tClass) {
+ this.tClass = tClass;
+ this.activity = activity;
+ this.dataKey = dataKey;
+ this.startPage = startPage;
+ this.lifecycleProvider = lifecycleProvider;
+ this.dataCallBack = dataCallBack;
+ this.maCache = ACache.getInstance(BaseApplication.Companion.context());
+ }
+
+ private void getData(int page) {
+ T t = getLocalData(page);
+ if (t == null) {
+ activity.showProgressDialog("加载中……");
+ } else {
+ if (dataCallBack != null) {
+ dataCallBack.upView(t, page);
+ }
+ }
+ getDataFromNet(page);
+ }
+
+ public void getData() {
+ getData(startPage);
+ }
+
+ public void refresh() {
+ refresh = true;
+ getDataFromNet(startPage);
+ }
+
+ String getKey(String a) {
+ return a + SharedPref.getInstance(BaseApplication.Companion.context()).getString("DataCacheKey", "");
+ }
+
+ public void loadMore() {
+ getData(page + 1);
+ }
+
+ void saveData(T t, int page) {
+ maCache.put(getKey(dataKey) + "_" + page, new Gson().toJson(t));
+ }
+
+ T getLocalData(int page) {
+ if (TextUtils.isEmpty(maCache.get(getKey(dataKey) + "_" + page))) {
+ return null;
+ }
+ T t = new Gson().fromJson(maCache.get(getKey(dataKey) + "_" + page), tClass);
+ return t;
+ }
+
+ void getDataFromNet(final int page) {
+ this.page = page;
+ dataCallBack.getFlowable(page).compose(XApi.getApiTransformer())
+ .compose(XApi.getScheduler())
+ .compose(lifecycleProvider.bindToLifecycle())
+ .subscribe(new ApiSubscriber() {
+ @Override
+ protected void onFail(NetError error) {
+ if (getLocalData(page) != null) {
+ dataCallBack.netError(error);
+ } else {
+ dataCallBack.netErrorForNoData(error);
+ }
+ activity.closeProgressDialog();
+ if (error.getType() == NetError.AuthError) {
+ activity.toast("登陆失效", new Runnable() {
+ @Override
+ public void run() {
+ Lennon.Companion.requserLogin();
+ }
+ });
+ return;
+ }
+ }
+
+ @Override
+ public void onNext(T o) {
+ if (getLocalData(page) != null) {
+ String a = new Gson().toJson(getLocalData(page));
+ String b = new Gson().toJson(o);
+ if (a.equals(b) && refresh) {
+ dataCallBack.upView(o, page);
+ } else if (a.equals(b) && !refresh) {
+
+ } else {
+ dataCallBack.upView(o, page);
+ saveData(o, page);
+ }
+ } else {
+ dataCallBack.upView(o, page);
+ saveData(o, page);
+ }
+ activity.closeProgressDialog();
+ }
+ });
+ }
+
+ public interface DataCallBack {
+ /**
+ * @param t
+ * @param page
+ */
+ void upView(@NonNull T t, int page);
+
+ /**
+ * @param error
+ */
+ void netErrorForNoData(@NonNull NetError error);
+
+ /**
+ * @param error
+ */
+ void netError(@NonNull NetError error);
+
+ /**
+ * @param page
+ * @return Flowable
+ */
+ Flowable getFlowable(int page);
+ }
+}
diff --git a/utill/src/main/java/com/lennon/cn/utill/conf/Lennon.kt b/utill/src/main/java/com/lennon/cn/utill/conf/Lennon.kt
new file mode 100644
index 0000000..19eed4e
--- /dev/null
+++ b/utill/src/main/java/com/lennon/cn/utill/conf/Lennon.kt
@@ -0,0 +1,106 @@
+package com.lennon.cn.utill.conf
+
+import android.app.Activity
+import cn.droidlover.xdroidmvp.net.NetError
+import com.lennon.cn.utill.utill.DensityUtils
+import lennon.com.utill.R
+
+class Lennon {
+ companion object {
+
+ var provider: LennonProvider? = null
+
+ fun registProvider(provider: LennonProvider) {
+ this.provider = provider
+ }
+
+ fun getFileProvide(): String {
+ if (provider == null) {
+ throw Throwable("请先注册provider")
+ }
+ return provider!!.getFileProvide()
+ }
+
+ fun appName(): String {
+ if (provider == null) {
+ throw Throwable("请先注册provider")
+ }
+ return provider!!.appName()
+ }
+
+ fun requserLogin() {
+ if (provider == null) {
+ throw Throwable("请先注册provider")
+ }
+ provider!!.requserLogin()
+ }
+
+ fun appExit() {
+ if (provider == null) {
+ throw Throwable("请先注册provider")
+ }
+ provider!!.appExit()
+ }
+
+ fun getLogo(): Int {
+ if (provider == null) {
+ throw Throwable("请先注册provider")
+ }
+ return provider!!.getLogo()
+ }
+
+ fun getTitleColor(): Int {
+ if (provider == null) {
+ throw Throwable("请先注册provider")
+ }
+ return if (provider!!.getTitleColor() > 0) {
+ provider!!.getTitleColor()
+ } else {
+ R.color.color_fd0202
+ }
+ }
+
+ fun clean() {
+ if (provider == null) {
+ throw Throwable("请先注册provider")
+ }
+ provider!!.clean()
+ }
+
+ fun isTest(): Boolean {
+ if (provider == null) {
+ throw Throwable("请先注册provider")
+ }
+ return provider!!.isTest()
+ }
+
+ fun getFilePathName(): String {
+ if (provider == null) {
+ throw Throwable("请先注册provider")
+ }
+ return provider!!.getFilePathName()
+ }
+
+ fun useDensity(activity: Activity) {
+ if (provider == null) {
+ DensityUtils.setDefault(activity)
+ } else {
+ provider!!.useDensity(activity)
+ }
+ }
+
+ fun handleNetError(error: NetError): Boolean {
+ if (provider == null) {
+ throw Throwable("请先注册provider")
+ }
+ return provider!!.handleNetError(error)
+ }
+
+ fun restartApp() {
+ if (provider == null) {
+ throw Throwable("请先注册provider")
+ }
+ provider!!.restartApp()
+ }
+ }
+}
\ No newline at end of file
diff --git a/utill/src/main/java/com/lennon/cn/utill/conf/LennonProvider.kt b/utill/src/main/java/com/lennon/cn/utill/conf/LennonProvider.kt
new file mode 100644
index 0000000..fa5e4fe
--- /dev/null
+++ b/utill/src/main/java/com/lennon/cn/utill/conf/LennonProvider.kt
@@ -0,0 +1,27 @@
+package com.lennon.cn.utill.conf
+
+import android.app.Activity
+import cn.droidlover.xdroidmvp.net.NetError
+import com.lennon.cn.utill.utill.DensityUtils
+
+abstract class LennonProvider {
+ abstract fun appName(): String
+ abstract fun requserLogin()
+ abstract fun appExit()
+ abstract fun getLogo(): Int
+ abstract fun getTitleColor(): Int
+ abstract fun clean()
+ abstract fun isTest(): Boolean
+ abstract fun getFilePathName(): String
+ open fun useDensity(activity: Activity) {
+// if (Utill.isPad(activity)) {
+// DensityUtils.setOrientation(activity, DensityUtils.HEIGHT)
+// } else {
+ DensityUtils.setDefault(activity)
+// }
+ }
+
+ abstract fun handleNetError(error: NetError): Boolean
+ abstract fun restartApp()
+ abstract fun getFileProvide(): String
+}
\ No newline at end of file
diff --git a/utill/src/main/java/com/lennon/cn/utill/dialog/BottomSearchSelectDialog.java b/utill/src/main/java/com/lennon/cn/utill/dialog/BottomSearchSelectDialog.java
new file mode 100644
index 0000000..d04ce84
--- /dev/null
+++ b/utill/src/main/java/com/lennon/cn/utill/dialog/BottomSearchSelectDialog.java
@@ -0,0 +1,257 @@
+package com.lennon.cn.utill.dialog;
+
+import android.annotation.TargetApi;
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.PixelFormat;
+import android.graphics.Typeface;
+import android.os.IBinder;
+import android.view.Gravity;
+import android.view.KeyEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.WindowManager;
+import android.widget.PopupWindow;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+
+import com.lennon.cn.utill.adapter.StringItemAdapter;
+import com.lennon.cn.utill.bean.StringBean;
+import com.lennon.cn.utill.widget.SearchView;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import cn.droidlover.xrecyclerview.RecyclerItemCallback;
+import cn.droidlover.xrecyclerview.XRecyclerView;
+import lennon.com.utill.R;
+
+public class BottomSearchSelectDialog extends PopupWindow {
+ protected Context context;
+ private WindowManager wm;
+ private View maskView;
+ private SearchView dialog_search;
+ private XRecyclerView xRecyclerView;
+ private TextView cancle;
+ private Listener listener;
+ private List list;
+ private List typefaces;
+ private List colors;
+ private List textSize;
+
+ public void setTypefaces(List typefaces) {
+ this.typefaces = typefaces;
+ }
+
+ public void setColors(List colors) {
+ this.colors = colors;
+ }
+
+ public void setTextSize(List textSize) {
+ this.textSize = textSize;
+ }
+
+
+ public void setListener(Listener listener) {
+ this.listener = listener;
+ }
+
+ public interface Listener {
+ void onItemClick(int position, T model);
+
+ boolean isResult(@NonNull String text, @NonNull T t);
+
+ void onCancel();
+ }
+
+ public BottomSearchSelectDialog(Context context, final T... a) {
+ List t = new ArrayList<>();
+ if (a != null) {
+ Collections.addAll(t, a);
+ }
+ this.context = context;
+ this.list = t;
+ wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
+ setContentView(generateCustomView());
+ setWidth(ViewGroup.LayoutParams.MATCH_PARENT);
+ setHeight(ViewGroup.LayoutParams.MATCH_PARENT);
+ setOutsideTouchable(true);
+ setFocusable(true);
+ setBackgroundDrawable(context.getResources().getDrawable(android.R.color.transparent));
+ setAnimationStyle(R.style.Animations_BottomPush);
+ }
+
+ public BottomSearchSelectDialog(Context context, List typefaces,
+ List colors,
+ List textSize, final T... a) {
+ this.typefaces = typefaces;
+ this.colors = colors;
+ this.textSize = textSize;
+ List t = new ArrayList<>();
+ if (a != null) {
+ Collections.addAll(t, a);
+ }
+ this.context = context;
+ this.list = t;
+ wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
+ setContentView(generateCustomView());
+ setWidth(ViewGroup.LayoutParams.MATCH_PARENT);
+ setHeight(ViewGroup.LayoutParams.MATCH_PARENT);
+ setOutsideTouchable(true);
+ setFocusable(true);
+ setBackgroundDrawable(context.getResources().getDrawable(android.R.color.transparent));
+ setAnimationStyle(R.style.Animations_BottomPush);
+ }
+
+ public BottomSearchSelectDialog(Context context, List list) {
+ this.context = context;
+ this.list = list;
+ wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
+ setContentView(generateCustomView());
+ setWidth(ViewGroup.LayoutParams.MATCH_PARENT);
+ setHeight(ViewGroup.LayoutParams.MATCH_PARENT);
+ setOutsideTouchable(true);
+ setFocusable(true);
+ setBackgroundDrawable(context.getResources().getDrawable(android.R.color.transparent));
+ setAnimationStyle(R.style.Animations_BottomPush);
+ }
+
+ private View generateCustomView() {
+ View root = View.inflate(context, R.layout.dialog_bottom_search_select, null);
+ dialog_search = root.findViewById(R.id.dialog_bottom_search_select_search);
+ cancle = root.findViewById(R.id.dialog_bottom_search_select_cancle);
+ xRecyclerView = root.findViewById(R.id.dialog_bottom_search_select_list);
+ xRecyclerView.verticalLayoutManager(context);
+ final StringItemAdapter adapter = new StringItemAdapter(context);
+ xRecyclerView.setAdapter(adapter);
+ adapter.setRecItemClick(new RecyclerItemCallback() {
+ @Override
+ public void onItemClick(int position, T model, int tag, StringItemAdapter.ViewHolder holder) {
+ super.onItemClick(position, model, tag, holder);
+ if (listener != null) {
+ listener.onItemClick(position, model);
+ }
+ }
+ });
+ dialog_search.setSearchViewListener(new SearchView.SearchViewListener() {
+ @Override
+ public void onClear() {
+ adapter.setData(BottomSearchSelectDialog.this.list);
+ }
+
+ @Override
+ public void onSearch(String text) {
+ List l = new ArrayList<>();
+ if (listener != null) {
+ for (T t : list) {
+ if (listener.isResult(text, t)) {
+ l.add(t);
+ }
+ }
+ } else {
+ l.addAll(list);
+ }
+ adapter.setData(l);
+ }
+
+ @Override
+ public void onResult(String text) {
+
+ }
+
+ @Override
+ public void onSearchByButton(String text) {
+
+ }
+ });
+ cancle.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ if (listener != null) {
+ listener.onCancel();
+ }
+ }
+ });
+ if (list != null) {
+ adapter.setData(list);
+ }
+ if (typefaces != null) {
+ adapter.setTypefaces(typefaces);
+ }
+ if (textSize != null) {
+ adapter.setTextSize(textSize);
+ }
+ if (colors != null) {
+ adapter.setColors(colors);
+ }
+ return root;
+ }
+
+ @TargetApi(23)
+ private void initType() {
+ // 解决华为手机在home建进入后台后,在进入应用,蒙层出现在popupWindow上层的bug。
+ // android4.0及以上版本都有这个hide方法,根据jvm原理,可以直接调用,选择android6.0版本进行编译即可。
+ setWindowLayoutType(WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL);
+ }
+
+ @Override
+ public void showAtLocation(View parent, int gravity, int x, int y) {
+ addMaskView(parent.getWindowToken());
+ super.showAtLocation(parent, gravity, x, y);
+ }
+
+ @Override
+ public void showAsDropDown(View anchor, int xoff, int yoff) {
+ addMaskView(anchor.getWindowToken());
+ super.showAsDropDown(anchor, xoff, yoff);
+ }
+
+ @Override
+ public void dismiss() {
+ removeMaskView();
+ super.dismiss();
+ }
+
+ /**
+ * 显示在界面的底部
+ */
+ public void show(Activity activity) {
+ showAtLocation(activity.getWindow().getDecorView(), Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, 0, 0);
+ }
+
+ private void addMaskView(IBinder token) {
+ WindowManager.LayoutParams p = new WindowManager.LayoutParams();
+ p.width = WindowManager.LayoutParams.MATCH_PARENT;
+ p.height = WindowManager.LayoutParams.MATCH_PARENT;
+ p.format = PixelFormat.TRANSLUCENT;
+ p.type = WindowManager.LayoutParams.TYPE_APPLICATION_PANEL;
+ p.token = token;
+ p.windowAnimations = android.R.style.Animation_Toast;
+ maskView = new View(context);
+ maskView.setBackgroundColor(0x7f000000);
+ maskView.setFitsSystemWindows(false);
+ // 华为手机在home建进入后台后,在进入应用,蒙层出现在popupWindow上层,导致界面卡死,
+ // 这里新增加按bug返回。
+ // initType方法已经解决该问题,但是还是留着这个按back返回功能,防止其他手机出现华为手机类似问题。
+ maskView.setOnKeyListener(new View.OnKeyListener() {
+ @Override
+ public boolean onKey(View v, int keyCode, KeyEvent event) {
+ if (keyCode == KeyEvent.KEYCODE_BACK) {
+ removeMaskView();
+ return true;
+ }
+ return false;
+ }
+ });
+ wm.addView(maskView, p);
+ }
+
+ private void removeMaskView() {
+ if (maskView != null) {
+ wm.removeViewImmediate(maskView);
+ maskView = null;
+ }
+ }
+}
diff --git a/utill/src/main/java/com/lennon/cn/utill/dialog/BottomSelectDialog.java b/utill/src/main/java/com/lennon/cn/utill/dialog/BottomSelectDialog.java
new file mode 100644
index 0000000..7be7eb8
--- /dev/null
+++ b/utill/src/main/java/com/lennon/cn/utill/dialog/BottomSelectDialog.java
@@ -0,0 +1,223 @@
+package com.lennon.cn.utill.dialog;
+
+import android.annotation.TargetApi;
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.PixelFormat;
+import android.graphics.Typeface;
+import android.os.IBinder;
+import android.view.*;
+import android.widget.PopupWindow;
+import android.widget.TextView;
+
+import androidx.annotation.ColorRes;
+
+import cn.droidlover.xrecyclerview.RecyclerItemCallback;
+import cn.droidlover.xrecyclerview.XRecyclerView;
+
+import com.lennon.cn.utill.adapter.StringItemAdapter;
+import com.lennon.cn.utill.bean.StringBean;
+
+import lennon.com.utill.R;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Created by lennon on 2018/5/16.
+ */
+
+public class BottomSelectDialog extends PopupWindow {
+ protected Context context;
+ private WindowManager wm;
+ private View maskView;
+ private XRecyclerView xRecyclerView;
+ private TextView cancel;
+ private Listener listener;
+ private List list;
+ private List typefaces;
+ private List colors;
+ private List textSize;
+
+ public void setTypefaces(List typefaces) {
+ this.typefaces = typefaces;
+ }
+
+ public void setColors(List colors) {
+ this.colors = colors;
+ }
+
+ public void setTextSize(List textSize) {
+ this.textSize = textSize;
+ }
+
+
+ public void setListener(Listener listener) {
+ this.listener = listener;
+ }
+
+ public interface Listener {
+ void onItemClick(int position, T model);
+
+ void onCancel();
+ }
+
+ public BottomSelectDialog(Context context, final T... a) {
+ List t = new ArrayList<>();
+ if (a != null) {
+ Collections.addAll(t, a);
+ }
+ this.context = context;
+ this.list = t;
+ wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
+ setContentView(generateCustomView());
+ setWidth(ViewGroup.LayoutParams.MATCH_PARENT);
+ setHeight(ViewGroup.LayoutParams.MATCH_PARENT);
+ setOutsideTouchable(true);
+ setFocusable(true);
+ setBackgroundDrawable(context.getResources().getDrawable(android.R.color.transparent));
+ setAnimationStyle(R.style.Animations_BottomPush);
+ }
+
+ public BottomSelectDialog(Context context, List typefaces,
+ List colors,
+ List textSize, final T... a) {
+ this.typefaces = typefaces;
+ this.colors = colors;
+ this.textSize = textSize;
+ List t = new ArrayList<>();
+ if (a != null) {
+ Collections.addAll(t, a);
+ }
+ this.context = context;
+ this.list = t;
+ wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
+ setContentView(generateCustomView());
+ setWidth(ViewGroup.LayoutParams.MATCH_PARENT);
+ setHeight(ViewGroup.LayoutParams.MATCH_PARENT);
+ setOutsideTouchable(true);
+ setFocusable(true);
+ setBackgroundDrawable(context.getResources().getDrawable(android.R.color.transparent));
+ setAnimationStyle(R.style.Animations_BottomPush);
+ }
+
+ public BottomSelectDialog(Context context, List list) {
+ this.context = context;
+ this.list = list;
+ wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
+ setContentView(generateCustomView());
+ setWidth(ViewGroup.LayoutParams.MATCH_PARENT);
+ setHeight(ViewGroup.LayoutParams.MATCH_PARENT);
+ setOutsideTouchable(true);
+ setFocusable(true);
+ setBackgroundDrawable(context.getResources().getDrawable(android.R.color.transparent));
+ setAnimationStyle(R.style.Animations_BottomPush);
+ }
+
+ public View generateCustomView() {
+ View root = View.inflate(context, R.layout.dialog_bottom_select, null);
+ xRecyclerView = root.findViewById(R.id.list);
+ xRecyclerView.verticalLayoutManager(context);
+ StringItemAdapter adapter = new StringItemAdapter(context);
+ xRecyclerView.setAdapter(adapter);
+ adapter.setRecItemClick(new RecyclerItemCallback() {
+ @Override
+ public void onItemClick(int position, T model, int tag, StringItemAdapter.ViewHolder holder) {
+ super.onItemClick(position, model, tag, holder);
+ if (listener != null) {
+ listener.onItemClick(position, model);
+ }
+ }
+ });
+ if (list != null) {
+ adapter.setData(list);
+ }
+ if (typefaces != null) {
+ adapter.setTypefaces(typefaces);
+ }
+ if (textSize != null) {
+ adapter.setTextSize(textSize);
+ }
+ if (colors != null) {
+ adapter.setColors(colors);
+ }
+ cancel = root.findViewById(R.id.cancel);
+ cancel.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ if (listener != null) {
+ listener.onCancel();
+ }
+ dismiss();
+ }
+ });
+ return root;
+ }
+
+ @TargetApi(23)
+ private void initType() {
+ // 解决华为手机在home建进入后台后,在进入应用,蒙层出现在popupWindow上层的bug。
+ // android4.0及以上版本都有这个hide方法,根据jvm原理,可以直接调用,选择android6.0版本进行编译即可。
+ setWindowLayoutType(WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL);
+ }
+
+ @Override
+ public void showAtLocation(View parent, int gravity, int x, int y) {
+ addMaskView(parent.getWindowToken());
+ super.showAtLocation(parent, gravity, x, y);
+ }
+
+ @Override
+ public void showAsDropDown(View anchor, int xoff, int yoff) {
+ addMaskView(anchor.getWindowToken());
+ super.showAsDropDown(anchor, xoff, yoff);
+ }
+
+ @Override
+ public void dismiss() {
+ removeMaskView();
+ super.dismiss();
+ }
+
+ /**
+ * 显示在界面的底部
+ */
+ public void show(Activity activity) {
+ showAtLocation(activity.getWindow().getDecorView(), Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, 0, 0);
+ }
+
+ private void addMaskView(IBinder token) {
+ WindowManager.LayoutParams p = new WindowManager.LayoutParams();
+ p.width = WindowManager.LayoutParams.MATCH_PARENT;
+ p.height = WindowManager.LayoutParams.MATCH_PARENT;
+ p.format = PixelFormat.TRANSLUCENT;
+ p.type = WindowManager.LayoutParams.TYPE_APPLICATION_PANEL;
+ p.token = token;
+ p.windowAnimations = android.R.style.Animation_Toast;
+ maskView = new View(context);
+ maskView.setBackgroundColor(0x7f000000);
+ maskView.setFitsSystemWindows(false);
+ // 华为手机在home建进入后台后,在进入应用,蒙层出现在popupWindow上层,导致界面卡死,
+ // 这里新增加按bug返回。
+ // initType方法已经解决该问题,但是还是留着这个按back返回功能,防止其他手机出现华为手机类似问题。
+ maskView.setOnKeyListener(new View.OnKeyListener() {
+ @Override
+ public boolean onKey(View v, int keyCode, KeyEvent event) {
+ if (keyCode == KeyEvent.KEYCODE_BACK) {
+ removeMaskView();
+ return true;
+ }
+ return false;
+ }
+ });
+ wm.addView(maskView, p);
+ }
+
+ private void removeMaskView() {
+ if (maskView != null) {
+ wm.removeViewImmediate(maskView);
+ maskView = null;
+ }
+ }
+}
diff --git a/utill/src/main/java/com/lennon/cn/utill/dialog/CommonAlertDialog.java b/utill/src/main/java/com/lennon/cn/utill/dialog/CommonAlertDialog.java
new file mode 100644
index 0000000..ed73600
--- /dev/null
+++ b/utill/src/main/java/com/lennon/cn/utill/dialog/CommonAlertDialog.java
@@ -0,0 +1,169 @@
+package com.lennon.cn.utill.dialog;
+
+import android.app.Dialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.view.*;
+import android.widget.EditText;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+import lennon.com.utill.R;
+
+/**
+ * Created by dingyi on 2016/11/23.
+ */
+
+public class CommonAlertDialog extends Dialog {
+
+ private TextView mTitleTv;
+ private TextView mMsgTv;
+ private TextView mSureTv;
+ private TextView mCancleTv;
+ private EditText mQtyEdt;
+ private EditText mContentEdt;
+ private boolean cancelable = true;
+
+ private OnAlertDialogListener mOnListener;
+ private String mQtyString;
+ private int mIndex;
+
+ public CommonAlertDialog(Context context) {
+ super(context, R.style.common_dialog);
+ setParams();
+ }
+
+ public void setIndex(int index) {
+ this.mIndex = index;
+ }
+
+ public int getIndex() {
+ return mIndex;
+ }
+
+ public void setTitle(String msg) {
+ mTitleTv.setText(msg);
+ }
+
+ public void setMsg(String msg) {
+ mMsgTv.setVisibility(View.VISIBLE);
+ mQtyEdt.setVisibility(View.GONE);
+ mContentEdt.setVisibility(View.GONE);
+ mMsgTv.setText(msg);
+ }
+
+ public void setSureMsg(String msg) {
+ mSureTv.setText(msg);
+ }
+
+ public void setCancleMsg(String msg) {
+ mCancleTv.setText(msg);
+ }
+
+ @Override
+ public void setCancelable(boolean flag) {
+ super.setCancelable(flag);
+ cancelable = flag;
+ }
+
+ public void setQty(String text) {
+ mMsgTv.setVisibility(View.GONE);
+ mContentEdt.setVisibility(View.GONE);
+ mQtyEdt.setVisibility(View.VISIBLE);
+ mQtyString = text;
+ mQtyEdt.setText(text);
+ mQtyEdt.setSelection(text.length());
+ }
+
+ public void setContent(String content) {
+ mMsgTv.setVisibility(View.GONE);
+ mQtyEdt.setVisibility(View.GONE);
+ mContentEdt.setVisibility(View.VISIBLE);
+ mContentEdt.setText(content);
+ mContentEdt.setSelection(mContentEdt.getText().length());
+ }
+
+
+ public void setDialogListener(OnAlertDialogListener listener) {
+ this.mOnListener = listener;
+ }
+
+
+ public void disableCancle() {
+ mCancleTv.setVisibility(View.GONE);
+ }
+
+ private void setParams() {
+ setContentView(R.layout.common_alert_dialog);
+ Window window = getWindow();
+ window.setLayout(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
+ mTitleTv = (TextView) findViewById(R.id.common_alert_dialog_title_tv);
+ mMsgTv = (TextView) findViewById(R.id.common_alert_dialog_msg_tv);
+ mSureTv = (TextView) findViewById(R.id.common_alert_dialog_sure_tv);
+ mCancleTv = (TextView) findViewById(R.id.common_alert_dialog_cancle_tv);
+ mQtyEdt = (EditText) findViewById(R.id.common_alert_dialog_qty_edt);
+ mContentEdt = (EditText) findViewById(R.id.common_alert_dialog_content_edt);
+ mSureTv.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ if (null != mOnListener) {
+ if (mMsgTv.getVisibility() == View.VISIBLE) {
+ mOnListener.onSure();
+ } else if (mContentEdt.getVisibility() == View.VISIBLE) {
+ mOnListener.onSure(mContentEdt.getText().toString());
+ } else {
+ mOnListener.onSure(mIndex, mQtyString);
+ }
+ }
+ }
+ });
+ mCancleTv.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ if (null != mOnListener) {
+ mOnListener.onCancle();
+ }
+ }
+ });
+
+ mQtyEdt.addTextChangedListener(mWatcher);
+ setOnKeyListener(new OnKeyListener() {
+ @Override
+ public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
+ if (keyCode == KeyEvent.KEYCODE_SEARCH) {
+ if (mOnListener != null) {
+ mOnListener.onCancle();
+ return true;
+ }
+ return false;
+ } else {
+ return false; //默认返回 false
+ }
+ }
+ });
+ }
+
+ private TextWatcher mWatcher = new TextWatcher() {
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {
+
+ }
+
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count,
+ int after) {
+
+ }
+
+ @Override
+ public void afterTextChanged(Editable s) {
+ if (s != null && !"".equals(s.toString())) {
+ mQtyString = s.toString();
+ } else {
+ mQtyString = "0";
+ }
+ }
+ };
+}
diff --git a/utill/src/main/java/com/lennon/cn/utill/dialog/CustomProgressDialog.java b/utill/src/main/java/com/lennon/cn/utill/dialog/CustomProgressDialog.java
new file mode 100644
index 0000000..e894884
--- /dev/null
+++ b/utill/src/main/java/com/lennon/cn/utill/dialog/CustomProgressDialog.java
@@ -0,0 +1,112 @@
+package com.lennon.cn.utill.dialog;
+
+import android.app.Dialog;
+import android.content.Context;
+import android.view.View;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import net.qiujuer.genius.ui.widget.Loading;
+
+import lennon.com.utill.R;
+
+
+/**
+ * @author luoying
+ */
+public class CustomProgressDialog extends Dialog {
+
+ private Context mContext;
+ private Loading loading;
+
+ public CustomProgressDialog(Context context) {
+ super(context, R.style.dialog_progress);
+ this.mContext = context;
+ setParams();
+ }
+
+ public CustomProgressDialog(Context context, String title, String msg) {
+ super(context, R.style.dialog_progress);
+ this.mContext = context;
+ setParams();
+ setTitile(title);
+ setMessage(msg);
+ }
+
+ public CustomProgressDialog(Context context, int msg_resid) {
+ super(context, R.style.dialog_progress);
+ this.mContext = context;
+ setParams();
+ setMessage(msg_resid);
+ }
+
+ public CustomProgressDialog(Context context, int title_resid, int msg_resid) {
+ super(context, R.style.dialog_progress);
+ this.mContext = context;
+ setParams();
+ setTitile(title_resid);
+ setMessage(msg_resid);
+ }
+
+ @Override
+ public void onWindowFocusChanged(boolean hasFocus) {
+ loading = (Loading) findViewById(R.id.progressdialog_anim_progress);
+ loading.start();
+ }
+
+ /**
+ * setTitile 标题
+ *
+ * @param strTitle
+ * @return
+ */
+ public void setTitile(String strTitle) {
+
+ }
+
+ /**
+ * setTitile 标题
+ *
+ * @param title_resid
+ * @return
+ */
+ public void setTitile(int title_resid) {
+
+ }
+
+ /**
+ * setMessage 提示内容
+ *
+ * @param strMessage
+ * @return
+ */
+ public void setMessage(String strMessage) {
+ TextView tvMsg = (TextView) findViewById(R.id.progressdialog_ms_tv);
+ if (tvMsg != null) {
+ tvMsg.setVisibility(View.VISIBLE);
+ tvMsg.setText(strMessage);
+ } else {
+ tvMsg.setVisibility(View.GONE);
+ }
+ }
+
+ /**
+ * setMessage 提示内容
+ *
+ * @param resid
+ * @return
+ */
+ public void setMessage(int resid) {
+ TextView tvMsg = (TextView) findViewById(R.id.progressdialog_ms_tv);
+ if (tvMsg != null) {
+ tvMsg.setText(resid);
+ }
+ }
+
+ private void setParams() {
+ setContentView(R.layout.customprogressdialog);
+ // 设置全屏
+ getWindow().setLayout(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
+ }
+
+}
diff --git a/utill/src/main/java/com/lennon/cn/utill/dialog/OnAlertDialogListener.java b/utill/src/main/java/com/lennon/cn/utill/dialog/OnAlertDialogListener.java
new file mode 100644
index 0000000..c6d696a
--- /dev/null
+++ b/utill/src/main/java/com/lennon/cn/utill/dialog/OnAlertDialogListener.java
@@ -0,0 +1,12 @@
+package com.lennon.cn.utill.dialog;
+
+/**
+ * Created by dingyi on 2016/12/2.
+ */
+
+public class OnAlertDialogListener {
+ public void onSure(){};
+ public void onSure(String content){};
+ public void onSure(int index, String content){};
+ public void onCancle(){};
+}
diff --git a/utill/src/main/java/com/lennon/cn/utill/utill/AmtUtils.java b/utill/src/main/java/com/lennon/cn/utill/utill/AmtUtils.java
new file mode 100644
index 0000000..6527716
--- /dev/null
+++ b/utill/src/main/java/com/lennon/cn/utill/utill/AmtUtils.java
@@ -0,0 +1,250 @@
+package com.lennon.cn.utill.utill;
+
+import java.math.BigDecimal;
+
+public class AmtUtils {
+
+ /**
+ * 功能描述:金额字符串转换:单位分转成单元
+ *
+ * 传入需要转换的金额字符串
+ *
+ * @return 转换后的金额字符串
+ */
+ public static String fenToYuan(Object o) {
+ if (o == null) {
+ return "0.00";
+ }
+ String s = o.toString();
+// if ("".equals(s)) {
+// return "0.00";
+// }
+ if (s.contains(".")) {
+ s = s.substring(0, s.indexOf("."));
+ }
+ int len = -1;
+ StringBuilder sb = new StringBuilder();
+ if (s != null && s.trim().length() > 0 && !"null".equalsIgnoreCase(s)) {
+ s = removeZero(s);
+ if (s != null && s.trim().length() > 0 && !"null".equalsIgnoreCase(s)) {
+ len = s.length();
+ int tmp = s.indexOf("-");
+ if (tmp >= 0) {
+ if (len == 2) {
+ sb.append("-0.0").append(s.substring(1));
+ } else if (len == 3) {
+ sb.append("-0.").append(s.substring(1));
+ } else {
+ sb.append(s.substring(0, len - 2)).append(".").append(s.substring(len - 2));
+ }
+ } else {
+ if (len == 1) {
+ sb.append("0.0").append(s);
+ } else if (len == 2) {
+ sb.append("0.").append(s);
+ } else {
+ sb.append(s.substring(0, len - 2)).append(".").append(s.substring(len - 2));
+ }
+ }
+ } else {
+ sb.append("0.00");
+ }
+ } else {
+ sb.append("0.00");
+ }
+ return sb.toString();
+ }
+
+ /**
+ * 功能描述:金额字符串转换:单位元转成单分
+ *
+ * 传入需要转换的金额字符串
+ *
+ * @return 转换后的金额字符串
+ */
+ public static String yuanToFen(Object o) {
+ if (o == null) {
+ return "0";
+ }
+ String s = o.toString();
+ int posIndex = -1;
+ String str = "";
+ StringBuilder sb = new StringBuilder();
+ if (s != null && s.trim().length() > 0 && !"null".equalsIgnoreCase(s)) {
+ posIndex = s.indexOf(".");
+ if (posIndex > 0) {
+ int len = s.length();
+ if (len == posIndex + 1) {
+ str = s.substring(0, posIndex);
+ if (str == "0") {
+ str = "";
+ }
+ sb.append(str).append("00");
+ } else if (len == posIndex + 2) {
+ str = s.substring(0, posIndex);
+ if (str == "0") {
+ str = "";
+ }
+ sb.append(str).append(s.substring(posIndex + 1, posIndex + 2)).append("0");
+ } else if (len == posIndex + 3) {
+ str = s.substring(0, posIndex);
+ if (str == "0") {
+ str = "";
+ }
+ sb.append(str).append(s.substring(posIndex + 1, posIndex + 3));
+ } else {
+ str = s.substring(0, posIndex);
+ if (str == "0") {
+ str = "";
+ }
+ sb.append(str).append(s.substring(posIndex + 1, posIndex + 3));
+ }
+ } else {
+ sb.append(s).append("00");
+ }
+ } else {
+ sb.append("0");
+ }
+ str = removeZero(sb.toString());
+ if (str != null && str.trim().length() > 0 && !"null".equalsIgnoreCase(str.trim())) {
+ return str;
+ } else {
+ return "0";
+ }
+ }
+
+ /**
+ * 功能描述:去除字符串首部为"0"字符
+ *
+ * @param str 传入需要转换的字符串
+ * @return 转换后的字符串
+ */
+ public static String removeZero(String str) {
+ char ch;
+ String result = "";
+ if (str != null && str.trim().length() > 0 && !"null".equalsIgnoreCase(str.trim())) {
+ try {
+ for (int i = 0; i < str.length(); i++) {
+ ch = str.charAt(i);
+ if (ch != '0') {
+ result = str.substring(i);
+ break;
+ }
+ }
+ } catch (Exception e) {
+ result = "";
+ }
+ } else {
+ result = "";
+ }
+ return result;
+
+ }
+
+ /**
+ * 金额(分)
+ *
+ * @param rate 手续费v
+ * 小数点后位数
+ * @return
+ */
+ public static String getSettleAmt(String amountfen, double rate) {
+ String feeAmtStr = String.valueOf(Double.valueOf(AmtUtils.fenToYuan(amountfen)) * rate);
+ BigDecimal mData = new BigDecimal(feeAmtStr).setScale(2, BigDecimal.ROUND_HALF_UP);
+ String resultAmt = AmtUtils.yuanToFen(String.valueOf(mData));
+ return resultAmt;
+ }
+
+ /**
+ * 金额为分的格式
+ */
+ private static final String CURRENCY_FEN_REGEX = "\\-?[0-9]+";
+
+ /**
+ * 将分为单位的转换为元并返回金额格式的字符串 (除100)
+ *
+ * @param amount
+ * @return
+ * @throws Exception
+ */
+ public static String changeF2Y(Long amount) throws Exception {
+ if (!amount.toString().matches(CURRENCY_FEN_REGEX)) {
+ throw new Exception("金额格式有误");
+ }
+ int flag = 0;
+ String amString = amount.toString();
+ if (amString.charAt(0) == '-') {
+ flag = 1;
+ amString = amString.substring(1);
+ }
+ StringBuffer result = new StringBuffer();
+ if (amString.length() == 1) {
+ result.append("0.0").append(amString);
+ } else if (amString.length() == 2) {
+ result.append("0.").append(amString);
+ } else {
+ String intString = amString.substring(0, amString.length() - 2);
+ for (int i = 1; i <= intString.length(); i++) {
+ if ((i - 1) % 3 == 0 && i != 1) {
+ result.append(",");
+ }
+ result.append(intString.substring(intString.length() - i, intString.length() - i + 1));
+ }
+ result.reverse().append(".").append(amString.substring(amString.length() - 2));
+ }
+ if (flag == 1) {
+ return "-" + result.toString();
+ } else {
+ return result.toString();
+ }
+ }
+
+ /**
+ * 将分为单位的转换为元 (除100)
+ *
+ * @param amount
+ * @return
+ * @throws Exception
+ */
+ public static String changeF2Y(String amount) throws Exception {
+ if (!amount.matches(CURRENCY_FEN_REGEX)) {
+ throw new Exception("金额格式有误");
+ }
+ return String.format("%.2f", BigDecimal.valueOf(Long.valueOf(amount)).divide(new BigDecimal(100)));
+ }
+
+ /**
+ * 将元为单位的转换为分 (乘100)
+ *
+ * @param amount
+ * @return
+ */
+ public static String changeY2F(Long amount) {
+ return BigDecimal.valueOf(amount).multiply(new BigDecimal(100)).toString();
+ }
+
+ /**
+ * 将元为单位的转换为分 替换小数点,支持以逗号区分的金额
+ *
+ * @param amount
+ * @return
+ */
+ public static String changeY2F(String amount) {
+ String currency = amount.replaceAll("\\$|\\¥|\\,", "");
+ //处理包含, ¥ 或者$的金额
+ int index = currency.indexOf(".");
+ int length = currency.length();
+ long amLong = 0L;
+ if (index == -1) {
+ amLong = Long.parseLong(currency + "00");
+ } else if (length - index >= 3) {
+ amLong = Long.parseLong((currency.substring(0, index + 3)).replace(".", ""));
+ } else if (length - index == 2) {
+ amLong = Long.parseLong((currency.substring(0, index + 2)).replace(".", "") + 0);
+ } else {
+ amLong = Long.parseLong((currency.substring(0, index + 1)).replace(".", "") + "00");
+ }
+ return Long.toString(amLong);
+ }
+
+}
diff --git a/utill/src/main/java/com/lennon/cn/utill/utill/AnimationUtil.java b/utill/src/main/java/com/lennon/cn/utill/utill/AnimationUtil.java
new file mode 100644
index 0000000..0f071e9
--- /dev/null
+++ b/utill/src/main/java/com/lennon/cn/utill/utill/AnimationUtil.java
@@ -0,0 +1,307 @@
+package com.lennon.cn.utill.utill;
+
+import android.view.animation.AlphaAnimation;
+import android.view.animation.Animation;
+import android.view.animation.RotateAnimation;
+import android.view.animation.ScaleAnimation;
+
+public class AnimationUtil {
+ /**
+ * 默认动画持续时间
+ */
+ public static final long DEFAULT_ANIMATION_DURATION = 400;
+
+
+ /**
+ * 获取一个旋转动画
+ *
+ * @param fromDegrees 开始角度
+ * @param toDegrees 结束角度
+ * @param pivotXType 旋转中心点X轴坐标相对类型
+ * @param pivotXValue 旋转中心点X轴坐标
+ * @param pivotYType 旋转中心点Y轴坐标相对类型
+ * @param pivotYValue 旋转中心点Y轴坐标
+ * @param durationMillis 持续时间
+ * @param animationListener 动画监听器
+ * @return 一个旋转动画
+ */
+ public static RotateAnimation getRotateAnimation(float fromDegrees, float toDegrees, int pivotXType, float pivotXValue, int pivotYType, float pivotYValue, long durationMillis, Animation.AnimationListener animationListener) {
+ RotateAnimation rotateAnimation = new RotateAnimation(fromDegrees,
+ toDegrees, pivotXType, pivotXValue, pivotYType, pivotYValue);
+ rotateAnimation.setDuration(durationMillis);
+ if (animationListener != null) {
+ rotateAnimation.setAnimationListener(animationListener);
+ }
+ return rotateAnimation;
+ }
+
+
+ /**
+ * 获取一个根据视图自身中心点旋转的动画
+ *
+ * @param durationMillis 动画持续时间
+ * @param animationListener 动画监听器
+ * @return 一个根据中心点旋转的动画
+ */
+ public static RotateAnimation getRotateAnimationByCenter(long durationMillis, Animation.AnimationListener animationListener) {
+ return getRotateAnimation(0f, 359f, Animation.RELATIVE_TO_SELF, 0.5f,
+ Animation.RELATIVE_TO_SELF, 0.5f, durationMillis,
+ animationListener);
+ }
+
+
+ /**
+ * 获取一个根据中心点旋转的动画
+ *
+ * @param duration 动画持续时间
+ * @return 一个根据中心点旋转的动画
+ */
+ public static RotateAnimation getRotateAnimationByCenter(long duration) {
+ return getRotateAnimationByCenter(duration, null);
+ }
+
+
+ /**
+ * 获取一个根据视图自身中心点旋转的动画
+ *
+ * @param animationListener 动画监听器
+ * @return 一个根据中心点旋转的动画
+ */
+ public static RotateAnimation getRotateAnimationByCenter(Animation.AnimationListener animationListener) {
+ return getRotateAnimationByCenter(DEFAULT_ANIMATION_DURATION,
+ animationListener);
+ }
+
+
+ /**
+ * 获取一个根据中心点旋转的动画
+ *
+ * @return 一个根据中心点旋转的动画,默认持续时间为DEFAULT_ANIMATION_DURATION
+ */
+ public static RotateAnimation getRotateAnimationByCenter() {
+ return getRotateAnimationByCenter(DEFAULT_ANIMATION_DURATION, null);
+ }
+
+
+ /**
+ * 获取一个透明度渐变动画
+ *
+ * @param fromAlpha 开始时的透明度
+ * @param toAlpha 结束时的透明度都
+ * @param durationMillis 持续时间
+ * @param animationListener 动画监听器
+ * @return 一个透明度渐变动画
+ */
+ public static AlphaAnimation getAlphaAnimation(float fromAlpha, float toAlpha, long durationMillis, Animation.AnimationListener animationListener) {
+ AlphaAnimation alphaAnimation = new AlphaAnimation(fromAlpha, toAlpha);
+ alphaAnimation.setDuration(durationMillis);
+ if (animationListener != null) {
+ alphaAnimation.setAnimationListener(animationListener);
+ }
+ return alphaAnimation;
+ }
+
+
+ /**
+ * 获取一个透明度渐变动画
+ *
+ * @param fromAlpha 开始时的透明度
+ * @param toAlpha 结束时的透明度都
+ * @param durationMillis 持续时间
+ * @return 一个透明度渐变动画
+ */
+ public static AlphaAnimation getAlphaAnimation(float fromAlpha, float toAlpha, long durationMillis) {
+ return getAlphaAnimation(fromAlpha, toAlpha, durationMillis, null);
+ }
+
+
+ /**
+ * 获取一个透明度渐变动画
+ *
+ * @param fromAlpha 开始时的透明度
+ * @param toAlpha 结束时的透明度都
+ * @param animationListener 动画监听器
+ * @return 一个透明度渐变动画,默认持续时间为DEFAULT_ANIMATION_DURATION
+ */
+ public static AlphaAnimation getAlphaAnimation(float fromAlpha, float toAlpha, Animation.AnimationListener animationListener) {
+ return getAlphaAnimation(fromAlpha, toAlpha, DEFAULT_ANIMATION_DURATION, animationListener);
+ }
+
+
+ /**
+ * 获取一个透明度渐变动画
+ *
+ * @param fromAlpha 开始时的透明度
+ * @param toAlpha 结束时的透明度都
+ * @return 一个透明度渐变动画,默认持续时间为DEFAULT_ANIMATION_DURATION
+ */
+ public static AlphaAnimation getAlphaAnimation(float fromAlpha, float toAlpha) {
+ return getAlphaAnimation(fromAlpha, toAlpha, DEFAULT_ANIMATION_DURATION, null);
+ }
+
+
+ /**
+ * 获取一个由完全显示变为不可见的透明度渐变动画
+ *
+ * @param durationMillis 持续时间
+ * @param animationListener 动画监听器
+ * @return 一个由完全显示变为不可见的透明度渐变动画
+ */
+ public static AlphaAnimation getHiddenAlphaAnimation(long durationMillis, Animation.AnimationListener animationListener) {
+ return getAlphaAnimation(1.0f, 0.0f, durationMillis, animationListener);
+ }
+
+
+ /**
+ * 获取一个由完全显示变为不可见的透明度渐变动画
+ *
+ * @param durationMillis 持续时间
+ * @return 一个由完全显示变为不可见的透明度渐变动画
+ */
+ public static AlphaAnimation getHiddenAlphaAnimation(long durationMillis) {
+ return getHiddenAlphaAnimation(durationMillis, null);
+ }
+
+
+ /**
+ * 获取一个由完全显示变为不可见的透明度渐变动画
+ *
+ * @param animationListener 动画监听器
+ * @return 一个由完全显示变为不可见的透明度渐变动画,默认持续时间为DEFAULT_ANIMATION_DURATION
+ */
+ public static AlphaAnimation getHiddenAlphaAnimation(Animation.AnimationListener animationListener) {
+ return getHiddenAlphaAnimation(DEFAULT_ANIMATION_DURATION, animationListener);
+ }
+
+
+ /**
+ * 获取一个由完全显示变为不可见的透明度渐变动画
+ *
+ * @return 一个由完全显示变为不可见的透明度渐变动画,默认持续时间为DEFAULT_ANIMATION_DURATION
+ */
+ public static AlphaAnimation getHiddenAlphaAnimation() {
+ return getHiddenAlphaAnimation(DEFAULT_ANIMATION_DURATION, null);
+ }
+
+
+ /**
+ * 获取一个由不可见变为完全显示的透明度渐变动画
+ *
+ * @param durationMillis 持续时间
+ * @param animationListener 动画监听器
+ * @return 一个由不可见变为完全显示的透明度渐变动画
+ */
+ public static AlphaAnimation getShowAlphaAnimation(long durationMillis, Animation.AnimationListener animationListener) {
+ return getAlphaAnimation(0.0f, 1.0f, durationMillis, animationListener);
+ }
+
+
+ /**
+ * 获取一个由不可见变为完全显示的透明度渐变动画
+ *
+ * @param durationMillis 持续时间
+ * @return 一个由不可见变为完全显示的透明度渐变动画
+ */
+ public static AlphaAnimation getShowAlphaAnimation(long durationMillis) {
+ return getAlphaAnimation(0.0f, 1.0f, durationMillis, null);
+ }
+
+
+ /**
+ * 获取一个由不可见变为完全显示的透明度渐变动画
+ *
+ * @param animationListener 动画监听器
+ * @return 一个由不可见变为完全显示的透明度渐变动画,默认持续时间为DEFAULT_ANIMATION_DURATION
+ */
+ public static AlphaAnimation getShowAlphaAnimation(Animation.AnimationListener animationListener) {
+ return getAlphaAnimation(0.0f, 1.0f, DEFAULT_ANIMATION_DURATION, animationListener);
+ }
+
+
+ /**
+ * 获取一个由不可见变为完全显示的透明度渐变动画
+ *
+ * @return 一个由不可见变为完全显示的透明度渐变动画,默认持续时间为DEFAULT_ANIMATION_DURATION
+ */
+ public static AlphaAnimation getShowAlphaAnimation() {
+ return getAlphaAnimation(0.0f, 1.0f, DEFAULT_ANIMATION_DURATION, null);
+ }
+
+
+ /**
+ * 获取一个缩小动画
+ *
+ * @param durationMillis 时间
+ * @param animationListener 监听
+ * @return 一个缩小动画
+ */
+ public static ScaleAnimation getLessenScaleAnimation(long durationMillis, Animation.AnimationListener animationListener) {
+ ScaleAnimation scaleAnimation = new ScaleAnimation(1.0f, 0.0f, 1.0f,
+ 0.0f, ScaleAnimation.RELATIVE_TO_SELF,
+ ScaleAnimation.RELATIVE_TO_SELF);
+ scaleAnimation.setDuration(durationMillis);
+ scaleAnimation.setAnimationListener(animationListener);
+ return scaleAnimation;
+ }
+
+
+ /**
+ * 获取一个缩小动画
+ *
+ * @param durationMillis 时间
+ * @return 一个缩小动画
+ */
+ public static ScaleAnimation getLessenScaleAnimation(long durationMillis) {
+ return getLessenScaleAnimation(durationMillis, null);
+ }
+
+
+ /**
+ * 获取一个缩小动画
+ *
+ * @param animationListener 监听
+ * @return 返回一个缩小的动画
+ */
+ public static ScaleAnimation getLessenScaleAnimation(Animation.AnimationListener animationListener) {
+ return getLessenScaleAnimation(DEFAULT_ANIMATION_DURATION, animationListener);
+ }
+
+
+ /**
+ * 获取一个放大动画
+ *
+ * @param durationMillis 时间
+ * @param animationListener 监听
+ * @return 返回一个放大的效果
+ */
+ public static ScaleAnimation getAmplificationAnimation(long durationMillis, Animation.AnimationListener animationListener) {
+ ScaleAnimation scaleAnimation = new ScaleAnimation(0.0f, 1.0f, 0.0f,
+ 1.0f, ScaleAnimation.RELATIVE_TO_SELF,
+ ScaleAnimation.RELATIVE_TO_SELF);
+ scaleAnimation.setDuration(durationMillis);
+ scaleAnimation.setAnimationListener(animationListener);
+ return scaleAnimation;
+ }
+
+
+ /**
+ * 获取一个放大动画
+ *
+ * @param durationMillis 时间
+ * @return 返回一个放大的效果
+ */
+ public static ScaleAnimation getAmplificationAnimation(long durationMillis) {
+ return getAmplificationAnimation(durationMillis, null);
+ }
+
+
+ /**
+ * 获取一个放大动画
+ *
+ * @param animationListener 监听
+ * @return 返回一个放大的效果
+ */
+ public static ScaleAnimation getAmplificationAnimation(Animation.AnimationListener animationListener) {
+ return getAmplificationAnimation(DEFAULT_ANIMATION_DURATION, animationListener);
+ }
+}
diff --git a/utill/src/main/java/com/lennon/cn/utill/utill/AppStatusManager.java b/utill/src/main/java/com/lennon/cn/utill/utill/AppStatusManager.java
new file mode 100644
index 0000000..3608900
--- /dev/null
+++ b/utill/src/main/java/com/lennon/cn/utill/utill/AppStatusManager.java
@@ -0,0 +1,48 @@
+package com.lennon.cn.utill.utill;
+
+/**
+ * Created by lennon on 2018/1/23.
+ */
+
+public class AppStatusManager {
+ private static AppStatusManager mInstance = null;
+
+ private int appStatus = AppStatusConstant.APP_FORCE_KILLED;
+
+ private AppStatusManager() {
+
+ }
+
+ public static AppStatusManager getInstance() {
+ if(mInstance==null) {
+ synchronized (AppStatusManager.class) {
+ if(mInstance==null) {
+ mInstance = new AppStatusManager();
+ }
+ }
+ }
+ return mInstance;
+ }
+
+ public void setAppStatus(int appStatus) {
+ this.appStatus = appStatus;
+ }
+
+ public int getAppStatus() {
+ return appStatus;
+ }
+
+
+ public static class AppStatusConstant {
+
+ /**
+ * App被回收,初始状态
+ */
+ public static final int APP_FORCE_KILLED = 0;
+
+ /**
+ * 正常运行
+ */
+ public static final int APP_NORMAL = 1;
+ }
+}
diff --git a/utill/src/main/java/com/lennon/cn/utill/utill/AudioPlayerUtil.java b/utill/src/main/java/com/lennon/cn/utill/utill/AudioPlayerUtil.java
new file mode 100644
index 0000000..4eb22ef
--- /dev/null
+++ b/utill/src/main/java/com/lennon/cn/utill/utill/AudioPlayerUtil.java
@@ -0,0 +1,86 @@
+package com.lennon.cn.utill.utill;
+
+import android.content.Context;
+import android.media.MediaMetadataRetriever;
+import android.media.MediaPlayer;
+import android.net.Uri;
+import cn.droidlover.xdroidmvp.log.XLog;
+
+import java.io.IOException;
+import java.util.HashMap;
+
+/**
+ * @author lennon
+ *
+ * 作者:lennon on 2019/2/18 16:30
+ *
+ * 邮箱:1136160757@qq.com
+ */
+public class AudioPlayerUtil {
+ private static final String TAG = "AudioRecordTest";
+ private MediaPlayer mPlayer;
+
+ public AudioPlayerUtil() {
+ }
+
+ public MediaPlayer start(String mFileName, MediaPlayer.OnCompletionListener listener) {
+ if (this.mPlayer == null) {
+ this.mPlayer = new MediaPlayer();
+ } else {
+ this.mPlayer.reset();
+ }
+
+ try {
+ this.mPlayer.setDataSource(mFileName);
+ this.mPlayer.prepareAsync();
+ this.mPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
+ @Override
+ public void onPrepared(MediaPlayer mediaPlayer) {
+ mediaPlayer.start();
+ }
+ });
+ if (listener != null) {
+ this.mPlayer.setOnCompletionListener(listener);
+ }
+ } catch (Exception var4) {
+ var4.printStackTrace();
+ }
+ return mPlayer;
+
+ }
+
+ public MediaPlayer start(Context context, String mFileUrl, MediaPlayer.OnCompletionListener listener) {
+ if (this.mPlayer == null) {
+ this.mPlayer = new MediaPlayer();
+ } else {
+ this.mPlayer.reset();
+ }
+ try {
+ Uri uri = Uri.parse(mFileUrl);
+ this.mPlayer.setDataSource(context, uri);
+ this.mPlayer.prepareAsync();
+ this.mPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
+ @Override
+ public void onPrepared(MediaPlayer mediaPlayer) {
+ mediaPlayer.start();
+ }
+ });
+ if (listener != null) {
+ this.mPlayer.setOnCompletionListener(listener);
+ }
+ } catch (Exception var4) {
+ var4.printStackTrace();
+ }
+ return mPlayer;
+
+ }
+
+ public void stop() {
+ if (this.mPlayer != null) {
+ this.mPlayer.stop();
+ this.mPlayer.release();
+ this.mPlayer = null;
+ }
+
+ }
+}
diff --git a/utill/src/main/java/com/lennon/cn/utill/utill/AudioRecorderUtil.java b/utill/src/main/java/com/lennon/cn/utill/utill/AudioRecorderUtil.java
new file mode 100644
index 0000000..9da9804
--- /dev/null
+++ b/utill/src/main/java/com/lennon/cn/utill/utill/AudioRecorderUtil.java
@@ -0,0 +1,196 @@
+package com.lennon.cn.utill.utill;
+
+import android.media.MediaRecorder;
+import android.os.Handler;
+
+import java.io.File;
+import java.io.IOException;
+
+/**
+ * @author lennon
+ *
+ * 作者:lennon on 2019/2/18 16:29
+ *
+ * 邮箱:1136160757@qq.com
+ */
+public class AudioRecorderUtil {
+ private final String TAG = AudioRecorderUtil.class.getName();
+ public static final int MAX_LENGTH = 60000;
+ private String filePath;
+ private String folderPath;
+ private MediaRecorder mMediaRecorder;
+ private int maxLength;
+ private long startTime;
+ private long endTime;
+ private OnAudioStatusUpdateListener audioStatusUpdateListener;
+ private final Handler mHandler = new Handler();
+ private Runnable mUpdateMicStatusTimer = new Runnable() {
+ @Override
+ public void run() {
+ AudioRecorderUtil.this.updateMicStatus();
+ }
+ };
+ private int BASE = 1;
+ private int SPACE = 100;
+
+ public AudioRecorderUtil(String folderPath) {
+ File path = new File(folderPath);
+ if (!path.exists()) {
+ path.mkdirs();
+ }
+
+ this.folderPath = folderPath;
+ this.maxLength = '\uea60';
+ }
+
+ public String start() {
+ if (this.mMediaRecorder == null) {
+ this.mMediaRecorder = new MediaRecorder();
+ } else {
+ try {
+ this.mMediaRecorder.stop();
+ this.mMediaRecorder.reset();
+ this.mMediaRecorder.release();
+ } catch (Exception var2) {
+ this.mMediaRecorder.reset();
+ }
+ }
+
+ this.mHandler.removeCallbacks(this.mUpdateMicStatusTimer);
+
+ try {
+ this.mMediaRecorder.setAudioSource(1);
+ this.mMediaRecorder.setOutputFormat(0);
+ this.mMediaRecorder.setAudioEncoder(1);
+ this.filePath = this.folderPath + File.separator + System.currentTimeMillis() + ".mp3";
+ this.mMediaRecorder.setOutputFile(this.filePath);
+ this.mMediaRecorder.setMaxDuration(this.maxLength);
+ this.mMediaRecorder.prepare();
+ this.mMediaRecorder.setOnInfoListener(new MediaRecorder.OnInfoListener() {
+ @Override
+ public void onInfo(MediaRecorder mr, int what, int extra) {
+ if (what == 800) {
+ AudioRecorderUtil.this.stop();
+ }
+
+ }
+ });
+ this.mMediaRecorder.start();
+ this.startTime = System.currentTimeMillis();
+ this.updateMicStatus();
+ if (this.audioStatusUpdateListener != null) {
+ this.audioStatusUpdateListener.onStart();
+ }
+ } catch (IllegalStateException var3) {
+ if (this.audioStatusUpdateListener != null) {
+ this.audioStatusUpdateListener.onError(var3);
+ }
+
+ this.cancel();
+ } catch (IOException var4) {
+ if (this.audioStatusUpdateListener != null) {
+ this.audioStatusUpdateListener.onError(var4);
+ }
+
+ this.cancel();
+ }
+ return filePath;
+ }
+
+ public long getSumTime() {
+ return this.startTime == 0L ? 0L : System.currentTimeMillis() - this.startTime;
+ }
+
+ public long stop() {
+ if (this.mMediaRecorder == null) {
+ return 0L;
+ } else {
+ this.endTime = System.currentTimeMillis();
+
+ try {
+ this.mMediaRecorder.stop();
+ this.mMediaRecorder.reset();
+ this.mMediaRecorder.release();
+ this.mMediaRecorder = null;
+ if (this.audioStatusUpdateListener != null) {
+ this.audioStatusUpdateListener.onStop(this.filePath);
+ }
+ } catch (RuntimeException var3) {
+ this.mMediaRecorder.reset();
+ this.mMediaRecorder.release();
+ this.mMediaRecorder = null;
+ File file = new File(this.filePath);
+ if (file.exists()) {
+ file.delete();
+ }
+
+ if (this.audioStatusUpdateListener != null) {
+ this.audioStatusUpdateListener.onError(var3);
+ }
+ }
+
+ this.filePath = "";
+ return this.endTime - this.startTime;
+ }
+ }
+
+ public void cancel() {
+ try {
+ this.mMediaRecorder.stop();
+ this.mMediaRecorder.reset();
+ this.mMediaRecorder.release();
+ this.mMediaRecorder = null;
+ } catch (RuntimeException var2) {
+ this.mMediaRecorder.reset();
+ this.mMediaRecorder.release();
+ this.mMediaRecorder = null;
+ }
+
+ File file = new File(this.filePath);
+ if (file.exists()) {
+ file.delete();
+ }
+
+ this.filePath = "";
+ if (this.audioStatusUpdateListener != null) {
+ this.audioStatusUpdateListener.onCancel();
+ }
+
+ }
+
+ public void setMaxLength(int maxLength) {
+ this.maxLength = maxLength;
+ }
+
+ private void updateMicStatus() {
+ if (this.mMediaRecorder != null) {
+ double ratio = (double) this.mMediaRecorder.getMaxAmplitude() / (double) this.BASE;
+ double db = 0.0D;
+ if (ratio > 1.0D) {
+ db = 20.0D * Math.log10(ratio);
+ if (null != this.audioStatusUpdateListener) {
+ this.audioStatusUpdateListener.onProgress(db, System.currentTimeMillis() - this.startTime);
+ }
+ }
+
+ this.mHandler.postDelayed(this.mUpdateMicStatusTimer, (long) this.SPACE);
+ }
+
+ }
+
+ public void setOnAudioStatusUpdateListener(OnAudioStatusUpdateListener audioStatusUpdateListener) {
+ this.audioStatusUpdateListener = audioStatusUpdateListener;
+ }
+
+ public interface OnAudioStatusUpdateListener {
+ void onStart();
+
+ void onProgress(double var1, long var3);
+
+ void onError(Exception var1);
+
+ void onCancel();
+
+ void onStop(String var1);
+ }
+}
\ No newline at end of file
diff --git a/utill/src/main/java/com/lennon/cn/utill/utill/BitmapOperations.kt b/utill/src/main/java/com/lennon/cn/utill/utill/BitmapOperations.kt
new file mode 100644
index 0000000..7742c50
--- /dev/null
+++ b/utill/src/main/java/com/lennon/cn/utill/utill/BitmapOperations.kt
@@ -0,0 +1,109 @@
+package com.lennon.cn.utill.utill
+
+import android.graphics.Bitmap
+import android.graphics.Canvas
+import android.graphics.Matrix
+import android.graphics.Paint
+
+object BitmapOperations {
+
+ private val paint: Paint
+ get() {
+ val paint = Paint()
+ paint.isAntiAlias = true
+ return paint
+ }
+
+ /**
+ * 按比例缩放图片
+ * baseBitmap: 需要缩放的原图
+ * float x:横向缩放比例
+ * float y:纵向缩放比例
+ */
+ fun bitmapScale(baseBitmap: Bitmap, x: Float, y: Float): Bitmap {
+ // 因为要将图片放大,所以要根据放大的尺寸重新创建Bitmap
+ val afterBitmap = Bitmap.createBitmap((baseBitmap.width * x).toInt(), (baseBitmap.height * y).toInt(), baseBitmap.config)
+ val canvas = Canvas(afterBitmap)
+ // 初始化Matrix对象
+ val matrix = Matrix()
+ // 根据传入的参数设置缩放比例
+ matrix.setScale(x, y)
+ // 根据缩放比例,把图片draw到Canvas上
+ canvas.drawBitmap(baseBitmap, matrix, paint)
+ return afterBitmap
+ }
+
+ /**
+ * 按给定尺寸缩放图片
+ * baseBitmap: 需要缩放的原图
+ * new_width:缩放后的宽度
+ * new_height:缩放后的高度
+ */
+ fun bitmapScale(baseBitmap: Bitmap, new_width: Int, new_height: Int): Bitmap {
+ // 因为要将图片放大,所以要根据放大的尺寸重新创建Bitmap
+ val afterBitmap = Bitmap.createBitmap(new_width, new_height, baseBitmap.config)
+ val canvas = Canvas(afterBitmap)
+ // 初始化Matrix对象
+ val matrix = Matrix()
+ // 根据传入的参数设置缩放比例
+ val sx = new_width.toFloat() / baseBitmap.width.toFloat()
+ val sy = new_height.toFloat() / baseBitmap.height.toFloat()
+ matrix.setScale(sx, sy)
+ // 根据缩放比例,把图片draw到Canvas上
+ canvas.drawBitmap(baseBitmap, matrix, paint)
+ return afterBitmap
+ }
+
+ /**
+ * 倾斜图片
+ */
+ fun bitmapSkew(baseBitmap: Bitmap, dx: Float, dy: Float): Bitmap {
+ // 根据图片的倾斜比例,计算变换后图片的大小,
+ val afterBitmap = Bitmap.createBitmap(baseBitmap.width + (baseBitmap.width * dx).toInt(), baseBitmap.height + (baseBitmap.height * dy).toInt(), baseBitmap.config)
+ val canvas = Canvas(afterBitmap)
+ val matrix = Matrix()
+ // 设置图片倾斜的比例
+ matrix.setSkew(dx, dy)
+ canvas.drawBitmap(baseBitmap, matrix, paint)
+ return afterBitmap
+ }
+
+ /**
+ * 图片移动
+ */
+ fun bitmapTranslate(baseBitmap: Bitmap, dx: Float, dy: Float): Bitmap {
+ // 需要根据移动的距离来创建图片的拷贝图大小
+ val afterBitmap = Bitmap.createBitmap((baseBitmap.width + dx).toInt(), (baseBitmap.height + dy).toInt(), baseBitmap.config)
+ val canvas = Canvas(afterBitmap)
+ val matrix = Matrix()
+ // 设置移动的距离
+ matrix.setTranslate(dx, dy)
+ canvas.drawBitmap(baseBitmap, matrix, paint)
+ return afterBitmap
+ }
+
+ /**
+ * 图片绕中心旋转
+ */
+ fun bitmapRotate(baseBitmap: Bitmap, degrees: Float): Bitmap {
+ // 创建一个和原图一样大小的图片
+ val afterBitmap = Bitmap.createBitmap(baseBitmap.width, baseBitmap.height, baseBitmap.config)
+ val canvas = Canvas(afterBitmap)
+ val matrix = Matrix()
+ // 根据原图的中心位置旋转
+ matrix.setRotate(degrees, baseBitmap.width.toFloat() / 2.0f, baseBitmap.height.toFloat() / 2.0f)
+ canvas.drawBitmap(baseBitmap, matrix, paint)
+ return afterBitmap
+ }
+
+ /**
+ * 图片绕中心旋转
+ */
+ fun rotaingImage(bitmap: Bitmap, angle: Int): Bitmap {
+ //旋转图片 动作
+ val matrix = Matrix()
+ matrix.postRotate(angle.toFloat())
+ // 创建新的图片
+ return Bitmap.createBitmap(bitmap, 0, 0, bitmap.width, bitmap.height, matrix, true)
+ }
+}
diff --git a/utill/src/main/java/com/lennon/cn/utill/utill/CountdownUtill.java b/utill/src/main/java/com/lennon/cn/utill/utill/CountdownUtill.java
new file mode 100644
index 0000000..5d33a04
--- /dev/null
+++ b/utill/src/main/java/com/lennon/cn/utill/utill/CountdownUtill.java
@@ -0,0 +1,57 @@
+package com.lennon.cn.utill.utill;
+
+import android.annotation.SuppressLint;
+import android.app.Activity;
+import android.os.CountDownTimer;
+import android.widget.TextView;
+import lennon.com.utill.R;
+
+/**
+ * Created by lennon on 2017/9/24.
+ */
+
+public class CountdownUtill extends CountDownTimer {
+ private Activity mActivity;
+ private TextView mBtn;
+ private boolean mIsEnable = false;
+ private Listener listener;
+ private String startString = "", endString = "";
+
+ public CountdownUtill(Activity activity, long millisInFuture, long countDownInterval, TextView button, Listener listener) {
+ super(millisInFuture, countDownInterval);
+ this.mActivity = activity;
+ this.mBtn = button;
+ this.mIsEnable = true;
+ this.listener = listener;
+ }
+
+ @SuppressLint("SetTextI18n")
+ @Override
+ public void onFinish() {
+ mBtn.setText("0" + mActivity.getResources().getString(R.string.resend_sms));
+ if (listener != null) {
+ listener.onFinish();
+ }
+ }
+
+ @SuppressLint("SetTextI18n")
+ @Override
+ public void onTick(long millisUntilFinished) {
+ if (mIsEnable)
+ mBtn.setEnabled(false);
+ mIsEnable = false;
+ mBtn.setText(startString + (millisUntilFinished / 1000) + mActivity.getResources().getString(R.string.resend_sms) + endString);
+ }
+
+ public void setStartString(String startString) {
+ this.startString = startString;
+ }
+
+ public void setEndString(String endString) {
+ this.endString = endString;
+ }
+
+ public interface Listener {
+ void onFinish();
+ }
+}
diff --git a/utill/src/main/java/com/lennon/cn/utill/utill/DensityUtils.kt b/utill/src/main/java/com/lennon/cn/utill/utill/DensityUtils.kt
new file mode 100644
index 0000000..53fcf17
--- /dev/null
+++ b/utill/src/main/java/com/lennon/cn/utill/utill/DensityUtils.kt
@@ -0,0 +1,148 @@
+package com.lennon.cn.utill.utill
+
+import android.app.Activity
+import android.app.Application
+import android.content.ComponentCallbacks
+import android.content.Context
+import android.content.res.Configuration
+import android.util.DisplayMetrics
+
+object DensityUtils {
+ private var appDensity: Float = 0.toFloat()
+ private var appScaledDensity: Float = 0.toFloat()
+ private var appDisplayMetrics: DisplayMetrics? = null
+ private var barHeight: Int = 0
+ val WIDTH = "width"
+ val HEIGHT = "height"
+
+ /**
+ * 在Application里初始化一下
+ * @param application
+ */
+ fun setDensity(application: Application) {
+ //获取application的DisplayMetrics
+ appDisplayMetrics = application.resources.displayMetrics
+ //获取状态栏高度
+ barHeight = getStatusBarHeight(application)
+
+ if (appDensity == 0f) {
+ //初始化的时候赋值
+ appDensity = appDisplayMetrics!!.density
+ appScaledDensity = appDisplayMetrics!!.scaledDensity
+
+ //添加字体变化的监听
+ application.registerComponentCallbacks(object : ComponentCallbacks {
+ override fun onConfigurationChanged(newConfig: Configuration) {
+ //字体改变后,将appScaledDensity重新赋值
+ if (newConfig != null && newConfig.fontScale > 0) {
+ appScaledDensity = application.resources.displayMetrics.scaledDensity
+ }
+ }
+
+ override fun onLowMemory() {}
+ })
+ }
+ }
+
+ /**
+ * 此方法在BaseActivity中做初始化(如果不封装BaseActivity的话,直接用下面那个方法就好)
+ * 在setContentView()之前设置
+ * @param activity
+ */
+ fun setDefault(activity: Activity) {
+ setAppOrientation(activity, WIDTH)
+ }
+
+ /**
+ * 此方法用于在某一个Activity里面更改适配的方向
+ * 在setContentView()之前设置
+ * @param activity
+ * @param orientation
+ */
+ fun setOrientation(activity: Activity, orientation: String) {
+ setAppOrientation(activity, orientation)
+ }
+ /**
+ * 此方法用于在某一个Activity里面更改适配的方向
+ * 在setContentView()之前设置
+ * @param activity
+ * @param orientation
+ */
+ fun setOrientation(activity: Activity, orientation: String,f: Float) {
+ setAppOrientation(activity, orientation,f)
+ }
+ /**
+ * targetDensity
+ * targetScaledDensity
+ * targetDensityDpi
+ * 这三个参数是统一修改过后的值
+ * orientation:方向值,传入width或height
+ */
+ private fun setAppOrientation(activity: Activity, orientation: String, f: Float) {
+
+ val targetDensity: Float
+
+ if (orientation == "height") {
+ targetDensity = (appDisplayMetrics!!.heightPixels - barHeight) / f//设计图的高度 单位:dp
+ } else {
+ targetDensity = appDisplayMetrics!!.widthPixels / f//设计图的宽度 单位:dp
+ }
+
+ val targetScaledDensity = targetDensity * (appScaledDensity / appDensity)
+ val targetDensityDpi = (160 * targetDensity).toInt()
+
+ /**
+ *
+ * 最后在这里将修改过后的值赋给系统参数
+ * 只修改Activity的density值
+ */
+ val activityDisplayMetrics = activity.resources.displayMetrics
+ activityDisplayMetrics.density = targetDensity
+ activityDisplayMetrics.scaledDensity = targetScaledDensity
+ activityDisplayMetrics.densityDpi = targetDensityDpi
+ }
+
+ /**
+ * targetDensity
+ * targetScaledDensity
+ * targetDensityDpi
+ * 这三个参数是统一修改过后的值
+ * orientation:方向值,传入width或height
+ */
+ private fun setAppOrientation(activity: Activity, orientation: String) {
+ val targetDensity: Float
+ if (orientation == "height") {
+ targetDensity = (appDisplayMetrics!!.heightPixels - barHeight) / 1080f//设计图的高度 单位:dp
+ } else {
+ targetDensity = appDisplayMetrics!!.widthPixels / 420f//设计图的宽度 单位:dp
+ }
+
+ val targetScaledDensity = targetDensity * (appScaledDensity / appDensity)
+ val targetDensityDpi = (160 * targetDensity).toInt()
+
+ /**
+ *
+ * 最后在这里将修改过后的值赋给系统参数
+ * 只修改Activity的density值
+ */
+ val activityDisplayMetrics = activity.resources.displayMetrics
+ activityDisplayMetrics.density = targetDensity
+ activityDisplayMetrics.scaledDensity = targetScaledDensity
+ activityDisplayMetrics.densityDpi = targetDensityDpi
+ }
+
+ /**
+ * 获取状态栏高度
+ *
+ * @param context
+ * @return
+ */
+ fun getStatusBarHeight(context: Context): Int {
+ var result = 0
+ val resourceId = context.resources.getIdentifier("status_bar_height", "dimen", "android")
+ if (resourceId > 0) {
+ result = context.resources.getDimensionPixelSize(resourceId)
+ }
+ return result
+ }
+}
diff --git a/utill/src/main/java/com/lennon/cn/utill/utill/FileUtil.java b/utill/src/main/java/com/lennon/cn/utill/utill/FileUtil.java
new file mode 100644
index 0000000..9cebc61
--- /dev/null
+++ b/utill/src/main/java/com/lennon/cn/utill/utill/FileUtil.java
@@ -0,0 +1,859 @@
+package com.lennon.cn.utill.utill;
+
+import android.app.Application;
+import android.content.Context;
+import android.content.res.AssetFileDescriptor;
+import android.content.res.AssetManager;
+import android.graphics.Bitmap;
+import android.os.Environment;
+import android.os.StatFs;
+import android.text.TextUtils;
+import cn.droidlover.xdroidmvp.log.XLog;
+import com.lennon.cn.utill.base.BaseApplication;
+
+import java.io.*;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+
+/**
+ * 文件操作工具包
+ *
+ * @author liux (http://my.oschina.net/liux)
+ * @version 1.0
+ * @created 2012-3-21
+ */
+public class FileUtil {
+ public static AssetFileDescriptor getAssetFileDescription(Application application, String filename) throws IOException {
+ AssetManager manager = application.getAssets();
+ return manager.openFd(filename);
+ }
+
+ /**
+ * 根据文件绝对路径获取文件名
+ *
+ * @param filePath
+ * @return
+ */
+ public static String getFileName(String filePath) {
+ if (TextUtils.isEmpty(filePath)) {
+ return "";
+ } else {
+ return filePath.substring(filePath.lastIndexOf(File.separator) + 1);
+ }
+ }
+
+ //创建一个临时目录,用于复制临时文件,如assets目录下的离线资源文件
+ public static String createTmpDir(Context context) {
+ String sampleDir = "baiduTTS";
+ String tmpDir = Environment.getExternalStorageDirectory().toString() + "/" + sampleDir;
+ if (!FileUtil.makeDir(tmpDir)) {
+ tmpDir = context.getExternalFilesDir(sampleDir).getAbsolutePath();
+ if (!FileUtil.makeDir(sampleDir)) {
+ throw new RuntimeException("create model resources dir failed :" + tmpDir);
+ }
+ }
+ return tmpDir;
+ }
+
+ public static boolean makeDir(String dirPath) {
+ File file = new File(dirPath);
+ if (!file.exists()) {
+ return file.mkdirs();
+ } else {
+ return true;
+ }
+ }
+
+ public static void copyFromAssets(AssetManager assets, String source, String dest, boolean isCover) throws IOException {
+ File file = new File(dest);
+ if (isCover || (!isCover && !file.exists())) {
+ InputStream is = null;
+ FileOutputStream fos = null;
+ try {
+ is = assets.open(source);
+ String path = dest;
+ fos = new FileOutputStream(path);
+ byte[] buffer = new byte[1024];
+ int size = 0;
+ while ((size = is.read(buffer, 0, 1024)) >= 0) {
+ fos.write(buffer, 0, size);
+ }
+ } finally {
+ if (fos != null) {
+ try {
+ fos.close();
+ } finally {
+ if (is != null) {
+ is.close();
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * 写文本文件 在Android系统中,文件保存在 /data/data/PACKAGE_NAME/files 目录下
+ *
+ * @param context
+ */
+ public static void write(Context context, String fileName, String content) {
+ if (content == null) {
+ content = "";
+ }
+
+ try {
+ FileOutputStream fos = context.openFileOutput(fileName,
+ Context.MODE_PRIVATE);
+ fos.write(content.getBytes());
+
+ fos.close();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * 读取文本文件
+ *
+ * @param context
+ * @param fileName
+ * @return
+ */
+ public static String read(Context context, String fileName) {
+ try {
+ FileInputStream in = context.openFileInput(fileName);
+ return readInStream(in);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return "";
+ }
+
+ public static String readInStream(InputStream inStream) {
+ try {
+ ByteArrayOutputStream outStream = new ByteArrayOutputStream();
+ byte[] buffer = new byte[512];
+ int length = -1;
+ while ((length = inStream.read(buffer)) != -1) {
+ outStream.write(buffer, 0, length);
+ }
+
+ outStream.close();
+ inStream.close();
+ return outStream.toString();
+ } catch (IOException e) {
+ XLog.e("FileTest " + e.getMessage());
+ }
+ return null;
+ }
+
+ public static File createFile(String folderPath, String fileName) {
+ File destDir = new File(folderPath);
+ if (!destDir.exists()) {
+ destDir.mkdirs();
+ }
+ return new File(folderPath, fileName + fileName);
+ }
+
+ /**
+ * 向手机写图片
+ *
+ * @param buffer
+ * @param folder
+ * @param fileName
+ * @return
+ */
+ public static boolean writeFile(byte[] buffer, String folder,
+ String fileName) {
+ boolean writeSucc = false;
+
+ boolean sdCardExist = Environment.getExternalStorageState().equals(
+ Environment.MEDIA_MOUNTED);
+
+ String folderPath = "";
+ if (sdCardExist) {
+ folderPath = Environment.getExternalStorageDirectory()
+ + File.separator + folder + File.separator;
+ } else {
+ writeSucc = false;
+ }
+
+ File fileDir = new File(folderPath);
+ if (!fileDir.exists()) {
+ fileDir.mkdirs();
+ }
+
+ File file = new File(folderPath + fileName);
+ FileOutputStream out = null;
+ try {
+ out = new FileOutputStream(file);
+ out.write(buffer);
+ writeSucc = true;
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally {
+ try {
+ if (out != null) {
+ out.close();
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ return writeSucc;
+ }
+
+ /**
+ * 根据文件的绝对路径获取文件名但不包含扩展名
+ *
+ * @param filePath
+ * @return
+ */
+ public static String getFileNameNoFormat(String filePath) {
+ if (StringUtils.isEmpty(filePath)) {
+ return "";
+ }
+ int point = filePath.lastIndexOf('.');
+ return filePath.substring(filePath.lastIndexOf(File.separator) + 1,
+ point);
+ }
+
+ /**
+ * 获取文件扩展名
+ *
+ * @param fileName
+ * @return
+ */
+ public static String getFileFormat(String fileName) {
+ if (StringUtils.isEmpty(fileName)) {
+ return "";
+ }
+
+ int point = fileName.lastIndexOf('.');
+ return fileName.substring(point + 1);
+ }
+
+ /**
+ * 获取文件大小
+ *
+ * @param filePath
+ * @return
+ */
+ public static long getFileSize(String filePath) {
+ long size = 0;
+
+ File file = new File(filePath);
+ if (file != null && file.exists()) {
+ size = file.length();
+ }
+ return size;
+ }
+
+ /**
+ * 获取文件大小
+ *
+ * @param size 字节
+ * @return
+ */
+ public static String getFileSize(long size) {
+ if (size <= 0) {
+ return "0";
+ }
+ java.text.DecimalFormat df = new java.text.DecimalFormat("##.##");
+ float temp = (float) size / 1024;
+ if (temp >= 1024) {
+ return df.format(temp / 1024) + "M";
+ } else {
+ return df.format(temp) + "K";
+ }
+ }
+
+ /**
+ * 转换文件大小
+ *
+ * @param fileS
+ * @return B/KB/MB/GB
+ */
+ public static String formatFileSize(long fileS) {
+ java.text.DecimalFormat df = new java.text.DecimalFormat("#.00");
+ String fileSizeString = "";
+ if (fileS < 1024) {
+ fileSizeString = df.format((double) fileS) + "B";
+ } else if (fileS < 1048576) {
+ fileSizeString = df.format((double) fileS / 1024) + "KB";
+ } else if (fileS < 1073741824) {
+ fileSizeString = df.format((double) fileS / 1048576) + "MB";
+ } else {
+ fileSizeString = df.format((double) fileS / 1073741824) + "G";
+ }
+ return fileSizeString;
+ }
+
+ /**
+ * 获取目录文件大小
+ *
+ * @param dir
+ * @return
+ */
+ public static long getDirSize(File dir) {
+ if (dir == null) {
+ return 0;
+ }
+ if (!dir.isDirectory()) {
+ return 0;
+ }
+ long dirSize = 0;
+ File[] files = dir.listFiles();
+ if (files != null) {
+
+ for (File file : files) {
+ if (file.isFile()) {
+ dirSize += file.length();
+ } else if (file.isDirectory()) {
+ dirSize += file.length();
+ dirSize += getDirSize(file); // 递归调用继续统计
+ }
+ }
+ }
+ return dirSize;
+ }
+
+ public static AssetFileDescriptor getAssetFileDescription(String path) throws IOException {
+ return BaseApplication.Companion.getAppliction().getAssets().openFd(path);
+ }
+
+ /**
+ * 获取目录文件个数
+ *
+ * @return
+ */
+ public long getFileList(File dir) {
+ long count = 0;
+ File[] files = dir.listFiles();
+ count = files.length;
+ for (File file : files) {
+ if (file.isDirectory()) {
+ count = count + getFileList(file);// 递归
+ count--;
+ }
+ }
+ return count;
+ }
+
+ public static byte[] toBytes(InputStream in) throws IOException {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ int ch;
+ while ((ch = in.read()) != -1) {
+ out.write(ch);
+ }
+ byte buffer[] = out.toByteArray();
+ out.close();
+ return buffer;
+ }
+
+ /**
+ * 检查文件是否存在
+ *
+ * @param name
+ * @return
+ */
+ public static boolean checkFileExists(String name) {
+ boolean status;
+ if (!"".equals(name)) {
+ File path = Environment.getExternalStorageDirectory();
+ File newPath = new File(path.toString() + name);
+ status = newPath.exists();
+ } else {
+ status = false;
+ }
+ return status;
+ }
+
+ /**
+ * 检查路径是否存在
+ *
+ * @param path
+ * @return
+ */
+ public static boolean checkFilePathExists(String path) {
+ return new File(path).exists();
+ }
+
+ /**
+ * 计算SD卡的剩余空间
+ *
+ * @return 返回-1,说明没有安装sd卡
+ */
+ public static long getFreeDiskSpace() {
+ String status = Environment.getExternalStorageState();
+ long freeSpace = 0;
+ if (status.equals(Environment.MEDIA_MOUNTED)) {
+ try {
+ File path = Environment.getExternalStorageDirectory();
+ StatFs stat = new StatFs(path.getPath());
+ long blockSize = stat.getBlockSize();
+ long availableBlocks = stat.getAvailableBlocks();
+ freeSpace = availableBlocks * blockSize / 1024;
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ } else {
+ return -1;
+ }
+ return (freeSpace);
+ }
+
+ /**
+ * 新建目录
+ *
+ * @param directoryName
+ * @return
+ */
+ public static boolean createDirectory(String directoryName) {
+ boolean status;
+ if (!"".equals(directoryName)) {
+ File path = Environment.getExternalStorageDirectory();
+ File newPath = new File(path.toString() + directoryName);
+ status = newPath.mkdir();
+ status = true;
+ } else {
+ status = false;
+ }
+ return status;
+ }
+
+ /**
+ * 检查是否安装SD卡
+ *
+ * @return
+ */
+ public static boolean checkSaveLocationExists() {
+ String sDCardStatus = Environment.getExternalStorageState();
+ boolean status;
+ if (sDCardStatus.equals(Environment.MEDIA_MOUNTED)) {
+ status = true;
+ } else {
+ status = false;
+ }
+ return status;
+ }
+
+ /**
+ * 检查是否安装外置的SD卡
+ *
+ * @return
+ */
+ public static boolean checkExternalSDExists() {
+
+ Map evn = System.getenv();
+ return evn.containsKey("SECONDARY_STORAGE");
+ }
+
+ /**
+ * 复制单个文件
+ *
+ * @param oldPath String 原文件路径 如:c:/fqf.txt
+ * @param newPath String 复制后路径 如:f:/fqf.txt
+ * @return boolean
+ */
+ public void copyFile(String oldPath, String newPath) {
+ try {
+ int bytesum = 0;
+ int byteread = 0;
+ File oldfile = new File(oldPath);
+ if (oldfile.exists()) { //文件存在时
+ InputStream inStream = new FileInputStream(oldPath); //读入原文件
+ FileOutputStream fs = new FileOutputStream(newPath);
+ byte[] buffer = new byte[1444];
+ int length;
+ while ((byteread = inStream.read(buffer)) != -1) {
+ bytesum += byteread; //字节数 文件大小
+ System.out.println(bytesum);
+ fs.write(buffer, 0, byteread);
+ }
+ inStream.close();
+ }
+ } catch (Exception e) {
+ System.out.println("复制单个文件操作出错");
+ e.printStackTrace();
+
+ }
+ }
+
+ public static void copyFileforAsses(String assetName, String newPath) {
+ try {
+ int bytesum = 0;
+ int byteread = 0;
+ InputStream inStream = BaseApplication.Companion.context().getAssets().open(assetName);
+ FileOutputStream fs = new FileOutputStream(newPath);
+ byte[] buffer = new byte[1444];
+ int length;
+ while ((byteread = inStream.read(buffer)) != -1) {
+ bytesum += byteread; //字节数 文件大小
+ System.out.println(bytesum);
+ fs.write(buffer, 0, byteread);
+ }
+ inStream.close();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * 删除目录(包括:目录里的所有文件)
+ *
+ * @param fileName
+ * @return
+ */
+ public static boolean deleteDirectory(String fileName) {
+ boolean status;
+ SecurityManager checker = new SecurityManager();
+
+ if (!"".equals(fileName)) {
+
+ File path = Environment.getExternalStorageDirectory();
+ File newPath = new File(path.toString() + fileName);
+ checker.checkDelete(newPath.toString());
+ if (newPath.isDirectory()) {
+ String[] listfile = newPath.list();
+ try {
+ for (int i = 0; i < listfile.length; i++) {
+ File deletedFile = new File(newPath.toString() + "/"
+ + listfile[i].toString());
+ deletedFile.delete();
+ }
+ newPath.delete();
+ status = true;
+ } catch (Exception e) {
+ e.printStackTrace();
+ status = false;
+ }
+
+ } else {
+ status = false;
+ }
+ } else {
+ status = false;
+ }
+ return status;
+ }
+
+ /**
+ * 删除文件
+ *
+ * @param fileName
+ * @return
+ */
+ public static boolean deleteFile(String fileName) {
+ boolean status;
+ SecurityManager checker = new SecurityManager();
+
+ if (!"".equals(fileName)) {
+
+ File path = Environment.getExternalStorageDirectory();
+ File newPath = new File(path.toString() + fileName);
+ checker.checkDelete(newPath.toString());
+ if (newPath.isFile()) {
+ try {
+ newPath.delete();
+ status = true;
+ } catch (SecurityException se) {
+ se.printStackTrace();
+ status = false;
+ }
+ } else {
+ status = false;
+ }
+ } else {
+ status = false;
+ }
+ return status;
+ }
+
+ /**
+ * 删除空目录
+ *
+ * 返回 0代表成功 ,1 代表没有删除权限, 2代表不是空目录,3 代表未知错误
+ *
+ * @return
+ */
+ public static int deleteBlankPath(String path) {
+ File f = new File(path);
+ if (!f.canWrite()) {
+ return 1;
+ }
+ if (f.list() != null && f.list().length > 0) {
+ return 2;
+ }
+ if (f.delete()) {
+ return 0;
+ }
+ return 3;
+ }
+
+ /**
+ * 重命名
+ *
+ * @param oldName
+ * @param newName
+ * @return
+ */
+ public static boolean reNamePath(String oldName, String newName) {
+ File f = new File(oldName);
+ return f.renameTo(new File(newName));
+ }
+
+ /**
+ * 删除文件
+ *
+ * @param filePath
+ */
+ public static boolean deleteFileWithPath(String filePath) {
+ SecurityManager checker = new SecurityManager();
+ File f = new File(filePath);
+ checker.checkDelete(filePath);
+ if (f.isFile()) {
+ f.delete();
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * 清空一个文件夹
+ */
+ public static void clearFileWithPath(String filePath) {
+ List files = FileUtil.listPathFiles(filePath);
+ if (files.isEmpty()) {
+ return;
+ }
+ for (File f : files) {
+ if (f.isDirectory()) {
+ clearFileWithPath(f.getAbsolutePath());
+ } else {
+ f.delete();
+ }
+ }
+ }
+
+ /**
+ * 获取SD卡的根目录
+ *
+ * @return
+ */
+ public static String getSDRoot() {
+
+ return Environment.getExternalStorageDirectory().getAbsolutePath();
+ }
+
+ /**
+ * 获取手机外置SD卡的根目录
+ *
+ * @return
+ */
+ public static String getExternalSDRoot() {
+
+ Map evn = System.getenv();
+
+ return evn.get("SECONDARY_STORAGE");
+ }
+
+ /**
+ * 列出root目录下所有子目录
+ *
+ * @return 绝对路径
+ */
+ public static List listPath(String root) {
+ List allDir = new ArrayList();
+ SecurityManager checker = new SecurityManager();
+ File path = new File(root);
+ checker.checkRead(root);
+ // 过滤掉以.开始的文件夹
+ if (path.isDirectory()) {
+ for (File f : path.listFiles()) {
+ if (f.isDirectory() && !f.getName().startsWith(".")) {
+ allDir.add(f.getAbsolutePath());
+ }
+ }
+ }
+ return allDir;
+ }
+
+ /**
+ * 获取一个文件夹下的所有文件
+ *
+ * @param root
+ * @return
+ */
+ public static List listPathFiles(String root) {
+ List allDir = new ArrayList();
+ SecurityManager checker = new SecurityManager();
+ File path = new File(root);
+ checker.checkRead(root);
+ File[] files = path.listFiles();
+ for (File f : files) {
+ if (f.isFile()) {
+ allDir.add(f);
+ } else {
+ listPath(f.getAbsolutePath());
+ }
+ }
+ return allDir;
+ }
+
+ public enum PathStatus {
+ SUCCESS, EXITS, ERROR
+ }
+
+ /**
+ * 创建目录
+ */
+ public static PathStatus createPath(String newPath) {
+ File path = new File(newPath);
+ if (path.exists()) {
+ return PathStatus.EXITS;
+ }
+ if (path.mkdir()) {
+ return PathStatus.SUCCESS;
+ } else {
+ return PathStatus.ERROR;
+ }
+ }
+
+ /**
+ * 截取路径名
+ *
+ * @return
+ */
+ public static String getPathName(String absolutePath) {
+ int start = absolutePath.lastIndexOf(File.separator) + 1;
+ int end = absolutePath.length();
+ return absolutePath.substring(start, end);
+ }
+
+ /**
+ * 获取应用程序缓存文件夹下的指定目录
+ *
+ * @param context
+ * @param dir
+ * @return
+ */
+ public static String getAppCache(Context context, String dir) {
+ String savePath = context.getCacheDir().getAbsolutePath() + "/" + dir + "/";
+ File savedir = new File(savePath);
+ if (!savedir.exists()) {
+ savedir.mkdirs();
+ }
+ savedir = null;
+ return savePath;
+ }
+
+ /**
+ * 关闭流
+ *
+ * @param closeables
+ */
+ public static void closeIO(Closeable... closeables) {
+ if (null == closeables || closeables.length <= 0) {
+ return;
+ }
+ for (Closeable cb : closeables) {
+ try {
+ if (null == cb) {
+ continue;
+ }
+ cb.close();
+ } catch (IOException e) {
+ throw new RuntimeException(
+ FileUtil.class.getClass().getName(), e);
+ }
+ }
+ }
+
+ /**
+ * 图片写入文件
+ *
+ * @param bitmap 图片
+ * @param filePath 文件路径
+ * @return 是否写入成功
+ */
+ public static boolean bitmapToFile(Bitmap bitmap, int quality, Bitmap.CompressFormat format, String filePath) {
+ boolean isSuccess = false;
+ if (bitmap == null) {
+ return isSuccess;
+ }
+ File file = new File(filePath.substring(0,
+ filePath.lastIndexOf(File.separator)));
+ if (!file.exists()) {
+ file.mkdirs();
+ }
+
+ OutputStream out = null;
+ try {
+ out = new BufferedOutputStream(new FileOutputStream(filePath),
+ 8 * 1024);
+ isSuccess = bitmap.compress(format, quality, out);
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ } finally {
+ closeIO(out);
+ }
+ return isSuccess;
+ }
+
+ /**
+ * 获取SD卡下指定文件夹的绝对路径
+ *
+ * @return 返回SD卡下的指定文件夹的绝对路径
+ */
+ public static String getSavePath(String folderName) {
+ return getSaveFolder(folderName).getAbsolutePath();
+ }
+
+ /**
+ * 获取文件夹对象
+ *
+ * @return 返回SD卡下的指定文件夹对象,若文件夹不存在则创建
+ */
+ public static File getSaveFolder(String folderName) {
+ File file = new File(getSDCardPath() + File.separator + folderName
+ + File.separator);
+ file.mkdirs();
+ return file;
+ }
+
+ public static String getSDCardPath() {
+ return Environment.getExternalStorageDirectory().getAbsolutePath();
+ }
+
+ /**
+ * 写入文件
+ *
+ * @param in
+ * @param file
+ */
+ public static void writeFile(InputStream in, File file) throws IOException {
+ if (!file.getParentFile().exists()) {
+ file.getParentFile().mkdirs();
+ }
+
+ if (file != null && file.exists()) {
+ file.delete();
+ }
+
+ FileOutputStream out = new FileOutputStream(file);
+ byte[] buffer = new byte[1024 * 128];
+ int len = -1;
+ while ((len = in.read(buffer)) != -1) {
+ out.write(buffer, 0, len);
+ }
+ out.flush();
+ out.close();
+ in.close();
+
+ }
+}
\ No newline at end of file
diff --git a/utill/src/main/java/com/lennon/cn/utill/utill/GetDeviceId.java b/utill/src/main/java/com/lennon/cn/utill/utill/GetDeviceId.java
new file mode 100644
index 0000000..5eac5a8
--- /dev/null
+++ b/utill/src/main/java/com/lennon/cn/utill/utill/GetDeviceId.java
@@ -0,0 +1,271 @@
+package com.lennon.cn.utill.utill;
+
+import android.app.Activity;
+import android.content.Context;
+import android.os.Build;
+import android.text.TextUtils;
+import cn.droidlover.xdroidmvp.cache.SharedPref;
+import cn.droidlover.xdroidmvp.log.XLog;
+import com.lennon.cn.utill.base.BaseApplication;
+
+import java.io.*;
+import java.util.ArrayList;
+import java.util.List;
+
+
+public class GetDeviceId {
+ //保存的文件 采用隐藏文件的形式进行保存
+ private static final String DEVICES_FILE_NAME = ".DEVICES";
+
+ /**
+ * 获取设备唯一标识符
+ *
+ * @param context
+ * @return
+ */
+ public static String getDeviceId(Activity context) {
+ //读取保存的在sd卡中的唯一标识符
+ List deviceIds = readDeviceID(context);
+ if (deviceIds != null) {
+ XLog.e("readDeviceID-------------------------" + deviceIds.toString());
+ }
+ if (deviceIds != null && deviceIds.size() > 0) {
+ if (deviceIds.size() == 1) {
+ String deviceId = deviceIds.get(0);
+ //判断是否已经生成过,
+ if (deviceId != null && !"".equals(deviceId)) {
+ if (deviceId.contains("-") && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ return VersionUtill.getUUID();
+ }
+ return deviceId.replace("deviceId:", "").trim();
+ }
+ } else {
+ if (!TextUtils.isEmpty(deviceIds.get(0))) {
+ String deviceId = deviceIds.get(0).replace("deviceId:", "").trim();
+ //判断是否已经生成过,
+ if (!"".equals(deviceId)) {
+ return deviceId;
+ }
+ }
+ }
+ }
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ return VersionUtill.getUUID();
+ } else {
+ return VersionUtill.getAndroidId(context);
+ }
+ }
+
+ /**
+ * 读取固定的文件中的内容,这里就是读取sd卡中保存的设备唯一标识符
+ *
+ * @param context
+ * @return
+ */
+ public static List readDeviceID(Context context) {
+ File file = getDevicesDir(context);
+ File newFile = getNewDevicesDir(context);
+ List strings = getFileContent(new File(newFile.getAbsolutePath() + "/", "devices.txt"));
+ if (strings.size() > 0) {
+ return strings;
+ }
+// return getFileContent(file);
+
+// try {
+// List strings = new ArrayList<>();
+// FileInputStream fis = new FileInputStream(newFile);
+// InputStreamReader isr = new InputStreamReader(fis, "UTF-8");
+// BufferedReader in = new BufferedReader(isr);
+// String temp;
+// while ((temp = in.readLine()) != null) {
+// strings.add(temp);
+// }
+// in.close();
+// XLog.e("-------------readDeviceIdFile" + strings.toString());
+// if (strings.size() > 0) {
+// return strings;
+// }
+// } catch (IOException e) {
+// e.printStackTrace();
+// }
+ try {
+ strings = new ArrayList<>();
+ FileInputStream fis = new FileInputStream(file);
+ InputStreamReader isr = new InputStreamReader(fis, "UTF-8");
+ BufferedReader in = new BufferedReader(isr);
+ String temp;
+ while ((temp = in.readLine()) != null) {
+ strings.add(temp);
+ }
+ in.close();
+ XLog.e("-------------readDeviceIdFile" + strings.toString());
+ return strings;
+ } catch (IOException e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+ /**
+ * 保存 内容到 SD卡中, 这里保存的就是 设备唯一标识符
+ *
+ * @param str
+ * @param context
+ */
+ public static void saveDeviceID(String str, Context context) {
+ File file = getDevicesDir(context);
+ File newFile = getNewDevicesDir(context);
+ File f = new File(newFile.getPath(), newFile.getName() + ".txt");
+ try {
+ if (f.exists()) {
+ f.delete();
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ XLog.e(e.getMessage());
+ }
+
+// try {
+ writeTxtToFile("deviceId:" + str, newFile.getAbsolutePath() + "/", "devices.txt");
+// writer.write("deviceId:" + str);
+// writer.newLine();
+ writeTxtToFile("deviceId-version:2", newFile.getAbsolutePath() + "/", "devices.txt");
+// out.close();
+// } catch (IOException e) {
+// e.printStackTrace();
+// }
+// writeTxtToFile("deviceId:" + str, file.getParent(), file.getName());
+// writeTxtToFile("deviceId-version:2", file.getParent(), file.getName());
+ try {
+ FileOutputStream fos = new FileOutputStream(file);
+ OutputStreamWriter out = new OutputStreamWriter(fos, "UTF-8");
+ BufferedWriter writer = new BufferedWriter(out);
+ writer.write("deviceId:" + str);
+ writer.newLine();
+ writer.write("deviceId-version:2");
+ out.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ }
+
+
+ // 将字符串写入到文本文件中
+ private static void writeTxtToFile(String strcontent, String filePath, String fileName) {
+ //生成文件夹之后,再生成文件,不然会出错
+ makeFilePath(filePath, fileName);
+
+ String strFilePath = filePath + fileName;
+ // 每次写入时,都换行写
+ String strContent = strcontent + "\r\n";
+ try {
+ File file = new File(strFilePath);
+ if (!file.exists()) {
+ XLog.d("TestFile", "Create the file:" + strFilePath);
+ file.getParentFile().mkdirs();
+ file.createNewFile();
+ }
+ RandomAccessFile raf = new RandomAccessFile(file, "rwd");
+ raf.seek(file.length());
+ raf.write(strContent.getBytes());
+ raf.close();
+ } catch (Exception e) {
+ XLog.e("TestFile", "Error on write File:" + e);
+ }
+ }
+
+//生成文件
+
+ private static File makeFilePath(String filePath, String fileName) {
+ File file = null;
+ makeRootDirectory(filePath);
+ try {
+ file = new File(filePath + fileName);
+ if (!file.exists()) {
+ file.createNewFile();
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return file;
+ }
+
+//生成文件夹
+
+ private static void makeRootDirectory(String filePath) {
+ File file = null;
+ try {
+ file = new File(filePath);
+ if (!file.exists()) {
+ file.mkdir();
+ }
+ } catch (Exception e) {
+ XLog.e("error:", e + "");
+ }
+ }
+
+ //读取指定目录下的所有TXT文件的文件内容
+ private static List getFileContent(File file) {
+ List content = new ArrayList<>();
+ if (!file.isDirectory()) { //检查此路径名的文件是否是一个目录(文件夹)
+// if (file.getName().endsWith("txt")) {//文件格式为""文件
+ try {
+ InputStream instream = new FileInputStream(file);
+ if (instream != null) {
+ InputStreamReader inputreader
+ = new InputStreamReader(instream, "UTF-8");
+ BufferedReader buffreader = new BufferedReader(inputreader);
+ String line = "";
+ //分行读取
+ while ((line = buffreader.readLine()) != null) {
+ String s = "" + line;
+ content.add(s);
+ }
+ instream.close();//关闭输入流
+ }
+ } catch (java.io.FileNotFoundException e) {
+ XLog.e("TestFile", "The File doesn't not exist.");
+ } catch (IOException e) {
+ XLog.e("TestFile", e.getMessage());
+ }
+// }
+ }
+ return content;
+ }
+
+ /**
+ * 统一处理设备唯一标识 保存的文件的地址
+ *
+ * @param context
+ * @return
+ */
+ private static File getDevicesDir(Context context) {
+ File mCropFile = null;
+ mCropFile = new File(BaseApplication.Companion.getDataFile(), DEVICES_FILE_NAME);
+ if (!mCropFile.getParentFile().exists()) {
+ mCropFile.getParentFile().mkdirs();
+ }
+ if (!mCropFile.exists()) {
+ try {
+ mCropFile.createNewFile();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ XLog.e("getDevicesDir-----------------" + context.getFilesDir() + "-------------" + mCropFile.getParent() + "-----------------" + mCropFile.getName());
+ return mCropFile;
+ }
+
+ private static File getNewDevicesDir(Context context) {
+ File mCropFile = null;
+ mCropFile = new File(context.getFilesDir(), "devices");
+ if (!mCropFile.getParentFile().exists()) {
+ mCropFile.getParentFile().mkdirs();
+ }
+ XLog.e("getDevicesDir-----------------" + context.getFilesDir() + "-------------" + mCropFile.getParent() + "-----------------" + mCropFile.getName() + "-------------" + mCropFile.getPath());
+ return mCropFile;
+ }
+
+}
+
diff --git a/utill/src/main/java/com/lennon/cn/utill/utill/IDCard.java b/utill/src/main/java/com/lennon/cn/utill/utill/IDCard.java
new file mode 100644
index 0000000..ff89d4e
--- /dev/null
+++ b/utill/src/main/java/com/lennon/cn/utill/utill/IDCard.java
@@ -0,0 +1,196 @@
+package com.lennon.cn.utill.utill;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+import java.util.Hashtable;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Created by lennon on 2017/6/2.
+ */
+
+public class IDCard {
+ /*********************************** 身份证验证开始 ****************************************/
+ /**
+ * 身份证号码验证 1、号码的结构 公民身份号码是特征组合码,由十七位数字本体码和一位校验码组成。排列顺序从左至右依次为:六位数字地址码,
+ * 八位数字出生日期码,三位数字顺序码和一位数字校验码。 2、地址码(前六位数)
+ * 表示编码对象常住户口所在县(市、旗、区)的行政区划代码,按GB/T2260的规定执行。 3、出生日期码(第七位至十四位)
+ * 表示编码对象出生的年、月、日,按GB/T7408的规定执行,年、月、日代码之间不用分隔符。 4、顺序码(第十五位至十七位)
+ * 表示在同一地址码所标识的区域范围内,对同年、同月、同日出生的人编定的顺序号, 顺序码的奇数分配给男性,偶数分配给女性。 5、校验码(第十八位数)
+ * (1)十七位数字本体码加权求和公式 S = Sum(Ai * Wi), i = 0, ... , 16 ,先对前17位数字的权求和
+ * Ai:表示第i位置上的身份证号码数字值 Wi:表示第i位置上的加权因子 Wi: 7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2
+ * (2)计算模 Y = mod(S, 11) (3)通过模得到对应的校验码 Y: 0 1 2 3 4 5 6 7 8 9 10 校验码: 1 0 X 9 8 7 6 5 4 3 2
+ */
+
+ /**
+ * 功能:身份证的有效验证
+ *
+ * @param IDStr 身份证号
+ * @return 有效:返回"" 无效:返回String信息
+ * @throws ParseException
+ */
+ public static String IDCardValidate(String IDStr) {
+ String errorInfo = "";// 记录错误信息
+ String[] ValCodeArr = {"1", "0", "x", "9", "8", "7", "6", "5", "4",
+ "3", "2"};
+ String[] Wi = {"7", "9", "10", "5", "8", "4", "2", "1", "6", "3", "7",
+ "9", "10", "5", "8", "4", "2"};
+ String Ai = "";
+ // ================ 号码的长度 15位或18位 ================
+ if (IDStr.length() != 15 && IDStr.length() != 18) {
+ errorInfo = "身份证号码长度应该为15位或18位。";
+ return errorInfo;
+ }
+ // =======================(end)========================
+
+ // ================ 数字 除最后以为都为数字 ================
+ if (IDStr.length() == 18) {
+ Ai = IDStr.substring(0, 17);
+ } else {
+ Ai = IDStr.substring(0, 6) + "19" + IDStr.substring(6, 15);
+ }
+ if (!isNumeric(Ai)) {
+ errorInfo = "身份证15位号码都应为数字 ; 18位号码除最后一位外,都应为数字。";
+ return errorInfo;
+ }
+ // =======================(end)========================
+
+ // ================ 出生年月是否有效 ================
+ String strYear = Ai.substring(6, 10);// 年份
+ String strMonth = Ai.substring(10, 12);// 月份
+ String strDay = Ai.substring(12, 14);// 月份
+ if (!isDate(strYear + "-" + strMonth + "-" + strDay)) {
+ errorInfo = "身份证生日无效。";
+ return errorInfo;
+ }
+ GregorianCalendar gc = new GregorianCalendar();
+ SimpleDateFormat s = new SimpleDateFormat("yyyy-MM-dd");
+ try {
+ if ((gc.get(Calendar.YEAR) - Integer.parseInt(strYear)) > 150
+ || (gc.getTime().getTime() - s.parse(
+ strYear + "-" + strMonth + "-" + strDay).getTime()) < 0) {
+ errorInfo = "身份证生日不在有效范围。";
+ return errorInfo;
+ }
+ } catch (NumberFormatException e) {
+ e.printStackTrace();
+ return "识别出错";
+ } catch (ParseException e) {
+ e.printStackTrace();
+ return "识别出错";
+ }
+ if (Integer.parseInt(strMonth) > 12 || Integer.parseInt(strMonth) == 0) {
+ errorInfo = "身份证月份无效";
+ return errorInfo;
+ }
+ if (Integer.parseInt(strDay) > 31 || Integer.parseInt(strDay) == 0) {
+ errorInfo = "身份证日期无效";
+ return errorInfo;
+ }
+ // =====================(end)=====================
+
+ // ================ 地区码时候有效 ================
+ Hashtable h = GetAreaCode();
+ if (h.get(Ai.substring(0, 2)) == null) {
+ errorInfo = "身份证地区编码错误。";
+ return errorInfo;
+ }
+ // ==============================================
+
+ // ================ 判断最后一位的值 ================
+ int TotalmulAiWi = 0;
+ for (int i = 0; i < 17; i++) {
+ TotalmulAiWi = TotalmulAiWi
+ + Integer.parseInt(String.valueOf(Ai.charAt(i)))
+ * Integer.parseInt(Wi[i]);
+ }
+ int modValue = TotalmulAiWi % 11;
+ String strVerifyCode = ValCodeArr[modValue];
+ Ai = Ai + strVerifyCode;
+
+ if (IDStr.length() == 18) {
+ if (!Ai.equals(IDStr)) {
+ errorInfo = "身份证无效,不是合法的身份证号码";
+ return errorInfo;
+ }
+ } else {
+ return "";
+ }
+ // =====================(end)=====================
+ return "";
+ }
+
+ /**
+ * 功能:设置地区编码
+ *
+ * @return Hashtable 对象
+ */
+ @SuppressWarnings("unchecked")
+ private static Hashtable GetAreaCode() {
+ Hashtable hashtable = new Hashtable();
+ hashtable.put("11", "北京");
+ hashtable.put("12", "天津");
+ hashtable.put("13", "河北");
+ hashtable.put("14", "山西");
+ hashtable.put("15", "内蒙古");
+ hashtable.put("21", "辽宁");
+ hashtable.put("22", "吉林");
+ hashtable.put("23", "黑龙江");
+ hashtable.put("31", "上海");
+ hashtable.put("32", "江苏");
+ hashtable.put("33", "浙江");
+ hashtable.put("34", "安徽");
+ hashtable.put("35", "福建");
+ hashtable.put("36", "江西");
+ hashtable.put("37", "山东");
+ hashtable.put("41", "河南");
+ hashtable.put("42", "湖北");
+ hashtable.put("43", "湖南");
+ hashtable.put("44", "广东");
+ hashtable.put("45", "广西");
+ hashtable.put("46", "海南");
+ hashtable.put("50", "重庆");
+ hashtable.put("51", "四川");
+ hashtable.put("52", "贵州");
+ hashtable.put("53", "云南");
+ hashtable.put("54", "西藏");
+ hashtable.put("61", "陕西");
+ hashtable.put("62", "甘肃");
+ hashtable.put("63", "青海");
+ hashtable.put("64", "宁夏");
+ hashtable.put("65", "新疆");
+ hashtable.put("71", "台湾");
+ hashtable.put("81", "香港");
+ hashtable.put("82", "澳门");
+ hashtable.put("91", "国外");
+ return hashtable;
+ }
+
+ /**
+ * 功能:判断字符串是否为数字
+ *
+ * @param str
+ * @return
+ */
+ private static boolean isNumeric(String str) {
+ @SuppressWarnings("AlibabaAvoidPatternCompileInMethod") Pattern pattern = Pattern.compile("[0-9]*");
+ Matcher isNum = pattern.matcher(str);
+ return isNum.matches();
+ }
+
+ /**
+ * 功能:判断字符串是否为日期格式
+ *
+ * @param
+ * @return
+ */
+ public static boolean isDate(String strDate) {
+ @SuppressWarnings("AlibabaAvoidPatternCompileInMethod") Pattern pattern = Pattern
+ .compile("^((\\d{2}(([02468][048])|([13579][26]))[\\-\\/\\s]?((((0?[13578])|(1[02]))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])))))|(\\d{2}(([02468][1235679])|([13579][01345789]))[\\-\\/\\s]?((((0?[13578])|(1[02]))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\\-\\/\\s]?((0?[1-9])|(1[0-9])|(2[0-8]))))))(\\s(((0?[0-9])|([1-2][0-3]))\\:([0-5]?[0-9])((\\s)|(\\:([0-5]?[0-9])))))?$");
+ Matcher m = pattern.matcher(strDate);
+ return m.matches();
+ }
+}
diff --git a/utill/src/main/java/com/lennon/cn/utill/utill/JsonUtils.java b/utill/src/main/java/com/lennon/cn/utill/utill/JsonUtils.java
new file mode 100644
index 0000000..599883e
--- /dev/null
+++ b/utill/src/main/java/com/lennon/cn/utill/utill/JsonUtils.java
@@ -0,0 +1,136 @@
+package com.lennon.cn.utill.utill;
+
+
+import android.text.TextUtils;
+import cn.droidlover.xdroidmvp.log.XLog;
+import com.google.gson.*;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+public class JsonUtils {
+ private static Gson mGson;
+
+ static {
+ if (mGson == null) {
+ mGson = new Gson();
+ }
+ }
+
+ public static String toJson(Object object) {
+ return mGson.toJson(object);
+ }
+
+ @SuppressWarnings("unchecked")
+ public static List