diff --git a/.gitignore b/.gitignore
index 603b140..aa724b7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -12,3 +12,4 @@
/captures
.externalNativeBuild
.cxx
+local.properties
diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..26d3352
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml
index 43fd926..3c7772a 100644
--- a/.idea/codeStyles/Project.xml
+++ b/.idea/codeStyles/Project.xml
@@ -1,12 +1,26 @@
+
+
-
-
-
+
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
new file mode 100644
index 0000000..61a9130
--- /dev/null
+++ b/.idea/compiler.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/dictionaries/Administrator.xml b/.idea/dictionaries/Administrator.xml
new file mode 100644
index 0000000..40ee46b
--- /dev/null
+++ b/.idea/dictionaries/Administrator.xml
@@ -0,0 +1,7 @@
+
+
+
+ umeng
+
+
+
\ No newline at end of file
diff --git a/.idea/encodings.xml b/.idea/encodings.xml
deleted file mode 100644
index 15a15b2..0000000
--- a/.idea/encodings.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
-
-
\ No newline at end of file
diff --git a/.idea/gradle.xml b/.idea/gradle.xml
index b652698..9bba60d 100644
--- a/.idea/gradle.xml
+++ b/.idea/gradle.xml
@@ -4,7 +4,6 @@
+
diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml
index 223c698..cd6b2f1 100644
--- a/.idea/jarRepositories.xml
+++ b/.idea/jarRepositories.xml
@@ -16,20 +16,30 @@
+
+
+
+
+
-
+
-
-
-
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/markdown-navigator.xml b/.idea/markdown-navigator.xml
deleted file mode 100644
index f2aa065..0000000
--- a/.idea/markdown-navigator.xml
+++ /dev/null
@@ -1,86 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/markdown-navigator/profiles_settings.xml b/.idea/markdown-navigator/profiles_settings.xml
deleted file mode 100644
index db06266..0000000
--- a/.idea/markdown-navigator/profiles_settings.xml
+++ /dev/null
@@ -1,3 +0,0 @@
-
-
-
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
index 89482aa..b45762e 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -1,16 +1,11 @@
-
-
-
-
-
-
+
-
+
diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml
deleted file mode 100644
index 7f68460..0000000
--- a/.idea/runConfigurations.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
index fdf1fc8..35eb1dd 100644
--- a/.idea/vcs.xml
+++ b/.idea/vcs.xml
@@ -1,7 +1,6 @@
-
-
+
\ No newline at end of file
diff --git a/README.md b/README.md
index c5a187c..eac3fba 100644
--- a/README.md
+++ b/README.md
@@ -1,25 +1,26 @@
# Reader
-一款在任阅基础上改进的网络小说阅读器📕,采用Kt编写,支持追书、看书。拥有语音朗读,仿真翻页等功能。相比原作者:
+一款网络小说阅读器📕,采用Kt编写,支持追书、看书。支持TTS语音朗读,仿真翻页等功能。相比old分支:
- 重写代码逻辑,优化代码结构,Md设计风格
-
- + 使用郭神的LitePal框架存储
-
+
+ + sql分层处理,MVVM 架构
+
* 语音朗读、插画、国际化、黑夜模式等功能都进行了实现
-
- - 适配了安卓9.0,使用AndroidX控件,对刘海屏等异形屏幕有了很好的支持
-
-注: 之前项目采用Java编写,之后才转的Kotlin代码,可能有些替换不完善。欢迎大家提问题。本人一定尽快修复
-## 使用技术
-Kt、AndroidX、Retrofit、Okhttp3、Glide、LitePal等
+ - 适配了安卓10,使用AndroidX控件,对刘海屏等异形屏幕有了很好的支持
+
+注: old分支之前项目采用Java编写,之后用studio一键转的Kotlin代码,没有kotlin特有的语法糖之类,
+如果有同学想看java代码,old分支应该更容易懂。master分支为全新代码架构,欢迎大家提问题。本人一定尽快修复
+
+## 使用技术
+Kt、AndroidX、Retrofit、Okhttp3、Glide、LitePal、MVVM、协程等
## TIP
-- 目前书源为轻小说书源,书中大多带了插图,因此屏蔽了tts语音朗读功能,之后会切换成正常小说书源并添加语音朗读功能
+- 当前书源为轻小说书源,书中大多带了插图。(不提供正常小说的原因有版权问题,同时防止有人直接用代码改个名字就去上架)
+ 因为书籍为爬取的数据,服务器在美国,所以国内监管比较严的时候可能需要翻墙或切换网络去多尝试几次。
-* 同时请各位大神手下留情不要攻击或者爬取数据,供大家学习使用。之后会切换成网络源。
+* 同时请大家不要攻击或者爬取数据,供大家学习使用。
## 项目截图
@@ -28,9 +29,9 @@ Kt、AndroidX、Retrofit、Okhttp3、Glide、LitePal等
| --- | --- | --- |
| | | |
| | | |
-| | | |
+| | | |
+
-
## LICENSE
@@ -50,3 +51,4 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
```
+
diff --git a/app/.gitignore b/app/.gitignore
index 796b96d..e25efbd 100644
--- a/app/.gitignore
+++ b/app/.gitignore
@@ -1 +1,3 @@
/build
+/release
+/google
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
index 0fccfd2..0d2dad3 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -1,38 +1,162 @@
-apply plugin: 'com.android.application'
-
-apply plugin: 'kotlin-android'
+plugins {
+ id 'com.android.application'
+ id 'kotlin-android'
+ id 'kotlin-android-extensions'
+}
-apply plugin: 'kotlin-android-extensions'
+def name = "reader"
+def code = 1
+def version = "1.0.0"
android {
- compileSdkVersion rootProject.ext.android.compileSdkVersion
+ compileSdkVersion 30
+ buildToolsVersion "29.0.3"
+
defaultConfig {
- applicationId rootProject.ext.android.applicationId
- minSdkVersion rootProject.ext.android.minSdkVersion
- targetSdkVersion rootProject.ext.android.targetSdkVersion
- versionCode rootProject.ext.android.versionCode
- versionName rootProject.ext.android.versionName
+ applicationId "com.novel.read"
+ minSdkVersion 21
+ targetSdkVersion 30
+ versionCode code
+ versionName version
+
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+
+ ndk {
+ abiFilters "armeabi", "arm64-v8a"// "armeabi-v7a",
+ }
+ multiDexEnabled true
+ }
+
+ signingConfigs {
+ release {
+ keyAlias 'key0'
+ keyPassword '1qaz@WSX'
+ storeFile file('reader.jks')
+ storePassword '1qaz@WSX'
+ }
}
+
buildTypes {
+ debug {
+ minifyEnabled true
+ shrinkResources true
+ proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+ signingConfig signingConfigs.release
+ }
release {
- minifyEnabled false
+ buildConfigField "boolean", "LOG_DEBUG", "false" //不显示log
+ minifyEnabled true
+ shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+ signingConfig signingConfigs.release
+ }
+
+ android.applicationVariants.all { variant ->
+ variant.outputs.all {
+ def flavor = variant.productFlavors[0].name
+ outputFileName = "${name}_${flavor}_${defaultConfig.versionName}.apk"
+ }
}
}
+
+ flavorDimensions "mode"
+ productFlavors {
+ app {
+ dimension "mode"
+ manifestPlaceholders = [APP_CHANNEL_VALUE: "app"]
+ }
+ google {
+ dimension "mode"
+ applicationId "com.novel.read"
+ manifestPlaceholders = [APP_CHANNEL_VALUE: "google"]
+ }
+ }
+
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
+ kotlinOptions {
+ jvmTarget = '1.8'
+ }
+
}
dependencies {
- implementation fileTree(dir: 'libs', include: ['*.jar'])
- testImplementation rootProject.ext.dependencies["junit"]
- androidTestImplementation rootProject.ext.dependencies["runner"]
- androidTestImplementation rootProject.ext.dependencies["espresso_core"]
- implementation project(path: ':net_serivce')
- implementation project(path: ':common_lib')
+ implementation fileTree(dir: 'libs', include: ['*.aar'])
+ testImplementation 'junit:junit:4.13.1'
+ androidTestImplementation 'androidx.test:runner:1.3.0'
+ androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
+ implementation "com.android.support:multidex:1.0.3"
+
+ //kotlin
+ implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
+
+ //androidX
+ implementation 'androidx.core:core-ktx:1.3.2'
+ implementation 'androidx.appcompat:appcompat:1.2.0'
+ implementation 'androidx.media:media:1.2.1'
+ implementation 'androidx.preference:preference-ktx:1.1.1'
+ implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
+ implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
+ implementation 'androidx.viewpager2:viewpager2:1.0.0'
+ implementation 'com.google.android.material:material:1.2.1'
+ implementation 'com.google.android:flexbox:1.1.0'
+ implementation 'com.google.code.gson:gson:2.8.6'
+
+ //基本的网络框架
+ implementation 'com.squareup.okhttp3:okhttp:3.14.9'
+ implementation 'com.squareup.retrofit2:retrofit:2.9.0'
+ implementation 'com.squareup.retrofit2:converter-gson:2.7.2'
+ implementation 'com.squareup.retrofit2:converter-scalars:2.9.0'
+
+ //anko
+ def anko_version = '0.10.8'
+ implementation "org.jetbrains.anko:anko-sdk27:$anko_version"
+ implementation "org.jetbrains.anko:anko-sdk27-listeners:$anko_version"
+
+ //sql
+ implementation 'org.litepal.android:kotlin:3.0.0'
+
+ //协程
+ def coroutines_version = '1.3.7'
+ implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version"
+ implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines_version"
+
+ //liveEventBus
+ implementation 'com.jeremyliao:live-event-bus-x:1.7.2'
+
+ //lifecycle
+ def lifecycle_version = '2.2.0'
+ implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version"
+ implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version"
+
+ //Glide
+ implementation 'com.github.bumptech.glide:glide:4.11.0'
+
+ //MarkDown
+ implementation 'io.noties.markwon:core:4.6.0'
+ implementation 'io.noties.markwon:image-glide:4.6.0'
+ //转换繁体
+ implementation 'com.hankcs:hanlp:portable-1.7.8'
+
+ //brvah
+ implementation 'com.github.CymChad:BaseRecyclerViewAdapterHelper:3.0.6'
+
+ //字符串比较
+ implementation 'net.ricecode:string-similarity:1.0.0'
+
+ //epub
+ implementation('com.positiondev.epublib:epublib-core:3.1') {
+ exclude group: 'org.slf4j'
+ exclude group: 'xmlpull'
+ }
+
+ //flex
+ implementation 'com.google.android:flexbox:1.1.0'
implementation 'com.allenliu.versionchecklib:library:2.2.0'
-}
+
+ implementation 'com.permissionx.guolindev:permissionx:1.4.0'
+
+}
\ No newline at end of file
diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro
index f1b4245..bc660d7 100644
--- a/app/proguard-rules.pro
+++ b/app/proguard-rules.pro
@@ -19,3 +19,235 @@
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
+# 混合时不使用大小写混合,混合后的类名为小写
+-dontusemixedcaseclassnames
+
+# 指定不去忽略非公共库的类
+-dontskipnonpubliclibraryclasses
+
+# 这句话能够使我们的项目混淆后产生映射文件
+# 包含有类名->混淆后类名的映射关系
+-verbose
+
+# 指定不去忽略非公共库的类成员
+-dontskipnonpubliclibraryclassmembers
+
+# 不做预校验,preverify是proguard的四个步骤之一,Android不需要preverify,去掉这一步能够加快混淆速度。
+-dontpreverify
+
+# 保留Annotation不混淆
+-keepattributes *Annotation*,InnerClasses
+
+# 避免混淆泛型
+-keepattributes Signature
+
+# 抛出异常时保留代码行号
+-keepattributes SourceFile,LineNumberTable
+
+# 指定混淆是采用的算法,后面的参数是一个过滤器
+# 这个过滤器是谷歌推荐的算法,一般不做更改
+-optimizations !code/simplification/cast,!field/*,!class/merging/*
+
+
+
+#############################################
+#
+# Android开发中一些需要保留的公共部分
+#
+#############################################
+# 屏蔽错误Unresolved class name
+#noinspection ShrinkerUnresolvedReference
+
+# 保留我们使用的四大组件,自定义的Application等等这些类不被混淆
+# 因为这些子类都有可能被外部调用
+# 保留我们使用的四大组件,自定义的Application等等这些类不被混淆
+# 因为这些子类都有可能被外部调用
+-keep public class * extends android.app.Activity
+-keep public class * extends android.app.Application
+-keep public class * extends android.app.Service
+-keep public class * extends android.content.BroadcastReceiver
+-keep public class * extends android.content.ContentProvider
+-keep public class * extends android.app.backup.BackupAgentHelper
+-keep public class * extends android.preference.Preference
+-keep public class * extends android.view.View
+
+# 保留androidx下的所有类及其内部类
+-keep class androidx.** {*;}
+
+# 保留继承的
+-keep public class * extends androidx.**
+
+# 保留R下面的资源
+-keep class **.R$* {*;}
+
+# 保留本地native方法不被混淆
+-keepclasseswithmembernames class * {
+ native ;
+}
+
+# 保留在Activity中的方法参数是view的方法,
+# 这样以来我们在layout中写的onClick就不会被影响
+-keepclassmembers class * extends android.app.Activity{
+ public void *(android.view.View);
+}
+
+# 保留枚举类不被混淆
+-keepclassmembers enum * {
+ public static **[] values();
+ public static ** valueOf(java.lang.String);
+}
+
+# 保留我们自定义控件(继承自View)不被混淆
+-keep public class * extends android.view.View{
+ *** get*();
+ void set*(***);
+ public (android.content.Context);
+ public (android.content.Context, android.util.AttributeSet);
+ public (android.content.Context, android.util.AttributeSet, int);
+}
+
+# 保留Parcelable序列化类不被混淆
+-keep class * implements android.os.Parcelable {
+ public static final android.os.Parcelable$Creator *;
+}
+
+# 保留Serializable序列化的类不被混淆
+-keepclassmembers class * implements java.io.Serializable {
+ static final long serialVersionUID;
+ private static final java.io.ObjectStreamField[] serialPersistentFields;
+ !static !transient ;
+ !private ;
+ !private ;
+ private void writeObject(java.io.ObjectOutputStream);
+ private void readObject(java.io.ObjectInputStream);
+ java.lang.Object writeReplace();
+ java.lang.Object readResolve();
+}
+
+# 对于带有回调函数的onXXEvent、**On*Listener的,不能被混淆
+-keepclassmembers class * {
+ void *(**On*Event);
+ void *(**On*Listener);
+}
+# 移除Log类打印各个等级日志的代码,打正式包的时候可以做为禁log使用,这里可以作为禁止log打印的功能使用
+# 记得proguard-android.txt中一定不要加-dontoptimize才起作用
+# 另外的一种实现方案是通过BuildConfig.DEBUG的变量来控制
+-assumenosideeffects class android.util.Log {
+ public static int v(...);
+ public static int i(...);
+ public static int w(...);
+ public static int d(...);
+ public static int e(...);
+}
+
+# 保持js引擎调用的java类
+-keep class **.analyzeRule.**{*;}
+# 保持web类
+-keep class **.web.**{*;}
+#数据类
+-keep class **.data.**{*;}
+
+-dontwarn rx.**
+-dontwarn okio.**
+-dontwarn javax.annotation.**
+-dontwarn org.apache.log4j.lf5.viewer.**
+-dontnote org.apache.log4j.lf5.viewer.**
+-dontwarn freemarker.**
+-dontnote org.python.core.**
+-dontwarn com.hwangjr.rxbus.**
+-dontwarn okhttp3.**
+-dontwarn org.conscrypt.**
+-dontwarn com.jeremyliao.liveeventbus.**
+
+-keep class com.google.gson.** { *; }
+-keep class com.ke.gson.** { *; }
+-keep class com.jeremyliao.liveeventbus.** { *; }
+-keep class okhttp3.**{*;}
+-keep class okio.**{*;}
+-keep class com.hwangjr.rxbus.**{*;}
+-keep class org.conscrypt.**{*;}
+-keep class android.support.**{*;}
+-keep class me.grantland.widget.**{*;}
+-keep class de.hdodenhof.circleimageview.**{*;}
+-keep class tyrant.explosionfield.**{*;}
+-keep class tyrantgit.explosionfield.**{*;}
+-keep class freemarker.**{*;}
+-keep class com.gyf.barlibrary.** {*;}
+
+-keep class org.slf4j.**{*;}
+-dontwarn org.slf4j.**
+
+-keep class org.codehaus.**{*;}
+-dontwarn org.codehaus.**
+-keep class com.jayway.**{*;}
+-dontwarn com.jayway.**
+-keep class com.fasterxml.**{*;}
+
+-keep class javax.swing.**{*;}
+-dontwarn javax.swing.**
+-keep class java.awt.**{*;}
+-dontwarn java.awt.**
+-keep class sun.misc.**{*;}
+-dontwarn sun.misc.**
+-keep class sun.reflect.**{*;}
+-dontwarn sun.reflect.**
+
+## Rhino
+-keep class javax.script.** { *; }
+-keep class com.sun.script.javascript.** { *; }
+-keep class org.mozilla.javascript.** { *; }
+
+###EPUB
+-dontwarn nl.siegmann.epublib.**
+-dontwarn org.xmlpull.**
+-keep class nl.siegmann.epublib.**{*;}
+-keep class javax.xml.**{*;}
+-keep class org.xmlpull.**{*;}
+
+-keep class org.simpleframework.**{*;}
+-dontwarn org.simpleframework.xml.**
+
+-keepclassmembers class * {
+ public (org.json.JSONObject);
+}
+-keepclassmembers enum * {
+ public static **[] values();
+ public static ** valueOf(java.lang.String);
+}
+
+
+-keep class com.burst.k17reader_sdk.** { *; }
+-keep class com.chineseall.reader.utils.** { *; }
+
+-keep class org.litepal.** { *;}
+-keep class * extends org.litepal.crud.DataSupport { *;}
+-keep class * extends org.litepal.crud.LitePalSupport { *;}
+
+-keep class com.allenliu.versionchecklib.**{*;}
+
+-dontwarn com.tencent.bugly.**
+-keep public class com.tencent.bugly.**{*;}
+
+
+-keep class com.uc.** {*;}
+-keep class com.zui.** {*;}
+-keep class com.miui.** {*;}
+-keep class com.heytap.** {*;}
+-keep class a.** {*;}
+-keep class com.vivo.** {*;}
+-keep class com.umeng.** {*;}
+
+-keepclassmembers enum * {
+ public static **[] values();
+ public static ** valueOf(java.lang.String);
+}
+
+-dontwarn com.google.ads.**
+-keep public class com.google.ads.**{
+ public protected *;
+}
+
+-dontwarn com.youth.banner.**
+-keep class com.youth.banner.**{*;}
+
+-keep class com.android.vending.billing.**
diff --git a/app/reader.jks b/app/reader.jks
new file mode 100644
index 0000000..9401a7f
Binary files /dev/null and b/app/reader.jks differ
diff --git a/app/src/androidTest/java/com/novel/read/ExampleInstrumentedTest.kt b/app/src/androidTest/java/com/novel/read/ExampleInstrumentedTest.kt
index a2dbbae..a15eac6 100644
--- a/app/src/androidTest/java/com/novel/read/ExampleInstrumentedTest.kt
+++ b/app/src/androidTest/java/com/novel/read/ExampleInstrumentedTest.kt
@@ -19,6 +19,6 @@ class ExampleInstrumentedTest {
fun useAppContext() {
// Context of the app under test.
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
- assertEquals("com.zlj.base_libaray", appContext.packageName)
+ assertEquals("com.yjd.tuzibook", appContext.packageName)
}
-}
+}
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index d784d9c..09b0643 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -3,71 +3,96 @@
xmlns:tools="http://schemas.android.com/tools"
package="com.novel.read">
+
+
+
-
-
-
-
+
+
+
+
+
+
+
-
-
-
-
+ android:requestLegacyExternalStorage="true"
+ android:supportsRtl="true"
+ android:theme="@style/AppTheme.Light"
+ tools:ignore="AllowBackup,GoogleAppIndexingWarning,UnusedAttribute">
+
+
+
+
+
+
+
+
+
+
+ android:name="com.novel.read.ui.daily.DailyActivity"
+ android:launchMode="singleTask" />
+ android:name="com.novel.read.ui.channel.ChannelInfoActivity"
+ android:launchMode="singleTask" />
+ android:name="com.novel.read.ui.channel.ChannelActivity"
+ android:launchMode="singleTask"
+ android:screenOrientation="behind" />
+
+ android:name="com.novel.read.ui.search.SearchActivity"
+ android:launchMode="singleTask" />
+ android:name="com.novel.read.ui.read.ReadBookActivity"
+ android:configChanges="locale|keyboardHidden|orientation|screenSize|smallestScreenSize|screenLayout"
+ android:launchMode="singleTask" />
+
+
+
-
-
-
+
+
+
-
+
\ No newline at end of file
diff --git a/app/src/main/assets/bg/羊皮纸1.jpg b/app/src/main/assets/bg/羊皮纸1.jpg
new file mode 100644
index 0000000..40f3977
Binary files /dev/null and b/app/src/main/assets/bg/羊皮纸1.jpg differ
diff --git a/app/src/main/assets/defaultData/httpTTS.json b/app/src/main/assets/defaultData/httpTTS.json
new file mode 100644
index 0000000..a249a3b
--- /dev/null
+++ b/app/src/main/assets/defaultData/httpTTS.json
@@ -0,0 +1,62 @@
+[
+ {
+ "id": 1598233029304,
+ "name": "度小美",
+ "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=0&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}"
+ },
+ {
+ "id": 1598233029305,
+ "name": "度小宇",
+ "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=1&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}"
+ },
+ {
+ "id": 1598233029306,
+ "name": "度逍遥",
+ "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=5003&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}"
+ },
+ {
+ "id": 1598233029307,
+ "name": "度丫丫",
+ "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=4&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}"
+ },
+ {
+ "id": 1598233029308,
+ "name": "度小娇",
+ "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=5&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}"
+ },
+ {
+ "id": 1598233029309,
+ "name": "度米朵",
+ "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=103&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}"
+ },
+ {
+ "id": 1598233029310,
+ "name": "度博文",
+ "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=106&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}"
+ },
+ {
+ "id": 1598233029311,
+ "name": "度小童",
+ "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=110&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}"
+ },
+ {
+ "id": 1598233029312,
+ "name": "度小萌",
+ "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=111&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}"
+ },
+ {
+ "id": 1598233029313,
+ "name": "百度骚男",
+ "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=11&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}"
+ },
+ {
+ "id": 1598233029314,
+ "name": "百度评书",
+ "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=6&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}"
+ },
+ {
+ "id": 1598233029315,
+ "name": "百度主持",
+ "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=9&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}"
+ }
+]
\ No newline at end of file
diff --git a/app/src/main/assets/defaultData/readConfig.json b/app/src/main/assets/defaultData/readConfig.json
new file mode 100644
index 0000000..32c8ea4
--- /dev/null
+++ b/app/src/main/assets/defaultData/readConfig.json
@@ -0,0 +1,52 @@
+[
+ {
+ "bgStr": "#EFEFF7",
+ "bgStrNight": "#212021",
+ "textColor": "#383429",
+ "textColorNight": "#94969C",
+ "bgType": 0,
+ "bgTypeNight": 0,
+ "darkStatusIcon": true,
+ "darkStatusIconNight": false
+ },
+ {
+ "bgStr": "#DDC090",
+ "bgStrNight": "#3C3F43",
+ "textColor": "#3E3422",
+ "textColorNight": "#DCDFE1",
+ "bgType": 0,
+ "bgTypeNight": 0,
+ "darkStatusIcon": true,
+ "darkStatusIconNight": false
+ },
+ {
+ "bgStr": "#C2D8AA",
+ "bgStrNight": "#3C3F43",
+ "textColor": "#596C44",
+ "textColorNight": "#88C16F",
+ "bgType": 0,
+ "bgTypeNight": 0,
+ "darkStatusIcon": false,
+ "darkStatusIconNight": false
+ },
+ {
+ "bgStr": "#DBB8E2",
+ "bgStrNight": "#3C3F43",
+ "textColor": "#68516C",
+ "textColorNight": "#F6AEAE",
+ "bgType": 0,
+ "bgTypeNight": 0,
+ "darkStatusIcon": false,
+ "darkStatusIconNight": false
+ },
+ {
+ "bgStr": "#ABCEE0",
+ "bgStrNight": "#3C3F43",
+ "textColor": "#3D4C54",
+ "textColorNight": "#90BFF5",
+ "bgType": 0,
+ "bgTypeNight": 0,
+ "darkStatusIcon": false,
+ "darkStatusIconNight": false
+ }
+]
\ No newline at end of file
diff --git a/app/src/main/assets/defaultData/themeConfig.json b/app/src/main/assets/defaultData/themeConfig.json
new file mode 100644
index 0000000..a8826cf
--- /dev/null
+++ b/app/src/main/assets/defaultData/themeConfig.json
@@ -0,0 +1,26 @@
+[
+ {
+ "themeName": "典雅蓝",
+ "isNightTheme": false,
+ "primaryColor": "#03A9F4",
+ "accentColor": "#AD1457",
+ "backgroundColor": "#F5F5F5",
+ "bottomBackground": "#EEEEEE"
+ },
+ {
+ "themeName": "黑白",
+ "isNightTheme": true,
+ "primaryColor": "#303030",
+ "accentColor": "#E0E0E0",
+ "backgroundColor": "#424242",
+ "bottomBackground": "#424242"
+ },
+ {
+ "themeName": "A屏黑",
+ "isNightTheme": true,
+ "primaryColor": "#000000",
+ "accentColor": "#FFFFFF",
+ "backgroundColor": "#000000",
+ "bottomBackground": "#000000"
+ }
+]
\ No newline at end of file
diff --git a/app/src/main/assets/defaultData/txtTocRule.json b/app/src/main/assets/defaultData/txtTocRule.json
new file mode 100644
index 0000000..57cb4bf
--- /dev/null
+++ b/app/src/main/assets/defaultData/txtTocRule.json
@@ -0,0 +1,128 @@
+[
+ {
+ "id": -1,
+ "enable": true,
+ "name": "目录(去空白)",
+ "rule": "(?<=[ \\s])(?:序章|楔子|正文(?!完|结)|终章|后记|尾声|番外|第?\\s{0,4}[\\d零一二两三四五六七八九十百千万壹贰叁肆伍陆柒捌玖拾佰仟]+?\\s{0,4}(?:章|节(?!课)|卷|集(?![合和])|部(?![分赛游])|篇(?!张))).{0,30}$",
+ "serialNumber": 0
+ },
+ {
+ "id": -2,
+ "enable": true,
+ "name": "目录",
+ "rule": "^[ \\t]{0,4}(?:序章|楔子|正文(?!完|结)|终章|后记|尾声|番外|第?\\s{0,4}[\\d零一二两三四五六七八九十百千万壹贰叁肆伍陆柒捌玖拾佰仟]+?\\s{0,4}(?:章|节(?!课)|卷|集(?![合和])|部(?![分赛游])|篇(?!张))).{0,30}$",
+ "serialNumber": 1
+ },
+ {
+ "id": -3,
+ "enable": false,
+ "name": "目录(匹配简介)",
+ "rule": "(?<=[ \\s])(?:(?:内容|文章)?简介|文案|前言|序章|楔子|正文(?!完|结)|终章|后记|尾声|番外|第?\\s{0,4}[\\d零一二两三四五六七八九十百千万壹贰叁肆伍陆柒捌玖拾佰仟]+?\\s{0,4}(?:章|节(?!课)|卷|集(?![合和])|部(?![分赛游])|回(?![合来事去])|场(?![和合比电是])|篇(?!张))).{0,30}$",
+ "serialNumber": 2
+ },
+ {
+ "id": -4,
+ "enable": false,
+ "name": "目录(古典、轻小说备用)",
+ "rule": "^[ \\t]{0,4}(?:序章|楔子|正文(?!完|结)|终章|后记|尾声|番外|第?\\s{0,4}[\\d零一二两三四五六七八九十百千万壹贰叁肆伍陆柒捌玖拾佰仟]+?\\s{0,4}(?:章|节(?!课)|卷|集(?![合和])|部(?![分赛游])|回(?![合来事去])|场(?![和合比电是])|话|篇(?!张))).{0,30}$",
+ "serialNumber": 3
+ },
+ {
+ "id": -5,
+ "enable": false,
+ "name": "数字(纯数字标题)",
+ "rule": "(?<=[ \\s])\\d+\\.?[ \\t]{0,4}$",
+ "serialNumber": 4
+ },
+ {
+ "id": -6,
+ "enable": true,
+ "name": "数字 分隔符 标题名称",
+ "rule": "^[ \\t]{0,4}\\d{1,5}[::,., 、_—\\-].{1,30}$",
+ "serialNumber": 5
+ },
+ {
+ "id": -7,
+ "enable": true,
+ "name": "大写数字 分隔符 标题名称",
+ "rule": "^[ \\t]{0,4}(?:序章|楔子|正文(?!完|结)|终章|后记|尾声|番外|[零一二两三四五六七八九十百千万壹贰叁肆伍陆柒捌玖拾佰仟]{1,8})[ 、_—\\-].{1,30}$",
+ "serialNumber": 6
+ },
+ {
+ "id": -8,
+ "enable": true,
+ "name": "正文 标题/序号",
+ "rule": "^[ \\t]{0,4}正文[ ]{1,4}.{0,20}$",
+ "serialNumber": 7
+ },
+ {
+ "id": -9,
+ "enable": true,
+ "name": "Chapter/Section/Part/Episode 序号 标题",
+ "rule": "^[ \\t]{0,4}(?:[Cc]hapter|[Ss]ection|[Pp]art|PART|[Nn][oO]\\.|[Ee]pisode|(?:内容|文章)?简介|文案|前言|序章|楔子|正文(?!完|结)|终章|后记|尾声|番外)\\s{0,4}\\d{1,4}.{0,30}$",
+ "serialNumber": 8
+ },
+ {
+ "id": -10,
+ "enable": false,
+ "name": "Chapter(去简介)",
+ "rule": "^[ \\t]{0,4}(?:[Cc]hapter|[Ss]ection|[Pp]art|PART|[Nn][Oo]\\.|[Ee]pisode)\\s{0,4}\\d{1,4}.{0,30}$",
+ "serialNumber": 9
+ },
+ {
+ "id": -11,
+ "enable": true,
+ "name": "特殊符号 序号 标题",
+ "rule": "(?<=[\\s ])[【〔〖「『〈[\\[](?:第|[Cc]hapter)[\\d零一二两三四五六七八九十百千万壹贰叁肆伍陆柒捌玖拾佰仟]{1,10}[章节].{0,20}$",
+ "serialNumber": 10
+ },
+ {
+ "id": -12,
+ "enable": false,
+ "name": "特殊符号 标题(成对)",
+ "rule": "(?<=[\\s ]{0,4})(?:[\\[〈「『〖〔《(【\\(].{1,30}[\\)】)》〕〗』」〉\\]]?|(?:内容|文章)?简介|文案|前言|序章|楔子|正文(?!完|结)|终章|后记|尾声|番外)[ ]{0,4}$",
+ "serialNumber": 11
+ },
+ {
+ "id": -13,
+ "enable":true,
+ "name": "特殊符号 标题(单个)",
+ "rule": "(?<=[\\s ]{0,4})(?:[☆★✦✧].{1,30}|(?:内容|文章)?简介|文案|前言|序章|楔子|正文(?!完|结)|终章|后记|尾声|番外)[ ]{0,4}$",
+ "serialNumber": 12
+ },
+ {
+ "id": -14,
+ "enable": true,
+ "name": "章/卷 序号 标题",
+ "rule": "^[ \\t ]{0,4}(?:(?:内容|文章)?简介|文案|前言|序章|楔子|正文(?!完|结)|终章|后记|尾声|番外|[卷章][\\d零一二两三四五六七八九十百千万壹贰叁肆伍陆柒捌玖拾佰仟]{1,8})[ ]{0,4}.{0,30}$",
+ "serialNumber": 13
+ },
+ {
+ "id": -15,
+ "enable":false,
+ "name": "顶格标题",
+ "rule": "^\\S.{1,20}$",
+ "serialNumber": 14
+ },
+ {
+ "id": -16,
+ "enable":false,
+ "name": "双标题(前向)",
+ "rule": "(?m)(?<=[ \\t ]{0,4})第[\\d零一二两三四五六七八九十百千万壹贰叁肆伍陆柒捌玖拾佰仟]{1,8}章.{0,30}$(?=[\\s ]{0,8}第[\\d零一二两三四五六七八九十百千万壹贰叁肆伍陆柒捌玖拾佰仟]{1,8}章)",
+ "serialNumber": 15
+ },
+ {
+ "id": -17,
+ "enable":false,
+ "name": "双标题(后向)",
+ "rule": "(?m)(?<=[ \\t ]{0,4}第[\\d零一二两三四五六七八九十百千万壹贰叁肆伍陆柒捌玖拾佰仟]{1,8}章.{0,30}$[\\s ]{0,8})第[\\d零一二两三四五六七八九十百千万壹贰叁肆伍陆柒捌玖拾佰仟]{1,8}章.{0,30}$",
+ "serialNumber": 16
+ },
+ {
+ "id":-18,
+ "enable": true,
+ "name": "标题 特殊符号 序号",
+ "rule": "^.{1,20}[((][\\d零一二两三四五六七八九十百千万壹贰叁肆伍陆柒捌玖拾佰仟]{1,8}[))][ \t]{0,4}$",
+ "serialNumber": 17
+ }
+]
\ No newline at end of file
diff --git a/app/src/main/assets/font/number.ttf b/app/src/main/assets/font/number.ttf
new file mode 100644
index 0000000..f2804db
Binary files /dev/null and b/app/src/main/assets/font/number.ttf differ
diff --git a/app/src/main/assets/litepal.xml b/app/src/main/assets/litepal.xml
index 486ab39..6c0b221 100644
--- a/app/src/main/assets/litepal.xml
+++ b/app/src/main/assets/litepal.xml
@@ -1,23 +1,13 @@
-
-
-
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/java/com/novel/read/App.kt b/app/src/main/java/com/novel/read/App.kt
new file mode 100644
index 0000000..4a8262a
--- /dev/null
+++ b/app/src/main/java/com/novel/read/App.kt
@@ -0,0 +1,123 @@
+package com.novel.read
+
+import android.app.NotificationChannel
+import android.app.NotificationManager
+import android.content.Context
+import android.content.res.Configuration
+import android.os.Build
+import android.provider.Settings
+import androidx.annotation.RequiresApi
+import androidx.appcompat.app.AppCompatDelegate
+import androidx.multidex.MultiDexApplication
+import com.jeremyliao.liveeventbus.LiveEventBus
+import com.novel.read.constant.AppConst.channelIdDownload
+import com.novel.read.constant.AppConst.channelIdReadAloud
+import com.novel.read.constant.EventBus
+import com.novel.read.data.db.BookDatabase
+import com.novel.read.help.ActivityHelp
+import com.novel.read.help.AppConfig
+import com.novel.read.help.ReadBookConfig
+import com.novel.read.help.ThemeConfig
+import com.novel.read.utils.LanguageUtils
+import com.novel.read.utils.ext.postEvent
+import org.litepal.LitePal
+
+@Suppress("DEPRECATION")
+class App : MultiDexApplication() {
+
+ companion object {
+ @JvmStatic
+ lateinit var INSTANCE: App
+ private set
+
+ @JvmStatic
+ lateinit var db: BookDatabase
+ private set
+
+ lateinit var androidId: String
+ var versionCode = 0
+ var versionName = ""
+ }
+
+ override fun onCreate() {
+ super.onCreate()
+ INSTANCE = this
+ androidId = Settings.System.getString(contentResolver, Settings.Secure.ANDROID_ID)
+ LanguageUtils.setConfiguration(this)
+ LitePal.initialize(this)
+ db = BookDatabase.get()
+ packageManager.getPackageInfo(packageName, 0)?.let {
+ versionCode = it.versionCode
+ versionName = it.versionName
+ }
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) createChannelId()
+ applyDayNight()
+ LiveEventBus
+ .config()
+ .lifecycleObserverAlwaysActive(true)
+ .autoClear(false)
+ registerActivityLifecycleCallbacks(ActivityHelp)
+ }
+
+ override fun onConfigurationChanged(newConfig: Configuration) {
+ super.onConfigurationChanged(newConfig)
+ when (newConfig.uiMode and Configuration.UI_MODE_NIGHT_MASK) {
+ Configuration.UI_MODE_NIGHT_YES,
+ Configuration.UI_MODE_NIGHT_NO -> applyDayNight()
+ }
+ }
+
+
+ fun applyDayNight() {
+ AppConfig.upEInkMode()
+ ReadBookConfig.upBg()
+ ThemeConfig.applyTheme(this)
+ initNightMode()
+ postEvent(EventBus.RECREATE, "")
+ }
+
+
+ private fun initNightMode() {
+ val targetMode =
+ if (AppConfig.isNightTheme) {
+ AppCompatDelegate.MODE_NIGHT_YES
+ } else {
+ AppCompatDelegate.MODE_NIGHT_NO
+ }
+ AppCompatDelegate.setDefaultNightMode(targetMode)
+ }
+
+ /**
+ * 创建通知ID
+ */
+ @RequiresApi(Build.VERSION_CODES.O)
+ private fun createChannelId() {
+ (getSystemService(Context.NOTIFICATION_SERVICE) as? NotificationManager)?.let {
+ //用唯一的ID创建渠道对象
+ val downloadChannel = NotificationChannel(
+ channelIdDownload,
+ getString(R.string.action_download),
+ NotificationManager.IMPORTANCE_LOW
+ )
+ //初始化channel
+ downloadChannel.enableLights(false)
+ downloadChannel.enableVibration(false)
+ downloadChannel.setSound(null, null)
+
+ //用唯一的ID创建渠道对象
+ val readAloudChannel = NotificationChannel(
+ channelIdReadAloud,
+ getString(R.string.read_aloud),
+ NotificationManager.IMPORTANCE_LOW
+ )
+ //初始化channel
+ readAloudChannel.enableLights(false)
+ readAloudChannel.enableVibration(false)
+ readAloudChannel.setSound(null, null)
+
+ //向notification manager 提交channel
+ it.createNotificationChannels(listOf(downloadChannel, readAloudChannel))
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/novel/read/Ext.kt b/app/src/main/java/com/novel/read/Ext.kt
deleted file mode 100644
index 72e8070..0000000
--- a/app/src/main/java/com/novel/read/Ext.kt
+++ /dev/null
@@ -1,22 +0,0 @@
-package com.novel.read
-
-import android.content.Context
-import android.widget.ImageView
-import android.widget.Toast
-
-fun Context.showToast(msg:String){
- Toast.makeText(this,msg,Toast.LENGTH_SHORT).show()
-}
-
-fun Context.getScreenContentWidth(): Int {
- val displayMetrics = this.resources.displayMetrics
- return displayMetrics.widthPixels
-}
-
-fun Context.dp2px(dps: Int): Int {
- return Math.round(dps.toFloat() * getDensityDpiScale(this))
-}
-
-fun getDensityDpiScale(context: Context): Float {
- return context.resources.displayMetrics.xdpi / 160.0f
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/novel/read/activity/NovelBookDetailActivity.kt b/app/src/main/java/com/novel/read/activity/NovelBookDetailActivity.kt
deleted file mode 100644
index 86f1945..0000000
--- a/app/src/main/java/com/novel/read/activity/NovelBookDetailActivity.kt
+++ /dev/null
@@ -1,205 +0,0 @@
-package com.novel.read.activity
-
-import android.annotation.SuppressLint
-import android.app.ProgressDialog
-import android.content.Intent
-import android.util.Log
-import android.view.View
-import androidx.recyclerview.widget.LinearLayoutManager
-import com.mango.mangolib.event.EventManager
-import com.novel.read.R
-import com.novel.read.adapter.LoveLyAdapter
-import com.novel.read.base.NovelBaseActivity
-import com.novel.read.constants.Constant
-import com.novel.read.constants.Constant.RequestCode.Companion.REQUEST_READ
-import com.novel.read.constants.Constant.ResultCode.Companion.RESULT_IS_COLLECTED
-import com.novel.read.event.BookArticleEvent
-import com.novel.read.event.GetBookDetailEvent
-import com.novel.read.event.GetRecommendBookEvent
-import com.novel.read.event.UpdateBookEvent
-import com.novel.read.http.AccountManager
-import com.novel.read.model.db.CollBookBean
-import com.novel.read.model.db.dbManage.BookRepository
-import com.novel.read.model.protocol.RecommendBookResp
-import com.novel.read.showToast
-import com.novel.read.utlis.DateUtli
-import com.novel.read.utlis.GlideImageLoader
-import com.squareup.otto.Subscribe
-import kotlinx.android.synthetic.main.activity_book_detail.*
-import org.litepal.LitePal
-import java.util.*
-
-class NovelBookDetailActivity(override val layoutId: Int = R.layout.activity_book_detail) : NovelBaseActivity(), View.OnClickListener {
-
- private lateinit var mAdapter: LoveLyAdapter
- private val mList = ArrayList()
- private var mBookId: Int = 0
- private var isCollected = false
- private var mCollBookBean: CollBookBean? = null
- private lateinit var mProgressDialog: ProgressDialog
-
- override fun initView() {
- mBookId = intent.getIntExtra(Constant.Bundle.BookId, 0)
- rlv_lovely.layoutManager = LinearLayoutManager(this)
- mAdapter = LoveLyAdapter(mList)
- rlv_lovely.adapter = mAdapter
- mProgressDialog = ProgressDialog(this)
- }
-
- override fun initData() {
- refresh.showLoading()
- refresh.setOnReloadingListener { getData() }
- getData()
- toolbar.setNavigationOnClickListener { finish() }
- tv_add_book.setOnClickListener(this)
- tv_start_read.setOnClickListener(this)
- }
-
- private fun getData() {
- AccountManager.getInstance().getRecommendBook(mBookId.toString(), "10")
- AccountManager.getInstance().getBookDetail(mBookId.toString())
- }
-
- override fun onClick(v: View?) {
- when (v?.id) {
- R.id.tv_add_book ->
- //点击存储
- if (isCollected) {
- //放弃点击
- BookRepository.getInstance().deleteCollBookInRx(mCollBookBean)
- tv_add_book.text = resources.getString(R.string.add_book)
- isCollected = false
- } else {
- mProgressDialog.setTitle("正在添加到书架中")
- mProgressDialog.show()
- AccountManager.getInstance().getBookArticle(mBookId.toString())
-
- }
- R.id.tv_start_read ->
- startActivityForResult(
- Intent(this, NovelReadActivity::class.java)
- .putExtra(NovelReadActivity.EXTRA_IS_COLLECTED, isCollected)
- .putExtra(NovelReadActivity.EXTRA_COLL_BOOK, mCollBookBean), REQUEST_READ
- )
- }
- }
-
- @SuppressLint("SetTextI18n")
- @Subscribe
- fun getBookDetail(event: GetBookDetailEvent) {
- refresh.showFinish()
- if (event.isFail) {
- refresh.showError()
- } else {
- val bookBean = event.result!!.book
- GlideImageLoader.displayCornerImage(this, bookBean.cover, iv_book)
- tv_book_name.text = bookBean.title
-
- tv_book_author.text = bookBean.author + " | "
- tv_book_length.text = getString(R.string.book_word, bookBean.words / 10000)
-
- if (event.result!!.last_article != null) {
- tv_new_title.text =
- getString(R.string.new_chapter, event.result!!.last_article.title)
- tv_update_time.text =
- DateUtli.dateConvert(event.result!!.last_article.create_time, 0)
- }
-
- tv_human_num.text = bookBean.hot.toString() + ""
- tv_love_look_num.text = bookBean.like
- tv_Intro.text = bookBean.description
- mCollBookBean = BookRepository.getInstance().getCollBook(bookBean.id.toString())
- //判断是否收藏
- if (mCollBookBean != null) {
- isCollected = true
- tv_add_book.text = resources.getString(R.string.already_add)
- tv_start_read.text = resources.getString(R.string.go_read)
- } else {
- mCollBookBean = event.result!!.collBookBean
- }
- }
- }
-
- @Subscribe
- fun getRecommendBook(event: GetRecommendBookEvent) {
- if (event.isFail) {
- Log.e("getRecommendBook", event.er?.msg)
- } else {
- mList.clear()
- mList.addAll(event.result!!.book)
- mAdapter.notifyDataSetChanged()
- }
- }
-
- override fun onResume() {
- super.onResume()
- EventManager.instance.registerSubscriber(this)
- }
-
- override fun onPause() {
- super.onPause()
- EventManager.instance.unregisterSubscriber(this)
- }
-
- @Subscribe
- fun getArticle(event: BookArticleEvent) {
- if (event.isFail) {
- dismiss()
- showToast(getString(R.string.net_error))
- } else {
- //存储收藏
- var success = false
- if (mCollBookBean != null) {
- success = mCollBookBean!!.saveOrUpdate("bookId=?", mCollBookBean!!.id)
- }
- if (success) {
- val bookChapterBean = event.result!!.chapterBean
- for (i in bookChapterBean.indices) {
- bookChapterBean[i].collBookBean = mCollBookBean
- }
- LitePal.saveAllAsync(bookChapterBean).listen { success1 ->
- if (success1) {
- if (tv_add_book != null) {
- tv_add_book.text = resources.getString(R.string.already_add)
- }
- isCollected = true
- } else {
- LitePal.deleteAll(CollBookBean::class.java, "bookId =?", mCollBookBean!!.id)
- showToast(getString(R.string.net_error))
- }
- dismiss()
- }
- } else {
- showToast(getString(R.string.net_error))
- dismiss()
- }
- }
-
- }
-
- private fun dismiss() {
- mProgressDialog.dismiss()
- }
-
- override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
- super.onActivityResult(requestCode, resultCode, data)
- //如果进入阅读页面收藏了,页面结束的时候,就需要返回改变收藏按钮
- if (requestCode == REQUEST_READ) {
- if (data == null) {
- return
- }
-
- isCollected = data.getBooleanExtra(RESULT_IS_COLLECTED, false)
-
- if (isCollected) {
- tv_add_book.text = resources.getString(R.string.already_add)
- tv_start_read.text = resources.getString(R.string.go_read)
- }
- }
- }
-
- override fun onDestroy() {
- super.onDestroy()
- EventManager.instance.postEvent(UpdateBookEvent())
- }
-}
diff --git a/app/src/main/java/com/novel/read/activity/NovelBookTypeListActivity.kt b/app/src/main/java/com/novel/read/activity/NovelBookTypeListActivity.kt
deleted file mode 100644
index 4c755d6..0000000
--- a/app/src/main/java/com/novel/read/activity/NovelBookTypeListActivity.kt
+++ /dev/null
@@ -1,89 +0,0 @@
-package com.novel.read.activity
-
-import androidx.recyclerview.widget.LinearLayoutManager
-import com.mango.mangolib.event.EventManager
-import com.novel.read.R
-import com.novel.read.adapter.BookListAdapter
-import com.novel.read.base.NovelBaseActivity
-import com.novel.read.constants.Constant
-import com.novel.read.constants.Constant.COMMENT_SIZE
-import com.novel.read.event.SearchListEvent
-import com.novel.read.http.AccountManager
-import com.novel.read.inter.OnLoadMoreListener
-import com.novel.read.model.protocol.SearchResp
-import com.squareup.otto.Subscribe
-import kotlinx.android.synthetic.main.activity_book_type_list.*
-import java.util.*
-
-class NovelBookTypeListActivity(override val layoutId: Int = R.layout.activity_book_type_list) : NovelBaseActivity() {
-
- private var mList: MutableList = ArrayList()
- private lateinit var mAdapter: BookListAdapter
- private var mCategoryId: String? = null
- private var mTitle: String? = null
- private var page: Int = 1
- private var loadSize: Int = 0
-
- override fun initView() {
- EventManager.instance.registerSubscriber(this)
-
- mCategoryId = intent.getStringExtra(Constant.Bundle.CategoryId)
- mTitle = intent.getStringExtra(Constant.Bundle.mTitle)
-
- rlv_type_list.layoutManager = LinearLayoutManager(this)
- mAdapter = BookListAdapter(mList, rlv_type_list)
- rlv_type_list.adapter = mAdapter
-
- mAdapter.setOnLoadMoreListener(object : OnLoadMoreListener {
- override fun onLoadMore() {
- if (mAdapter.isLoadingMore) {
- rlv_type_list.stopScroll()
- } else {
- if (loadSize >= COMMENT_SIZE) {
- mAdapter.isLoadingMore = true
- mAdapter.notifyDataSetChanged()
- page++
- getData()
- }
- }
- }
- })
- }
-
- override fun initData() {
- refresh.showLoading()
- refresh.setOnReloadingListener { this.getData() }
- getData()
- toolbar.title = mTitle
- toolbar.setNavigationOnClickListener { finish() }
-
- }
-
- private fun getData() {
- mCategoryId?.let { AccountManager.getInstance().getSearchBookList(it, "", page) }
- }
-
- @Subscribe
- fun getSearchList(event: SearchListEvent) {
- refresh.showFinish()
- if (event.isFail) {
- refresh.showError()
- } else {
- loadSize = event.result!!.book.size
- if (mAdapter.isLoadingMore) {
- mAdapter.isLoadingMore = false
- mList.addAll(event.result!!.book)
- mAdapter.notifyDataSetChanged()
- } else {
- mList.clear()
- mList.addAll(event.result!!.book)
- mAdapter.notifyDataSetChanged()
- }
- }
- }
-
- override fun onDestroy() {
- super.onDestroy()
- EventManager.instance.unregisterSubscriber(this)
- }
-}
diff --git a/app/src/main/java/com/novel/read/activity/NovelMainActivity.kt b/app/src/main/java/com/novel/read/activity/NovelMainActivity.kt
deleted file mode 100644
index 3d2d5e3..0000000
--- a/app/src/main/java/com/novel/read/activity/NovelMainActivity.kt
+++ /dev/null
@@ -1,148 +0,0 @@
-package com.novel.read.activity
-
-import android.annotation.SuppressLint
-import android.content.Context
-import android.content.Intent
-import android.os.Bundle
-import android.util.Log
-import android.view.KeyEvent
-import android.view.View
-import androidx.fragment.app.Fragment
-import com.mango.mangolib.event.EventManager
-import com.novel.read.R
-import com.novel.read.base.NovelBaseActivity
-import com.novel.read.constants.Constant
-import com.novel.read.event.*
-import com.novel.read.fragment.BookFragment
-import com.novel.read.fragment.MoreFragment
-import com.novel.read.fragment.RecommendFragment
-import com.novel.read.fragment.StackFragment
-import com.novel.read.http.AccountManager
-import com.novel.read.model.db.dbManage.BookRepository
-import com.novel.read.showToast
-import com.novel.read.utlis.SpUtil
-import com.squareup.otto.Subscribe
-import kotlinx.android.synthetic.main.activity_main.*
-
-class NovelMainActivity(override val layoutId: Int = R.layout.activity_main) : NovelBaseActivity() {
-
- private lateinit var mCurrentFrag: Fragment
- private lateinit var mMainFragment: BookFragment
- private lateinit var mRecommendFragment: RecommendFragment
- private lateinit var mStackFragment: StackFragment
- private lateinit var mMoreFragment: MoreFragment
-
- //记录用户首次点击返回键的时间
- private var firstTime: Long = 0
-
- override fun initView() {
- mCurrentFrag = Fragment()
- mMainFragment = BookFragment.newInstance()
- mRecommendFragment = RecommendFragment.newInstance()
- mStackFragment = StackFragment.newInstance()
- mMoreFragment = MoreFragment.newInstance()
- AccountManager.getInstance().login(this)
- }
-
- override fun initData() {
- bottom_bar.setOnNavigationItemSelectedListener { menuItem ->
- when (menuItem.itemId) {
- R.id.tab_one -> {
- switchFragment(mMainFragment)
- return@setOnNavigationItemSelectedListener true
- }
- R.id.tab_two -> {
- switchFragment(mRecommendFragment)
- return@setOnNavigationItemSelectedListener true
- }
- R.id.tab_three -> {
- switchFragment(mStackFragment)
- return@setOnNavigationItemSelectedListener true
- }
- R.id.tab_four -> {
- switchFragment(mMoreFragment)
- return@setOnNavigationItemSelectedListener true
- }
- }
- false
- }
-
- if (BookRepository.getInstance().collBooks.size > 0) {
- switchFragment(mMainFragment)
- } else {
- bottom_bar.selectedItemId = R.id.tab_two
- }
- }
-
- private fun switchFragment(targetFragment: Fragment) {
- val transaction = supportFragmentManager.beginTransaction()
- if (!targetFragment.isAdded) {
- transaction.hide(mCurrentFrag)
- transaction.add(R.id.fl_content, targetFragment, targetFragment.javaClass.name)
- } else {
- transaction.hide(mCurrentFrag).show(targetFragment)
- }
- mCurrentFrag = targetFragment
- transaction.commit()
- }
-
- override fun onResume() {
- super.onResume()
- EventManager.instance.registerSubscriber(this)
- }
-
- override fun onPause() {
- super.onPause()
- EventManager.instance.unregisterSubscriber(this)
- }
-
- @Subscribe
- fun login(event: LoginEvent) {
- if (event.isFail) {
- Log.e("NovelMainActivity", "login: " + event.er!!.msg)
- } else {
- SpUtil.setStringValue(Constant.Uid, event.result!!.uid.toString())
- }
- }
-
- override fun onKeyUp(keyCode: Int, event: KeyEvent): Boolean {
- if (keyCode == KeyEvent.KEYCODE_BACK && event.action == KeyEvent.ACTION_UP) {
- if (!isVisible(bottom_bar)) {
- bottom_bar.visibility = View.VISIBLE
- mMainFragment.updateBook(UpdateBookEvent())
- } else {
- val secondTime = System.currentTimeMillis()
- if (secondTime - firstTime > 1000) {
- firstTime = secondTime
- showToast("再次点击退出界面")
- } else {
- finish()
- }
- }
- return true
- }
- return super.onKeyUp(keyCode, event)
- }
-
- @Subscribe
- fun setBottomBar(event: HideBottomBarEvent) {
- if (event.result!!) {
- bottom_bar.visibility = View.GONE
- } else {
- bottom_bar.visibility = View.VISIBLE
- }
- }
-
- @Subscribe
- fun toRecommendFragment(event: SwitchFragmentEvent) {
- bottom_bar.selectedItemId = R.id.tab_two
- }
-
- companion object {
- fun reStart(context: Context) {
- val intent = Intent(context, NovelMainActivity::class.java)
- intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK
- context.startActivity(intent)
- }
- }
-}
diff --git a/app/src/main/java/com/novel/read/activity/NovelRankListActivity.kt b/app/src/main/java/com/novel/read/activity/NovelRankListActivity.kt
deleted file mode 100644
index e6b5d1b..0000000
--- a/app/src/main/java/com/novel/read/activity/NovelRankListActivity.kt
+++ /dev/null
@@ -1,91 +0,0 @@
-package com.novel.read.activity
-
-import androidx.recyclerview.widget.LinearLayoutManager
-import com.novel.read.R
-import com.novel.read.adapter.RankListAdapter
-import com.novel.read.base.NovelBaseActivity
-import com.novel.read.constants.Constant
-import com.novel.read.constants.Constant.COMMENT_SIZE
-import com.novel.read.http.AccountManager
-import com.novel.read.inter.OnLoadMoreListener
-import com.novel.read.model.protocol.RankByUpdateResp
-import kotlinx.android.synthetic.main.activity_rank_list.*
-import retrofit2.Call
-import retrofit2.Callback
-import retrofit2.Response
-import java.util.*
-
-/**
- * 推荐fragment中点击更多跳转来的。
- */
-class NovelRankListActivity(override val layoutId: Int= R.layout.activity_rank_list) : NovelBaseActivity() {
-
- private lateinit var mAdapter: RankListAdapter
- private var mList: MutableList = ArrayList()
- private var page = 1
- private var loadSize: Int = 0
- private var type: String = ""
- private var sex: String = ""
-
- override fun initView() {
- rlv_book_list.layoutManager = LinearLayoutManager(this)
- mAdapter = RankListAdapter(mList, rlv_book_list)
- rlv_book_list.adapter = mAdapter
- sex = intent.getStringExtra(Constant.Sex)
- type = intent.getStringExtra(Constant.Type)
- when (type) {
- Constant.ListType.Human -> toolbar.title = getString(R.string.popular_selection)
- Constant.ListType.EditRecommend -> toolbar.title = getString(R.string.edit_recommend)
- Constant.ListType.HotSearch -> toolbar.title = getString(R.string.hot_search)
- }
- getData()
- }
-
- override fun initData() {
- toolbar.setNavigationOnClickListener { finish() }
-
- mAdapter.setOnLoadMoreListener(object : OnLoadMoreListener {
- override fun onLoadMore() {
- if (mAdapter.isLoadingMore) {
-
- } else {
- if (loadSize >= COMMENT_SIZE) {
- mAdapter.isLoadingMore = true
- mAdapter.notifyDataSetChanged()
- page++
- getData()
- }
- }
- }
- })
- }
-
- private fun getData() {
- AccountManager.getInstance().getRankList(type, sex, Constant.DateTyp.Week, page.toString(), RankCallBack())
- }
-
- private inner class RankCallBack : Callback {
-
- override fun onResponse(call: Call, response: Response) {
- if (response.isSuccessful) {
- if (response.body() != null) {
- loadSize = response.body()!!.book.size
- if (mAdapter.isLoadingMore) {
- mAdapter.isLoadingMore = false
- mList.addAll(response.body()!!.book)
- mAdapter.notifyDataSetChanged()
- } else {
- mList.clear()
- mList.addAll(response.body()!!.book)
- mAdapter.notifyDataSetChanged()
- }
-
- }
- }
- }
-
- override fun onFailure(call: Call, t: Throwable) {
-
- }
- }
-}
diff --git a/app/src/main/java/com/novel/read/activity/NovelReadActivity.kt b/app/src/main/java/com/novel/read/activity/NovelReadActivity.kt
deleted file mode 100644
index 1d754e8..0000000
--- a/app/src/main/java/com/novel/read/activity/NovelReadActivity.kt
+++ /dev/null
@@ -1,655 +0,0 @@
-package com.novel.read.activity
-
-import android.annotation.SuppressLint
-import android.app.Activity
-import android.app.Service
-import android.content.*
-import android.os.Build
-import android.os.Handler
-import android.os.IBinder
-import android.os.Message
-import android.util.Log
-import android.view.KeyEvent
-import android.view.View.*
-import android.view.WindowManager
-import android.view.animation.Animation
-import android.view.animation.AnimationUtils
-import android.widget.SeekBar
-import androidx.appcompat.app.AlertDialog
-import androidx.core.content.ContextCompat
-import androidx.core.view.GravityCompat
-import androidx.drawerlayout.widget.DrawerLayout
-import androidx.recyclerview.widget.LinearLayoutManager
-import com.mango.mangolib.event.EventManager
-import com.novel.read.R
-import com.novel.read.adapter.CategoryAdapter
-import com.novel.read.adapter.MarkAdapter
-import com.novel.read.base.NovelBaseActivity
-import com.novel.read.constants.Constant
-import com.novel.read.constants.Constant.ResultCode.Companion.RESULT_IS_COLLECTED
-import com.novel.read.event.BookArticleEvent
-import com.novel.read.event.ErrorChapterEvent
-import com.novel.read.event.FinishChapterEvent
-import com.novel.read.event.RxBus
-import com.novel.read.http.AccountManager
-import com.novel.read.model.db.BookChapterBean
-import com.novel.read.model.db.BookSignTable
-import com.novel.read.model.db.CollBookBean
-import com.novel.read.model.db.DownloadTaskBean
-import com.novel.read.model.db.dbManage.BookRepository
-import com.novel.read.service.DownloadMessage
-import com.novel.read.service.DownloadService
-import com.novel.read.showToast
-import com.novel.read.utlis.BrightnessUtils
-import com.novel.read.utlis.ScreenUtils
-import com.novel.read.utlis.SpUtil
-import com.novel.read.utlis.SystemBarUtils
-import com.novel.read.widget.dialog.ReadSettingDialog
-import com.novel.read.widget.page.PageLoader
-import com.novel.read.widget.page.PageView
-import com.novel.read.widget.page.ReadSettingManager
-import com.novel.read.widget.page.TxtChapter
-import com.squareup.otto.Subscribe
-import kotlinx.android.synthetic.main.activity_read.*
-import kotlinx.android.synthetic.main.layout_download.*
-import kotlinx.android.synthetic.main.layout_light.*
-import kotlinx.android.synthetic.main.layout_read_mark.*
-import java.util.*
-
-/**
- * 阅读页📕
- */
-class NovelReadActivity : NovelBaseActivity(), DownloadService.OnDownloadListener {
-
- private lateinit var mCategoryAdapter: CategoryAdapter
- private val mChapters = ArrayList()
- private lateinit var mCurrentChapter: TxtChapter //当前章节
- private var currentChapter = 0
- private lateinit var mMarkAdapter: MarkAdapter
- private val mMarks = ArrayList()
- private lateinit var mPageLoader: PageLoader
- private var mTopInAnim: Animation? = null
- private var mTopOutAnim: Animation? = null
- private var mBottomInAnim: Animation? = null
- private var mBottomOutAnim: Animation? = null
-
- private lateinit var mSettingDialog: ReadSettingDialog
- private var isCollected = false // isFromSDCard
- private var isNightMode = false
- private var isFullScreen = false
- private val isRegistered = false
-
- private lateinit var mCollBook: CollBookBean
- private lateinit var mBookId: String
-
- @SuppressLint("HandlerLeak")
- private val mHandler = object : Handler() {
- override fun handleMessage(msg: Message) {
- super.handleMessage(msg)
- when (msg.what) {
- WHAT_CATEGORY -> rlv_list.setSelection(mPageLoader.chapterPos)
- WHAT_CHAPTER -> mPageLoader.openChapter()
- }
- }
- }
-
- override val layoutId: Int get() = R.layout.activity_read
-
- // 接收电池信息和时间更新的广播
- private val mReceiver = object : BroadcastReceiver() {
- override fun onReceive(context: Context, intent: Intent) {
- if (Objects.requireNonNull(intent.action) == Intent.ACTION_BATTERY_CHANGED) {
- val level = intent.getIntExtra("level", 0)
- mPageLoader.updateBattery(level)
- } else if (intent.action == Intent.ACTION_TIME_TICK) {
- mPageLoader.updateTime()
- }// 监听分钟的变化
- }
- }
-
- private var mService: DownloadService.IDownloadManager? = null
- private var mConn: ServiceConnection? = null
-
- override fun initView() {
- EventManager.instance.registerSubscriber(this)
- mCollBook = intent.getSerializableExtra(EXTRA_COLL_BOOK) as CollBookBean
- isCollected = intent.getBooleanExtra(EXTRA_IS_COLLECTED, false)
- mBookId = mCollBook.id
- initService()
- // 如果 API < 18 取消硬件加速
- if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2) {
- read_pv_page.setLayerType(LAYER_TYPE_SOFTWARE, null)
- }
- window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
-
- //获取页面加载器
- mPageLoader = read_pv_page.getPageLoader(mCollBook)
-
- mSettingDialog = ReadSettingDialog(this, mPageLoader)
- //禁止滑动展示DrawerLayout
- read_dl_slide.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED)
- //侧边打开后,返回键能够起作用
- read_dl_slide.isFocusableInTouchMode = false
- //半透明化StatusBar
- SystemBarUtils.transparentStatusBar(this)
- //隐藏StatusBar
- read_pv_page.post { this.hideSystemBar() }
- read_abl_top_menu.setPadding(0, ScreenUtils.statusBarHeight, 0, 0)
- ll_download.setPadding(0, ScreenUtils.statusBarHeight, 0, ScreenUtils.dpToPx(15))
-
- val lp = window.attributes
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
- lp.layoutInDisplayCutoutMode = 1
- }
- window.attributes = lp
-
- //设置当前Activity的Brightness
- if (ReadSettingManager.getInstance().isBrightnessAuto) {
- BrightnessUtils.setDefaultBrightness(this)
- } else {
- BrightnessUtils.setBrightness(this, ReadSettingManager.getInstance().brightness)
- }
-
- //注册广播
- val intentFilter = IntentFilter()
- intentFilter.addAction(Intent.ACTION_BATTERY_CHANGED)
- intentFilter.addAction(Intent.ACTION_TIME_TICK)
- registerReceiver(mReceiver, intentFilter)
-
- if (!SpUtil.getBooleanValue(Constant.BookGuide, false)) {
- iv_guide.visibility = VISIBLE
- toggleMenu(false)
- }
-
- if (isCollected) {
- mPageLoader.collBook.bookChapters = BookRepository.getInstance().getBookChaptersInRx(mBookId)
- // 刷新章节列表
- mPageLoader.refreshChapterList()
- // 如果是网络小说并被标记更新的,则从网络下载目录
- if (mCollBook.isUpdate && !mCollBook.isLocal) {
- AccountManager.getInstance().getBookArticle(mBookId)
- }
- } else {
- AccountManager.getInstance().getBookArticle(mBookId)
- }
-
- }
-
- override fun initData() {
- tv_book_name.text = mCollBook.title
- mCategoryAdapter = CategoryAdapter()
- rlv_list.adapter = mCategoryAdapter
- rlv_list.isFastScrollEnabled = true
- rlv_mark.layoutManager = LinearLayoutManager(this)
- mMarkAdapter = MarkAdapter(mMarks)
- rlv_mark.adapter = mMarkAdapter
- isNightMode = ReadSettingManager.getInstance().isNightMode
- //夜间模式按钮的状态
- toggleNightMode()
- isFullScreen = ReadSettingManager.getInstance().isFullScreen
- toolbar.setNavigationOnClickListener { finish() }
- read_setting_sb_brightness.progress = ReadSettingManager.getInstance().brightness
- mPageLoader.setOnPageChangeListener(
- object : PageLoader.OnPageChangeListener {
-
- override fun onChapterChange(pos: Int) {
- var index: Int = pos
- if (pos >= mChapters.size) {
- index = mChapters.size - 1
- }
- mCategoryAdapter.setChapter(index)
- mCurrentChapter = mChapters[index]
- currentChapter = index
- }
-
- override fun requestChapters(requestChapters: List) {
- AccountManager.getInstance().getBookArticleDetail(mBookId, requestChapters)
- mHandler.sendEmptyMessage(WHAT_CATEGORY)
- }
-
- override fun onCategoryFinish(chapters: List) {
- mChapters.clear()
- mChapters.addAll(chapters)
- mCategoryAdapter.refreshItems(mChapters)
- }
-
- override fun onPageCountChange(count: Int) {}
-
- override fun onPageChange(pos: Int) {
-
- }
- }
- )
- read_pv_page.setTouchListener(object : PageView.TouchListener {
- override fun onTouch(): Boolean {
- return !hideReadMenu()
- }
-
- override fun center() {
- toggleMenu(true)
- }
-
- override fun prePage() {}
-
- override fun nextPage() {}
-
- override fun cancel() {}
- })
- read_tv_category.setOnClickListener {
- //移动到指定位置
- if (mCategoryAdapter.count > 0) {
- rlv_list.setSelection(mPageLoader.chapterPos)
- }
- //切换菜单
- toggleMenu(true)
- //打开侧滑动栏
- read_dl_slide.openDrawer(GravityCompat.START)
- }
- tv_light.setOnClickListener {
- ll_light.visibility = GONE
- rlReadMark.visibility = GONE
- if (isVisible(ll_light)) {
- ll_light.visibility = GONE
- } else {
- ll_light.visibility = VISIBLE
- }
- }
- tv_setting.setOnClickListener {
- ll_light.visibility = GONE
- rlReadMark.visibility = GONE
- toggleMenu(false)
- mSettingDialog.show()
- }
-
- read_setting_sb_brightness.setOnSeekBarChangeListener(object :
- SeekBar.OnSeekBarChangeListener {
- override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
-
- }
-
- override fun onStartTrackingTouch(seekBar: SeekBar) {
-
- }
-
- override fun onStopTrackingTouch(seekBar: SeekBar) {
- val progress = seekBar.progress
- //设置当前 Activity 的亮度
- BrightnessUtils.setBrightness(this@NovelReadActivity, progress)
- //存储亮度的进度条
- ReadSettingManager.getInstance().brightness = progress
- }
- })
-
- tvBookReadMode.setOnClickListener {
- isNightMode = !isNightMode
- mPageLoader.setNightMode(isNightMode)
- toggleNightMode()
- }
-
- read_tv_brief.setOnClickListener {
- val intent = Intent(this, NovelBookDetailActivity::class.java)
- intent.putExtra(Constant.Bundle.BookId, Integer.valueOf(mBookId))
- startActivity(intent)
- }
-
- read_tv_community.setOnClickListener {
- if (isVisible(read_ll_bottom_menu)) {
- if (isVisible(rlReadMark)) {
- gone(rlReadMark)
- } else {
- gone(ll_light)
- updateMark()
- visible(rlReadMark)
- }
- }
- }
-
- tvAddMark.setOnClickListener {
- mMarkAdapter.edit = false
- if (BookRepository.getInstance().getSignById(mCurrentChapter.chapterId)) {
- showToast(getString(R.string.sign_exist))
- return@setOnClickListener
- }
- BookRepository.getInstance().addSign(mBookId, mCurrentChapter.chapterId, mCurrentChapter.title)
- updateMark()
- }
-
- tvClear.setOnClickListener {
- if (mMarkAdapter.edit) {
- val sign = mMarkAdapter.selectList
- if (sign != "") {
- BookRepository.getInstance().deleteSign(sign)
- updateMark()
- }
- mMarkAdapter.edit = false
- } else {
- mMarkAdapter.edit = true
- }
- }
-
- tv_cache.setOnClickListener {
- if (!isCollected) { //没有收藏 先收藏 然后弹框
- //设置为已收藏
- isCollected = true
- //设置阅读时间
- mCollBook.lastRead = System.currentTimeMillis().toString()
- BookRepository.getInstance().saveCollBookWithAsync(mCollBook)
- }
- showDownLoadDialog()
-
- }
- rlv_list.setOnItemClickListener { _, _, position, _ ->
- read_dl_slide.closeDrawer(GravityCompat.START)
- mPageLoader.skipToChapter(position)
- }
- iv_guide.setOnClickListener {
- iv_guide.visibility = GONE
- SpUtil.setBooleanValue(Constant.BookGuide, true)
- }
- }
-
- private fun showDownLoadDialog() {
- val builder = AlertDialog.Builder(this)
- builder.setTitle(getString(R.string.d_cache_num))
- .setItems(
- arrayOf(
- getString(R.string.d_cache_last_50),
- getString(R.string.d_cache_last_all),
- getString(R.string.d_cache_all)
- )
- ) { _, which ->
- when (which) {
- 0 -> {
- //50章
- val last = currentChapter + 50
- if (last > mCollBook.bookChapters.size) {
- downLoadCache(mCollBook.bookChapters, mCollBook.bookChapters.size)
- } else {
- downLoadCache(mCollBook.bookChapters, last)
- }
- }
- 1 -> {
- //后面所有
- val lastBeans = ArrayList()
- for (i in currentChapter until mCollBook.bookChapters.size) {
- lastBeans.add(mCollBook.bookChapters[i])
- }
- downLoadCache(lastBeans, mCollBook.bookChapters.size - currentChapter)
- }
- 2 -> downLoadCache(mCollBook.bookChapters, mCollBook.bookChapters.size) //所有
- else -> {
- }
- }
- toggleMenu(true)
- }
- builder.show()
- }
-
- private fun downLoadCache(beans: List, size: Int) {
- val task = DownloadTaskBean()
- task.taskName = mCollBook.title
- task.bookId = mCollBook.id
- task.bookChapters = beans //计算要缓存的章节
- task.currentChapter = currentChapter
- task.lastChapter = size
-
- RxBus.getInstance().post(task)
- startService(Intent(this, DownloadService::class.java))
- }
-
- private fun toggleNightMode() {
- if (isNightMode) {
- tvBookReadMode.text = resources.getString(R.string.book_read_mode_day)
- val drawable = ContextCompat.getDrawable(this, R.drawable.ic_read_menu_moring)
- tvBookReadMode.setCompoundDrawablesWithIntrinsicBounds(null, drawable, null, null)
- cl_layout.setBackgroundColor(ContextCompat.getColor(this, R.color.read_bg_night))
- } else {
- tvBookReadMode.text = resources.getString(R.string.book_read_mode_day)
- val drawable = ContextCompat.getDrawable(this, R.drawable.ic_read_menu_night)
- tvBookReadMode.setCompoundDrawablesWithIntrinsicBounds(null, drawable, null, null)
- cl_layout.setBackgroundColor(
- ContextCompat.getColor(
- this,
- ReadSettingManager.getInstance().pageStyle.bgColor
- )
- )
- }
- }
-
- /**
- * 隐藏阅读界面的菜单显示
- *
- * @return 是否隐藏成功
- */
- private fun hideReadMenu(): Boolean {
- hideSystemBar()
- if (read_abl_top_menu.visibility == VISIBLE) {
- toggleMenu(true)
- return true
- } else if (mSettingDialog.isShowing) {
- mSettingDialog.dismiss()
- return true
- }
- return false
- }
-
- private fun showSystemBar() {
- //显示
- SystemBarUtils.showUnStableStatusBar(this)
- if (isFullScreen) {
- SystemBarUtils.showUnStableNavBar(this)
- }
- }
-
- private fun hideSystemBar() {
- //隐藏
- SystemBarUtils.hideStableStatusBar(this)
- if (isFullScreen) {
- SystemBarUtils.hideStableNavBar(this)
- }
- }
-
- /**
- * 切换菜单栏的可视状态
- * 默认是隐藏的
- */
- private fun toggleMenu(hideStatusBar: Boolean) {
- initMenuAnim()
- gone(ll_light, rlReadMark)
- if (read_abl_top_menu.visibility == VISIBLE) {
- //关闭
- read_abl_top_menu.startAnimation(mTopOutAnim)
- read_ll_bottom_menu.startAnimation(mBottomOutAnim)
- read_abl_top_menu.visibility = GONE
- read_ll_bottom_menu.visibility = GONE
-
- if (hideStatusBar) {
- hideSystemBar()
- }
- } else {
- read_abl_top_menu.visibility = VISIBLE
- read_ll_bottom_menu.visibility = VISIBLE
- read_abl_top_menu.startAnimation(mTopInAnim)
- read_ll_bottom_menu.startAnimation(mBottomInAnim)
-
- showSystemBar()
- }
- }
-
- //初始化菜单动画
- private fun initMenuAnim() {
- if (mTopInAnim != null) return
- mTopInAnim = AnimationUtils.loadAnimation(this, R.anim.slide_top_in)
- mTopOutAnim = AnimationUtils.loadAnimation(this, R.anim.slide_top_out)
- mBottomInAnim = AnimationUtils.loadAnimation(this, R.anim.slide_bottom_in)
- mBottomOutAnim = AnimationUtils.loadAnimation(this, R.anim.slide_bottom_out)
- //退出的速度要快
- mTopOutAnim!!.duration = 200
- mBottomOutAnim!!.duration = 200
- }
-
- @Subscribe
- fun getBookArticle(event: BookArticleEvent) {
- if (event.isFail) {
- //获取章节失败处理
- Log.e(TAG, event.er!!.msg)
- } else {
- val chapterBeans = event.result!!.chapterBean
- mPageLoader.collBook.bookChapters = chapterBeans
- mPageLoader.refreshChapterList()
-
- // 如果是目录更新的情况,那么就需要存储更新数据
- if (mCollBook.isUpdate && isCollected) {
- BookRepository.getInstance().saveBookChaptersWithAsync(chapterBeans, mCollBook)
- }
- }
- }
-
- @Subscribe
- fun finishChapter(event: FinishChapterEvent) {
- if (mPageLoader.pageStatus == PageLoader.STATUS_LOADING) {
- mHandler.sendEmptyMessage(WHAT_CHAPTER)
- }
- // 当完成章节的时候,刷新列表
- mCategoryAdapter.notifyDataSetChanged()
- }
-
- @Subscribe
- fun errorChapter(event: ErrorChapterEvent) {
- if (mPageLoader.pageStatus == PageLoader.STATUS_LOADING) {
- mPageLoader.chapterError()
- }
- }
-
- private fun updateMark() {
- mMarks.clear()
- mMarks.addAll(BookRepository.getInstance().getSign(mBookId))
- mMarkAdapter.notifyDataSetChanged()
- }
-
- override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean {
- when (keyCode) {
- KeyEvent.KEYCODE_VOLUME_UP -> return mPageLoader.skipToPrePage()
-
- KeyEvent.KEYCODE_VOLUME_DOWN -> return mPageLoader.skipToNextPage()
- }
- return super.onKeyDown(keyCode, event)
- }
-
- override fun onBackPressed() {
- if (read_abl_top_menu.visibility == VISIBLE) {
- // 非全屏下才收缩,全屏下直接退出
- if (!ReadSettingManager.getInstance().isFullScreen) {
- toggleMenu(true)
- return
- }
- } else if (mSettingDialog.isShowing) {
- mSettingDialog.dismiss()
- return
- } else if (read_dl_slide.isDrawerOpen(GravityCompat.START)) {
- read_dl_slide.closeDrawer(GravityCompat.START)
- return
- }
- Log.e(TAG, "onBackPressed: " + mCollBook.bookChapters.isEmpty())
-
- if (!mCollBook.isLocal && !isCollected && mCollBook.bookChapters.isNotEmpty()) {
- val alertDialog = AlertDialog.Builder(this)
- .setTitle(getString(R.string.add_book))
- .setMessage(getString(R.string.like_book))
- .setPositiveButton(getString(R.string.sure)) { dialog, which ->
- //设置为已收藏
- isCollected = true
- //设置阅读时间
- mCollBook.lastRead = System.currentTimeMillis().toString()
-
- BookRepository.getInstance().saveCollBookWithAsync(mCollBook)
-
- exit()
- }
- .setNegativeButton(getString(R.string.cancel)) { dialog, which -> exit() }.create()
- alertDialog.show()
- } else {
- exit()
- }
- }
-
- // 退出
- private fun exit() {
- // 返回给BookDetail。
- val result = Intent()
- result.putExtra(RESULT_IS_COLLECTED, isCollected)
- setResult(Activity.RESULT_OK, result)
- super.onBackPressed()
- }
-
- override fun onPause() {
- super.onPause()
- if (isCollected) {
- mPageLoader.saveRecord()
- }
- }
-
- override fun onDestroy() {
- super.onDestroy()
- EventManager.instance.unregisterSubscriber(this)
- mPageLoader.closeBook()
- unbindService(mConn)
- unregisterReceiver(mReceiver)
- }
-
- private fun initService() {
-
- mConn = object : ServiceConnection {
- override fun onServiceConnected(name: ComponentName, service: IBinder) {
- mService = service as DownloadService.IDownloadManager
- mService!!.setOnDownloadListener(this@NovelReadActivity)
- }
-
- override fun onServiceDisconnected(name: ComponentName) {}
- }
- //绑定
- bindService(Intent(this, DownloadService::class.java), mConn, Service.BIND_AUTO_CREATE)
- }
-
- override fun onDownloadChange(pos: Int, status: Int, msg: String) {
- Log.e(TAG, "onDownloadChange: $pos $status $msg")
-
- if (msg == getString(R.string.download_success) || msg == getString(R.string.download_error)) {
- //下载成功或失败后隐藏下载视图
- if (ll_download != null) {
- ll_download.visibility = GONE
- showToast(msg)
- }
- } else {
- if (ll_download != null) {
- ll_download.visibility = VISIBLE
- tv_progress.text = getString(
- R.string.download_loading,
- mService!!.downloadTaskList[pos].currentChapter,
- mService!!.downloadTaskList[pos].lastChapter
- )
- pb_loading.max = mService!!.downloadTaskList[pos].lastChapter
- pb_loading.progress = mService!!.downloadTaskList[pos].currentChapter
- }
- }
- }
-
-
- override fun onDownloadResponse(pos: Int, status: Int) {
- Log.e(TAG, "onDownloadResponse: $pos $status")
- }
-
- @Subscribe
- fun onDownLoadEvent(message: DownloadMessage) {
- showToast(message.message)
- }
-
- companion object {
-
- private const val TAG = "NovelReadActivity"
- const val EXTRA_COLL_BOOK = "extra_coll_book"
- const val EXTRA_IS_COLLECTED = "extra_is_collected"
- private const val WHAT_CATEGORY = 1
- private const val WHAT_CHAPTER = 2
- }
-}
diff --git a/app/src/main/java/com/novel/read/activity/NovelRecommendBookListActivity.kt b/app/src/main/java/com/novel/read/activity/NovelRecommendBookListActivity.kt
deleted file mode 100644
index da0c2b4..0000000
--- a/app/src/main/java/com/novel/read/activity/NovelRecommendBookListActivity.kt
+++ /dev/null
@@ -1,62 +0,0 @@
-package com.novel.read.activity
-
-import android.view.View
-import androidx.fragment.app.Fragment
-import androidx.viewpager.widget.ViewPager
-import com.novel.read.R
-import com.novel.read.adapter.ViewPageAdapter
-import com.novel.read.base.NovelBaseActivity
-import com.novel.read.constants.Constant
-import com.novel.read.fragment.BookListFragment
-import com.novel.read.widget.VpTabLayout
-import kotlinx.android.synthetic.main.activity_recommend_book_list.*
-import java.util.*
-
-class NovelRecommendBookListActivity(override val layoutId: Int= R.layout.activity_recommend_book_list) : NovelBaseActivity() {
-
- override fun initView() {
- val fragmentList = ArrayList()
- val sex = intent.getStringExtra(Constant.Sex)
- val type = intent.getStringExtra(Constant.Type)
- when (type) {
- Constant.ListType.Human -> toolbar.title = getString(R.string.popular_selection)
- Constant.ListType.EditRecommend -> toolbar.title = getString(R.string.edit_recommend)
- Constant.ListType.HotSearch -> toolbar.title = getString(R.string.hot_search)
- }
- val generalFragment = BookListFragment.newInstance(type, Constant.DateTyp.General, sex)
- val monthFragment = BookListFragment.newInstance(type, Constant.DateTyp.Month, sex)
- val weekFragment = BookListFragment.newInstance(type, Constant.DateTyp.Week, sex)
- fragmentList.add(generalFragment)
- fragmentList.add(monthFragment)
- fragmentList.add(weekFragment)
- val pageAdapter = ViewPageAdapter(supportFragmentManager, fragmentList)
- vp_recommend_type.adapter = pageAdapter
- vp_recommend_type.offscreenPageLimit = 2
- vp_recommend_type.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
- override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {
-
- }
-
- override fun onPageSelected(position: Int) {
- vp_tab.setAnim(position, vp_recommend_type)
- }
-
- override fun onPageScrollStateChanged(state: Int) {}
- })
- }
-
- override fun initData() {
- toolbar!!.setNavigationOnClickListener { finish() }
-
- vp_tab.setOnTabBtnClickListener(object : VpTabLayout.OnTabClickListener {
- override fun onTabBtnClick(var1: VpTabLayout.CommonTabBtn, var2: View) {
- when (var1) {
- VpTabLayout.CommonTabBtn.ONE -> vp_tab.setAnim(0, vp_recommend_type)
- VpTabLayout.CommonTabBtn.TWO -> vp_tab.setAnim(1, vp_recommend_type)
- VpTabLayout.CommonTabBtn.THREE -> vp_tab.setAnim(2, vp_recommend_type)
- }
- }
- })
-
- }
-}
diff --git a/app/src/main/java/com/novel/read/activity/NovelSearchActivity.kt b/app/src/main/java/com/novel/read/activity/NovelSearchActivity.kt
deleted file mode 100644
index 52a935a..0000000
--- a/app/src/main/java/com/novel/read/activity/NovelSearchActivity.kt
+++ /dev/null
@@ -1,255 +0,0 @@
-package com.novel.read.activity
-
-import android.content.DialogInterface
-import android.text.Editable
-import android.text.TextUtils
-import android.text.TextWatcher
-import android.view.KeyEvent
-import android.view.View
-import androidx.recyclerview.widget.LinearLayoutManager
-import com.google.android.flexbox.AlignItems
-import com.google.android.flexbox.FlexDirection
-import com.google.android.flexbox.FlexWrap
-import com.google.android.flexbox.FlexboxLayoutManager
-import com.mango.mangolib.event.EventManager
-import com.novel.read.R
-import com.novel.read.adapter.HistoryAdapter
-import com.novel.read.adapter.HotAdapter
-import com.novel.read.adapter.SearchAdapter
-import com.novel.read.base.NovelBaseActivity
-import com.novel.read.constants.Constant.COMMENT_SIZE
-import com.novel.read.event.HotSearchEvent
-import com.novel.read.event.SearchListEvent
-import com.novel.read.http.AccountManager
-import com.novel.read.inter.OnLoadMoreListener
-import com.novel.read.model.db.SearchListTable
-import com.novel.read.model.protocol.SearchResp
-import com.novel.read.utlis.DialogUtils
-import com.spreada.utils.chinese.ZHConverter
-import com.squareup.otto.Subscribe
-import kotlinx.android.synthetic.main.activity_search.*
-import kotlinx.android.synthetic.main.title_search.*
-import org.litepal.LitePal
-import java.util.*
-
-class NovelSearchActivity(override val layoutId: Int= R.layout.activity_search) : NovelBaseActivity() {
-
- private val mHotList = ArrayList()
- private lateinit var mHotAdapter: HotAdapter
-
- private var mHisList: MutableList = ArrayList()
- private lateinit var mHisAdapter: HistoryAdapter
-
- private val mSearchList = ArrayList()
- private lateinit var mSearchAdapter: SearchAdapter
-
- private var page = 1
- private var loadSize: Int = 0
-
- override fun initView() {
- EventManager.instance.registerSubscriber(this)
-
- val manager = FlexboxLayoutManager(this)
- //设置主轴排列方式
- manager.flexDirection = FlexDirection.ROW
- //设置是否换行
- manager.flexWrap = FlexWrap.WRAP
- manager.alignItems = AlignItems.STRETCH
- rlv_hot.layoutManager = manager
- mHotAdapter = HotAdapter(mHotList)
- rlv_hot.adapter = mHotAdapter
-
- mHisList = LitePal.order("saveTime desc").limit(5).find(SearchListTable::class.java)
- val manager2 = FlexboxLayoutManager(this)
- //设置主轴排列方式
- manager2.flexDirection = FlexDirection.ROW
- //设置是否换行
- manager2.flexWrap = FlexWrap.WRAP
- manager2.alignItems = AlignItems.STRETCH
- mHisAdapter = HistoryAdapter(mHisList)
- rlv_history.layoutManager = manager2
- rlv_history.adapter = mHisAdapter
-
- rlv_search.layoutManager = LinearLayoutManager(this)
- mSearchAdapter = SearchAdapter(mSearchList, rlv_search)
- rlv_search.adapter = mSearchAdapter
-
- mSearchAdapter.setOnLoadMoreListener(object : OnLoadMoreListener {
- override fun onLoadMore() {
- if (mSearchAdapter.isLoadingMore) {
-
- } else {
- if (loadSize >= COMMENT_SIZE) {
- mSearchAdapter.isLoadingMore = true
- mSearchAdapter.notifyDataSetChanged()
- page++
- getData()
- }
- }
- }
- })
-
- AccountManager.getInstance().getHotSearch()
- }
-
- private fun getData() {
- val str = convertCC(tv_search.text.toString().trim { it <= ' ' })
- AccountManager.getInstance().getSearchBookList("", str, page)
- }
-
- //繁簡轉換
- fun convertCC(input: String): String {
- return if (TextUtils.isEmpty(input) || input.isEmpty()) "" else ZHConverter.getInstance(
- ZHConverter.SIMPLIFIED
- ).convert(input)
- }
-
- override fun initData() {
- //输入框
- tv_search.addTextChangedListener(object : TextWatcher {
- override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {
-
- }
-
- override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
- if (s.toString().trim { it <= ' ' } == "") {
- refresh.visibility = View.GONE
- head_hot.visibility = View.VISIBLE
- head_history.visibility = View.VISIBLE
- rlv_hot.visibility = View.VISIBLE
- rlv_history.visibility = View.VISIBLE
- } else {
- refresh.visibility = View.VISIBLE
- head_hot.visibility = View.GONE
- head_history.visibility = View.GONE
- rlv_hot.visibility = View.GONE
- rlv_history.visibility = View.GONE
- refresh.showLoading()
- page = 1
- getData()
- }
-
- }
-
- override fun afterTextChanged(s: Editable) {
-
- }
- })
-
- //键盘的搜索
- tv_search.setOnKeyListener { v, keyCode, event ->
- //修改回车键功能
- if (keyCode == KeyEvent.KEYCODE_ENTER) {
- mSearchAdapter.setHolderType(true)
- saveKey()
- return@setOnKeyListener true
- }
- false
- }
-
- mHotAdapter.setOnItemClickListener(object :HotAdapter.OnItemClickListener{
- override fun onItemClick(view: View, pos: Int) {
- mSearchAdapter.setHolderType(true)
- refresh.visibility = View.VISIBLE
- tv_search.setText(mHotList[pos])
- saveKey()
- }
- })
-
- mHisAdapter.setOnItemClickListener(object :HistoryAdapter.OnItemClickListener{
- override fun onItemClick(view: View, pos: Int) {
- mSearchAdapter.setHolderType(true)
- refresh.visibility = View.VISIBLE
- tv_search.setText(mHisList[pos].key)
- saveKey()
- }
- })
-
- mSearchAdapter.setOnItemClickListener(object :SearchAdapter.OnItemClickListener{
- override fun onItemClick(view: View, pos: Int) {
- mSearchAdapter.setHolderType(true)
- tv_search.setText(mSearchList[pos].title)
- saveKey()
- }
- })
-
- head_history.setOnClickListener { view ->
-
- DialogUtils.getInstance().showAlertDialog(
- this,
- getString(R.string.clear_search),
- dialogListener = DialogInterface.OnClickListener { dialog, which ->
- LitePal.deleteAll(SearchListTable::class.java)
- mHisList.clear()
- mHisList.addAll(LitePal.order("saveTime desc").limit(5).find(SearchListTable::class.java))
- mHisAdapter.notifyDataSetChanged()
- })
- }
-
- tv_cancel.setOnClickListener {
- onBackPressed()
- }
-
- refresh.setOnReloadingListener { getData() }
-
- }
-
- private fun saveKey() {
- if (tv_search.text.toString().trim { it <= ' ' } == "") {
- return
- }
- val searchListTable = SearchListTable()
- searchListTable.key = tv_search.text.toString().trim { it <= ' ' }
- searchListTable.saveTime = System.currentTimeMillis()
- searchListTable.saveOrUpdate("key=?", tv_search.text.toString().trim { it <= ' ' })
- mHisList.clear()
- mHisList.addAll(LitePal.order("saveTime desc").limit(5).find(SearchListTable::class.java))
- mHisAdapter.notifyDataSetChanged()
- }
-
- override fun onBackPressed() {
- if (refresh.visibility == View.VISIBLE) {
- tv_search.setText("")
- mSearchAdapter.setHolderType(false)
- page = 1
- } else {
- super.onBackPressed()
- overridePendingTransition(R.anim.message_fade_in, R.anim.message_fade_out)
- }
- }
-
- @Subscribe
- fun getHotSearch(event: HotSearchEvent) {
- if (event.isFail) {
-
- } else {
- mHotList.clear()
- mHotList.addAll(event.result!!.key)
- mHotAdapter.notifyDataSetChanged()
- }
- }
-
- @Subscribe
- fun getSearchList(event: SearchListEvent) {
- refresh.showFinish()
- if (event.isFail) {
- refresh.showError()
- } else {
- loadSize = event.result!!.book.size
- if (mSearchAdapter.isLoadingMore) {
- mSearchAdapter.isLoadingMore = false
- mSearchList.addAll(event.result!!.book)
- mSearchAdapter.notifyDataSetChanged()
- } else {
- mSearchList.clear()
- mSearchList.addAll(event.result!!.book)
- mSearchAdapter.notifyDataSetChanged()
- }
- }
- }
-
- override fun onDestroy() {
- super.onDestroy()
- EventManager.instance.unregisterSubscriber(this)
- }
-}
diff --git a/app/src/main/java/com/novel/read/activity/NovelSettingActivity.kt b/app/src/main/java/com/novel/read/activity/NovelSettingActivity.kt
deleted file mode 100644
index 33a1667..0000000
--- a/app/src/main/java/com/novel/read/activity/NovelSettingActivity.kt
+++ /dev/null
@@ -1,152 +0,0 @@
-package com.novel.read.activity
-
-import android.annotation.SuppressLint
-import android.app.AlertDialog
-import android.text.TextUtils
-import android.view.View
-import com.allenliu.versionchecklib.v2.AllenVersionChecker
-import com.allenliu.versionchecklib.v2.builder.UIData
-import com.mango.mangolib.event.EventManager
-import com.novel.read.R
-import com.novel.read.base.NovelBaseActivity
-import com.novel.read.constants.Constant
-import com.novel.read.event.UpdateBookEvent
-import com.novel.read.event.VersionEvent
-import com.novel.read.http.AccountManager
-import com.novel.read.model.protocol.VersionResp
-import com.novel.read.utlis.CleanCacheUtils
-import com.novel.read.utlis.LocalManageUtil
-import com.novel.read.utlis.SpUtil
-import com.novel.read.utlis.VersionUtil
-import com.squareup.otto.Subscribe
-import kotlinx.android.synthetic.main.activity_setting.*
-
-class NovelSettingActivity(override val layoutId: Int = R.layout.activity_setting) : NovelBaseActivity(), View.OnClickListener {
-
- private var resp: VersionResp? = null
-
- override fun initView() {
- EventManager.instance.registerSubscriber(this)
- }
-
- @SuppressLint("SetTextI18n")
- override fun initData() {
- tv_language.text =
- resources.getStringArray(R.array.setting_dialog_language_choice)[SpUtil.getIntValue(
- Constant.Language,
- 1
- )]
- tv_version.text = "V" + VersionUtil.getPackageName(this)!!
- try {
- val cacheSize =
- CleanCacheUtils.getInstance().getTotalCacheSize(this@NovelSettingActivity)
- tv_cache_num.text = cacheSize
- } catch (e: Exception) {
- e.printStackTrace()
- }
- toolbar.setNavigationOnClickListener { finish() }
- AccountManager.getInstance().checkVersion(VersionUtil.getPackageCode(this))
-
- ll_choose_language.setOnClickListener(this)
- ll_clear_cache.setOnClickListener(this)
- tv_check.setOnClickListener(this)
- }
-
- override fun onClick(v: View?) {
- when (v?.id) {
- R.id.ll_choose_language -> showLanguageDialog()
- R.id.ll_clear_cache -> {
- //默认不勾选清空书架列表,防手抖!!
- val selected = booleanArrayOf(true, false)
- AlertDialog.Builder(this)
- .setTitle(getString(R.string.clear_cache))
- .setCancelable(true)
- .setMultiChoiceItems(arrayOf(getString(R.string.clear_cache), getString(R.string.clear_book)), selected) { _, which, isChecked -> selected[which] = isChecked }
- .setPositiveButton(getString(R.string.sure)) { dialog, _ ->
- Thread {
- CleanCacheUtils.getInstance()
- .clearCache(selected[0], selected[1], this@NovelSettingActivity)
- var cacheSize = ""
- try {
- cacheSize =
- CleanCacheUtils.getInstance()
- .getTotalCacheSize(this@NovelSettingActivity)
- } catch (e: Exception) {
- e.printStackTrace()
- }
- val finalCacheSize = cacheSize
- runOnUiThread {
- EventManager.instance.postEvent(UpdateBookEvent())
- tv_cache_num.text = finalCacheSize
- }
- }.start()
- dialog.dismiss()
- }
- .setNegativeButton(getString(R.string.cancel)) { dialog, _ -> dialog.dismiss() }
- .create().show()
- }
- R.id.tv_check ->
- //版本大小不为空 去更新。
- updateApk(resp!!)
- }
- }
-
- private fun showLanguageDialog() {
- AlertDialog.Builder(this)
- .setTitle(getString(R.string.choose_language))
- .setSingleChoiceItems(
- resources.getStringArray(R.array.setting_dialog_language_choice),
- SpUtil.getIntValue(Constant.Language, 1)
- ) { dialog, which ->
- val language =
- resources.getStringArray(R.array.setting_dialog_language_choice)[which]
- tv_language.text = language
- SpUtil.setIntValue(Constant.Language, which)
- dialog.dismiss()
-
- if (which == 0) {
- selectLanguage(0)
- } else {
- selectLanguage(1)
- }
- }
- .create().show()
- }
-
- private fun selectLanguage(select: Int) {
- LocalManageUtil.saveSelectLanguage(this, select)
- NovelMainActivity.reStart(this)
- }
-
- @Subscribe
- fun checkVersion(event: VersionEvent) {
- if (event.isFail) {
-
- } else {
- if (TextUtils.isEmpty(event.result!!.version.size)) {
- return
- }
- resp = event.result
- tv_check.visibility = View.VISIBLE
-
- }
- }
-
- private fun updateApk(resp: VersionResp) {
- val versionBean = resp.version
- val builder = AllenVersionChecker
- .getInstance()
- .downloadOnly(
- UIData.create()
- .setTitle(getString(R.string.new_version, versionBean.version))
- .setContent(versionBean.content)
- .setDownloadUrl(versionBean.download)
- )
- builder.executeMission(this)
- }
-
- override fun onDestroy() {
- super.onDestroy()
- EventManager.instance.unregisterSubscriber(this)
- }
-}
diff --git a/app/src/main/java/com/novel/read/activity/NovelSplashActivity.kt b/app/src/main/java/com/novel/read/activity/NovelSplashActivity.kt
deleted file mode 100644
index ee7f81f..0000000
--- a/app/src/main/java/com/novel/read/activity/NovelSplashActivity.kt
+++ /dev/null
@@ -1,69 +0,0 @@
-package com.novel.read.activity
-
-import android.content.Intent
-import android.os.Bundle
-import androidx.appcompat.app.AppCompatActivity
-import com.novel.read.R
-import com.novel.read.utlis.PermissionUtil
-import com.novel.read.utlis.StatusBarUtil
-import kotlinx.android.synthetic.main.activity_splash.*
-
-class NovelSplashActivity : AppCompatActivity(), PermissionUtil.PermissionCallBack {
-
- private var flag = false
- private var runnable: Runnable? = null
-
- private var mPermissionUtil: PermissionUtil = PermissionUtil.getInstance()
-
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- StatusBarUtil.setBarsStyle(this, R.color.colorPrimary, true)
- setContentView(R.layout.activity_splash)
- mPermissionUtil.requestPermissions(this, PERMISSION_CODE, this)
- }
-
- override fun onRequestPermissionsResult(
- requestCode: Int,
- permissions: Array,
- grantResults: IntArray
- ) {
- mPermissionUtil.requestResult(this, permissions, grantResults, this)
- }
-
- private fun init() {
- runnable = Runnable { goHome() }
- tvSkip.postDelayed(runnable, 2000)
- tvSkip.setOnClickListener { goHome() }
- }
-
- @Synchronized
- private fun goHome() {
- if (!flag) {
- flag = true
- startActivity(Intent(this, NovelMainActivity::class.java))
- finish()
- }
- }
-
- override fun onDestroy() {
- super.onDestroy()
- flag = true
- tvSkip.removeCallbacks(runnable)
- }
-
- override fun onPermissionSuccess() {
- init()
- }
-
- override fun onPermissionReject(strMessage: String) {
- finish()
- }
-
- override fun onPermissionFail() {
- mPermissionUtil.requestPermissions(this, PERMISSION_CODE, this)
- }
-
- companion object {
- private val PERMISSION_CODE = 999
- }
-}
diff --git a/app/src/main/java/com/novel/read/adapter/BookAdapter.kt b/app/src/main/java/com/novel/read/adapter/BookAdapter.kt
deleted file mode 100644
index 53694ca..0000000
--- a/app/src/main/java/com/novel/read/adapter/BookAdapter.kt
+++ /dev/null
@@ -1,163 +0,0 @@
-package com.novel.read.adapter
-
-import android.content.Context
-import android.content.Intent
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
-import android.widget.Button
-import android.widget.ImageView
-import android.widget.TextView
-import androidx.recyclerview.widget.RecyclerView
-
-import com.novel.read.R
-import com.novel.read.activity.NovelReadActivity
-import com.novel.read.model.db.CollBookBean
-import com.novel.read.utlis.GlideImageLoader
-
-import java.util.ArrayList
-
-class BookAdapter(private val mList: List) : RecyclerView.Adapter() {
- private lateinit var mContext: Context
-
- private var mClickListener: OnItemClickListener? = null
- private var mEdit: Boolean = false
-
- val selectList: List
- get() {
- val collBookBeans = ArrayList()
- for (i in mList.indices) {
- if (mList[i].isSelect) {
- collBookBeans.add(mList[i])
- }
- }
- return collBookBeans
- }
-
- override fun onCreateViewHolder(viewGroup: ViewGroup, i: Int): RecyclerView.ViewHolder {
- mContext = viewGroup.context
- val view: View
- if (i == VALUE_ITEM) {
- view = LayoutInflater.from(mContext).inflate(R.layout.rlv_item_book, viewGroup, false)
- return ViewHolder(view)
- } else if (i == EMPTY_ITEM) {
- view = LayoutInflater.from(mContext).inflate(R.layout.rlv_empty_add_book, viewGroup, false)
- return EmptyHolder(view)
- }
- throw IllegalArgumentException()
- }
-
- override fun onBindViewHolder(viewHolder: RecyclerView.ViewHolder, i: Int) {
- if (viewHolder is ViewHolder) {
- if (mEdit) { //编辑模式
- viewHolder.mIvCheck.isSelected = mList[i].isSelect
- viewHolder.mIvCheck.visibility = View.VISIBLE
- viewHolder.mTvBookName.text = mList[i].title
- viewHolder.mTvBookAuthor.text = mList[i].author
- if (mList[i].isUpdate) {
- viewHolder.mIvGeng.visibility = View.VISIBLE
- } else {
- viewHolder.mIvGeng.visibility = View.GONE
- }
- GlideImageLoader.displayCornerImage(mContext, mList[i].cover, viewHolder.mIvBook)
- viewHolder.itemView.setOnClickListener {
- viewHolder.mIvCheck.isSelected = !mList[i].isSelect
- mList[i].isSelect = !mList[i].isSelect
- }
- } else { //正常模式
- viewHolder.mIvCheck.visibility = View.GONE
- if (mList.size == i) { //最后的条目
- viewHolder.mTvBookName.text = ""
- viewHolder.mTvBookAuthor.text = ""
- viewHolder.mIvBook.setImageResource(R.drawable.ic_book_add)
- viewHolder.mIvGeng.visibility = View.GONE
- viewHolder.itemView.setOnClickListener { view ->
- mClickListener!!.onItemClick(
- view,
- i
- )
- }
- } else {
- viewHolder.mTvBookName.text = mList[i].title
- viewHolder.mTvBookAuthor.text = mList[i].author
- if (mList[i].isUpdate) {
- viewHolder.mIvGeng.visibility = View.VISIBLE
- } else {
- viewHolder.mIvGeng.visibility = View.GONE
- }
- GlideImageLoader.displayCornerImage(
- mContext,
- mList[i].cover,
- viewHolder.mIvBook
- )
- viewHolder.itemView.setOnClickListener {
- val intent = Intent(mContext, NovelReadActivity::class.java)
- intent.putExtra(NovelReadActivity.EXTRA_IS_COLLECTED, true)
- intent.putExtra(NovelReadActivity.EXTRA_COLL_BOOK, mList[i])
- mContext.startActivity(intent)
- }
- }
- }
- } else if (viewHolder is EmptyHolder) { //空条目
- viewHolder.mBtnAdd.setOnClickListener { view -> mClickListener!!.onItemClick(view, i) }
- }
- }
-
- override fun getItemCount(): Int {
- if (mList.isEmpty()) {
- return 1
- }
- return if (mEdit) {
- mList.size
- } else {
- mList.size + 1
- }
- }
-
- override fun getItemViewType(position: Int): Int {
- return if (mList.isEmpty()) {
- EMPTY_ITEM
- } else {
- VALUE_ITEM
- }
-
- }
-
- internal class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
- var mIvBook: ImageView = itemView.findViewById(R.id.iv_book)
- var mTvBookName: TextView = itemView.findViewById(R.id.tv_book_name)
- var mTvBookAuthor: TextView = itemView.findViewById(R.id.tv_book_author)
- var mIvCheck: ImageView = itemView.findViewById(R.id.iv_check)
- var mIvGeng: ImageView = itemView.findViewById(R.id.iv_geng)
-
- }
-
- internal class EmptyHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
- var mBtnAdd: Button = itemView.findViewById(R.id.btn_add)
-
- }
-
- fun setOnItemClickListener(mListener: OnItemClickListener) {
- this.mClickListener = mListener
- }
-
-
- interface OnItemClickListener {
- fun onItemClick(view: View, pos: Int)
- }
-
- fun setEdit(edit: Boolean) { //开启编辑模式
- mEdit = edit
- notifyDataSetChanged()
- }
-
-
- companion object {
-
- private const val VALUE_ITEM = 100 //正常item
-
- private const val EMPTY_ITEM = 101 //空白item
-
- }
-
-}
diff --git a/app/src/main/java/com/novel/read/adapter/BookListAdapter.kt b/app/src/main/java/com/novel/read/adapter/BookListAdapter.kt
deleted file mode 100644
index 5c0ec4f..0000000
--- a/app/src/main/java/com/novel/read/adapter/BookListAdapter.kt
+++ /dev/null
@@ -1,126 +0,0 @@
-package com.novel.read.adapter
-
-import android.content.Context
-import android.content.Intent
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
-import android.widget.ImageView
-import android.widget.TextView
-import androidx.recyclerview.widget.LinearLayoutManager
-import androidx.recyclerview.widget.RecyclerView
-import com.novel.read.R
-import com.novel.read.activity.NovelBookDetailActivity
-import com.novel.read.adapter.holder.EmptyHolder
-import com.novel.read.adapter.holder.MoreHolder
-import com.novel.read.constants.Constant
-import com.novel.read.constants.Constant.COMMENT_SIZE
-import com.novel.read.inter.OnLoadMoreListener
-import com.novel.read.model.protocol.SearchResp
-import com.novel.read.utlis.GlideImageLoader
-
-class BookListAdapter(private val mList: List, recyclerView: RecyclerView) : RecyclerView.Adapter() {
- private var mContext: Context? = null
-
- var isLoadingMore: Boolean = false
- private var lastVisibleItem: Int = 0
- private var totalItemCount: Int = 0
- private val visibleThreshold = 1
- private var mOnLoadMoreListener: OnLoadMoreListener? = null
-
- init {
- if (recyclerView.layoutManager is LinearLayoutManager) {
- val manager = recyclerView.layoutManager as LinearLayoutManager?
- recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
- override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
- super.onScrolled(recyclerView, dx, dy)
- totalItemCount = manager!!.itemCount
- lastVisibleItem = manager.findLastVisibleItemPosition()
- if (!isLoadingMore && totalItemCount == lastVisibleItem + visibleThreshold && totalItemCount >= COMMENT_SIZE) {
- if (mOnLoadMoreListener != null) {
- mOnLoadMoreListener!!.onLoadMore()
- }
- }
- }
- })
-
- }
- }
-
- fun setOnLoadMoreListener(listener: OnLoadMoreListener) {
- this.mOnLoadMoreListener = listener
- }
-
- override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
- if (mContext == null) {
- mContext = viewGroup.context
- }
- val view: View
- return when (viewType) {
- VALUE_ITEM -> {
- view = LayoutInflater.from(mContext).inflate(R.layout.rlv_item_book_list, viewGroup, false)
- ViewHolder(view)
- }
- EMPTY_ITEM -> {
- view = LayoutInflater.from(mContext).inflate(R.layout.rlv_empty_view, viewGroup, false)
- EmptyHolder(view)
- }
- PROCESS_ITEM -> {
- view = LayoutInflater.from(mContext).inflate(R.layout.load_more_layout, viewGroup, false)
- MoreHolder(view)
- }
- else -> throw IllegalArgumentException()
- }
- }
-
- override fun onBindViewHolder(viewHolder: RecyclerView.ViewHolder, i: Int) {
- if (viewHolder is ViewHolder) {
- val bookBean = mList[i]
- viewHolder.tvBookName.text = bookBean.title
- viewHolder.tvBookAuthor.text = bookBean.author
- viewHolder.tvBookDescription.text = bookBean.description
- GlideImageLoader.displayCornerImage(mContext!!, bookBean.cover!!, viewHolder.ivBook)
- viewHolder.itemView.setOnClickListener {
- val intent = Intent(mContext, NovelBookDetailActivity::class.java)
- intent.putExtra(Constant.Bundle.BookId, bookBean.id)
- mContext!!.startActivity(intent)
- }
- }else if (viewHolder is MoreHolder){
- viewHolder.bindModule(isLoadingMore)
- }
- }
-
- override fun getItemCount(): Int {
- return if (mList.isEmpty()) {
- 1
- } else mList.size + 1
- }
-
- override fun getItemViewType(position: Int): Int {
- if (mList.isNotEmpty() &&position == itemCount - 1) {
- return PROCESS_ITEM
- }
- return when {
- mList.isEmpty() -> EMPTY_ITEM
- else -> VALUE_ITEM
- }
-
- }
-
- internal class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
- var ivBook: ImageView = itemView.findViewById(R.id.iv_book)
- var tvBookName: TextView = itemView.findViewById(R.id.tv_book_name)
- var tvBookAuthor: TextView = itemView.findViewById(R.id.tv_book_author)
- var tvBookDescription: TextView = itemView.findViewById(R.id.tv_book_description)
- }
-
- companion object {
-
- private const val VALUE_ITEM = 100 //正常item
-
- private const val EMPTY_ITEM = 101 //空白item
-
- private const val PROCESS_ITEM = 102
- }
-
-}
diff --git a/app/src/main/java/com/novel/read/adapter/CategoryAdapter.java b/app/src/main/java/com/novel/read/adapter/CategoryAdapter.java
deleted file mode 100644
index 42f3b12..0000000
--- a/app/src/main/java/com/novel/read/adapter/CategoryAdapter.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package com.novel.read.adapter;
-
-import android.view.View;
-import android.view.ViewGroup;
-
-import com.novel.read.adapter.holder.CategoryHolder;
-import com.novel.read.widget.page.TxtChapter;
-
-public class CategoryAdapter extends EasyAdapter {
- private int currentSelected = 0;
-
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- View view = super.getView(position, convertView, parent);
- CategoryHolder holder = (CategoryHolder) view.getTag();
-
- if (position == currentSelected){
- holder.setSelectedChapter();
- }
-
- return view;
- }
-
- @Override
- protected IViewHolder onCreateViewHolder(int viewType) {
- return new CategoryHolder();
- }
-
- public void setChapter(int pos){
- currentSelected = pos;
- notifyDataSetChanged();
- }
-
-}
diff --git a/app/src/main/java/com/novel/read/adapter/EasyAdapter.java b/app/src/main/java/com/novel/read/adapter/EasyAdapter.java
deleted file mode 100644
index 36a3bb5..0000000
--- a/app/src/main/java/com/novel/read/adapter/EasyAdapter.java
+++ /dev/null
@@ -1,87 +0,0 @@
-package com.novel.read.adapter;
-
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.BaseAdapter;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-public abstract class EasyAdapter extends BaseAdapter {
-
- private List mList = new ArrayList();
-
- @Override
- public int getCount() {
- return mList.size();
- }
-
- @Override
- public T getItem(int position) {
- return mList.get(position);
- }
-
- @Override
- public long getItemId(int position) {
- return position;
- }
-
- public void addItem(T value){
- mList.add(value);
- notifyDataSetChanged();
- }
-
- public void addItem(int index,T value){
- mList.add(index, value);
- notifyDataSetChanged();
- }
-
- public void addItems(List values){
- mList.addAll(values);
- notifyDataSetChanged();
- }
-
- public void removeItem(T value){
- mList.remove(value);
- notifyDataSetChanged();
- }
-
- public List getItems(){
- return Collections.unmodifiableList(mList);
- }
-
- public int getItemSize(){
- return mList.size();
- }
-
- public void refreshItems(List list){
- mList.clear();
- mList.addAll(list);
- notifyDataSetChanged();
- }
-
- public void clear(){
- mList.clear();
- }
-
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- IViewHolder holder;
- if (convertView == null){
- holder = onCreateViewHolder(getItemViewType(position));
- convertView = holder.createItemView(parent);
- convertView.setTag(holder);
- //初始化
- holder.initView();
- }
- else {
- holder = (IViewHolder)convertView.getTag();
- }
- //执行绑定
- holder.onBind(getItem(position),position);
- return convertView;
- }
-
- protected abstract IViewHolder onCreateViewHolder(int viewType);
-}
diff --git a/app/src/main/java/com/novel/read/adapter/EditRecommendAdapter.kt b/app/src/main/java/com/novel/read/adapter/EditRecommendAdapter.kt
deleted file mode 100644
index 7b41eb9..0000000
--- a/app/src/main/java/com/novel/read/adapter/EditRecommendAdapter.kt
+++ /dev/null
@@ -1,62 +0,0 @@
-package com.novel.read.adapter
-
-import android.content.Context
-import android.content.Intent
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
-import android.widget.ImageView
-import android.widget.TextView
-import androidx.recyclerview.widget.RecyclerView
-
-import com.novel.read.R
-import com.novel.read.activity.NovelBookDetailActivity
-import com.novel.read.constants.Constant
-import com.novel.read.model.protocol.RecommendListResp
-import com.novel.read.utlis.GlideImageLoader
-
-/**
- * create by zlj on 2019/6/19
- * describe:
- */
-class EditRecommendAdapter(private val mList: List) : RecyclerView.Adapter() {
-
- private var mContext: Context? = null
-
- override fun onCreateViewHolder(viewGroup: ViewGroup, i: Int): ViewHolder {
- if (mContext == null) {
- mContext = viewGroup.context
- }
- val view = LayoutInflater.from(mContext)
- .inflate(R.layout.rlv_edit_recommend_item, viewGroup, false)
- return ViewHolder(view)
- }
-
- override fun onBindViewHolder(viewHolder: ViewHolder, i: Int) {
- val listBean = mList[i]
- viewHolder.mTvBookName.text = listBean.book_title
- viewHolder.mTvAuthor.text = listBean.author
- viewHolder.mTvDescription.text = listBean.description
- viewHolder.mTvHumanNum.text = listBean.getHot()
- viewHolder.mTvLoveNum.text = listBean.getLike()
- GlideImageLoader.displayCornerImage(mContext!!, listBean.book_cover!!, viewHolder.mIvBook)
- viewHolder.itemView.setOnClickListener {
- val intent = Intent(mContext, NovelBookDetailActivity::class.java)
- intent.putExtra(Constant.Bundle.BookId, listBean.book_id)
- mContext!!.startActivity(intent)
- }
- }
-
- override fun getItemCount(): Int {
- return mList.size
- }
-
- class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
- var mIvBook: ImageView = itemView.findViewById(R.id.iv_book)
- var mTvBookName: TextView = itemView.findViewById(R.id.tv_book_name)
- var mTvAuthor: TextView = itemView.findViewById(R.id.tv_book_author)
- var mTvDescription: TextView = itemView.findViewById(R.id.tv_book_description)
- var mTvHumanNum: TextView = itemView.findViewById(R.id.tv_human_num)
- var mTvLoveNum: TextView = itemView.findViewById(R.id.tv_love_look_num)
- }
-}
diff --git a/app/src/main/java/com/novel/read/adapter/HistoryAdapter.kt b/app/src/main/java/com/novel/read/adapter/HistoryAdapter.kt
deleted file mode 100644
index b3fb85f..0000000
--- a/app/src/main/java/com/novel/read/adapter/HistoryAdapter.kt
+++ /dev/null
@@ -1,54 +0,0 @@
-package com.novel.read.adapter
-
-import android.content.Context
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
-import android.widget.TextView
-import androidx.recyclerview.widget.RecyclerView
-
-import com.novel.read.R
-import com.novel.read.model.db.SearchListTable
-
-/**
- * create by zlj on 2019/6/17
- * describe:
- */
-class HistoryAdapter(private val mList: List) :
- RecyclerView.Adapter() {
- private var mContext: Context? = null
-
- private lateinit var mClickListener: OnItemClickListener
-
- class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
- var mTvLabel: TextView = itemView.findViewById(R.id.tv_label)
- }
-
- override fun onCreateViewHolder(viewGroup: ViewGroup, i: Int): ViewHolder {
- if (mContext == null) {
- mContext = viewGroup.context
- }
- val view = LayoutInflater.from(mContext).inflate(R.layout.item_label, viewGroup, false)
- return ViewHolder(view)
- }
-
- override fun onBindViewHolder(viewHolder: ViewHolder, i: Int) {
- viewHolder.mTvLabel.text = mList[i].key
- viewHolder.itemView.setOnClickListener { view -> mClickListener.onItemClick(view, i) }
- }
-
-
- override fun getItemCount(): Int {
- return mList.size
- }
-
-
- fun setOnItemClickListener(mListener: OnItemClickListener) {
- this.mClickListener = mListener
- }
-
-
- interface OnItemClickListener {
- fun onItemClick(view: View, pos: Int)
- }
-}
diff --git a/app/src/main/java/com/novel/read/adapter/HotAdapter.kt b/app/src/main/java/com/novel/read/adapter/HotAdapter.kt
deleted file mode 100644
index 43fe3fa..0000000
--- a/app/src/main/java/com/novel/read/adapter/HotAdapter.kt
+++ /dev/null
@@ -1,54 +0,0 @@
-package com.novel.read.adapter
-
-import android.content.Context
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
-import android.widget.TextView
-import androidx.recyclerview.widget.RecyclerView
-
-import com.novel.read.R
-import com.novel.read.constants.Constant
-
-/**
- * create by 赵利君 on 2019/6/17
- * describe:
- */
-class HotAdapter(private val mList: List) : RecyclerView.Adapter() {
- private var mContext: Context? = null
- private lateinit var mClickListener: OnItemClickListener
-
- override fun onCreateViewHolder(viewGroup: ViewGroup, i: Int): ViewHolder {
- if (mContext == null) {
- mContext = viewGroup.context
- }
- val view = LayoutInflater.from(mContext).inflate(R.layout.item_label, viewGroup, false)
- return ViewHolder(view)
- }
-
- override fun onBindViewHolder(viewHolder: ViewHolder, i: Int) {
- viewHolder.mTvLabel.text = mList[i]
- viewHolder.mTvLabel.setBackgroundColor(Constant.tagColors[i])
- viewHolder.itemView.setOnClickListener { view -> mClickListener.onItemClick(view, i) }
-
- }
-
- override fun getItemCount(): Int {
- return if (mList.size > 8) {
- 8
- } else mList.size
- }
-
- class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
- var mTvLabel: TextView = itemView.findViewById(R.id.tv_label)
- }
-
- fun setOnItemClickListener(mListener: OnItemClickListener) {
- this.mClickListener = mListener
- }
-
-
- interface OnItemClickListener {
- fun onItemClick(view: View, pos: Int)
- }
-}
diff --git a/app/src/main/java/com/novel/read/adapter/HumanAdapter.kt b/app/src/main/java/com/novel/read/adapter/HumanAdapter.kt
deleted file mode 100644
index 94a744a..0000000
--- a/app/src/main/java/com/novel/read/adapter/HumanAdapter.kt
+++ /dev/null
@@ -1,58 +0,0 @@
-package com.novel.read.adapter
-
-import android.content.Context
-import android.content.Intent
-
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
-import android.widget.ImageView
-import android.widget.TextView
-import androidx.recyclerview.widget.RecyclerView
-
-import com.novel.read.R
-import com.novel.read.activity.NovelBookDetailActivity
-import com.novel.read.constants.Constant
-import com.novel.read.dp2px
-import com.novel.read.getScreenContentWidth
-import com.novel.read.model.protocol.RecommendListResp
-import com.novel.read.utlis.GlideImageLoader
-import kotlinx.android.synthetic.main.rlv_human_item.view.*
-
-/**
- * create by zlj on 2019/6/19
- * describe:
- */
-class HumanAdapter(private val mList: List) : RecyclerView.Adapter() {
- private lateinit var mContext: Context
-
- override fun onCreateViewHolder(viewGroup: ViewGroup, i: Int): ViewHolder {
- mContext = viewGroup.context
- val view = LayoutInflater.from(mContext).inflate(R.layout.rlv_human_item, viewGroup, false)
- val ivSize = (mContext.getScreenContentWidth() - mContext.dp2px(10) * 4) / 3
- view.cl_layout.layoutParams.width = ivSize
- return ViewHolder(view)
- }
-
- override fun onBindViewHolder(viewHolder: ViewHolder, i: Int) {
- viewHolder.mTvBookName.text = mList[i].book_title
- viewHolder.mTvAuthor.text = mList[i].author
- GlideImageLoader.displayCornerImage(mContext, mList[i].book_cover!!, viewHolder.mIvBook)
- viewHolder.itemView.setOnClickListener {
- val intent = Intent(mContext, NovelBookDetailActivity::class.java)
- intent.putExtra(Constant.Bundle.BookId, mList[i].book_id)
- mContext.startActivity(intent)
- }
- }
-
- override fun getItemCount(): Int {
- return mList.size
- }
-
- class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
- var mIvBook: ImageView = itemView.findViewById(R.id.iv_book)
- var mTvBookName: TextView = itemView.findViewById(R.id.tv_book_name)
- var mTvAuthor: TextView = itemView.findViewById(R.id.tv_book_author)
-
- }
-}
diff --git a/app/src/main/java/com/novel/read/adapter/IViewHolder.kt b/app/src/main/java/com/novel/read/adapter/IViewHolder.kt
deleted file mode 100644
index b69585e..0000000
--- a/app/src/main/java/com/novel/read/adapter/IViewHolder.kt
+++ /dev/null
@@ -1,15 +0,0 @@
-package com.novel.read.adapter
-
-import android.view.View
-import android.view.ViewGroup
-
-/**
- * Created by zlj
- */
-
-interface IViewHolder {
- fun createItemView(parent: ViewGroup): View
- fun initView()
- fun onBind(data: T, pos: Int)
- fun onClick()
-}
diff --git a/app/src/main/java/com/novel/read/adapter/LoveLyAdapter.kt b/app/src/main/java/com/novel/read/adapter/LoveLyAdapter.kt
deleted file mode 100644
index 6999f79..0000000
--- a/app/src/main/java/com/novel/read/adapter/LoveLyAdapter.kt
+++ /dev/null
@@ -1,59 +0,0 @@
-package com.novel.read.adapter
-
-import android.content.Context
-import android.content.Intent
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
-import android.widget.ImageView
-import android.widget.TextView
-import androidx.recyclerview.widget.RecyclerView
-
-import com.novel.read.R
-import com.novel.read.activity.NovelBookDetailActivity
-import com.novel.read.constants.Constant
-import com.novel.read.model.protocol.RecommendBookResp
-import com.novel.read.utlis.GlideImageLoader
-
-/**
- * 猜你喜欢adapter
- */
-class LoveLyAdapter(private val mList: List) : RecyclerView.Adapter() {
-
- private var mContext: Context? = null
-
- override fun onCreateViewHolder(viewGroup: ViewGroup, i: Int): RecyclerView.ViewHolder {
- if (mContext == null) {
- mContext = viewGroup.context
- }
- val view: View = LayoutInflater.from(mContext).inflate(R.layout.rlv_item_lovely, viewGroup, false)
- return ViewHolder(view)
- }
-
- override fun onBindViewHolder(viewHolder: RecyclerView.ViewHolder, i: Int) {
- if (viewHolder is ViewHolder) {
- val bookBean = mList[i]
- GlideImageLoader.displayCornerImage(mContext!!, bookBean.cover!!, viewHolder.mIvBook)
- viewHolder.mTvBookName.text = bookBean.title
- viewHolder.mTvBookAuthor.text =
- mContext!!.getString(R.string.author_zhu, bookBean.author)
- viewHolder.mTvDescription.text = bookBean.description
- viewHolder.itemView.setOnClickListener {
- val intent = Intent(mContext, NovelBookDetailActivity::class.java)
- intent.putExtra(Constant.Bundle.BookId, bookBean.id)
- mContext!!.startActivity(intent)
- }
- }
- }
-
- override fun getItemCount(): Int {
- return mList.size
- }
-
- internal class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
- var mIvBook: ImageView = itemView.findViewById(R.id.iv_book)
- var mTvBookName: TextView = itemView.findViewById(R.id.tv_book_name)
- var mTvBookAuthor: TextView = itemView.findViewById(R.id.tv_book_author)
- var mTvDescription: TextView = itemView.findViewById(R.id.tv_book_description)
- }
-}
diff --git a/app/src/main/java/com/novel/read/adapter/MarkAdapter.kt b/app/src/main/java/com/novel/read/adapter/MarkAdapter.kt
deleted file mode 100644
index c1e176e..0000000
--- a/app/src/main/java/com/novel/read/adapter/MarkAdapter.kt
+++ /dev/null
@@ -1,71 +0,0 @@
-package com.novel.read.adapter
-
-import android.content.Context
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
-import android.widget.CheckBox
-import android.widget.CompoundButton
-import android.widget.TextView
-import androidx.recyclerview.widget.RecyclerView
-
-import com.novel.read.R
-import com.novel.read.model.db.BookSignTable
-import com.novel.read.model.protocol.MarkResp
-
-class MarkAdapter(private val mList: List) : RecyclerView.Adapter() {
-
- private var mContext: Context? = null
- var edit: Boolean = false
- set(edit) {
- field = edit
- notifyDataSetChanged()
- }
-
- val selectList: String
- get() {
- val signs = StringBuilder()
- for (i in mList.indices) {
- if (mList[i].edit) {
- if (signs.toString() == "") {
- signs.append(mList[i].articleId)
- } else {
- signs.append(",").append(mList[i].articleId)
- }
- }
- }
- return signs.toString()
- }
-
- override fun onCreateViewHolder(viewGroup: ViewGroup, i: Int): RecyclerView.ViewHolder {
- if (mContext == null) {
- mContext = viewGroup.context
- }
- val view: View = LayoutInflater.from(mContext).inflate(R.layout.rlv_item_mark, viewGroup, false)
- return ViewHolder(view)
- }
-
- override fun onBindViewHolder(viewHolder: RecyclerView.ViewHolder, i: Int) {
- if (viewHolder is ViewHolder) {
- if (this.edit) {
- viewHolder.mCheck.visibility = View.VISIBLE
- viewHolder.mCheck.setOnCheckedChangeListener { compoundButton, b ->
- mList[i].edit = b
- }
- } else {
- viewHolder.mCheck.visibility = View.GONE
- }
- viewHolder.mTvMark.text = mList[i].content
- viewHolder.mCheck.isChecked = mList[i].edit
- }
- }
-
- override fun getItemCount(): Int {
- return mList.size
- }
-
- internal class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
- var mTvMark: TextView = itemView.findViewById(R.id.tvMarkItem)
- var mCheck: CheckBox = itemView.findViewById(R.id.checkbox)
- }
-}
diff --git a/app/src/main/java/com/novel/read/adapter/PageStyleAdapter.kt b/app/src/main/java/com/novel/read/adapter/PageStyleAdapter.kt
deleted file mode 100644
index 7c63254..0000000
--- a/app/src/main/java/com/novel/read/adapter/PageStyleAdapter.kt
+++ /dev/null
@@ -1,54 +0,0 @@
-package com.novel.read.adapter
-
-import android.content.Context
-import android.graphics.drawable.Drawable
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
-import android.widget.ImageView
-import androidx.recyclerview.widget.RecyclerView
-import com.mango.mangolib.event.EventManager
-import com.novel.read.R
-import com.novel.read.widget.page.PageLoader
-import com.novel.read.widget.page.PageStyle
-
-class PageStyleAdapter(val mList: List, private val mPageLoader: PageLoader) :
- RecyclerView.Adapter() {
- private var mContext: Context? = null
- private var currentChecked: Int = 0
-
- override fun onCreateViewHolder(viewGroup: ViewGroup, i: Int): PageHolder {
- if (mContext == null) {
- mContext = viewGroup.context
- }
- val view = LayoutInflater.from(mContext).inflate(R.layout.item_read_bg, viewGroup, false)
- return PageHolder(view)
- }
-
- override fun onBindViewHolder(pageHolder: PageHolder, i: Int) {
- pageHolder.mReadBg.background = mList[i]
- pageHolder.mIvChecked.visibility = View.GONE
- if (currentChecked == i) {
- pageHolder.mIvChecked.visibility = View.VISIBLE
- }
- pageHolder.itemView.setOnClickListener {
- currentChecked = i
- notifyDataSetChanged()
- mPageLoader.setPageStyle(PageStyle.values()[i])
- }
- }
-
- fun setPageStyleChecked(pageStyle: PageStyle) {
- currentChecked = pageStyle.ordinal
- }
-
- override fun getItemCount(): Int {
- return mList.size
- }
-
- class PageHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
- val mReadBg: View = itemView.findViewById(R.id.read_bg_view)
- val mIvChecked: ImageView = itemView.findViewById(R.id.read_bg_iv_checked)
-
- }
-}
diff --git a/app/src/main/java/com/novel/read/adapter/RankAdapter.kt b/app/src/main/java/com/novel/read/adapter/RankAdapter.kt
deleted file mode 100644
index 17dd482..0000000
--- a/app/src/main/java/com/novel/read/adapter/RankAdapter.kt
+++ /dev/null
@@ -1,59 +0,0 @@
-package com.novel.read.adapter
-
-import android.content.Context
-import android.content.Intent
-
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
-import android.widget.ImageView
-import android.widget.TextView
-import androidx.recyclerview.widget.RecyclerView
-
-import com.novel.read.R
-import com.novel.read.activity.NovelBookDetailActivity
-import com.novel.read.constants.Constant
-import com.novel.read.dp2px
-import com.novel.read.getScreenContentWidth
-import com.novel.read.model.protocol.RecommendListResp
-import com.novel.read.utlis.GlideImageLoader
-import kotlinx.android.synthetic.main.rlv_human_item.view.*
-
-/**
- * create by zlj on 2019/6/20
- * describe:
- */
-class RankAdapter(private val mList: List) :
- RecyclerView.Adapter() {
- private lateinit var mContext: Context
-
- override fun onCreateViewHolder(viewGroup: ViewGroup, i: Int): ViewHolder {
- mContext = viewGroup.context
- val view = LayoutInflater.from(mContext).inflate(R.layout.rlv_human_item, viewGroup, false)
- val ivSize = (mContext.getScreenContentWidth() - mContext.dp2px(10) * 4) / 3
- view.cl_layout.layoutParams.width = ivSize
- return ViewHolder(view)
- }
-
- override fun onBindViewHolder(viewHolder: ViewHolder, i: Int) {
- viewHolder.mTvBookName.text = mList[i].book_title
- viewHolder.mTvAuthor.text = mList[i].author
- GlideImageLoader.displayCornerImage(mContext, mList[i].book_cover!!, viewHolder.mIvBook)
- viewHolder.itemView.setOnClickListener {
- val intent = Intent(mContext, NovelBookDetailActivity::class.java)
- intent.putExtra(Constant.Bundle.BookId, mList[i].book_id)
- mContext.startActivity(intent)
- }
- }
-
- override fun getItemCount(): Int {
- return mList.size
- }
-
- class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
- var mIvBook: ImageView = itemView.findViewById(R.id.iv_book)
- var mTvBookName: TextView = itemView.findViewById(R.id.tv_book_name)
- var mTvAuthor: TextView = itemView.findViewById(R.id.tv_book_author)
-
- }
-}
diff --git a/app/src/main/java/com/novel/read/adapter/RankListAdapter.kt b/app/src/main/java/com/novel/read/adapter/RankListAdapter.kt
deleted file mode 100644
index eddf490..0000000
--- a/app/src/main/java/com/novel/read/adapter/RankListAdapter.kt
+++ /dev/null
@@ -1,125 +0,0 @@
-package com.novel.read.adapter
-
-import android.content.Context
-import android.content.Intent
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
-import android.widget.ImageView
-import android.widget.TextView
-import androidx.recyclerview.widget.LinearLayoutManager
-import androidx.recyclerview.widget.RecyclerView
-
-import com.novel.read.R
-import com.novel.read.activity.NovelBookDetailActivity
-import com.novel.read.adapter.holder.EmptyHolder
-import com.novel.read.adapter.holder.MoreHolder
-import com.novel.read.constants.Constant
-import com.novel.read.inter.OnLoadMoreListener
-import com.novel.read.model.protocol.RankByUpdateResp
-import com.novel.read.utlis.GlideImageLoader
-import com.novel.read.constants.Constant.COMMENT_SIZE
-
-class RankListAdapter( val mList: List, recyclerView: RecyclerView) : RecyclerView.Adapter() {
-
- private lateinit var mContext: Context
- var isLoadingMore: Boolean = false
- private var lastVisibleItem: Int = 0
- private var totalItemCount: Int = 0
- private val visibleThreshold = 1
- private var mOnLoadMoreListener: OnLoadMoreListener? = null
-
- init {
- if (recyclerView.layoutManager is LinearLayoutManager) {
- val manager = recyclerView.layoutManager as LinearLayoutManager?
- recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
- override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
- super.onScrolled(recyclerView, dx, dy)
- totalItemCount = manager!!.itemCount
- lastVisibleItem = manager.findLastVisibleItemPosition()
- if (!isLoadingMore && totalItemCount == lastVisibleItem + visibleThreshold && totalItemCount >= COMMENT_SIZE) {
- if (mOnLoadMoreListener != null) {
- mOnLoadMoreListener!!.onLoadMore()
- }
- }
- }
- })
- }
- }
-
- fun setOnLoadMoreListener(listener: OnLoadMoreListener) {
- this.mOnLoadMoreListener = listener
- }
-
- override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
- mContext = viewGroup.context
-
- val view: View
- when (viewType) {
- VALUE_ITEM -> {
- view = LayoutInflater.from(mContext).inflate(R.layout.rlv_item_book_list, viewGroup, false)
- return ViewHolder(view)
- }
- EMPTY_ITEM -> {
- view = LayoutInflater.from(mContext).inflate(R.layout.rlv_empty_view, viewGroup, false)
- return EmptyHolder(view)
- }
- PROCESS_ITEM -> {
- view = LayoutInflater.from(mContext).inflate(R.layout.load_more_layout, viewGroup, false)
- return MoreHolder(view)
- }
- }
- throw IllegalArgumentException()
- }
-
- override fun onBindViewHolder(viewHolder: RecyclerView.ViewHolder, i: Int) {
- if (viewHolder is ViewHolder) {
- val bookBean = mList[i]
- viewHolder.tvBookName.text = bookBean.title
- viewHolder.tvBookAuthor.text = bookBean.author
- viewHolder.tvBookDescription.text = bookBean.description
- GlideImageLoader.displayCornerImage(mContext, bookBean.cover, viewHolder.ivBook)
- viewHolder.itemView.setOnClickListener {
- val intent = Intent(mContext, NovelBookDetailActivity::class.java)
- intent.putExtra(Constant.Bundle.BookId, bookBean.id)
- mContext.startActivity(intent)
- }
- }else if (viewHolder is MoreHolder){
- viewHolder.bindModule(isLoadingMore)
- }
- }
-
- override fun getItemCount(): Int {
- return if (mList.isEmpty()) {
- 1
- } else mList.size + 1
- }
-
- override fun getItemViewType(position: Int): Int {
- if (mList.isNotEmpty() && position == itemCount - 1) {
- return PROCESS_ITEM
- }
- return when {
- mList.isEmpty() -> EMPTY_ITEM
- else -> VALUE_ITEM
- }
- }
-
- internal class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
- var ivBook: ImageView = itemView.findViewById(R.id.iv_book)
- var tvBookName: TextView = itemView.findViewById(R.id.tv_book_name)
- var tvBookAuthor: TextView = itemView.findViewById(R.id.tv_book_author)
- var tvBookDescription: TextView = itemView.findViewById(R.id.tv_book_description)
-
- }
-
- companion object {
-
- private const val VALUE_ITEM = 100 //正常item
-
- private const val EMPTY_ITEM = 101 //空白item
-
- private const val PROCESS_ITEM = 102
- }
-
-}
diff --git a/app/src/main/java/com/novel/read/adapter/SearchAdapter.kt b/app/src/main/java/com/novel/read/adapter/SearchAdapter.kt
deleted file mode 100644
index 3802822..0000000
--- a/app/src/main/java/com/novel/read/adapter/SearchAdapter.kt
+++ /dev/null
@@ -1,173 +0,0 @@
-package com.novel.read.adapter
-
-import android.content.Context
-import android.content.Intent
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
-import android.widget.ImageView
-import android.widget.TextView
-import androidx.recyclerview.widget.LinearLayoutManager
-import androidx.recyclerview.widget.RecyclerView
-import com.novel.read.R
-import com.novel.read.activity.NovelBookDetailActivity
-import com.novel.read.adapter.holder.EmptyHolder
-import com.novel.read.adapter.holder.MoreHolder
-import com.novel.read.constants.Constant
-import com.novel.read.constants.Constant.COMMENT_SIZE
-import com.novel.read.inter.OnLoadMoreListener
-import com.novel.read.model.protocol.SearchResp
-import com.novel.read.utlis.GlideImageLoader
-
-class SearchAdapter(private val mList: List, recyclerView: RecyclerView) :
- RecyclerView.Adapter() {
-
- private var mContext: Context? = null
-
- private var book = false
- private var mClickListener: OnItemClickListener? = null
-
- var isLoadingMore: Boolean = false
- private var lastVisibleItem: Int = 0
- private var totalItemCount: Int = 0
- private val visibleThreshold = 1
- private var mOnLoadMoreListener: OnLoadMoreListener? = null
-
- init {
- if (recyclerView.layoutManager is LinearLayoutManager) {
- val manager = recyclerView.layoutManager as LinearLayoutManager?
- recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
- override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
- super.onScrolled(recyclerView, dx, dy)
- totalItemCount = manager!!.itemCount
- lastVisibleItem = manager.findLastVisibleItemPosition()
- if (!isLoadingMore && totalItemCount == lastVisibleItem + visibleThreshold && totalItemCount >= COMMENT_SIZE) {
- if (mOnLoadMoreListener != null) {
- mOnLoadMoreListener!!.onLoadMore()
- }
- }
- }
- })
-
- }
- }
-
- fun setOnLoadMoreListener(listener: OnLoadMoreListener) {
- this.mOnLoadMoreListener = listener
- }
-
- override fun onCreateViewHolder(viewGroup: ViewGroup, i: Int): RecyclerView.ViewHolder {
- if (mContext == null) {
- mContext = viewGroup.context
- }
- val view: View
- when (i) {
- VALUE_ITEM -> {
- view = LayoutInflater.from(mContext)
- .inflate(R.layout.rlv_item_search, viewGroup, false)
- return ViewHolder(view)
- }
- BOOK_ITEM -> {
- view = LayoutInflater.from(mContext)
- .inflate(R.layout.rlv_item_book_list_search, viewGroup, false)
- return BookHolder(view)
- }
- EMPTY_ITEM -> {
- view =
- LayoutInflater.from(mContext).inflate(R.layout.rlv_empty_view, viewGroup, false)
- return EmptyHolder(view)
- }
- PROCESS_ITEM -> {
- view = LayoutInflater.from(mContext)
- .inflate(R.layout.load_more_layout, viewGroup, false)
- return MoreHolder(view)
- }
- else -> throw IllegalArgumentException()
- }
- }
-
- override fun onBindViewHolder(viewHolder: RecyclerView.ViewHolder, i: Int) {
- when (viewHolder) {
- is ViewHolder -> {
- val bookBean = mList[i]
- viewHolder.mTvBookName.text = bookBean.title
- viewHolder.itemView.setOnClickListener { view ->
- mClickListener!!.onItemClick(view, i)
- }
- }
- is BookHolder -> {
- val bookBean = mList[i]
- viewHolder.tvBookName.text = bookBean.title
- viewHolder.tvBookAuthor.text = bookBean.author
- viewHolder.tvBookDescription.text = bookBean.description
- GlideImageLoader.displayCornerImage(mContext!!, bookBean.cover!!, viewHolder.ivBook)
- viewHolder.itemView.setOnClickListener { view ->
- val intent = Intent(mContext, NovelBookDetailActivity::class.java)
- intent.putExtra(Constant.Bundle.BookId, bookBean.id)
- mContext!!.startActivity(intent)
- }
- }
- is MoreHolder -> viewHolder.bindModule(isLoadingMore)
- }
- }
-
- override fun getItemCount(): Int {
- return if (mList.isEmpty()) {
- 1
- } else mList.size + 1
- }
-
- override fun getItemViewType(position: Int): Int {
- if (mList.isNotEmpty() && position == itemCount - 1) {
- return PROCESS_ITEM
- }
-
- return if (mList.isEmpty()) {
- EMPTY_ITEM
- } else {
- if (book) {
- BOOK_ITEM
- } else {
- VALUE_ITEM
- }
- }
- }
-
- fun setHolderType(book: Boolean) {
- this.book = book
- notifyDataSetChanged()
- }
-
- internal class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
- var mTvBookName: TextView = itemView.findViewById(R.id.tv_book_name)
-
- }
-
- internal class BookHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
- var ivBook: ImageView = itemView.findViewById(R.id.iv_book)
- var tvBookName: TextView = itemView.findViewById(R.id.tv_book_name)
- var tvBookAuthor: TextView = itemView.findViewById(R.id.tv_book_author)
- var tvBookDescription: TextView = itemView.findViewById(R.id.tv_book_description)
-
- }
-
- fun setOnItemClickListener(mListener: OnItemClickListener) {
- this.mClickListener = mListener
- }
-
- interface OnItemClickListener {
- fun onItemClick(view: View, pos: Int)
- }
-
- companion object {
-
- private const val VALUE_ITEM = 100 //正常item
-
- private const val EMPTY_ITEM = 101 //空白item
-
- private const val BOOK_ITEM = 102 //书本item
-
- private const val PROCESS_ITEM = 103
- }
-
-}
diff --git a/app/src/main/java/com/novel/read/adapter/StackAdapter.kt b/app/src/main/java/com/novel/read/adapter/StackAdapter.kt
deleted file mode 100644
index a729319..0000000
--- a/app/src/main/java/com/novel/read/adapter/StackAdapter.kt
+++ /dev/null
@@ -1,61 +0,0 @@
-package com.novel.read.adapter
-
-import android.content.Context
-import android.content.Intent
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
-import android.widget.ImageView
-import android.widget.TextView
-import androidx.recyclerview.widget.RecyclerView
-
-import com.novel.read.R
-import com.novel.read.activity.NovelBookTypeListActivity
-import com.novel.read.constants.Constant
-import com.novel.read.model.protocol.CategoryTypeResp
-import com.novel.read.utlis.GlideImageLoader
-
-class StackAdapter(private val mList: List) : RecyclerView.Adapter() {
-
- private var mContext: Context? = null
-
- override fun onCreateViewHolder(viewGroup: ViewGroup, i: Int): RecyclerView.ViewHolder {
- if (mContext == null) {
- mContext = viewGroup.context
- }
- val view: View = LayoutInflater.from(mContext).inflate(R.layout.rlv_item_book_type, viewGroup, false)
- return ViewHolder(view)
- }
-
- override fun onBindViewHolder(viewHolder: RecyclerView.ViewHolder, i: Int) {
- if (viewHolder is ViewHolder) {
-
- var input = mList[i].title
- val regex = "(.{2})"
- input = input.replace(regex.toRegex(), "$1\n")
- viewHolder.mTvType.text = input
- viewHolder.itemView.setOnClickListener { view ->
- val intent = Intent(mContext, NovelBookTypeListActivity::class.java)
- intent.putExtra(Constant.Bundle.CategoryId, mList[i].id.toString())
- intent.putExtra(Constant.Bundle.mTitle, mList[i].title)
- mContext!!.startActivity(intent)
- }
- GlideImageLoader.displayCornerImage(
- mContext!!,
- mList[i].cover,
- viewHolder.mIvType,
- R.drawable.ic_type_default
- )
- }
- }
-
- override fun getItemCount(): Int {
- return mList.size
- }
-
- internal class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
- var mIvType: ImageView = itemView.findViewById(R.id.iv_book)
- var mTvType: TextView = itemView.findViewById(R.id.tv_book_name)
-
- }
-}
diff --git a/app/src/main/java/com/novel/read/adapter/ViewHolderImpl.java b/app/src/main/java/com/novel/read/adapter/ViewHolderImpl.java
deleted file mode 100644
index 5ba4f86..0000000
--- a/app/src/main/java/com/novel/read/adapter/ViewHolderImpl.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package com.novel.read.adapter;
-
-import android.content.Context;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-
-import org.jetbrains.annotations.NotNull;
-
-public abstract class ViewHolderImpl implements IViewHolder {
- private View view;
- private Context context;
-
- protected abstract int getItemLayoutId();
-
- @NotNull
- @Override
- public View createItemView(ViewGroup parent) {
- view = LayoutInflater.from(parent.getContext())
- .inflate(getItemLayoutId(), parent, false);
- context = parent.getContext();
- return view;
- }
-
- protected V findById(int id){
- return (V) view.findViewById(id);
- }
-
- protected Context getContext(){
- return context;
- }
-
- protected View getItemView(){
- return view;
- }
-
- @Override
- public void onClick() {
- }
-}
diff --git a/app/src/main/java/com/novel/read/adapter/ViewPageAdapter.kt b/app/src/main/java/com/novel/read/adapter/ViewPageAdapter.kt
deleted file mode 100644
index dd4d2f7..0000000
--- a/app/src/main/java/com/novel/read/adapter/ViewPageAdapter.kt
+++ /dev/null
@@ -1,22 +0,0 @@
-package com.novel.read.adapter
-
-import androidx.fragment.app.Fragment
-import androidx.fragment.app.FragmentManager
-import androidx.fragment.app.FragmentPagerAdapter
-
-/**
- * Created by Administrator on 2017/2/24.
- */
-
-class ViewPageAdapter(fm: FragmentManager, private val fragmentList: List) :
- FragmentPagerAdapter(fm) {
-
- override fun getItem(position: Int): Fragment {
- return fragmentList[position]
- }
-
- override fun getCount(): Int {
- return fragmentList.size
- }
-
-}
diff --git a/app/src/main/java/com/novel/read/adapter/holder/CategoryHolder.java b/app/src/main/java/com/novel/read/adapter/holder/CategoryHolder.java
deleted file mode 100644
index 5dce728..0000000
--- a/app/src/main/java/com/novel/read/adapter/holder/CategoryHolder.java
+++ /dev/null
@@ -1,50 +0,0 @@
-package com.novel.read.adapter.holder;
-
-import android.graphics.drawable.Drawable;
-import android.widget.TextView;
-
-import androidx.core.content.ContextCompat;
-
-import com.novel.read.R;
-import com.novel.read.adapter.ViewHolderImpl;
-import com.novel.read.model.db.dbManage.BookManager;
-import com.novel.read.utlis.StringUtils;
-import com.novel.read.widget.page.TxtChapter;
-
-public class CategoryHolder extends ViewHolderImpl {
-
- private TextView mTvChapter;
-
- @Override
- public void initView() {
- mTvChapter = findById(R.id.category_tv_chapter);
- }
-
- @Override
- public void onBind(TxtChapter value, int pos){
- //首先判断是否该章已下载
- Drawable drawable = null;
- if (value.getBookId() != null && BookManager.isChapterCached(value.getBookId(),value.getTitle())){
- drawable = ContextCompat.getDrawable(getContext(),R.drawable.selector_category_load);
- }
- else {
- drawable = ContextCompat.getDrawable(getContext(), R.drawable.selector_category_unload);
- }
-
- mTvChapter.setSelected(false);
- mTvChapter.setTextColor(ContextCompat.getColor(getContext(),R.color.colorTitle));
- mTvChapter.setCompoundDrawablesWithIntrinsicBounds(drawable,null,null,null);
- mTvChapter.setText(StringUtils.INSTANCE.convertCC(value.getTitle()));
-
- }
-
- @Override
- protected int getItemLayoutId() {
- return R.layout.rlv_item_category;
- }
-
- public void setSelectedChapter(){
- mTvChapter.setTextColor(ContextCompat.getColor(getContext(),R.color.light_red));
- mTvChapter.setSelected(true);
- }
-}
diff --git a/app/src/main/java/com/novel/read/adapter/holder/EmptyHolder.kt b/app/src/main/java/com/novel/read/adapter/holder/EmptyHolder.kt
deleted file mode 100644
index 20736cf..0000000
--- a/app/src/main/java/com/novel/read/adapter/holder/EmptyHolder.kt
+++ /dev/null
@@ -1,6 +0,0 @@
-package com.novel.read.adapter.holder
-
-import android.view.View
-import androidx.recyclerview.widget.RecyclerView
-
-class EmptyHolder(itemView: View) : RecyclerView.ViewHolder(itemView)
diff --git a/app/src/main/java/com/novel/read/adapter/holder/MoreHolder.kt b/app/src/main/java/com/novel/read/adapter/holder/MoreHolder.kt
deleted file mode 100644
index 2e171be..0000000
--- a/app/src/main/java/com/novel/read/adapter/holder/MoreHolder.kt
+++ /dev/null
@@ -1,34 +0,0 @@
-package com.novel.read.adapter.holder
-
-import android.view.View
-import android.widget.ProgressBar
-import android.widget.TextView
-
-import androidx.recyclerview.widget.RecyclerView
-
-import com.novel.read.R
-
-/**
- * @author: LiJun 390057892@qq.com
- * @date: 2018/4/4 9:28
- */
-
-class MoreHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
-
- private val mProgressBar: ProgressBar = itemView.findViewById(R.id.progressBar)
- private val mTvName: TextView = itemView.findViewById(R.id.tv_name)
- private val mTvEnd: TextView = itemView.findViewById(R.id.tv_end)
-
- fun bindModule(loadMore: Boolean) {
- if (loadMore) {
- mTvName.visibility = View.VISIBLE
- mProgressBar.visibility = View.VISIBLE
- mTvEnd.visibility = View.GONE
- } else {
- mTvName.visibility = View.GONE
- mProgressBar.visibility = View.GONE
- mTvEnd.visibility = View.VISIBLE
- }
- }
-
-}
diff --git a/app/src/main/java/com/novel/read/base/BaseActivity.kt b/app/src/main/java/com/novel/read/base/BaseActivity.kt
new file mode 100644
index 0000000..557a224
--- /dev/null
+++ b/app/src/main/java/com/novel/read/base/BaseActivity.kt
@@ -0,0 +1,174 @@
+package com.novel.read.base
+
+import android.content.Context
+import android.content.res.Configuration
+import android.os.Bundle
+import android.util.AttributeSet
+import android.view.Menu
+import android.view.MenuItem
+import android.view.View
+import android.view.WindowManager
+import android.widget.FrameLayout
+import androidx.appcompat.app.AppCompatActivity
+import com.novel.read.R
+import com.novel.read.constant.AppConst
+import com.novel.read.constant.Theme
+import com.novel.read.lib.*
+import com.novel.read.ui.widget.TitleBar
+import com.novel.read.utils.ColorUtils
+import com.novel.read.utils.LanguageUtils
+import com.novel.read.utils.ext.disableAutoFill
+import com.novel.read.utils.ext.*
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.MainScope
+import kotlinx.coroutines.cancel
+
+abstract class BaseActivity(
+ private val layoutID: Int,
+ val fullScreen: Boolean = true,
+ private val theme: Theme = Theme.Auto,
+ private val toolBarTheme: Theme = Theme.Auto,
+ private val transparent: Boolean = false
+) : AppCompatActivity(),
+ CoroutineScope by MainScope() {
+
+ val isInMultiWindow: Boolean
+ get() {
+ return if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
+ isInMultiWindowMode
+ } else {
+ false
+ }
+ }
+
+ override fun attachBaseContext(newBase: Context) {
+ super.attachBaseContext(LanguageUtils.setConfiguration(newBase))
+ }
+
+ override fun onCreateView(
+ parent: View?,
+ name: String,
+ context: Context,
+ attrs: AttributeSet
+ ): View? {
+ if (AppConst.menuViewNames.contains(name) && parent?.parent is FrameLayout) {
+ (parent.parent as View).setBackgroundColor(backgroundColor)
+ }
+ return super.onCreateView(parent, name, context, attrs)
+ }
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ window.decorView.disableAutoFill()
+ initTheme()
+ setupSystemBar()
+ super.onCreate(savedInstanceState)
+ setContentView(layoutID)
+ if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
+ findViewById(R.id.title_bar)
+ ?.onMultiWindowModeChanged(isInMultiWindowMode, fullScreen)
+ }
+ onActivityCreated(savedInstanceState)
+ observeLiveBus()
+ }
+
+ override fun onMultiWindowModeChanged(isInMultiWindowMode: Boolean, newConfig: Configuration?) {
+ super.onMultiWindowModeChanged(isInMultiWindowMode, newConfig)
+ findViewById(R.id.title_bar)
+ ?.onMultiWindowModeChanged(isInMultiWindowMode, fullScreen)
+ setupSystemBar()
+ }
+
+ override fun onConfigurationChanged(newConfig: Configuration) {
+ super.onConfigurationChanged(newConfig)
+ findViewById(R.id.title_bar)
+ ?.onMultiWindowModeChanged(isInMultiWindow, fullScreen)
+ setupSystemBar()
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ cancel()
+ }
+
+ abstract fun onActivityCreated(savedInstanceState: Bundle?)
+
+ final override fun onCreateOptionsMenu(menu: Menu?): Boolean {
+ return menu?.let {
+ val bool = onCompatCreateOptionsMenu(it)
+ it.applyTint(this, toolBarTheme)
+ bool
+ } ?: super.onCreateOptionsMenu(menu)
+ }
+
+ override fun onMenuOpened(featureId: Int, menu: Menu): Boolean {
+ menu.applyOpenTint(this)
+ return super.onMenuOpened(featureId, menu)
+ }
+
+ open fun onCompatCreateOptionsMenu(menu: Menu) = super.onCreateOptionsMenu(menu)
+
+ final override fun onOptionsItemSelected(item: MenuItem): Boolean {
+ item.let {
+ if (it.itemId == android.R.id.home) {
+ supportFinishAfterTransition()
+ return true
+ }
+ }
+ return onCompatOptionsItemSelected(item)
+ }
+
+ open fun onCompatOptionsItemSelected(item: MenuItem) = super.onOptionsItemSelected(item)
+
+ private fun initTheme() {
+ when (theme) {
+ Theme.Transparent -> setTheme(R.style.AppTheme_Transparent)
+ Theme.Dark -> {
+ setTheme(R.style.AppTheme_Dark)
+ ATH.applyBackgroundTint(window.decorView)
+ }
+ Theme.Light -> {
+ setTheme(R.style.AppTheme_Light)
+ ATH.applyBackgroundTint(window.decorView)
+ }
+ else -> {
+ if (ColorUtils.isColorLight(primaryColor)) {
+ setTheme(R.style.AppTheme_Light)
+ } else {
+ setTheme(R.style.AppTheme_Dark)
+ }
+ ATH.applyBackgroundTint(window.decorView)
+ }
+ }
+ }
+
+ private fun setupSystemBar() {
+ if (fullScreen && !isInMultiWindow) {
+ window.clearFlags(
+ WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS
+ or WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION
+ )
+ window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
+ window.decorView.systemUiVisibility =
+ View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LAYOUT_STABLE
+ }
+ ATH.setStatusBarColorAuto(this, fullScreen)
+ if (toolBarTheme == Theme.Dark) {
+ ATH.setLightStatusBar(window, false)
+ } else if (toolBarTheme == Theme.Light) {
+ ATH.setLightStatusBar(window, true)
+ }
+ upNavigationBarColor()
+ }
+
+ open fun upNavigationBarColor() {
+ ATH.setNavigationBarColorAuto(this)
+ }
+
+ open fun observeLiveBus() {
+ }
+
+ override fun finish() {
+ currentFocus?.hideSoftInput()
+ super.finish()
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/novel/read/base/BaseDialogFragment.kt b/app/src/main/java/com/novel/read/base/BaseDialogFragment.kt
new file mode 100644
index 0000000..8cdb006
--- /dev/null
+++ b/app/src/main/java/com/novel/read/base/BaseDialogFragment.kt
@@ -0,0 +1,58 @@
+package com.novel.read.base
+
+import android.os.Bundle
+import android.view.View
+import androidx.fragment.app.DialogFragment
+import androidx.fragment.app.FragmentManager
+import com.novel.read.lib.ThemeStore
+import com.novel.read.help.coroutine.Coroutine
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.Job
+import kotlin.coroutines.CoroutineContext
+
+
+abstract class BaseDialogFragment : DialogFragment(), CoroutineScope {
+ override val coroutineContext: CoroutineContext
+ get() = job + Dispatchers.Main
+ private lateinit var job: Job
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ job = Job()
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+ view.setBackgroundColor(ThemeStore.backgroundColor())
+ onFragmentCreated(view, savedInstanceState)
+ observeLiveBus()
+ }
+
+ abstract fun onFragmentCreated(view: View, savedInstanceState: Bundle?)
+
+ override fun show(manager: FragmentManager, tag: String?) {
+ try {
+ //在每个add事务前增加一个remove事务,防止连续的add
+ manager.beginTransaction().remove(this).commit()
+ super.show(manager, tag)
+ } catch (e: Exception) {
+ //同一实例使用不同的tag会异常,这里捕获一下
+ e.printStackTrace()
+ }
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ job.cancel()
+ }
+
+ fun execute(
+ scope: CoroutineScope = this,
+ context: CoroutineContext = Dispatchers.IO,
+ block: suspend CoroutineScope.() -> T
+ ) = Coroutine.async(scope, context) { block() }
+
+ open fun observeLiveBus() {
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/novel/read/base/BaseFragment.kt b/app/src/main/java/com/novel/read/base/BaseFragment.kt
new file mode 100644
index 0000000..feaacf5
--- /dev/null
+++ b/app/src/main/java/com/novel/read/base/BaseFragment.kt
@@ -0,0 +1,96 @@
+package com.novel.read.base
+
+import android.annotation.SuppressLint
+import android.content.res.Configuration
+import android.os.Bundle
+import android.view.*
+import androidx.appcompat.view.SupportMenuInflater
+import androidx.appcompat.widget.Toolbar
+import androidx.fragment.app.Fragment
+import com.novel.read.R
+import com.novel.read.ui.widget.TitleBar
+import com.novel.read.utils.ext.*
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.Job
+import kotlin.coroutines.CoroutineContext
+
+@Suppress("MemberVisibilityCanBePrivate")
+abstract class BaseFragment(layoutID: Int) : Fragment(layoutID),
+ CoroutineScope {
+ lateinit var job: Job
+ var supportToolbar: Toolbar? = null
+ private set
+
+ val menuInflater: MenuInflater
+ @SuppressLint("RestrictedApi")
+ get() = SupportMenuInflater(requireContext())
+
+ override val coroutineContext: CoroutineContext
+ get() = job + Dispatchers.Main
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ job = Job()
+ return super.onCreateView(inflater, container, savedInstanceState)
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+ onMultiWindowModeChanged()
+ onFragmentCreated(view, savedInstanceState)
+ observeLiveBus()
+ }
+
+ abstract fun onFragmentCreated(view: View, savedInstanceState: Bundle?)
+
+ override fun onMultiWindowModeChanged(isInMultiWindowMode: Boolean) {
+ super.onMultiWindowModeChanged(isInMultiWindowMode)
+ onMultiWindowModeChanged()
+ }
+
+ override fun onConfigurationChanged(newConfig: Configuration) {
+ super.onConfigurationChanged(newConfig)
+ onMultiWindowModeChanged()
+ }
+
+ private fun onMultiWindowModeChanged() {
+ (activity as? BaseActivity)?.let {
+ view?.findViewById(R.id.title_bar)
+ ?.onMultiWindowModeChanged(it.isInMultiWindow, it.fullScreen)
+ }
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ job.cancel()
+ }
+
+ fun setSupportToolbar(toolbar: Toolbar) {
+ supportToolbar = toolbar
+ supportToolbar?.let {
+ it.menu.apply {
+ onCompatCreateOptionsMenu(this)
+ applyTint(requireContext())
+ }
+
+ it.setOnMenuItemClickListener { item ->
+ onCompatOptionsItemSelected(item)
+ true
+ }
+ }
+ }
+
+ open fun observeLiveBus() {
+ }
+
+ open fun onCompatCreateOptionsMenu(menu: Menu) {
+ }
+
+ open fun onCompatOptionsItemSelected(item: MenuItem) {
+ }
+
+}
diff --git a/app/src/main/java/com/novel/read/base/BasePreferenceFragment.kt b/app/src/main/java/com/novel/read/base/BasePreferenceFragment.kt
new file mode 100644
index 0000000..e10fb01
--- /dev/null
+++ b/app/src/main/java/com/novel/read/base/BasePreferenceFragment.kt
@@ -0,0 +1,60 @@
+package com.novel.read.base
+
+import android.annotation.SuppressLint
+import androidx.fragment.app.DialogFragment
+import androidx.preference.*
+import com.novel.read.ui.widget.prefs.EditTextPreferenceDialog
+import com.novel.read.ui.widget.prefs.ListPreferenceDialog
+import com.novel.read.ui.widget.prefs.MultiSelectListPreferenceDialog
+
+abstract class BasePreferenceFragment : PreferenceFragmentCompat() {
+
+ private val dialogFragmentTag = "androidx.preference.PreferenceFragment.DIALOG"
+
+ @SuppressLint("RestrictedApi")
+ override fun onDisplayPreferenceDialog(preference: Preference) {
+
+ var handled = false
+ if (callbackFragment is OnPreferenceDisplayDialogCallback) {
+ handled =
+ (callbackFragment as OnPreferenceDisplayDialogCallback)
+ .onPreferenceDisplayDialog(this, preference)
+ }
+ if (!handled && activity is OnPreferenceDisplayDialogCallback) {
+ handled = (activity as OnPreferenceDisplayDialogCallback)
+ .onPreferenceDisplayDialog(this, preference)
+ }
+
+ if (handled) {
+ return
+ }
+
+ // check if dialog is already showing
+ if (parentFragmentManager.findFragmentByTag(dialogFragmentTag) != null) {
+ return
+ }
+
+ val f: DialogFragment = when (preference) {
+ is EditTextPreference -> {
+ EditTextPreferenceDialog.newInstance(preference.getKey())
+ }
+ is ListPreference -> {
+ ListPreferenceDialog.newInstance(preference.getKey())
+ }
+ is MultiSelectListPreference -> {
+ MultiSelectListPreferenceDialog.newInstance(preference.getKey())
+ }
+ else -> {
+ throw IllegalArgumentException(
+ "Cannot display dialog for an unknown Preference type: "
+ + preference.javaClass.simpleName
+ + ". Make sure to implement onPreferenceDisplayDialog() to handle "
+ + "displaying a custom dialog for this Preference."
+ )
+ }
+ }
+ f.setTargetFragment(this, 0)
+ f.show(parentFragmentManager, dialogFragmentTag)
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/novel/read/base/BaseService.kt b/app/src/main/java/com/novel/read/base/BaseService.kt
index 1a20fc6..d179802 100644
--- a/app/src/main/java/com/novel/read/base/BaseService.kt
+++ b/app/src/main/java/com/novel/read/base/BaseService.kt
@@ -1,25 +1,26 @@
package com.novel.read.base
import android.app.Service
+import android.content.Intent
+import com.novel.read.help.coroutine.Coroutine
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.MainScope
+import kotlinx.coroutines.cancel
+import kotlin.coroutines.CoroutineContext
-import io.reactivex.disposables.CompositeDisposable
-import io.reactivex.disposables.Disposable
+abstract class BaseService : Service(), CoroutineScope by MainScope() {
-abstract class BaseService : Service() {
+ fun execute(
+ scope: CoroutineScope = this,
+ context: CoroutineContext = Dispatchers.IO,
+ block: suspend CoroutineScope.() -> T
+ ) = Coroutine.async(scope, context) { block() }
- private var mDisposable: CompositeDisposable? = null
-
- protected fun addDisposable(disposable: Disposable) {
- if (mDisposable == null) {
- mDisposable = CompositeDisposable()
- }
- mDisposable!!.add(disposable)
- }
+ override fun onBind(intent: Intent?) = null
override fun onDestroy() {
super.onDestroy()
- if (mDisposable != null) {
- mDisposable!!.dispose()
- }
+ cancel()
}
-}
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/novel/read/base/BaseViewModel.kt b/app/src/main/java/com/novel/read/base/BaseViewModel.kt
new file mode 100644
index 0000000..d0e99f7
--- /dev/null
+++ b/app/src/main/java/com/novel/read/base/BaseViewModel.kt
@@ -0,0 +1,154 @@
+package com.novel.read.base
+
+import android.app.Application
+import android.content.Context
+import androidx.annotation.CallSuper
+import androidx.lifecycle.AndroidViewModel
+import androidx.lifecycle.viewModelScope
+import com.novel.read.App
+import com.novel.read.R
+import com.novel.read.network.api.ApiException
+import com.novel.read.help.coroutine.Coroutine
+import kotlinx.coroutines.*
+import org.jetbrains.anko.AnkoLogger
+import org.jetbrains.anko.toast
+import retrofit2.HttpException
+import java.net.ConnectException
+import java.net.SocketTimeoutException
+import java.net.UnknownHostException
+import kotlin.coroutines.CoroutineContext
+
+typealias Block = suspend (CoroutineScope) -> T
+typealias Error = suspend (Exception) -> Unit
+typealias Cancel = suspend (Exception) -> Unit
+
+open class BaseViewModel(application: Application) : AndroidViewModel(application),
+ CoroutineScope by MainScope(),
+ AnkoLogger {
+
+ val context: Context by lazy { this.getApplication() }
+
+ fun execute(
+ scope: CoroutineScope = this,
+ context: CoroutineContext = Dispatchers.IO,
+ block: suspend CoroutineScope.() -> T
+ ): Coroutine {
+ return Coroutine.async(scope, context) { block() }
+ }
+
+ fun submit(
+ scope: CoroutineScope = this,
+ context: CoroutineContext = Dispatchers.IO,
+ block: suspend CoroutineScope.() -> Deferred
+ ): Coroutine {
+ return Coroutine.async(scope, context) { block().await() }
+ }
+
+ @CallSuper
+ override fun onCleared() {
+ super.onCleared()
+ cancel()
+ }
+
+ open fun toast(message: Int) {
+ launch {
+ context.toast(message)
+ }
+ }
+
+ open fun toast(message: CharSequence?) {
+ launch {
+ context.toast(message ?: toString())
+ }
+ }
+
+ open fun longToast(message: Int) {
+ launch {
+ context.toast(message)
+ }
+ }
+
+ open fun longToast(message: CharSequence?) {
+ launch {
+ context.toast(message ?: toString())
+ }
+ }
+
+ /**
+ * 创建并执行协程
+ * @param block 协程中执行
+ * @param error 错误时执行
+ * @param cancel 取消时只需
+ * @param showErrorToast 是否弹出错误吐司
+ * @return Job
+ */
+ protected fun launch(
+ block: Block,
+ error: Error? = null,
+ cancel: Cancel? = null,
+ showErrorToast: Boolean = true
+ ): Job {
+ return viewModelScope.launch {
+ try {
+ block.invoke(this)
+ } catch (e: Exception) {
+ when (e) {
+ is CancellationException -> {
+ cancel?.invoke(e)
+ }
+ else -> {
+ onError(e, showErrorToast)
+ error?.invoke(e)
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * 创建并执行协程
+ * @param block 协程中执行
+ * @return Deferred
+ */
+ protected fun async(block: Block): Deferred {
+ return viewModelScope.async { block.invoke(this) }
+ }
+
+ /**
+ * 取消协程
+ * @param job 协程job
+ */
+ protected fun cancelJob(job: Job?) {
+ if (job != null && job.isActive && !job.isCompleted && !job.isCancelled) {
+ job.cancel()
+ }
+ }
+
+ /**
+ * 统一处理错误
+ * @param e 异常
+ * @param showErrorToast 是否显示错误吐司
+ */
+ private fun onError(e: Exception, showErrorToast: Boolean) {
+ when (e) {
+ is ApiException -> {
+ when (e.code) {
+ -1001 -> {
+ // 登录失效,清除用户信息、清除cookie/token
+ }
+ // 其他api错误
+ -1 -> if (showErrorToast) toast(e.message)
+ // 其他错误
+ else -> if (showErrorToast) toast(e.message)
+ }
+ }
+ // 网络请求失败
+ is ConnectException, is SocketTimeoutException, is UnknownHostException, is HttpException ->
+ if (showErrorToast) toast(R.string.network_request_failed)
+ // 其他错误
+ else ->
+ if (showErrorToast) toast(e.message ?: return)
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/novel/read/base/MyApp.kt b/app/src/main/java/com/novel/read/base/MyApp.kt
deleted file mode 100644
index c7fd6c7..0000000
--- a/app/src/main/java/com/novel/read/base/MyApp.kt
+++ /dev/null
@@ -1,63 +0,0 @@
-package com.novel.read.base
-
-import android.app.Application
-
-import android.content.Context
-import android.content.Intent
-import android.content.res.Configuration
-import android.util.Log
-
-
-import androidx.appcompat.app.AppCompatDelegate
-
-import com.novel.read.constants.Constant
-import com.novel.read.service.DownloadService
-import com.novel.read.utlis.LocalManageUtil
-import com.novel.read.utlis.SpUtil
-
-
-import org.litepal.LitePal
-import kotlin.properties.Delegates
-
-/**
- * create by zlj on 2019/6/10
- */
-class MyApp : Application() {
-
- override fun onCreate() {
- super.onCreate()
- context = applicationContext
- LitePal.initialize(this)
- setNight()
- LocalManageUtil.setApplicationLanguage(this)
- startService(Intent(context, DownloadService::class.java))
- }
-
- private fun setNight() {
- if (SpUtil.getBooleanValue(Constant.NIGHT, false)) {
- AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)
- } else {
- AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
- }
- }
-
-
- override fun attachBaseContext(base: Context) {
- SpUtil.init(base)
- //保存系统选择语言
- LocalManageUtil.saveSystemCurrentLanguage(base)
- super.attachBaseContext(LocalManageUtil.setLocal(base))
- }
-
- override fun onConfigurationChanged(newConfig: Configuration) {
- super.onConfigurationChanged(newConfig)
- //保存系统选择语言
- LocalManageUtil.onConfigurationChanged(applicationContext)
- }
-
- companion object {
- var context: Context by Delegates.notNull()
- private set
- }
-
-}
diff --git a/app/src/main/java/com/novel/read/base/NovelBaseActivity.kt b/app/src/main/java/com/novel/read/base/NovelBaseActivity.kt
deleted file mode 100644
index f78b3a3..0000000
--- a/app/src/main/java/com/novel/read/base/NovelBaseActivity.kt
+++ /dev/null
@@ -1,78 +0,0 @@
-package com.novel.read.base
-
-import android.content.Context
-import android.content.Intent
-import android.os.Bundle
-import android.view.View
-import androidx.appcompat.app.AppCompatActivity
-import androidx.appcompat.app.AppCompatDelegate
-import com.novel.read.R
-import com.novel.read.constants.Constant
-import com.novel.read.utlis.LocalManageUtil
-import com.novel.read.utlis.SpUtil
-import com.novel.read.utlis.StatusBarUtil
-
-/**
- * create by 赵利君 on 2019/6/10
- * describe:
- */
-abstract class NovelBaseActivity : AppCompatActivity() {
-
- private var mNowMode: Boolean = false
-
- protected abstract val layoutId: Int
-
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- StatusBarUtil.setBarsStyle(this, R.color.colorPrimary, true)
- mNowMode = SpUtil.getBooleanValue(Constant.NIGHT)
- setContentView(layoutId)
- initView()
- initData()
-
- }
-
- private fun setTheme() {
- if (SpUtil.getBooleanValue(Constant.NIGHT) != mNowMode) {
- if (SpUtil.getBooleanValue(Constant.NIGHT)) {
- AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)
- } else {
- AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
- }
- recreate()
- }
- }
-
- protected abstract fun initView()
-
- protected abstract fun initData()
-
- override fun onResume() {
- super.onResume()
- setTheme()
- }
-
- protected fun gone(vararg views: View) {
- if (views.isNotEmpty()) {
- for (view in views) {
- view.visibility = View.GONE
- }
- }
- }
-
- protected fun visible(vararg views: View) {
- if (views.isNotEmpty()) {
- for (view in views) {
- view.visibility = View.VISIBLE
- }
- }
- }
-
- protected fun isVisible(view: View): Boolean {
- return view.visibility == View.VISIBLE
- }
-
- override fun attachBaseContext(newBase: Context) {
- super.attachBaseContext(LocalManageUtil.setLocal(newBase))
- }
-}
diff --git a/app/src/main/java/com/novel/read/base/NovelBaseFragment.kt b/app/src/main/java/com/novel/read/base/NovelBaseFragment.kt
deleted file mode 100644
index a2c3dbb..0000000
--- a/app/src/main/java/com/novel/read/base/NovelBaseFragment.kt
+++ /dev/null
@@ -1,59 +0,0 @@
-package com.novel.read.base
-
-
-import android.content.Intent
-import android.os.Bundle
-
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
-import androidx.annotation.LayoutRes
-import androidx.fragment.app.Fragment
-
-
-abstract class NovelBaseFragment : Fragment() {
-
- override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
- return inflater.inflate(getLayoutId(),null)
- }
-
- override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
- super.onViewCreated(view, savedInstanceState)
- initView()
- initData()
- }
-
- /**
- * 加载布局
- */
- @LayoutRes
- abstract fun getLayoutId():Int
-
- abstract fun initView()
-
- abstract fun initData()
-
- fun toActivity(toClsActivity: Class<*>) {
- this.toActivity(toClsActivity, null as Bundle?)
- }
-
- fun toActivity(toClsActivity: Class<*>, bundle: Bundle?) {
- val intent = Intent(this.context, toClsActivity)
- if (bundle != null) {
- intent.putExtras(bundle)
- }
-
- this.startActivity(intent)
- }
-
- fun toActivityForResult(toClsActivity: Class<*>, bundle: Bundle?, requestCode: Int) {
- val intent = Intent(this.context, toClsActivity)
- if (bundle != null) {
- intent.putExtras(bundle)
- }
-
- startActivityForResult(intent, requestCode)
- }
-
-
-}
diff --git a/app/src/main/java/com/novel/read/base/VMBaseActivity.kt b/app/src/main/java/com/novel/read/base/VMBaseActivity.kt
new file mode 100644
index 0000000..a480c8e
--- /dev/null
+++ b/app/src/main/java/com/novel/read/base/VMBaseActivity.kt
@@ -0,0 +1,15 @@
+package com.novel.read.base
+
+import androidx.lifecycle.ViewModel
+import com.novel.read.constant.Theme
+
+abstract class VMBaseActivity(
+ layoutID: Int,
+ fullScreen: Boolean = true,
+ theme: Theme = Theme.Auto,
+ toolBarTheme: Theme = Theme.Auto
+) : BaseActivity(layoutID, fullScreen, theme, toolBarTheme) {
+
+ protected abstract val viewModel: VM
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/novel/read/base/VMBaseFragment.kt b/app/src/main/java/com/novel/read/base/VMBaseFragment.kt
new file mode 100644
index 0000000..3ecae3e
--- /dev/null
+++ b/app/src/main/java/com/novel/read/base/VMBaseFragment.kt
@@ -0,0 +1,9 @@
+package com.novel.read.base
+
+import androidx.lifecycle.ViewModel
+
+abstract class VMBaseFragment(layoutID: Int) : BaseFragment(layoutID) {
+
+ protected abstract val viewModel: VM
+
+}
diff --git a/app/src/main/java/com/novel/read/constant/AppConst.kt b/app/src/main/java/com/novel/read/constant/AppConst.kt
new file mode 100644
index 0000000..c7f4876
--- /dev/null
+++ b/app/src/main/java/com/novel/read/constant/AppConst.kt
@@ -0,0 +1,77 @@
+package com.novel.read.constant
+
+import android.annotation.SuppressLint
+import android.graphics.Color
+import java.text.SimpleDateFormat
+
+@SuppressLint("SimpleDateFormat")
+object AppConst {
+
+ const val APP_TAG = "TuZi"
+
+ const val channelIdDownload = "channel_download"
+ const val channelIdReadAloud = "channel_read_aloud"
+ const val channelIdWeb = "channel_web"
+
+ const val UA_NAME = "User-Agent"
+ const val CONCEAL = "http://yijianda8.com/conceal/"
+
+ val timeFormat: SimpleDateFormat by lazy {
+ SimpleDateFormat("HH:mm")
+ }
+
+ val dateFormat: SimpleDateFormat by lazy {
+ SimpleDateFormat("yyyy/MM/dd HH:mm")
+ }
+
+ val fileNameFormat: SimpleDateFormat by lazy {
+ SimpleDateFormat("yy-MM-dd-HH-mm-ss")
+ }
+
+ val keyboardToolChars: List by lazy {
+ arrayListOf(
+ "※", "@", "&", "|", "%", "/", ":", "[", "]", "{", "}", "<", ">", "\\",
+ "$", "#", "!", ".", "href", "src", "textNodes", "xpath", "json", "css",
+ "id", "class", "tag"
+ )
+ }
+
+ const val notificationIdRead = 1144771
+ const val notificationIdAudio = 1144772
+ const val notificationIdWeb = 1144773
+ const val notificationIdDownload = 1144774
+
+
+ const val refresh = 1
+ const val loading = 2
+ const val complete = 3
+ const val error = 4
+ const val loadMore = 5
+ const val loadComplete = 6
+ const val loadMoreFail = 7
+ const val noMore = 8
+
+ @kotlin.jvm.JvmField
+ val tagColors = intArrayOf(
+ Color.parseColor("#90C5F0"),
+ Color.parseColor("#91CED5"),
+ Color.parseColor("#F88F55"),
+ Color.parseColor("#C0AFD0"),
+ Color.parseColor("#E78F8F"),
+ Color.parseColor("#67CCB7"),
+ Color.parseColor("#F6BC7E"),
+ Color.parseColor("#90C5F0"),
+ Color.parseColor("#91CED5")
+ )
+
+ const val home = 0
+ const val man = 1
+ const val woman = 2
+
+ const val shellName = "001"
+
+ val menuViewNames = arrayOf(
+ "com.android.internal.view.menu.ListMenuItemView",
+ "androidx.appcompat.view.menu.ListMenuItemView"
+ )
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/novel/read/constant/AppPattern.kt b/app/src/main/java/com/novel/read/constant/AppPattern.kt
new file mode 100644
index 0000000..bb89765
--- /dev/null
+++ b/app/src/main/java/com/novel/read/constant/AppPattern.kt
@@ -0,0 +1,16 @@
+package com.novel.read.constant
+
+import java.util.regex.Pattern
+
+object AppPattern {
+ val JS_PATTERN: Pattern =
+ Pattern.compile("([\\w\\W]*?|@js:[\\w\\W]*$)", Pattern.CASE_INSENSITIVE)
+ val EXP_PATTERN: Pattern = Pattern.compile("\\{\\{([\\w\\W]*?)\\}\\}")
+ val imgPattern: Pattern =
+ Pattern.compile("", Pattern.CASE_INSENSITIVE)
+
+ val nameRegex = Regex("\\s+作\\s*者.*")
+ val authorRegex = Regex(".*?作\\s*?者[::]")
+ val fileNameRegex = Regex("[\\\\/:*?\"<>|.]")
+ val splitGroupRegex = Regex("[,;,;]")
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/novel/read/constant/BookType.kt b/app/src/main/java/com/novel/read/constant/BookType.kt
new file mode 100644
index 0000000..533d2f0
--- /dev/null
+++ b/app/src/main/java/com/novel/read/constant/BookType.kt
@@ -0,0 +1,13 @@
+package com.novel.read.constant
+
+object BookType {
+ const val default = 0 // 0 文本
+ const val audio = 1 // 1 音频
+ const val local = "loc_book"
+ const val net = "net_book"
+
+
+ const val serial="01"
+ const val stop="02"
+ const val complete="03"
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/novel/read/constant/EventBus.kt b/app/src/main/java/com/novel/read/constant/EventBus.kt
new file mode 100644
index 0000000..f9c218c
--- /dev/null
+++ b/app/src/main/java/com/novel/read/constant/EventBus.kt
@@ -0,0 +1,28 @@
+package com.novel.read.constant
+
+object EventBus {
+ const val MEDIA_BUTTON = "mediaButton"
+ const val RECREATE = "RECREATE"
+ const val UP_BOOK = "upBookToc"
+ const val UPDATE_BOOK = "UPDATE_BOOK"
+ const val ALOUD_STATE = "aloud_state"
+ const val TTS_PROGRESS = "ttsStart"
+ const val TTS_DS = "ttsDs"
+ const val BATTERY_CHANGED = "batteryChanged"
+ const val TIME_CHANGED = "timeChanged"
+ const val UP_CONFIG = "upConfig"
+ const val OPEN_CHAPTER = "openChapter"
+ const val AUDIO_SUB_TITLE = "audioSubTitle"
+ const val AUDIO_STATE = "audioState"
+ const val AUDIO_PROGRESS = "audioProgress"
+ const val AUDIO_SIZE = "audioSize"
+ const val AUDIO_SPEED = "audioSpeed"
+ const val SHOW_RSS = "showRss"
+ const val SHOW_AD = "showAd"
+ const val WEB_SERVICE = "webService"
+ const val UP_DOWNLOAD = "upDownload"
+ const val SAVE_CONTENT = "saveContent"
+ const val CHECK_SOURCE = "checkSource"
+ const val CHECK_SOURCE_DONE = "checkSourceDone"
+ const val REPLACE_RULE_SAVE = "replaceRuleSave"
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/novel/read/constant/IntentAction.kt b/app/src/main/java/com/novel/read/constant/IntentAction.kt
new file mode 100644
index 0000000..b5dfb12
--- /dev/null
+++ b/app/src/main/java/com/novel/read/constant/IntentAction.kt
@@ -0,0 +1,30 @@
+package com.novel.read.constant
+
+object IntentAction {
+ const val start = "start"
+ const val play = "play"
+ const val stop = "stop"
+ const val resume = "resume"
+ const val pause = "pause"
+ const val addTimer = "addTimer"
+ const val setTimer = "setTimer"
+ const val prevParagraph = "prevParagraph"
+ const val nextParagraph = "nextParagraph"
+ const val upTtsSpeechRate = "upTtsSpeechRate"
+ const val adjustProgress = "adjustProgress"
+ const val adjustSpeed = "adjustSpeed"
+ const val prev = "prev"
+ const val next = "next"
+ const val moveTo = "moveTo"
+ const val init = "init"
+ const val remove = "remove"
+
+
+ //page skip use
+ const val bookTypeId = "bookTypeId"
+ const val channelName = "channelName"
+ const val bookId = "bookId"
+ const val rankType = "rankType"
+ const val homeType = "homeType"
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/novel/read/constant/LayoutType.kt b/app/src/main/java/com/novel/read/constant/LayoutType.kt
new file mode 100644
index 0000000..bb98fab
--- /dev/null
+++ b/app/src/main/java/com/novel/read/constant/LayoutType.kt
@@ -0,0 +1,23 @@
+package com.novel.read.constant
+
+object LayoutType {
+ const val HOT = 1
+ const val CLICK = 2
+ const val RECOMMEND= 3
+ const val END = 4
+
+ const val BOY_HOT = 6
+ const val BOY_END = 7
+ const val BOY_SEARCH = 8
+
+ const val GIRL_HOT = 9
+ const val GIRL_END = 10
+ const val GIRL_SEARCH = 11
+
+ const val HEAD = 100
+ const val OTHER = 101
+
+
+ const val INIT_BOOK = 102
+ const val SEARCH_BOOK = 103
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/novel/read/constant/PreferKey.kt b/app/src/main/java/com/novel/read/constant/PreferKey.kt
new file mode 100644
index 0000000..54319ae
--- /dev/null
+++ b/app/src/main/java/com/novel/read/constant/PreferKey.kt
@@ -0,0 +1,70 @@
+package com.novel.read.constant
+
+object PreferKey {
+ const val versionCode = "versionCode"
+ const val language = "language"
+ const val themeMode = "themeMode"
+ const val hideStatusBar = "hideStatusBar"
+ const val clickTurnPage = "clickTurnPage"
+ const val clickAllNext = "clickAllNext"
+ const val hideNavigationBar = "hideNavigationBar"
+ const val precisionSearch = "precisionSearch"
+ const val speakEngine = "speakEngine"
+ const val readAloudByPage = "readAloudByPage"
+ const val ttsSpeechRate = "ttsSpeechRate"
+ const val prevKeys = "prevKeyCodes"
+ const val nextKeys = "nextKeyCodes"
+ const val showRss = "showRss"
+ const val bookshelfLayout = "bookshelfLayout"
+ const val bookshelfSort = "bookshelfSort"
+ const val recordLog = "recordLog"
+ const val processText = "process_text"
+ const val cleanCache = "cleanCache"
+ const val saveTabPosition = "saveTabPosition"
+ const val fontFolder = "fontFolder"
+ const val backupPath = "backupUri"
+ const val restoreIgnore = "restoreIgnore"
+ const val threadCount = "threadCount"
+ const val webPort = "webPort"
+ const val keepLight = "keep_light"
+ const val webService = "webService"
+ const val webDavUrl = "web_dav_url"
+ const val webDavAccount = "web_dav_account"
+ const val webDavPassword = "web_dav_password"
+ const val webDavCreateDir = "webDavCreateDir"
+ const val webDavCacheBackup = "webDavCacheBackup"
+ const val changeSourceLoadToc = "changeSourceLoadToc"
+ const val changeSourceLoadInfo = "changeSourceLoadInfo"
+ const val chineseConverterType = "chineseConverterType"
+ const val launcherIcon = "launcherIcon"
+ const val textSelectAble = "selectText"
+ const val lastBackup = "lastBackup"
+ const val shareLayout = "shareLayout"
+ const val readStyleSelect = "readStyleSelect"
+ const val systemTypefaces = "system_typefaces"
+ const val readBodyToLh = "readBodyToLh"
+ const val textFullJustify = "textFullJustify"
+ const val textBottomJustify = "textBottomJustify"
+ const val autoReadSpeed = "autoReadSpeed"
+ const val barElevation = "barElevation"
+ const val transparentStatusBar = "transparentStatusBar"
+ const val defaultCover = "defaultCover"
+ const val replaceEnableDefault = "replaceEnableDefault"
+ const val showBrightnessView = "showBrightnessView"
+ const val autoClearExpired = "autoClearExpired"
+
+ const val cPrimary = "colorPrimary"
+ const val cAccent = "colorAccent"
+ const val cBackground = "colorBackground"
+ const val cBBackground = "colorBottomBackground"
+
+ const val cNPrimary = "colorPrimaryNight"
+ const val cNAccent = "colorAccentNight"
+ const val cNBackground = "colorBackgroundNight"
+ const val cNBBackground = "colorBottomBackgroundNight"
+
+ const val installCount = "installCount"
+ const val installTime = "installTime"
+ const val appraiseShow = "appraiseShow"
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/novel/read/constant/Status.kt b/app/src/main/java/com/novel/read/constant/Status.kt
new file mode 100644
index 0000000..ddbab5a
--- /dev/null
+++ b/app/src/main/java/com/novel/read/constant/Status.kt
@@ -0,0 +1,7 @@
+package com.novel.read.constant
+
+object Status {
+ const val STOP = 0
+ const val PLAY = 1
+ const val PAUSE = 3
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/novel/read/constant/Theme.kt b/app/src/main/java/com/novel/read/constant/Theme.kt
new file mode 100644
index 0000000..d9bcfc6
--- /dev/null
+++ b/app/src/main/java/com/novel/read/constant/Theme.kt
@@ -0,0 +1,20 @@
+package com.novel.read.constant
+
+import com.novel.read.help.AppConfig
+import com.novel.read.utils.ColorUtils
+
+
+enum class Theme {
+ Dark, Light, Auto, Transparent;
+
+ companion object {
+ fun getTheme() =
+ if (AppConfig.isNightTheme) Dark
+ else Light
+
+ fun getTheme(backgroundColor: Int) =
+ if (ColorUtils.isColorLight(backgroundColor)) Light
+ else Dark
+
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/novel/read/constants/Constant.kt b/app/src/main/java/com/novel/read/constants/Constant.kt
deleted file mode 100644
index 630e97d..0000000
--- a/app/src/main/java/com/novel/read/constants/Constant.kt
+++ /dev/null
@@ -1,115 +0,0 @@
-package com.novel.read.constants
-
-import android.graphics.Color
-
-import com.novel.read.utlis.FileUtils
-
-import java.io.File
-
-// ┏┓ ┏┓
-//┏┛┻━━━┛┻┓
-//┃ ┃
-//┃ ━ ┃
-//┃ ┳┛ ┗┳ ┃
-//┃ ┃
-//┃ ┻ ┃
-//┃ ┃
-//┗━┓ ┏━┛
-// ┃ ┃ 神兽保佑
-// ┃ ┃ 代码无BUG!
-// ┃ ┗━━━┓
-// ┃ ┣┓
-// ┃ ┏┛
-// ┗┓┓┏━┳┓┏┛
-// ┃┫┫ ┃┫┫
-// ┗┻┛ ┗┻┛
-/**
- * Created by zlj on 2019/7/27.
- * desc: 常量
- */
-object Constant {
-
- const val NIGHT = "NIGHT"
- const val Language = "Language"
- const val BookSort = "BookSort"
- const val Uid = "Uid"
- const val Sex = "Sex"
- const val Type = "Type"
- const val DateType = "DateType"
- const val BookGuide = "BookGuide" //图书引导是否提示过
-
- const val FORMAT_BOOK_DATE = "yyyy-MM-dd HH:mm:ss"
- const val FORMAT_TIME = "HH:mm"
- const val COMMENT_SIZE = 10
-
- const val FeedBackEmail = "390057892@qq.com"
-
- /**
- * 百度语音合成
- */
- const val appId = "16826023"
- const val appKey = "vEuU5gIWGwq5hivdTAaKz0P9"
- const val secretKey = "FcWRYUIrOPyE7dy51qfYZmg8Y1ZyP1c4 "
-
- //BookCachePath (因为getCachePath引用了Context,所以必须是静态变量,不能够是静态常量)
- @kotlin.jvm.JvmField
- var BOOK_CACHE_PATH: String = (FileUtils.getCachePath() + File.separator
- + "book_cache" + File.separator)
-
- @kotlin.jvm.JvmField
- val tagColors = intArrayOf(
- Color.parseColor("#90C5F0"),
- Color.parseColor("#91CED5"),
- Color.parseColor("#F88F55"),
- Color.parseColor("#C0AFD0"),
- Color.parseColor("#E78F8F"),
- Color.parseColor("#67CCB7"),
- Color.parseColor("#F6BC7E"),
- Color.parseColor("#90C5F0"),
- Color.parseColor("#91CED5")
- )
-
- //榜单类型
- interface ListType {
- companion object {
- const val Human = "1"
- const val EditRecommend = "2"
- const val HotSearch = "3"
- }
- }
-
- interface GenderType {
- companion object {
- const val Man = "1"
- const val Woman = "2"
- }
- }
-
- interface DateTyp {
- companion object {
- const val General = "3"
- const val Month = "2"
- const val Week = "1"
- }
- }
-
- interface Bundle {
- companion object {
- const val CategoryId = "category_id"
- const val mTitle = "mTitle"
- const val BookId = "BookId"
- }
- }
-
- interface RequestCode {
- companion object {
- const val REQUEST_READ = 1
- }
- }
-
- interface ResultCode {
- companion object {
- const val RESULT_IS_COLLECTED = "result_is_collected"
- }
- }
-}
diff --git a/app/src/main/java/com/novel/read/data/README.md b/app/src/main/java/com/novel/read/data/README.md
new file mode 100644
index 0000000..a935461
--- /dev/null
+++ b/app/src/main/java/com/novel/read/data/README.md
@@ -0,0 +1,17 @@
+# 存储数据用
+* dao 数据操作
+* entities 数据模型
+* \Book 书籍信息
+* \BookChapter 目录信息
+* \BookGroup 书籍分组
+* \Bookmark 书签
+* \BookSource 书源
+* \Cookie http cookie
+* \ReplaceRule 替换规则
+* \RssArticle rss条目
+* \RssReadRecord rss阅读记录
+* \RssSource rss源
+* \RssStar rss收藏
+* \SearchBook 搜索结果
+* \SearchKeyword 搜索关键字
+* \TxtTocRule txt文件目录规则
diff --git a/app/src/main/java/com/novel/read/data/db/BookDao.kt b/app/src/main/java/com/novel/read/data/db/BookDao.kt
new file mode 100644
index 0000000..00b1896
--- /dev/null
+++ b/app/src/main/java/com/novel/read/data/db/BookDao.kt
@@ -0,0 +1,50 @@
+package com.novel.read.data.db
+
+import android.content.ContentValues
+import com.novel.read.data.db.entity.Book
+import org.litepal.LitePal
+
+
+class BookDao {
+
+ fun getAllBooks(): MutableList = LitePal.findAll(Book::class.java)
+
+ fun lastReadBook(): Book = LitePal.order("durChapterTime desc").findFirst(Book::class.java)
+
+ fun update(book: Book) {
+ val values = ContentValues()
+ values.put("authorPenname", book.authorPenname)
+ values.put("bookName", book.bookName)
+ values.put("bookStatus", book.bookStatus)
+ values.put("categoryName", book.categoryName)
+ values.put("channelName", book.channelName)
+ values.put("cName", book.cName)
+ values.put("coverImageUrl", book.coverImageUrl)
+ values.put("introduction", book.introduction)
+ values.put("keyWord", book.keyWord)
+ values.put("lastUpdateChapterDate", book.lastUpdateChapterDate)
+ values.put("status", book.status)
+ values.put("wordCount", book.wordCount)
+ values.put("durChapterTime", book.durChapterTime)
+ values.put("durChapterIndex", book.durChapterIndex)
+ values.put("durChapterPos", book.durChapterPos)
+ values.put("durChapterTitle", book.durChapterTitle)
+ values.put("totalChapterNum", book.totalChapterNum)
+ LitePal.updateAll(Book::class.java, values, "bookId=?", book.bookId.toString())
+ }
+
+ fun getBook(bookId: String): Book? =
+ LitePal.where("bookId=?", bookId).findFirst(Book::class.java)
+
+ fun insert(book: Book) = book.saveOrUpdate("bookId=?", book.bookId.toString())
+
+ fun delete(book: Book): Int =
+ LitePal.deleteAll(Book::class.java, "bookId=?", book.bookId.toString())
+
+ fun saveBook(book: List?) {
+ if (book != null && book.isNotEmpty()) {
+ LitePal.saveAll(book)
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/novel/read/data/db/BookDatabase.kt b/app/src/main/java/com/novel/read/data/db/BookDatabase.kt
new file mode 100644
index 0000000..2b0b795
--- /dev/null
+++ b/app/src/main/java/com/novel/read/data/db/BookDatabase.kt
@@ -0,0 +1,67 @@
+package com.novel.read.data.db
+
+class BookDatabase private constructor() {
+
+ companion object {
+ private var instance: BookDatabase? = null
+ get() {
+ if (field == null) {
+ field = BookDatabase()
+ }
+ return field
+ }
+
+ fun get(): BookDatabase {
+ return instance!!
+ }
+ }
+
+ private var chapterDao: ChapterDao? = null
+ private var bookDao: BookDao? = null
+ private var readRecordDao: ReadRecordDao? = null
+ private var bookMarkDao: BookMarkDao? = null
+ private var searchHistoryDao: SearchHistoryDao? = null
+ private var userDao: UserDao? = null
+
+ fun getChapterDao(): ChapterDao {
+ if (chapterDao == null) {
+ chapterDao = ChapterDao()
+ }
+ return chapterDao!!
+ }
+
+ fun getBookDao(): BookDao {
+ if (bookDao == null) {
+ bookDao = BookDao()
+ }
+ return bookDao!!
+ }
+
+ fun getReadRecordDao(): ReadRecordDao {
+ if (readRecordDao == null) {
+ readRecordDao = ReadRecordDao()
+ }
+ return readRecordDao!!
+ }
+
+ fun getBookMarkDao(): BookMarkDao {
+ if (bookMarkDao == null) {
+ bookMarkDao = BookMarkDao()
+ }
+ return bookMarkDao!!
+ }
+
+ fun getSearchDao(): SearchHistoryDao {
+ if (searchHistoryDao == null) {
+ searchHistoryDao = SearchHistoryDao()
+ }
+ return searchHistoryDao!!
+ }
+
+ fun getUserDao(): UserDao {
+ if (userDao == null) {
+ userDao = UserDao()
+ }
+ return userDao!!
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/novel/read/data/db/BookMarkDao.kt b/app/src/main/java/com/novel/read/data/db/BookMarkDao.kt
new file mode 100644
index 0000000..e486936
--- /dev/null
+++ b/app/src/main/java/com/novel/read/data/db/BookMarkDao.kt
@@ -0,0 +1,39 @@
+package com.novel.read.data.db
+
+import com.novel.read.data.db.entity.Bookmark
+import org.litepal.LitePal
+
+class BookMarkDao {
+
+ fun observeByBook(bookId: Long): List? =
+ LitePal.where("bookId=?", bookId.toString()).find(Bookmark::class.java)
+
+ fun liveDataSearch(bookId: String, key: String): List? =
+ LitePal.where(
+ "bookId=? and (chapterName like ? or content like ?)",
+ bookId.toString(),
+ "%${key}%", "%${key}%"
+ )
+ .find(Bookmark::class.java)
+
+ fun insert(bookmark: Bookmark) {
+ bookmark.saveOrUpdate(
+ "bookId=? and chapterIndex=?",
+ bookmark.bookId.toString(),
+ bookmark.chapterIndex.toString()
+ )
+ }
+
+ fun update(bookmark: Bookmark) {
+ bookmark.saveOrUpdate(
+ "bookId=? and chapterIndex=?",
+ bookmark.bookId.toString(),
+ bookmark.chapterIndex.toString()
+ )
+ }
+
+ fun delete(bookmark: Bookmark) {
+ bookmark.delete()
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/novel/read/data/db/ChapterDao.kt b/app/src/main/java/com/novel/read/data/db/ChapterDao.kt
new file mode 100644
index 0000000..399cfa0
--- /dev/null
+++ b/app/src/main/java/com/novel/read/data/db/ChapterDao.kt
@@ -0,0 +1,48 @@
+package com.novel.read.data.db
+
+import com.novel.read.data.db.entity.BookChapter
+import org.litepal.LitePal
+
+class ChapterDao {
+
+ fun observeByBook(bookId: String): List? =
+ LitePal.where("bookId=?", bookId.toString()).find(BookChapter::class.java)
+
+ fun liveDataSearch(bookId: String, key: String): List? =
+ LitePal.where("bookId=? and chapterName like ?", bookId, "%${key}%")
+ .find(BookChapter::class.java)
+
+ fun getChapter(chapterId: Long): BookChapter? =
+ LitePal.where("chapterId =?", chapterId.toString()).findFirst(BookChapter::class.java)
+
+ fun getChapter(bookId: Long, chapterIndex: Int): BookChapter? =
+ LitePal.where("bookId=? and chapterIndex =?", bookId.toString(), chapterIndex.toString())
+ .findFirst(BookChapter::class.java)
+
+ fun getChapterList(bookId: Long): List? =
+ LitePal.where("bookId=?", bookId.toString()).find(BookChapter::class.java)
+
+ fun getChapterList(bookId: Long, start: Int, end: Int): List =
+ LitePal.where(
+ "bookId=? and chapterIndex >=? and chapterIndex <=?",
+ bookId.toString(),
+ start.toString(),
+ end.toString()
+ ).order("chapterIndex desc").find(BookChapter::class.java)
+
+ fun getChapterCount(bookId: Long): Int {
+ return LitePal.where("bookId=?", bookId.toString()).count(BookChapter::class.java)
+ }
+
+ fun insert(bookChapters: Array) {
+ if (bookChapters.isNotEmpty()) {
+ LitePal.deleteAll(
+ BookChapter::class.java,
+ "bookId=?",
+ bookChapters[0].bookId.toString()
+ )
+ }
+ LitePal.saveAll(bookChapters.toList())
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/novel/read/data/db/ReadRecordDao.kt b/app/src/main/java/com/novel/read/data/db/ReadRecordDao.kt
new file mode 100644
index 0000000..65906e8
--- /dev/null
+++ b/app/src/main/java/com/novel/read/data/db/ReadRecordDao.kt
@@ -0,0 +1,23 @@
+package com.novel.read.data.db
+
+import com.novel.read.data.db.entity.ReadRecord
+import org.litepal.LitePal
+
+class ReadRecordDao {
+
+ fun getReadTime(bookName: String): Long? =
+ LitePal.where("bookName =?", bookName).findFirst(ReadRecord::class.java)?.readTime
+
+ fun insert(readRecord: ReadRecord) {
+ readRecord.saveOrUpdate("bookId=?", readRecord.bookId.toString())
+ }
+
+ fun delete(readRecord: ReadRecord) {
+ readRecord.delete()
+ }
+
+ fun getAll(): List {
+ return LitePal.findAll(ReadRecord::class.java)
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/novel/read/data/db/SearchHistoryDao.kt b/app/src/main/java/com/novel/read/data/db/SearchHistoryDao.kt
new file mode 100644
index 0000000..b2955cb
--- /dev/null
+++ b/app/src/main/java/com/novel/read/data/db/SearchHistoryDao.kt
@@ -0,0 +1,19 @@
+package com.novel.read.data.db
+
+import com.novel.read.data.db.entity.SearchHistory
+import org.litepal.LitePal
+
+class SearchHistoryDao {
+
+ fun getListByTime(): MutableList? =
+ LitePal.order("saveTime desc").limit(5).find(SearchHistory::class.java)
+
+ fun insert(searchHistory: SearchHistory, key: String) {
+ searchHistory.saveOrUpdate("key=?", key)
+ }
+
+ fun deleteAll() {
+ LitePal.deleteAll(SearchHistory::class.java)
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/novel/read/data/db/UserDao.kt b/app/src/main/java/com/novel/read/data/db/UserDao.kt
new file mode 100644
index 0000000..fc66fd9
--- /dev/null
+++ b/app/src/main/java/com/novel/read/data/db/UserDao.kt
@@ -0,0 +1,16 @@
+package com.novel.read.data.db
+
+import com.novel.read.data.db.entity.User
+import org.litepal.LitePal
+import org.litepal.extension.deleteAll
+
+class UserDao {
+
+ fun saveUser(user: User) = user.saveOrUpdate("userId=?", user.userId.toString())
+
+ fun getUser(): User? =
+ LitePal.findFirst(User::class.java)
+
+ fun deleteUser() = LitePal.deleteAll()
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/novel/read/data/db/entity/Book.kt b/app/src/main/java/com/novel/read/data/db/entity/Book.kt
new file mode 100644
index 0000000..f7c91a8
--- /dev/null
+++ b/app/src/main/java/com/novel/read/data/db/entity/Book.kt
@@ -0,0 +1,52 @@
+package com.novel.read.data.db.entity
+
+import com.google.gson.annotations.SerializedName
+import com.novel.read.constant.AppPattern
+import com.novel.read.constant.BookType
+import com.novel.read.utils.MD5Utils
+import org.litepal.crud.LitePalSupport
+import kotlin.math.max
+
+data class Book(
+ val authorPenname: String,
+ val bookId: Long,
+ val bookName: String,
+ val bookStatus: String,
+ val categoryName: String?,
+ val channelName: String?,
+ @SerializedName("className")
+ val cName: String?,
+ val coverImageUrl: String,
+ val introduction: String,
+ val keyWord: String,
+ var lastUpdateChapterDate: String,
+ val status: Int,
+ val wordCount: Long,
+ var totalChapterNum: Int = 0, // 书籍目录总数
+ var durChapterTitle: String? = null, // 当前章节名称
+ var durChapterIndex: Int = 0, // 当前章节索引
+ var durChapterPos: Int = 0, // 当前阅读的进度(首行字符的索引位置)
+ var durChapterTime: Long = System.currentTimeMillis(), // 最近一次阅读书籍的时间(打开正文的时间)
+ var origin: String = BookType.net,
+ var originName: String = "",
+ var bookTypeId: Int = 0
+) : LitePalSupport() {
+
+ fun isLocalBook(): Boolean {
+ return origin == BookType.local
+ }
+
+ fun getFolderName(): String {
+ return bookName.replace(AppPattern.fileNameRegex, "") + MD5Utils.md5Encode16(coverImageUrl)
+ }
+
+ fun isEpub(): Boolean {
+ return originName.endsWith(".epub", true)
+ }
+
+ fun canUpdate(): Boolean {
+ return bookStatus == BookType.serial
+ }
+
+ fun getUnreadChapterNum() = max(totalChapterNum - durChapterIndex - 1, 0)
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/novel/read/data/db/entity/BookChapter.kt b/app/src/main/java/com/novel/read/data/db/entity/BookChapter.kt
new file mode 100644
index 0000000..3052fd0
--- /dev/null
+++ b/app/src/main/java/com/novel/read/data/db/entity/BookChapter.kt
@@ -0,0 +1,19 @@
+package com.novel.read.data.db.entity
+
+import org.litepal.crud.LitePalSupport
+
+data class BookChapter(
+// val bookId: Int,
+// val chapterList: List,
+// val volumeId: Int,
+// val volumeName: String
+
+ val chapterId: Long,
+ val bookId: Long,
+ val chapterIndex: Int,
+ var chapterName: String,
+ val createTimeValue: Long,
+ val updateDate: String,
+ val updateTimeValue: Long,
+ val chapterUrl: String?,
+) : LitePalSupport()
\ No newline at end of file
diff --git a/app/src/main/java/com/novel/read/data/db/entity/Bookmark.kt b/app/src/main/java/com/novel/read/data/db/entity/Bookmark.kt
new file mode 100644
index 0000000..0132bdf
--- /dev/null
+++ b/app/src/main/java/com/novel/read/data/db/entity/Bookmark.kt
@@ -0,0 +1,16 @@
+package com.novel.read.data.db.entity
+
+import org.litepal.crud.LitePalSupport
+import java.io.Serializable
+
+data class Bookmark(
+ var time: Long = System.currentTimeMillis(),
+ var bookId: Long = 0,
+ var bookName: String = "",
+ val bookAuthor: String = "",
+ var chapterIndex: Int = 0,
+ var pageIndex: Int = 0,
+ var chapterName: String = "",
+ var content: String = ""
+
+) : LitePalSupport(), Serializable
\ No newline at end of file
diff --git a/app/src/main/java/com/novel/read/data/db/entity/ChapterDetailEntity.kt b/app/src/main/java/com/novel/read/data/db/entity/ChapterDetailEntity.kt
new file mode 100644
index 0000000..f3942ab
--- /dev/null
+++ b/app/src/main/java/com/novel/read/data/db/entity/ChapterDetailEntity.kt
@@ -0,0 +1,10 @@
+package com.novel.read.data.db.entity
+
+data class ChapterDetailEntity(
+ val chapterContent: String,
+ val chapterIndex: Int,
+ val chapterName: String,
+ val isRecommend: String,
+ val isVIP: String,
+ val wordCount: Int
+)
\ No newline at end of file
diff --git a/app/src/main/java/com/novel/read/data/db/entity/HttpTTS.kt b/app/src/main/java/com/novel/read/data/db/entity/HttpTTS.kt
new file mode 100644
index 0000000..0d3d8fa
--- /dev/null
+++ b/app/src/main/java/com/novel/read/data/db/entity/HttpTTS.kt
@@ -0,0 +1,9 @@
+package com.novel.read.data.db.entity
+
+import org.litepal.crud.LitePalSupport
+
+data class HttpTTS(
+ val id: Long = System.currentTimeMillis(),
+ var name: String = "",
+ var url: String = ""
+) : LitePalSupport()
\ No newline at end of file
diff --git a/app/src/main/java/com/novel/read/data/db/entity/ReadRecord.kt b/app/src/main/java/com/novel/read/data/db/entity/ReadRecord.kt
new file mode 100644
index 0000000..36f806c
--- /dev/null
+++ b/app/src/main/java/com/novel/read/data/db/entity/ReadRecord.kt
@@ -0,0 +1,15 @@
+package com.novel.read.data.db.entity
+
+import org.litepal.crud.LitePalSupport
+
+import java.io.Serializable
+
+/**
+ * Created by zlj
+ */
+class ReadRecord(
+ var androidId: String = "",
+ var bookName: String = "",
+ var bookId: Long = 0L,
+ var readTime: Long = 0L
+) : LitePalSupport(), Serializable
diff --git a/app/src/main/java/com/novel/read/model/db/SearchListTable.kt b/app/src/main/java/com/novel/read/data/db/entity/SearchHistory.kt
similarity index 63%
rename from app/src/main/java/com/novel/read/model/db/SearchListTable.kt
rename to app/src/main/java/com/novel/read/data/db/entity/SearchHistory.kt
index 6d6053a..2b42e37 100644
--- a/app/src/main/java/com/novel/read/model/db/SearchListTable.kt
+++ b/app/src/main/java/com/novel/read/data/db/entity/SearchHistory.kt
@@ -1,20 +1,13 @@
-package com.novel.read.model.db
-
+package com.novel.read.data.db.entity
+import com.novel.read.utils.StringUtils
import org.litepal.crud.LitePalSupport
-
import java.io.Serializable
-/**
- * create by zlj on 2019/6/19
- * describe:
- */
-class SearchListTable : LitePalSupport(), Serializable {
-
- var key: String = ""
+class SearchHistory(
+ var key: String = "",
var saveTime: Long = 0
-
-
+) : LitePalSupport(), Serializable {
override fun equals(other: Any?): Boolean {
return if (other != null && other.toString() == key) {
true
@@ -26,4 +19,8 @@ class SearchListTable : LitePalSupport(), Serializable {
result = 31 * result + saveTime.hashCode()
return result
}
-}
+
+ fun getBKey(): String {
+ return StringUtils.convertCC(key)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/novel/read/data/db/entity/User.kt b/app/src/main/java/com/novel/read/data/db/entity/User.kt
new file mode 100644
index 0000000..cb63dd1
--- /dev/null
+++ b/app/src/main/java/com/novel/read/data/db/entity/User.kt
@@ -0,0 +1,29 @@
+package com.novel.read.data.db.entity
+
+import org.litepal.crud.LitePalSupport
+import java.io.Serializable
+
+data class User(
+ val createTime: Long,
+ val email: String,
+ val headImageUrl: String,
+ val idToken: String,
+ val introduction: String?,
+ val ip: String,
+ val isEmailVerified: Int,
+ val lastLoginTime: Long?,
+ val nickName: String?,
+ val oldNickName: String?,
+ val os: String,
+ val password: String,
+ val phone: String,
+ val provider: String,
+ val sex: Int,
+ val updateTime: Long?,
+ val userId: Long,
+ val userName: String,
+ val validFlag: Int,
+ val vipEndTime: Long?,
+ val vipStartTime: Long?,
+ val vipStatus: Int
+) : LitePalSupport(), Serializable
\ No newline at end of file
diff --git a/app/src/main/java/com/novel/read/data/model/AppUpdateResp.kt b/app/src/main/java/com/novel/read/data/model/AppUpdateResp.kt
new file mode 100644
index 0000000..23a9a6b
--- /dev/null
+++ b/app/src/main/java/com/novel/read/data/model/AppUpdateResp.kt
@@ -0,0 +1,20 @@
+package com.novel.read.data.model
+
+data class AppUpdateResp(
+ val appEdition: AppEdition
+)
+
+data class AppEdition(
+ val createTime: String,
+ val editionCode: String,
+ val editionId: Int,
+ val fileUrl: String,
+ val forceUpdate: Int,
+ val insideEditionCode: Int,
+ val isDel: Int,
+ val packageSize: String,
+ val pushTime: String,
+ val shellName: String,
+ val status: Int,
+ val upgradeContent: String
+)
\ No newline at end of file
diff --git a/app/src/main/java/com/novel/read/data/model/BookInfoResp.kt b/app/src/main/java/com/novel/read/data/model/BookInfoResp.kt
new file mode 100644
index 0000000..e395fc6
--- /dev/null
+++ b/app/src/main/java/com/novel/read/data/model/BookInfoResp.kt
@@ -0,0 +1,33 @@
+package com.novel.read.data.model
+
+data class BookInfoResp(
+ val book: BookResp
+)
+
+data class BookResp(
+ val authorInformation: Any,
+ val authorName: String,
+ val authorUserId: Long,
+ val bookClass: Any,
+ val bookId: Long,
+ val bookName: String,
+ val bookSId: String,
+ val bookStatus: Any,
+ val bookTypeId: Int,
+ val categoryName: String?,
+ val channelName: Any?,
+ val coverImageUrl: String,
+ val createTime: Long,
+ val endStatus: Int,
+ val extBookId: Any,
+ val hits: Any,
+ val hotStatus: Any,
+ val introduction: String,
+ val keyWord: String,
+ val lastUpdateChapterDate: String,
+ val rankNumber: Any,
+ val rankType: Any,
+ val recommendStatus: Any,
+ val validFlag: Int,
+ val wordCount: Long
+)
\ No newline at end of file
diff --git a/app/src/main/java/com/novel/read/data/model/BookListResp.kt b/app/src/main/java/com/novel/read/data/model/BookListResp.kt
new file mode 100644
index 0000000..6029d23
--- /dev/null
+++ b/app/src/main/java/com/novel/read/data/model/BookListResp.kt
@@ -0,0 +1,52 @@
+package com.novel.read.data.model
+
+import com.novel.read.utils.StringUtils
+
+data class BookListResp(
+ val authorInformation: String,
+ var authorName: String?,
+ val authorUserId: Long,
+ val bookClass: Int,
+ val bookId: Long,
+ val bookName: String,
+ val bookSId: String,
+ val bookStatus: Int,
+ val bookTypeId: Int,
+ val categoryName: String?,
+ val channelName: String?,
+ val coverImageUrl: String,
+ val createTime: Long,
+ val endStatus: Int,
+ val hotStatus: Int,
+ val introduction: String?,
+ val keyWord: String,
+ val lastUpdateChapterDate: String?,
+ val recommendStatus: Int,
+ val validFlag: Int,
+ val wordCount: Long
+
+) {
+ fun getBAuthorName(): String {
+ return StringUtils.convertCC(authorName!!)
+ }
+
+ fun getBBookName(): String {
+ return StringUtils.convertCC(bookName)
+ }
+
+ fun getBCategoryName(): String {
+ return StringUtils.convertCC(categoryName ?: "")
+ }
+
+ fun getBChannel(): String {
+ return StringUtils.convertCC(channelName!!)
+ }
+
+ fun getBIntroduction(): String {
+ return StringUtils.convertCC(introduction!!)
+ }
+
+ fun getBKeyWord(): String {
+ return StringUtils.convertCC(keyWord)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/novel/read/data/model/BoyEndRank.kt b/app/src/main/java/com/novel/read/data/model/BoyEndRank.kt
new file mode 100644
index 0000000..dd5f071
--- /dev/null
+++ b/app/src/main/java/com/novel/read/data/model/BoyEndRank.kt
@@ -0,0 +1,51 @@
+package com.novel.read.data.model
+
+import com.chad.library.adapter.base.entity.MultiItemEntity
+import com.novel.read.constant.LayoutType
+import com.novel.read.utils.StringUtils
+
+data class BoyEndRank(
+ val authorInformation: String,
+ val authorName: String,
+ val authorUserId: Long,
+ val bookChannelId: Long,
+ val bookClass: Int,
+ val bookId: Long,
+ val bookName: String,
+ val bookSId: String,
+ val bookStatus: Int,
+ val bookTypeId: Long,
+ val categoryName: String,
+ val channelName: String,
+ val coverImageUrl: String,
+ val createTime: Long,
+ val endStatus: Int,
+ val extBookId: Int,
+ val hits: String,
+ val hotStatus: Int,
+ val introduction: String,
+ val keyWord: String,
+ val lastUpdateChapterDate: String,
+ val rankNumber: String,
+ val rankType: String,
+ val recommendStatus: Int,
+ val validFlag: Int,
+ val wordCount: Long
+){
+ fun getBAuthorName(): String {
+ return StringUtils.convertCC(authorName)
+ }
+
+ fun getBBookName(): String {
+ return StringUtils.convertCC(bookName)
+ }
+
+ fun getBCategoryName(): String {
+ return StringUtils.convertCC(categoryName)
+ }
+}
+
+data class BoyEndRankEntity(val boyEndRanks:List):MultiItemEntity{
+ override val itemType: Int
+ get() = LayoutType.BOY_END
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/novel/read/data/model/BoyHotRank.kt b/app/src/main/java/com/novel/read/data/model/BoyHotRank.kt
new file mode 100644
index 0000000..1a51daf
--- /dev/null
+++ b/app/src/main/java/com/novel/read/data/model/BoyHotRank.kt
@@ -0,0 +1,50 @@
+package com.novel.read.data.model
+
+import com.chad.library.adapter.base.entity.MultiItemEntity
+import com.novel.read.constant.LayoutType
+import com.novel.read.utils.StringUtils
+
+data class BoyHotRank(
+ val authorInformation: String,
+ val authorName: String,
+ val authorUserId: Long,
+ val bookChannelId: Long,
+ val bookClass: Int,
+ val bookId: Long,
+ val bookName: String,
+ val bookSId: String,
+ val bookStatus: Int,
+ val bookTypeId: Long,
+ val categoryName: String,
+ val channelName: String,
+ val coverImageUrl: String,
+ val createTime: Long,
+ val endStatus: Int,
+ val extBookId: Int,
+ val hits: String,
+ val hotStatus: Int,
+ val introduction: String,
+ val keyWord: String,
+ val lastUpdateChapterDate: String,
+ val rankNumber: String,
+ val rankType: String,
+ val recommendStatus: Int,
+ val validFlag: Int
+) {
+ fun getBAuthorName(): String {
+ return StringUtils.convertCC(authorName)
+ }
+
+ fun getBBookName(): String {
+ return StringUtils.convertCC(bookName)
+ }
+
+ fun getBCategoryName(): String {
+ return StringUtils.convertCC(categoryName)
+ }
+}
+
+data class BoyHotRankEntity(val boyHotRanks: List) : MultiItemEntity {
+ override val itemType: Int
+ get() = LayoutType.BOY_HOT
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/novel/read/data/model/BoySearchRank.kt b/app/src/main/java/com/novel/read/data/model/BoySearchRank.kt
new file mode 100644
index 0000000..c68c2b2
--- /dev/null
+++ b/app/src/main/java/com/novel/read/data/model/BoySearchRank.kt
@@ -0,0 +1,50 @@
+package com.novel.read.data.model
+
+import com.chad.library.adapter.base.entity.MultiItemEntity
+import com.novel.read.constant.LayoutType
+import com.novel.read.utils.StringUtils
+
+data class BoySearchRank(
+ val authorInformation: String,
+ val authorName: String,
+ val authorUserId: Long,
+ val bookChannelId: Long,
+ val bookClass: Int,
+ val bookId: Long,
+ val bookName: String,
+ val bookSId: String,
+ val bookStatus: Int,
+ val bookTypeId: Long,
+ val categoryName: String,
+ val channelName: String,
+ val coverImageUrl: String,
+ val createTime: Long,
+ val endStatus: Int,
+ val extBookId: Int,
+ val hits: String,
+ val hotStatus: Int,
+ val introduction: String,
+ val keyWord: String,
+ val lastUpdateChapterDate: String,
+ val rankNumber: String,
+ val rankType: String,
+ val recommendStatus: Int,
+ val validFlag: Int
+){
+ fun getBAuthorName(): String {
+ return StringUtils.convertCC(authorName)
+ }
+
+ fun getBBookName(): String {
+ return StringUtils.convertCC(bookName)
+ }
+
+ fun getBCategoryName(): String {
+ return StringUtils.convertCC(categoryName)
+ }
+}
+
+data class BoySearchRankEntity(val boySearchRanks:List):MultiItemEntity{
+ override val itemType: Int
+ get() = LayoutType.BOY_SEARCH
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/novel/read/data/model/ChannelResp.kt b/app/src/main/java/com/novel/read/data/model/ChannelResp.kt
new file mode 100644
index 0000000..bbc722f
--- /dev/null
+++ b/app/src/main/java/com/novel/read/data/model/ChannelResp.kt
@@ -0,0 +1,24 @@
+package com.novel.read.data.model
+
+import com.chad.library.adapter.base.entity.SectionEntity
+import com.novel.read.utils.StringUtils
+
+data class ChannelResp(
+ val allType: List
+)
+
+data class AllType(
+ val bookTypeId: Long,
+ val categoryName: String,
+ val createTime: Long,
+ val validFlag: Int,
+ val typeImageUrl:String,
+ val bookCount :Int
+) : SectionEntity {
+ override val isHeader: Boolean
+ get() = false
+
+ fun getBChannel(): String {
+ return StringUtils.convertCC(categoryName)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/novel/read/data/model/ChannelSection.kt b/app/src/main/java/com/novel/read/data/model/ChannelSection.kt
new file mode 100644
index 0000000..2bc8941
--- /dev/null
+++ b/app/src/main/java/com/novel/read/data/model/ChannelSection.kt
@@ -0,0 +1,8 @@
+package com.novel.read.data.model
+
+import com.chad.library.adapter.base.entity.SectionEntity
+
+data class ChannelSection(
+ override val isHeader: Boolean,
+ val obj: Any
+) : SectionEntity
\ No newline at end of file
diff --git a/app/src/main/java/com/novel/read/data/model/ChapterContentResp.kt b/app/src/main/java/com/novel/read/data/model/ChapterContentResp.kt
new file mode 100644
index 0000000..bde4345
--- /dev/null
+++ b/app/src/main/java/com/novel/read/data/model/ChapterContentResp.kt
@@ -0,0 +1,16 @@
+package com.novel.read.data.model
+
+data class ChapterContentResp(
+ val chapter: ChapterContent
+)
+
+data class ChapterContent(
+ val bookId: Long,
+ val chapterContent: String,
+ val chapterId: Long,
+ val chapterIndex: Int,
+ val chapterName: String,
+ val chapterUrl: Any,
+ val createTime: Long,
+ val validFlag: Int
+)
\ No newline at end of file
diff --git a/app/src/main/java/com/novel/read/data/model/ChapterResp.kt b/app/src/main/java/com/novel/read/data/model/ChapterResp.kt
new file mode 100644
index 0000000..be34a63
--- /dev/null
+++ b/app/src/main/java/com/novel/read/data/model/ChapterResp.kt
@@ -0,0 +1,16 @@
+package com.novel.read.data.model
+
+data class ChapterResp(
+ val chapterList: List?,
+ val count: Int
+)
+
+data class Chapter(
+ val bookId: Long,
+ val chapterId: Long,
+ val chapterIndex: Int,
+ val chapterName: String,
+ val chapterUrl: String?,
+ val createTime: Long,
+ val validFlag: Int
+)
\ No newline at end of file
diff --git a/app/src/main/java/com/novel/read/data/model/ClickRank.kt b/app/src/main/java/com/novel/read/data/model/ClickRank.kt
new file mode 100644
index 0000000..865a281
--- /dev/null
+++ b/app/src/main/java/com/novel/read/data/model/ClickRank.kt
@@ -0,0 +1,51 @@
+package com.novel.read.data.model
+
+import com.chad.library.adapter.base.entity.MultiItemEntity
+import com.novel.read.constant.LayoutType
+import com.novel.read.utils.StringUtils
+
+data class ClickRank(
+ val authorInformation: String,
+ val authorName: String,
+ val authorUserId: Long,
+ val bookChannelId: Long,
+ val bookClass: Int,
+ val bookId: Long,
+ val bookName: String,
+ val bookSId: String,
+ val bookStatus: Int,
+ val bookTypeId: Int,
+ val categoryName: String,
+ val channelName: String,
+ val coverImageUrl: String,
+ val createTime: Long,
+ val endStatus: Int,
+ val extBookId: Int,
+ val hits: String,
+ val hotStatus: Int,
+ val introduction: String,
+ val keyWord: String,
+ val lastUpdateChapterDate: String,
+ val rankNumber: String,
+ val rankType: String,
+ val recommendStatus: Int,
+ val validFlag: Int,
+ val wordCount: Long
+){
+ fun getBAuthorName(): String {
+ return StringUtils.convertCC(authorName)
+ }
+
+ fun getBBookName(): String {
+ return StringUtils.convertCC(bookName)
+ }
+
+ fun getBCategoryName(): String {
+ return StringUtils.convertCC(categoryName)
+ }
+}
+
+data class ClickEntity(val clickRanks:List):MultiItemEntity{
+ override val itemType: Int
+ get() = LayoutType.CLICK
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/novel/read/data/model/Default.kt b/app/src/main/java/com/novel/read/data/model/Default.kt
new file mode 100644
index 0000000..a9450d9
--- /dev/null
+++ b/app/src/main/java/com/novel/read/data/model/Default.kt
@@ -0,0 +1,3 @@
+package com.novel.read.data.model
+
+class Default()
\ No newline at end of file
diff --git a/app/src/main/java/com/novel/read/data/model/EndRank.kt b/app/src/main/java/com/novel/read/data/model/EndRank.kt
new file mode 100644
index 0000000..4cbc584
--- /dev/null
+++ b/app/src/main/java/com/novel/read/data/model/EndRank.kt
@@ -0,0 +1,49 @@
+package com.novel.read.data.model
+
+import com.chad.library.adapter.base.entity.MultiItemEntity
+import com.novel.read.constant.LayoutType
+import com.novel.read.utils.StringUtils
+
+data class EndRank(
+ val authorInformation: String,
+ val authorName: String,
+ val authorUserId: Long,
+ val bookClass: Int,
+ val bookId: Long,
+ val bookName: String,
+ val bookSId: String,
+ val bookStatus: Int,
+ val bookTypeId: Int,
+ val categoryName: String,
+ val channelName: String,
+ val coverImageUrl: String,
+ val createTime: Long,
+ val endStatus: Int,
+ val extBookId: Int,
+ val hits: String,
+ val hotStatus: Int,
+ val introduction: String,
+ val keyWord: String,
+ val lastUpdateChapterDate: String,
+ val rankNumber: String,
+ val rankType: String,
+ val recommendStatus: Int,
+ val validFlag: Int
+){
+ fun getBAuthorName(): String {
+ return StringUtils.convertCC(authorName)
+ }
+
+ fun getBBookName(): String {
+ return StringUtils.convertCC(bookName)
+ }
+
+ fun getBCategoryName(): String {
+ return StringUtils.convertCC(categoryName)
+ }
+}
+
+data class EndEntity(val endRanks: List) : MultiItemEntity {
+ override val itemType: Int
+ get() = LayoutType.END
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/novel/read/data/model/GirlEndRank.kt b/app/src/main/java/com/novel/read/data/model/GirlEndRank.kt
new file mode 100644
index 0000000..27b33cd
--- /dev/null
+++ b/app/src/main/java/com/novel/read/data/model/GirlEndRank.kt
@@ -0,0 +1,51 @@
+package com.novel.read.data.model
+
+import com.chad.library.adapter.base.entity.MultiItemEntity
+import com.novel.read.constant.LayoutType
+import com.novel.read.utils.StringUtils
+
+data class GirlEndRank(
+ val authorInformation: String,
+ val authorName: String,
+ val authorUserId: Long,
+ val bookChannelId: Long,
+ val bookClass: Int,
+ val bookId: Long,
+ val bookName: String,
+ val bookSId: String,
+ val bookStatus: Int,
+ val bookTypeId: Long,
+ val categoryName: String,
+ val channelName: String,
+ val coverImageUrl: String,
+ val createTime: Long,
+ val endStatus: Int,
+ val extBookId: Int,
+ val hits: String,
+ val hotStatus: Int,
+ val introduction: String,
+ val keyWord: String,
+ val lastUpdateChapterDate: String,
+ val rankNumber: String,
+ val rankType: String,
+ val recommendStatus: Int,
+ val validFlag: Int,
+ val wordCount: Long
+){
+ fun getBAuthorName(): String {
+ return StringUtils.convertCC(authorName)
+ }
+
+ fun getBBookName(): String {
+ return StringUtils.convertCC(bookName)
+ }
+
+ fun getBCategoryName(): String {
+ return StringUtils.convertCC(categoryName)
+ }
+}
+
+data class GirlEndRankEntity(val girlEndRanks:List):MultiItemEntity{
+ override val itemType: Int
+ get() = LayoutType.GIRL_END
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/novel/read/data/model/GirlHotRank.kt b/app/src/main/java/com/novel/read/data/model/GirlHotRank.kt
new file mode 100644
index 0000000..5c2e054
--- /dev/null
+++ b/app/src/main/java/com/novel/read/data/model/GirlHotRank.kt
@@ -0,0 +1,51 @@
+package com.novel.read.data.model
+
+import com.chad.library.adapter.base.entity.MultiItemEntity
+import com.novel.read.constant.LayoutType
+import com.novel.read.utils.StringUtils
+
+data class GirlHotRank(
+ val authorInformation: String,
+ val authorName: String,
+ val authorUserId: Long,
+ val bookChannelId: Long,
+ val bookClass: Int,
+ val bookId: Long,
+ val bookName: String,
+ val bookSId: String,
+ val bookStatus: Int,
+ val bookTypeId: Long,
+ val categoryName: String,
+ val channelName: String,
+ val coverImageUrl: String,
+ val createTime: Long,
+ val endStatus: Int,
+ val extBookId: Int,
+ val hits: String,
+ val hotStatus: Int,
+ val introduction: String,
+ val keyWord: String,
+ val lastUpdateChapterDate: String,
+ val rankNumber: String,
+ val rankType: String,
+ val recommendStatus: Int,
+ val validFlag: Int
+){
+
+ fun getBAuthorName(): String {
+ return StringUtils.convertCC(authorName)
+ }
+
+ fun getBBookName(): String {
+ return StringUtils.convertCC(bookName)
+ }
+
+ fun getBCategoryName(): String {
+ return StringUtils.convertCC(categoryName)
+ }
+}
+
+data class GirlHotRankEntity(val girlHotRanks:List):MultiItemEntity{
+ override val itemType: Int
+ get() = LayoutType.GIRL_HOT
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/novel/read/data/model/GirlSearchRank.kt b/app/src/main/java/com/novel/read/data/model/GirlSearchRank.kt
new file mode 100644
index 0000000..14f52ee
--- /dev/null
+++ b/app/src/main/java/com/novel/read/data/model/GirlSearchRank.kt
@@ -0,0 +1,51 @@
+package com.novel.read.data.model
+
+import com.chad.library.adapter.base.entity.MultiItemEntity
+import com.novel.read.constant.LayoutType
+import com.novel.read.utils.StringUtils
+
+data class GirlSearchRank(
+ val authorInformation: String,
+ val authorName: String,
+ val authorUserId: Long,
+ val bookChannelId: Long,
+ val bookClass: Int,
+ val bookId: Long,
+ val bookName: String,
+ val bookSId: String,
+ val bookStatus: Int,
+ val bookTypeId: Long,
+ val categoryName: String,
+ val channelName: String,
+ val coverImageUrl: String,
+ val createTime: Long,
+ val endStatus: Int,
+ val extBookId: Int,
+ val hits: String,
+ val hotStatus: Int,
+ val introduction: String,
+ val keyWord: String,
+ val lastUpdateChapterDate: String,
+ val rankNumber: String,
+ val rankType: String,
+ val recommendStatus: Int,
+ val validFlag: Int
+){
+
+ fun getBAuthorName(): String {
+ return StringUtils.convertCC(authorName)
+ }
+
+ fun getBBookName(): String {
+ return StringUtils.convertCC(bookName)
+ }
+
+ fun getBCategoryName(): String {
+ return StringUtils.convertCC(categoryName)
+ }
+}
+
+data class GirlSearchRankEntity(val girlSearchRanks:List):MultiItemEntity{
+ override val itemType: Int
+ get() = LayoutType.GIRL_SEARCH
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/novel/read/data/model/GoodsResp.kt b/app/src/main/java/com/novel/read/data/model/GoodsResp.kt
new file mode 100644
index 0000000..49e42e5
--- /dev/null
+++ b/app/src/main/java/com/novel/read/data/model/GoodsResp.kt
@@ -0,0 +1,15 @@
+package com.novel.read.data.model
+
+data class GoodsResp(
+ val bookCommodityClass: Int,
+ val bookCommodityId: Long,
+ val commodityCode: String,
+ val commodityCurrentValuation: Int,
+ val commodityName: String,
+ val commodityValuation: Int,
+ val createTime: Long,
+ val discount: Int,
+ val remark: String,
+ val thirdCommodityNumber: String,
+ val validFlag: Int
+)
\ No newline at end of file
diff --git a/app/src/main/java/com/novel/read/data/model/HomeBanner.kt b/app/src/main/java/com/novel/read/data/model/HomeBanner.kt
new file mode 100644
index 0000000..c528876
--- /dev/null
+++ b/app/src/main/java/com/novel/read/data/model/HomeBanner.kt
@@ -0,0 +1,11 @@
+package com.novel.read.data.model
+
+data class HomeBanner(
+ val bannerId: Int,
+ val bookChannelId: Long,
+ val bookId: Int,
+ val createTime: String,
+ val imgUrl: String,
+ val isDel: Int,
+ val type: Int
+)
\ No newline at end of file
diff --git a/app/src/main/java/com/novel/read/data/model/HomeResp.kt b/app/src/main/java/com/novel/read/data/model/HomeResp.kt
new file mode 100644
index 0000000..8adcf6a
--- /dev/null
+++ b/app/src/main/java/com/novel/read/data/model/HomeResp.kt
@@ -0,0 +1,16 @@
+package com.novel.read.data.model
+
+data class HomeResp(
+ val wordNumRank: List,
+ val clickRank: List,
+ val starRank: List,
+ val recommendRank: List,
+
+ val boyHotRank: List,
+ val boyEndRank: List,
+ val boyHotSearchRank: List,
+
+ val girlHotRank: List,
+ val girlEndRank: List,
+ val girlHotSearchRank: List,
+)
\ No newline at end of file
diff --git a/app/src/main/java/com/novel/read/data/model/HotRank.kt b/app/src/main/java/com/novel/read/data/model/HotRank.kt
new file mode 100644
index 0000000..3942806
--- /dev/null
+++ b/app/src/main/java/com/novel/read/data/model/HotRank.kt
@@ -0,0 +1,45 @@
+package com.novel.read.data.model
+
+import com.chad.library.adapter.base.entity.MultiItemEntity
+import com.novel.read.constant.LayoutType
+import com.novel.read.utils.StringUtils
+
+data class HotRank(
+ val authorInformation: String,
+ val authorName: String,
+ val authorUserId: Long,
+ val bookClass: Int,
+ val bookId: Long,
+ val bookName: String,
+ val bookSId: String,
+ val bookStatus: Int,
+ val bookTypeId: Int,
+ val categoryName: String,
+ val channelName: String,
+ val coverImageUrl: String,
+ val createTime: Long,
+ val endStatus: Int,
+ val extBookId: Int,
+ val hits: String,
+ val hotStatus: Int,
+ val introduction: String,
+ val keyWord: String,
+ val lastUpdateChapterDate: String,
+ val rankNumber: String,
+ val rankType: String,
+ val recommendStatus: Int,
+ val validFlag: Int
+){
+ fun getBName(): String {
+ return StringUtils.convertCC(bookName)
+ }
+
+ fun getBAuthor(): String {
+ return StringUtils.convertCC(authorName)
+ }
+}
+
+data class HotEntity(val hotRanks: List) : MultiItemEntity {
+ override val itemType: Int
+ get() = LayoutType.HOT
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/novel/read/data/model/LoginReq.kt b/app/src/main/java/com/novel/read/data/model/LoginReq.kt
new file mode 100644
index 0000000..77b2331
--- /dev/null
+++ b/app/src/main/java/com/novel/read/data/model/LoginReq.kt
@@ -0,0 +1,21 @@
+package com.novel.read.data.model
+
+data class LoginReq(
+ val email: String,
+ val headImageUrl: String,
+ val idToken: String,
+ val ip: String,
+ var isEmailVerified: Int,
+ val nickName: String,
+ val os: String = "Android",
+ val phone: String,
+ val provider: String
+){
+ fun setIsEmail(boolean: Boolean){
+ isEmailVerified = if (boolean){
+ 0
+ }else{
+ 1
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/novel/read/data/model/Pagination.kt b/app/src/main/java/com/novel/read/data/model/Pagination.kt
new file mode 100644
index 0000000..da2db28
--- /dev/null
+++ b/app/src/main/java/com/novel/read/data/model/Pagination.kt
@@ -0,0 +1,14 @@
+package com.novel.read.data.model
+
+import androidx.annotation.Keep
+
+/**
+ * Created by xiaojianjun on 2019-11-07.
+ */
+@Keep
+data class Pagination(
+ val count: Int,
+ val bookList: MutableList,
+ val bookRankList: MutableList,
+ val searchTermsList: MutableList
+)
\ No newline at end of file
diff --git a/app/src/main/java/com/novel/read/data/model/PaginationSimilar.kt b/app/src/main/java/com/novel/read/data/model/PaginationSimilar.kt
new file mode 100644
index 0000000..55f6eb0
--- /dev/null
+++ b/app/src/main/java/com/novel/read/data/model/PaginationSimilar.kt
@@ -0,0 +1,9 @@
+package com.novel.read.data.model
+
+import androidx.annotation.Keep
+
+
+@Keep
+data class PaginationSimilar(
+ val recommendBookList: MutableList
+)
\ No newline at end of file
diff --git a/app/src/main/java/com/novel/read/data/model/RecommendRank.kt b/app/src/main/java/com/novel/read/data/model/RecommendRank.kt
new file mode 100644
index 0000000..ca20870
--- /dev/null
+++ b/app/src/main/java/com/novel/read/data/model/RecommendRank.kt
@@ -0,0 +1,53 @@
+package com.novel.read.data.model
+
+import com.chad.library.adapter.base.entity.MultiItemEntity
+import com.novel.read.constant.LayoutType
+import com.novel.read.utils.StringUtils
+
+data class RecommendRank(
+ val authorInformation: String,
+ val authorName: String,
+ val authorUserId: Long,
+ val bookClass: Int,
+ val bookId: Long,
+ val bookName: String,
+ val bookSId: String,
+ val bookStatus: Int,
+ val bookTypeId: Int,
+ val categoryName: String,
+ val channelName: String,
+ val coverImageUrl: String,
+ val createTime: Long,
+ val endStatus: Int,
+ val extBookId: Int,
+ val hits: String,
+ val hotStatus: Int,
+ val introduction: String,
+ val keyWord: String,
+ val lastUpdateChapterDate: String,
+ val rankNumber: String,
+ val rankType: String,
+ val recommendStatus: Int,
+ val validFlag: Int
+) : MultiItemEntity {
+ override val itemType: Int
+ get() = LayoutType.RECOMMEND
+
+ fun getBAuthorName(): String {
+ return StringUtils.convertCC(authorName)
+ }
+
+ fun getBBookName(): String {
+ return StringUtils.convertCC(bookName)
+ }
+
+ fun getBCategoryName(): String {
+ return StringUtils.convertCC(categoryName)
+ }
+
+}
+
+data class RecommendEntity(val recommendRanks: List) : MultiItemEntity {
+ override val itemType: Int
+ get() = LayoutType.RECOMMEND
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/novel/read/data/model/SearchResp.kt b/app/src/main/java/com/novel/read/data/model/SearchResp.kt
new file mode 100644
index 0000000..0f9c4ad
--- /dev/null
+++ b/app/src/main/java/com/novel/read/data/model/SearchResp.kt
@@ -0,0 +1,53 @@
+package com.novel.read.data.model
+
+import com.novel.read.utils.StringUtils
+
+data class SearchResp(
+ val authorInformation: String,
+ val authorName: String,
+ val authorUserId: Long,
+ val bookChannelId: Long,
+ val bookClass: Int,
+ val bookId: Long,
+ val bookName: String,
+ val bookSId: String,
+ val bookStatus: Int,
+ val bookTypeId: Int,
+ val categoryName: String,
+ val channelName: String,
+ val coverImageUrl: String,
+ val createTime: Long,
+ val endStatus: Int,
+ val extBookId: Int,
+ val hotStatus: Int,
+ val introduction: String,
+ val keyWord: String,
+ val lastUpdateChapterDate: String,
+ val recommendStatus: Int,
+ val validFlag: Int,
+ val wordCount: Long,
+){
+ fun getBAuthorName(): String {
+ return StringUtils.convertCC(authorName)
+ }
+
+ fun getBBookName(): String {
+ return StringUtils.convertCC(bookName)
+ }
+
+ fun getBCategoryName(): String {
+ return StringUtils.convertCC(categoryName)
+ }
+
+ fun getBChannel(): String {
+ return StringUtils.convertCC(channelName)
+ }
+
+ fun getBIntroduction(): String {
+ return StringUtils.convertCC(introduction)
+ }
+
+ fun getBKeyWord(): String {
+ return StringUtils.convertCC(keyWord)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/novel/read/data/model/Tools.kt b/app/src/main/java/com/novel/read/data/model/Tools.kt
new file mode 100644
index 0000000..aecd2d5
--- /dev/null
+++ b/app/src/main/java/com/novel/read/data/model/Tools.kt
@@ -0,0 +1,5 @@
+package com.novel.read.data.model
+
+class Tools(var title: String, var img: Int) {
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/novel/read/data/model/TypeEntity.kt b/app/src/main/java/com/novel/read/data/model/TypeEntity.kt
new file mode 100644
index 0000000..2a6c108
--- /dev/null
+++ b/app/src/main/java/com/novel/read/data/model/TypeEntity.kt
@@ -0,0 +1,9 @@
+package com.novel.read.data.model
+
+import com.chad.library.adapter.base.entity.MultiItemEntity
+import com.novel.read.constant.LayoutType
+
+class TypeEntity: MultiItemEntity {
+ override val itemType: Int
+ get() = LayoutType.OTHER
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/novel/read/data/model/TypeName.kt b/app/src/main/java/com/novel/read/data/model/TypeName.kt
new file mode 100644
index 0000000..4adbf20
--- /dev/null
+++ b/app/src/main/java/com/novel/read/data/model/TypeName.kt
@@ -0,0 +1,69 @@
+package com.novel.read.data.model
+
+import com.novel.read.App
+import com.novel.read.R
+import com.novel.read.constant.LayoutType
+import kotlin.collections.ArrayList
+
+
+data class TypeName(
+ val rankType: Int,
+ val name: String,
+ var check: Boolean
+) {
+
+
+}
+
+fun rankList(layoutType: Int): List {
+ val list: MutableList =
+ ArrayList()
+ list.clear()
+ list.add(TypeName(LayoutType.HOT, App.INSTANCE.getString(R.string.big_hot_title), false))
+ list.add(TypeName(LayoutType.CLICK, App.INSTANCE.getString(R.string.click_title), false))
+ list.add(
+ TypeName(
+ LayoutType.RECOMMEND,
+ App.INSTANCE.getString(R.string.recommend_title),
+ false
+ )
+ )
+ list.add(TypeName(LayoutType.END, App.INSTANCE.getString(R.string.end_title), false))
+
+ list[layoutType - 1].check = true
+ return list
+}
+
+fun manList(layoutType: Int): List {
+ val list: MutableList =
+ ArrayList()
+ list.clear()
+ list.add(TypeName(LayoutType.BOY_HOT, App.INSTANCE.getString(R.string.big_hot_title), false))
+ list.add(TypeName(LayoutType.BOY_END, App.INSTANCE.getString(R.string.end_title2), false))
+ list.add(
+ TypeName(
+ LayoutType.BOY_SEARCH,
+ App.INSTANCE.getString(R.string.hot_search_title),
+ false
+ )
+ )
+ list[layoutType - 6].check = true
+ return list
+}
+
+fun womanList(layoutType: Int): List {
+ val list: MutableList =
+ ArrayList()
+ list.clear()
+ list.add(TypeName(LayoutType.GIRL_HOT, App.INSTANCE.getString(R.string.big_hot_title), false))
+ list.add(TypeName(LayoutType.GIRL_END, App.INSTANCE.getString(R.string.end_title2), false))
+ list.add(
+ TypeName(
+ LayoutType.GIRL_SEARCH,
+ App.INSTANCE.getString(R.string.hot_search_title),
+ false
+ )
+ )
+ list[layoutType - 9].check = true
+ return list
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/novel/read/data/model/UserResp.kt b/app/src/main/java/com/novel/read/data/model/UserResp.kt
new file mode 100644
index 0000000..942093e
--- /dev/null
+++ b/app/src/main/java/com/novel/read/data/model/UserResp.kt
@@ -0,0 +1,32 @@
+package com.novel.read.data.model
+
+import com.novel.read.data.db.entity.User
+
+data class UserResp(
+ val user: User
+)
+//
+//data class User(
+// val createTime: Long,
+// val email: String,
+// val headImageUrl: String,
+// val idToken: String,
+// val introduction: Any,
+// val ip: String,
+// val isEmailVerified: Int,
+// val lastLoginTime: Any,
+// val nickName: String,
+// val oldNickName: Any,
+// val os: String,
+// val password: String,
+// val phone: String,
+// val provider: String,
+// val sex: Any,
+// val updateTime: Any,
+// val userId: Long,
+// val userName: String,
+// val validFlag: Int,
+// val vipEndTime: Any,
+// val vipStartTime: Any,
+// val vipStatus: Int
+//)
\ No newline at end of file
diff --git a/app/src/main/java/com/novel/read/data/read/TextChapter.kt b/app/src/main/java/com/novel/read/data/read/TextChapter.kt
new file mode 100644
index 0000000..463321e
--- /dev/null
+++ b/app/src/main/java/com/novel/read/data/read/TextChapter.kt
@@ -0,0 +1,54 @@
+package com.novel.read.data.read
+
+import kotlin.math.min
+
+data class TextChapter(
+ val position: Int,
+ val title: String,
+ val chapterId: Int,
+ val pages: List,
+ val pageLines: List,
+ val pageLengths: List,
+ val chaptersSize: Int
+) {
+ fun page(index: Int): TextPage? {
+ return pages.getOrNull(index)
+ }
+
+ val lastPage: TextPage? get() = pages.lastOrNull()
+
+ val lastIndex: Int get() = pages.lastIndex
+
+ val pageSize: Int get() = pages.size
+
+ fun isLastIndex(index: Int): Boolean {
+ return index >= pages.size - 1
+ }
+
+ fun getReadLength(pageIndex: Int): Int {
+ var length = 0
+ val maxIndex = min(pageIndex, pages.size)
+ for (index in 0 until maxIndex) {
+ length += pageLengths[index]
+ }
+ return length
+ }
+
+ fun getUnRead(pageIndex: Int): String {
+ val stringBuilder = StringBuilder()
+ if (pages.isNotEmpty()) {
+ for (index in pageIndex..pages.lastIndex) {
+ stringBuilder.append(pages[index].text)
+ }
+ }
+ return stringBuilder.toString()
+ }
+
+ fun getContent(): String {
+ val stringBuilder = StringBuilder()
+ pages.forEach {
+ stringBuilder.append(it.text)
+ }
+ return stringBuilder.toString()
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/novel/read/data/read/TextChar.kt b/app/src/main/java/com/novel/read/data/read/TextChar.kt
new file mode 100644
index 0000000..03400b3
--- /dev/null
+++ b/app/src/main/java/com/novel/read/data/read/TextChar.kt
@@ -0,0 +1,9 @@
+package com.novel.read.data.read
+
+data class TextChar(
+ val charData: String,
+ var start: Float,
+ var end: Float,
+ var selected: Boolean = false,
+ var isImage: Boolean = false
+)
\ No newline at end of file
diff --git a/app/src/main/java/com/novel/read/data/read/TextLine.kt b/app/src/main/java/com/novel/read/data/read/TextLine.kt
new file mode 100644
index 0000000..237a252
--- /dev/null
+++ b/app/src/main/java/com/novel/read/data/read/TextLine.kt
@@ -0,0 +1,39 @@
+package com.novel.read.data.read
+
+import android.text.TextPaint
+import io.legado.app.ui.book.read.page.provider.ChapterProvider
+import io.legado.app.ui.book.read.page.provider.ChapterProvider.textHeight
+
+data class TextLine(
+ var text: String = "",
+ val textChars: ArrayList = arrayListOf(),
+ var lineTop: Float = 0f,
+ var lineBase: Float = 0f,
+ var lineBottom: Float = 0f,
+ val isTitle: Boolean = false,
+ val isImage: Boolean = false,
+ var isReadAloud: Boolean = false
+) {
+
+ fun upTopBottom(durY: Float, textPaint: TextPaint) {
+ lineTop = ChapterProvider.paddingTop + durY
+ lineBottom = lineTop + textPaint.textHeight
+ lineBase = lineBottom - textPaint.fontMetrics.descent
+ }
+
+ fun addTextChar(charData: String, start: Float, end: Float) {
+ textChars.add(TextChar(charData, start = start, end = end))
+ }
+
+ fun getTextCharAt(index: Int): TextChar {
+ return textChars[index]
+ }
+
+ fun getTextCharReverseAt(index: Int): TextChar {
+ return textChars[textChars.lastIndex - index]
+ }
+
+ fun getTextCharsCount(): Int {
+ return textChars.size
+ }
+}
diff --git a/app/src/main/java/com/novel/read/data/read/TextPage.kt b/app/src/main/java/com/novel/read/data/read/TextPage.kt
new file mode 100644
index 0000000..25189e1
--- /dev/null
+++ b/app/src/main/java/com/novel/read/data/read/TextPage.kt
@@ -0,0 +1,122 @@
+package com.novel.read.data.read
+
+import android.text.Layout
+import android.text.StaticLayout
+import com.novel.read.App
+import com.novel.read.R
+import com.novel.read.help.ReadBookConfig
+import io.legado.app.ui.book.read.page.provider.ChapterProvider
+import java.text.DecimalFormat
+
+data class TextPage(
+ var index: Int = 0,
+ var text: String = App.INSTANCE.getString(R.string.data_loading),
+ var title: String = "",
+ val textLines: ArrayList = arrayListOf(),
+ var pageSize: Int = 0,
+ var chapterSize: Int = 0,
+ var chapterIndex: Int = 0,
+ var height: Float = 0f
+) {
+
+ fun upLinesPosition() = ChapterProvider.apply {
+ if (!ReadBookConfig.textBottomJustify) return@apply
+ if (textLines.size <= 1) return@apply
+ if (textLines.last().isImage) return@apply
+ if (visibleHeight - height >= with(textLines.last()) { lineBottom - lineTop }) return@apply
+ val surplus = (visibleBottom - textLines.last().lineBottom)
+ if (surplus == 0f) return@apply
+ height += surplus
+ val tj = surplus / (textLines.size - 1)
+ for (i in 1 until textLines.size) {
+ val line = textLines[i]
+ line.lineTop = line.lineTop + tj * i
+ line.lineBase = line.lineBase + tj * i
+ line.lineBottom = line.lineBottom + tj * i
+ }
+ }
+
+ @Suppress("DEPRECATION")
+ fun format(): TextPage {
+ if (textLines.isEmpty() && ChapterProvider.visibleWidth > 0) {
+ val layout = StaticLayout(
+ text, ChapterProvider.contentPaint, ChapterProvider.visibleWidth,
+ Layout.Alignment.ALIGN_NORMAL, 1f, 0f, false
+ )
+ var y = (ChapterProvider.visibleHeight - layout.height) / 2f
+ if (y < 0) y = 0f
+ for (lineIndex in 0 until layout.lineCount) {
+ val textLine = TextLine()
+ textLine.lineTop = ChapterProvider.paddingTop + y + layout.getLineTop(lineIndex)
+ textLine.lineBase =
+ ChapterProvider.paddingTop + y + layout.getLineBaseline(lineIndex)
+ textLine.lineBottom =
+ ChapterProvider.paddingTop + y + layout.getLineBottom(lineIndex)
+ var x = ChapterProvider.paddingLeft +
+ (ChapterProvider.visibleWidth - layout.getLineMax(lineIndex)) / 2
+ textLine.text =
+ text.substring(layout.getLineStart(lineIndex), layout.getLineEnd(lineIndex))
+ for (i in textLine.text.indices) {
+ val char = textLine.text[i].toString()
+ val cw = StaticLayout.getDesiredWidth(char, ChapterProvider.contentPaint)
+ val x1 = x + cw
+ textLine.addTextChar(charData = char, start = x, end = x1)
+ x = x1
+ }
+ textLines.add(textLine)
+ }
+ height = ChapterProvider.visibleHeight.toFloat()
+ }
+ return this
+ }
+
+ fun removePageAloudSpan(): TextPage {
+ textLines.forEach { textLine ->
+ textLine.isReadAloud = false
+ }
+ return this
+ }
+
+ fun upPageAloudSpan(pageStart: Int) {
+ removePageAloudSpan()
+ var lineStart = 0
+ for ((index, textLine) in textLines.withIndex()) {
+ if (pageStart > lineStart && pageStart < lineStart + textLine.text.length) {
+ for (i in index - 1 downTo 0) {
+ if (textLines[i].text.endsWith("\n")) {
+ break
+ } else {
+ textLines[i].isReadAloud = true
+ }
+ }
+ for (i in index until textLines.size) {
+ if (textLines[i].text.endsWith("\n")) {
+ textLines[i].isReadAloud = true
+ break
+ } else {
+ textLines[i].isReadAloud = true
+ }
+ }
+ break
+ }
+ lineStart += textLine.text.length
+ }
+ }
+
+ val readProgress: String
+ get() {
+ val df = DecimalFormat("0.0%")
+ if (chapterSize == 0 || pageSize == 0 && chapterIndex == 0) {
+ return "0.0%"
+ } else if (pageSize == 0) {
+ return df.format((chapterIndex + 1.0f) / chapterSize.toDouble())
+ }
+ var percent =
+ df.format(chapterIndex * 1.0f / chapterSize + 1.0f / chapterSize * (index + 1) / pageSize.toDouble())
+ if (percent == "100.0%" && (chapterIndex + 1 != chapterSize || index + 1 != pageSize)) {
+ percent = "99.9%"
+ }
+ return percent
+ }
+
+}
diff --git a/app/src/main/java/com/novel/read/event/AddBookSignEvent.kt b/app/src/main/java/com/novel/read/event/AddBookSignEvent.kt
deleted file mode 100644
index 4566d2a..0000000
--- a/app/src/main/java/com/novel/read/event/AddBookSignEvent.kt
+++ /dev/null
@@ -1,14 +0,0 @@
-package com.novel.read.event
-
-import com.mango.mangolib.event.BaseEvent
-import com.mango.mangolib.http.ErrorResponse
-
-/**
- * create by 赵利君 on 2019/6/25
- * describe:
- */
-class AddBookSignEvent : BaseEvent {
- constructor(result: ErrorResponse) : super(result) {}
-
- constructor() {}
-}
diff --git a/app/src/main/java/com/novel/read/event/BookArticleEvent.kt b/app/src/main/java/com/novel/read/event/BookArticleEvent.kt
deleted file mode 100644
index 9901bb1..0000000
--- a/app/src/main/java/com/novel/read/event/BookArticleEvent.kt
+++ /dev/null
@@ -1,15 +0,0 @@
-package com.novel.read.event
-
-import com.mango.mangolib.event.BaseEvent
-import com.novel.read.model.protocol.BookArticleResp
-
-/**
- * create by 赵利君 on 2019/6/18
- * describe:
- */
-class BookArticleEvent : BaseEvent {
-
- constructor(result: BookArticleResp) : super(result) {}
-
- constructor() {}
-}
diff --git a/app/src/main/java/com/novel/read/event/DeleteBookSignEvent.kt b/app/src/main/java/com/novel/read/event/DeleteBookSignEvent.kt
deleted file mode 100644
index ee62dbd..0000000
--- a/app/src/main/java/com/novel/read/event/DeleteBookSignEvent.kt
+++ /dev/null
@@ -1,10 +0,0 @@
-package com.novel.read.event
-
-import com.mango.mangolib.event.BaseEvent
-import com.mango.mangolib.http.ErrorResponse
-
-class DeleteBookSignEvent : BaseEvent{
- constructor(result: ErrorResponse) : super(result) {}
-
- constructor() {}
-}
diff --git a/app/src/main/java/com/novel/read/event/DeleteResponseEvent.kt b/app/src/main/java/com/novel/read/event/DeleteResponseEvent.kt
deleted file mode 100644
index 1691041..0000000
--- a/app/src/main/java/com/novel/read/event/DeleteResponseEvent.kt
+++ /dev/null
@@ -1,7 +0,0 @@
-package com.novel.read.event
-
-import com.mango.mangolib.event.BaseEvent
-import com.novel.read.model.db.CollBookBean
-
-class DeleteResponseEvent(var isDelete: Boolean, var collBook: CollBookBean) : BaseEvent()
-
diff --git a/app/src/main/java/com/novel/read/event/DeleteTaskEvent.kt b/app/src/main/java/com/novel/read/event/DeleteTaskEvent.kt
deleted file mode 100644
index 4474419..0000000
--- a/app/src/main/java/com/novel/read/event/DeleteTaskEvent.kt
+++ /dev/null
@@ -1,6 +0,0 @@
-package com.novel.read.event
-
-import com.mango.mangolib.event.BaseEvent
-import com.novel.read.model.db.CollBookBean
-
-class DeleteTaskEvent(var collBook: CollBookBean) : BaseEvent()
diff --git a/app/src/main/java/com/novel/read/event/EditEvent.kt b/app/src/main/java/com/novel/read/event/EditEvent.kt
deleted file mode 100644
index 5cf201a..0000000
--- a/app/src/main/java/com/novel/read/event/EditEvent.kt
+++ /dev/null
@@ -1,15 +0,0 @@
-package com.novel.read.event
-
-import com.mango.mangolib.event.BaseEvent
-import com.novel.read.model.protocol.RecommendListResp
-
-/**
- * create by 赵利君 on 2019/6/18
- * describe:
- */
-class EditEvent : BaseEvent {
-
- constructor(result: RecommendListResp) : super(result) {}
-
- constructor() {}
-}
diff --git a/app/src/main/java/com/novel/read/event/ErrorChapterEvent.kt b/app/src/main/java/com/novel/read/event/ErrorChapterEvent.kt
deleted file mode 100644
index b65bead..0000000
--- a/app/src/main/java/com/novel/read/event/ErrorChapterEvent.kt
+++ /dev/null
@@ -1,9 +0,0 @@
-package com.novel.read.event
-
-import com.mango.mangolib.event.BaseEvent
-
-class ErrorChapterEvent : BaseEvent {
- constructor(result: Any) : super(result)
-
- constructor()
-}
diff --git a/app/src/main/java/com/novel/read/event/FinishChapterEvent.kt b/app/src/main/java/com/novel/read/event/FinishChapterEvent.kt
deleted file mode 100644
index d2d7a6c..0000000
--- a/app/src/main/java/com/novel/read/event/FinishChapterEvent.kt
+++ /dev/null
@@ -1,9 +0,0 @@
-package com.novel.read.event
-
-import com.mango.mangolib.event.BaseEvent
-
-class FinishChapterEvent : BaseEvent {
- constructor(result: Any) : super(result)
-
- constructor()
-}
diff --git a/app/src/main/java/com/novel/read/event/GetBookDetailEvent.kt b/app/src/main/java/com/novel/read/event/GetBookDetailEvent.kt
deleted file mode 100644
index d5bc678..0000000
--- a/app/src/main/java/com/novel/read/event/GetBookDetailEvent.kt
+++ /dev/null
@@ -1,15 +0,0 @@
-package com.novel.read.event
-
-import com.mango.mangolib.event.BaseEvent
-import com.novel.read.model.protocol.BookDetailResp
-
-/**
- * create by 赵利君 on 2019/6/18
- * describe:
- */
-class GetBookDetailEvent : BaseEvent {
-
- constructor(result: BookDetailResp) : super(result) {}
-
- constructor() {}
-}
diff --git a/app/src/main/java/com/novel/read/event/GetBookSignEvent.kt b/app/src/main/java/com/novel/read/event/GetBookSignEvent.kt
deleted file mode 100644
index 9e8b03b..0000000
--- a/app/src/main/java/com/novel/read/event/GetBookSignEvent.kt
+++ /dev/null
@@ -1,14 +0,0 @@
-package com.novel.read.event
-
-import com.mango.mangolib.event.BaseEvent
-import com.novel.read.model.protocol.MarkResp
-
-/**
- * create by 赵利君 on 2019/6/25
- * describe:
- */
-class GetBookSignEvent : BaseEvent {
- constructor(result: MarkResp) : super(result) {}
-
- constructor() {}
-}
diff --git a/app/src/main/java/com/novel/read/event/GetCategoryTypeEvent.kt b/app/src/main/java/com/novel/read/event/GetCategoryTypeEvent.kt
deleted file mode 100644
index 88c8e64..0000000
--- a/app/src/main/java/com/novel/read/event/GetCategoryTypeEvent.kt
+++ /dev/null
@@ -1,15 +0,0 @@
-package com.novel.read.event
-
-import com.mango.mangolib.event.BaseEvent
-import com.novel.read.model.protocol.CategoryTypeResp
-
-/**
- * create by zlj on 2019/6/18
- * describe:
- */
-class GetCategoryTypeEvent : BaseEvent {
-
- constructor(result: CategoryTypeResp) : super(result) {}
-
- constructor() {}
-}
diff --git a/app/src/main/java/com/novel/read/event/GetRecommendBookEvent.kt b/app/src/main/java/com/novel/read/event/GetRecommendBookEvent.kt
deleted file mode 100644
index fbdeff5..0000000
--- a/app/src/main/java/com/novel/read/event/GetRecommendBookEvent.kt
+++ /dev/null
@@ -1,15 +0,0 @@
-package com.novel.read.event
-
-import com.mango.mangolib.event.BaseEvent
-import com.novel.read.model.protocol.RecommendBookResp
-
-/**
- * create by 赵利君 on 2019/6/18
- * describe:
- */
-class GetRecommendBookEvent : BaseEvent {
-
- constructor(result: RecommendBookResp) : super(result) {}
-
- constructor() {}
-}
diff --git a/app/src/main/java/com/novel/read/event/HideBottomBarEvent.kt b/app/src/main/java/com/novel/read/event/HideBottomBarEvent.kt
deleted file mode 100644
index a9f7469..0000000
--- a/app/src/main/java/com/novel/read/event/HideBottomBarEvent.kt
+++ /dev/null
@@ -1,5 +0,0 @@
-package com.novel.read.event
-
-import com.mango.mangolib.event.BaseEvent
-
-class HideBottomBarEvent(result: Boolean?) : BaseEvent(result!!)
diff --git a/app/src/main/java/com/novel/read/event/HotSearchEvent.kt b/app/src/main/java/com/novel/read/event/HotSearchEvent.kt
deleted file mode 100644
index 06b220e..0000000
--- a/app/src/main/java/com/novel/read/event/HotSearchEvent.kt
+++ /dev/null
@@ -1,16 +0,0 @@
-package com.novel.read.event
-
-import com.mango.mangolib.event.BaseEvent
-import com.novel.read.model.protocol.HotSearchResp
-import com.novel.read.model.protocol.SearchResp
-
-/**
- * create by zlj on 2019/6/18
- * describe:
- */
-class HotSearchEvent : BaseEvent{
-
- constructor(result: HotSearchResp) : super(result) {}
-
- constructor() {}
-}
diff --git a/app/src/main/java/com/novel/read/event/HumanEvent.kt b/app/src/main/java/com/novel/read/event/HumanEvent.kt
deleted file mode 100644
index 43025b1..0000000
--- a/app/src/main/java/com/novel/read/event/HumanEvent.kt
+++ /dev/null
@@ -1,16 +0,0 @@
-package com.novel.read.event
-
-
-import com.mango.mangolib.event.BaseEvent
-import com.novel.read.model.protocol.RecommendListResp
-
-/**
- * create by 赵利君 on 2019/6/18
- * describe:
- */
-class HumanEvent : BaseEvent {
-
- constructor(result: RecommendListResp) : super(result) {}
-
- constructor() {}
-}
diff --git a/app/src/main/java/com/novel/read/event/LoginEvent.kt b/app/src/main/java/com/novel/read/event/LoginEvent.kt
deleted file mode 100644
index 000e2bb..0000000
--- a/app/src/main/java/com/novel/read/event/LoginEvent.kt
+++ /dev/null
@@ -1,10 +0,0 @@
-package com.novel.read.event
-
-import com.mango.mangolib.event.BaseEvent
-import com.novel.read.model.protocol.UidResp
-
-class LoginEvent : BaseEvent {
- constructor(result: UidResp) : super(result) {}
-
- constructor() {}
-}
diff --git a/app/src/main/java/com/novel/read/event/RankByUpdateEvent.kt b/app/src/main/java/com/novel/read/event/RankByUpdateEvent.kt
deleted file mode 100644
index 4642e32..0000000
--- a/app/src/main/java/com/novel/read/event/RankByUpdateEvent.kt
+++ /dev/null
@@ -1,15 +0,0 @@
-package com.novel.read.event
-
-import com.mango.mangolib.event.BaseEvent
-import com.novel.read.model.protocol.RankByUpdateResp
-
-/**
- * create by 赵利君 on 2019/6/18
- * describe:
- */
-class RankByUpdateEvent : BaseEvent {
-
- constructor(result: RankByUpdateResp) : super(result) {}
-
- constructor() {}
-}
diff --git a/app/src/main/java/com/novel/read/event/ReStartEvent.java b/app/src/main/java/com/novel/read/event/ReStartEvent.java
deleted file mode 100644
index 39d1224..0000000
--- a/app/src/main/java/com/novel/read/event/ReStartEvent.java
+++ /dev/null
@@ -1,6 +0,0 @@
-package com.novel.read.event;
-
-import com.mango.mangolib.event.BaseEvent;
-
-public class ReStartEvent extends BaseEvent {
-}
diff --git a/app/src/main/java/com/novel/read/event/RecommendListEvent.kt b/app/src/main/java/com/novel/read/event/RecommendListEvent.kt
deleted file mode 100644
index c8fbf76..0000000
--- a/app/src/main/java/com/novel/read/event/RecommendListEvent.kt
+++ /dev/null
@@ -1,15 +0,0 @@
-package com.novel.read.event
-
-import com.mango.mangolib.event.BaseEvent
-import com.novel.read.model.protocol.RecommendListResp
-
-/**
- * create by 赵利君 on 2019/6/18
- * describe:
- */
-class RecommendListEvent : BaseEvent {
-
- constructor(result: RecommendListResp) : super(result) {}
-
- constructor() {}
-}
diff --git a/app/src/main/java/com/novel/read/event/RxBus.java b/app/src/main/java/com/novel/read/event/RxBus.java
deleted file mode 100644
index 1cd13e3..0000000
--- a/app/src/main/java/com/novel/read/event/RxBus.java
+++ /dev/null
@@ -1,74 +0,0 @@
-package com.novel.read.event;
-
-import io.reactivex.Observable;
-import io.reactivex.subjects.PublishSubject;
-
-public class RxBus {
- private static volatile RxBus sInstance;
- private final PublishSubject