Compare commits
2 Commits
Author | SHA1 | Date |
---|---|---|
Z | 2f55751ef0 | 4 years ago |
Z | b7207b761f | 4 years ago |
@ -1,3 +0,0 @@ |
|||||||
# Default ignored files |
|
||||||
/shelf/ |
|
||||||
/workspace.xml |
|
@ -1,6 +0,0 @@ |
|||||||
<?xml version="1.0" encoding="UTF-8"?> |
|
||||||
<project version="4"> |
|
||||||
<component name="CompilerConfiguration"> |
|
||||||
<bytecodeTargetLevel target="1.8" /> |
|
||||||
</component> |
|
||||||
</project> |
|
@ -1,7 +0,0 @@ |
|||||||
<component name="ProjectDictionaryState"> |
|
||||||
<dictionary name="Administrator"> |
|
||||||
<words> |
|
||||||
<w>umeng</w> |
|
||||||
</words> |
|
||||||
</dictionary> |
|
||||||
</component> |
|
@ -0,0 +1,4 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||||
|
<project version="4"> |
||||||
|
<component name="Encoding" addBOMForNewFiles="with NO BOM" /> |
||||||
|
</project> |
@ -0,0 +1,86 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||||
|
<project version="4"> |
||||||
|
<component name="MarkdownProjectSettings" wasCopied="false"> |
||||||
|
<PreviewSettings splitEditorLayout="SPLIT" splitEditorPreview="PREVIEW" useGrayscaleRendering="false" zoomFactor="1.0" maxImageWidth="0" showGitHubPageIfSynced="false" allowBrowsingInPreview="false" synchronizePreviewPosition="true" highlightPreviewType="NONE" highlightFadeOut="5" highlightOnTyping="true" synchronizeSourcePosition="true" verticallyAlignSourceAndPreviewSyncPosition="true" showSearchHighlightsInPreview="false" showSelectionInPreview="true" openRemoteLinks="true" replaceUnicodeEmoji="false" lastLayoutSetsDefault="false"> |
||||||
|
<PanelProvider> |
||||||
|
<provider providerId="com.vladsch.idea.multimarkdown.editor.swing.html.panel" providerName="Default - Swing" /> |
||||||
|
</PanelProvider> |
||||||
|
</PreviewSettings> |
||||||
|
<ParserSettings gitHubSyntaxChange="false" emojiShortcuts="1" emojiImages="0"> |
||||||
|
<PegdownExtensions> |
||||||
|
<option name="ABBREVIATIONS" value="false" /> |
||||||
|
<option name="ANCHORLINKS" value="true" /> |
||||||
|
<option name="ASIDE" value="false" /> |
||||||
|
<option name="ATXHEADERSPACE" value="true" /> |
||||||
|
<option name="AUTOLINKS" value="false" /> |
||||||
|
<option name="DEFINITIONS" value="false" /> |
||||||
|
<option name="DEFINITION_BREAK_DOUBLE_BLANK_LINE" value="false" /> |
||||||
|
<option name="FENCED_CODE_BLOCKS" value="true" /> |
||||||
|
<option name="FOOTNOTES" value="false" /> |
||||||
|
<option name="HARDWRAPS" value="false" /> |
||||||
|
<option name="HTML_DEEP_PARSER" value="false" /> |
||||||
|
<option name="INSERTED" value="false" /> |
||||||
|
<option name="QUOTES" value="false" /> |
||||||
|
<option name="RELAXEDHRULES" value="true" /> |
||||||
|
<option name="SMARTS" value="false" /> |
||||||
|
<option name="STRIKETHROUGH" value="true" /> |
||||||
|
<option name="SUBSCRIPT" value="false" /> |
||||||
|
<option name="SUPERSCRIPT" value="false" /> |
||||||
|
<option name="SUPPRESS_HTML_BLOCKS" value="false" /> |
||||||
|
<option name="SUPPRESS_INLINE_HTML" value="false" /> |
||||||
|
<option name="TABLES" value="true" /> |
||||||
|
<option name="TASKLISTITEMS" value="true" /> |
||||||
|
<option name="TOC" value="false" /> |
||||||
|
<option name="WIKILINKS" value="false" /> |
||||||
|
</PegdownExtensions> |
||||||
|
<ParserOptions> |
||||||
|
<option name="ADMONITION_EXT" value="false" /> |
||||||
|
<option name="ATTRIBUTES_EXT" value="false" /> |
||||||
|
<option name="COMMONMARK_LISTS" value="true" /> |
||||||
|
<option name="DUMMY" value="false" /> |
||||||
|
<option name="EMOJI_SHORTCUTS" value="true" /> |
||||||
|
<option name="ENUMERATED_REFERENCES_EXT" value="false" /> |
||||||
|
<option name="FLEXMARK_FRONT_MATTER" value="false" /> |
||||||
|
<option name="GFM_LOOSE_BLANK_LINE_AFTER_ITEM_PARA" value="false" /> |
||||||
|
<option name="GFM_TABLE_RENDERING" value="true" /> |
||||||
|
<option name="GITBOOK_URL_ENCODING" value="false" /> |
||||||
|
<option name="GITHUB_LISTS" value="false" /> |
||||||
|
<option name="GITHUB_WIKI_LINKS" value="false" /> |
||||||
|
<option name="GITLAB_EXT" value="false" /> |
||||||
|
<option name="GITLAB_MATH_EXT" value="false" /> |
||||||
|
<option name="GITLAB_MERMAID_EXT" value="false" /> |
||||||
|
<option name="HEADER_ID_NON_ASCII_TO_LOWERCASE" value="false" /> |
||||||
|
<option name="HEADER_ID_NO_DUPED_DASHES" value="false" /> |
||||||
|
<option name="JEKYLL_FRONT_MATTER" value="false" /> |
||||||
|
<option name="MACROS_EXT" value="false" /> |
||||||
|
<option name="NO_TEXT_ATTRIBUTES" value="false" /> |
||||||
|
<option name="PARSE_HTML_ANCHOR_ID" value="false" /> |
||||||
|
<option name="PLANTUML_FENCED_CODE" value="false" /> |
||||||
|
<option name="PUML_FENCED_CODE" value="false" /> |
||||||
|
<option name="SIM_TOC_BLANK_LINE_SPACER" value="true" /> |
||||||
|
</ParserOptions> |
||||||
|
</ParserSettings> |
||||||
|
<HtmlSettings headerTopEnabled="false" headerBottomEnabled="false" bodyTopEnabled="false" bodyBottomEnabled="false" embedUrlContent="false" addPageHeader="true" embedImages="false" embedHttpImages="false" imageUriSerials="false" addDocTypeHtml="true" noParaTags="false" plantUmlConversion="0" mathConversion="0"> |
||||||
|
<GeneratorProvider> |
||||||
|
<provider providerId="com.vladsch.idea.multimarkdown.editor.swing.html.generator" providerName="Default Swing HTML Generator" /> |
||||||
|
</GeneratorProvider> |
||||||
|
<headerTop /> |
||||||
|
<headerBottom /> |
||||||
|
<bodyTop /> |
||||||
|
<bodyBottom /> |
||||||
|
</HtmlSettings> |
||||||
|
<CssSettings previewScheme="UI_SCHEME" cssUri="" isCssUriEnabled="false" isCssUriSerial="true" isCssTextEnabled="false" isDynamicPageWidth="true"> |
||||||
|
<StylesheetProvider> |
||||||
|
<provider providerId="com.vladsch.idea.multimarkdown.editor.swing.html.css" providerName="Default Swing Stylesheet" /> |
||||||
|
</StylesheetProvider> |
||||||
|
<ScriptProviders /> |
||||||
|
<cssText /> |
||||||
|
<cssUriHistory /> |
||||||
|
</CssSettings> |
||||||
|
<AnnotatorSettings targetHasSpaces="true" linkCaseMismatch="true" wikiCaseMismatch="true" wikiLinkHasDashes="true" notUnderWikiHome="true" targetNotWikiPageExt="true" notUnderSourceWikiHome="true" targetNameHasAnchor="true" targetPathHasAnchor="true" wikiLinkHasSlash="true" wikiLinkHasSubdir="true" wikiLinkHasOnlyAnchor="true" linkTargetsWikiHasExt="true" linkTargetsWikiHasBadExt="true" notUnderSameRepo="true" targetNotUnderVcs="false" linkNeedsExt="true" linkHasBadExt="true" linkTargetNeedsExt="true" linkTargetHasBadExt="true" wikiLinkNotInWiki="true" imageTargetNotInRaw="true" repoRelativeAcrossVcsRoots="true" multipleWikiTargetsMatch="true" unresolvedLinkReference="true" linkIsIgnored="true" anchorIsIgnored="true" anchorIsUnresolved="true" anchorLineReferenceIsUnresolved="true" anchorLineReferenceFormat="true" anchorHasDuplicates="true" abbreviationDuplicates="true" abbreviationNotUsed="true" attributeIdDuplicateDefinition="true" attributeIdNotUsed="true" footnoteDuplicateDefinition="true" footnoteUnresolved="true" footnoteDuplicates="true" footnoteNotUsed="true" macroDuplicateDefinition="true" macroUnresolved="true" macroDuplicates="true" macroNotUsed="true" referenceDuplicateDefinition="true" referenceUnresolved="true" referenceDuplicates="true" referenceNotUsed="true" referenceUnresolvedNumericId="true" enumRefDuplicateDefinition="true" enumRefUnresolved="true" enumRefDuplicates="true" enumRefNotUsed="true" enumRefLinkUnresolved="true" enumRefLinkDuplicates="true" simTocUpdateNeeded="true" simTocTitleSpaceNeeded="true" /> |
||||||
|
<HtmlExportSettings updateOnSave="false" parentDir="" targetDir="" cssDir="css" scriptDir="js" plainHtml="false" imageDir="" copyLinkedImages="false" imageUniquifyType="0" targetPathType="2" targetExt="" useTargetExt="false" noCssNoScripts="false" useElementStyleAttribute="false" linkToExportedHtml="true" exportOnSettingsChange="true" regenerateOnProjectOpen="false" linkFormatType="HTTP_ABSOLUTE" /> |
||||||
|
<LinkMapSettings> |
||||||
|
<textMaps /> |
||||||
|
</LinkMapSettings> |
||||||
|
</component> |
||||||
|
</project> |
@ -0,0 +1,3 @@ |
|||||||
|
<component name="MarkdownNavigator.ProfileManager"> |
||||||
|
<settings default="" pdf-export="" plain-text-search-scope="Project Files" /> |
||||||
|
</component> |
@ -0,0 +1,12 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||||
|
<project version="4"> |
||||||
|
<component name="RunConfigurationProducerService"> |
||||||
|
<option name="ignoredProducers"> |
||||||
|
<set> |
||||||
|
<option value="org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer" /> |
||||||
|
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer" /> |
||||||
|
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer" /> |
||||||
|
</set> |
||||||
|
</option> |
||||||
|
</component> |
||||||
|
</project> |
@ -1,6 +1,7 @@ |
|||||||
<?xml version="1.0" encoding="UTF-8"?> |
<?xml version="1.0" encoding="UTF-8"?> |
||||||
<project version="4"> |
<project version="4"> |
||||||
<component name="VcsDirectoryMappings"> |
<component name="VcsDirectoryMappings"> |
||||||
<mapping directory="" vcs="Git" /> |
<mapping directory="$PROJECT_DIR$/../.." vcs="Git" /> |
||||||
|
<mapping directory="$PROJECT_DIR$" vcs="Git" /> |
||||||
</component> |
</component> |
||||||
</project> |
</project> |
@ -1,160 +1,38 @@ |
|||||||
plugins { |
apply plugin: 'com.android.application' |
||||||
id 'com.android.application' |
|
||||||
id 'kotlin-android' |
|
||||||
id 'kotlin-parcelize' |
|
||||||
} |
|
||||||
|
|
||||||
def name = "reader" |
apply plugin: 'kotlin-android' |
||||||
def code = 1 |
|
||||||
def version = "1.0.0" |
|
||||||
|
|
||||||
android { |
apply plugin: 'kotlin-android-extensions' |
||||||
compileSdkVersion 30 |
|
||||||
buildToolsVersion "29.0.3" |
|
||||||
|
|
||||||
|
android { |
||||||
|
compileSdkVersion rootProject.ext.android.compileSdkVersion |
||||||
defaultConfig { |
defaultConfig { |
||||||
applicationId "com.novel.read" |
applicationId rootProject.ext.android.applicationId |
||||||
minSdkVersion 21 |
minSdkVersion rootProject.ext.android.minSdkVersion |
||||||
targetSdkVersion 30 |
targetSdkVersion rootProject.ext.android.targetSdkVersion |
||||||
versionCode code |
versionCode rootProject.ext.android.versionCode |
||||||
versionName version |
versionName rootProject.ext.android.versionName |
||||||
|
|
||||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" |
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" |
||||||
|
|
||||||
ndk { |
|
||||||
abiFilters "armeabi" |
|
||||||
} |
|
||||||
multiDexEnabled true |
|
||||||
resConfigs "zh", "zh-rCN" |
|
||||||
resConfigs "zh", "zh-rTW" |
|
||||||
resConfigs "zh", "zh-rHK" |
|
||||||
} |
|
||||||
|
|
||||||
signingConfigs { |
|
||||||
release { |
|
||||||
keyAlias 'key0' |
|
||||||
keyPassword '1qaz@WSX' |
|
||||||
storeFile file('reader.jks') |
|
||||||
storePassword '1qaz@WSX' |
|
||||||
} |
|
||||||
} |
|
||||||
buildFeatures { |
|
||||||
viewBinding true |
|
||||||
} |
} |
||||||
buildTypes { |
buildTypes { |
||||||
debug { |
|
||||||
minifyEnabled true |
|
||||||
shrinkResources true |
|
||||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' |
|
||||||
signingConfig signingConfigs.release |
|
||||||
} |
|
||||||
release { |
release { |
||||||
buildConfigField "boolean", "LOG_DEBUG", "false" //不显示log |
minifyEnabled false |
||||||
minifyEnabled true |
|
||||||
shrinkResources true |
|
||||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' |
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"] |
|
||||||
} |
} |
||||||
} |
} |
||||||
|
|
||||||
compileOptions { |
compileOptions { |
||||||
sourceCompatibility JavaVersion.VERSION_1_8 |
sourceCompatibility JavaVersion.VERSION_1_8 |
||||||
targetCompatibility JavaVersion.VERSION_1_8 |
targetCompatibility JavaVersion.VERSION_1_8 |
||||||
} |
} |
||||||
kotlinOptions { |
|
||||||
jvmTarget = '1.8' |
|
||||||
} |
|
||||||
|
|
||||||
} |
} |
||||||
|
|
||||||
dependencies { |
dependencies { |
||||||
implementation fileTree(dir: 'libs', include: ['*.aar']) |
implementation fileTree(dir: 'libs', include: ['*.jar']) |
||||||
testImplementation 'junit:junit:4.13.1' |
testImplementation rootProject.ext.dependencies["junit"] |
||||||
androidTestImplementation 'androidx.test:runner:1.3.0' |
androidTestImplementation rootProject.ext.dependencies["runner"] |
||||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' |
androidTestImplementation rootProject.ext.dependencies["espresso_core"] |
||||||
implementation "com.android.support:multidex:1.0.3" |
implementation project(path: ':net_serivce') |
||||||
|
implementation project(path: ':common_lib') |
||||||
//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 files('libs/ZHConverter.jar') |
|
||||||
//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.allenliu.versionchecklib:library:2.2.0' |
||||||
|
|
||||||
implementation 'com.permissionx.guolindev:permissionx:1.4.0' |
|
||||||
} |
} |
Binary file not shown.
@ -1,18 +0,0 @@ |
|||||||
{ |
|
||||||
"version": 2, |
|
||||||
"artifactType": { |
|
||||||
"type": "APK", |
|
||||||
"kind": "Directory" |
|
||||||
}, |
|
||||||
"applicationId": "com.novel.read", |
|
||||||
"variantName": "processAppReleaseResources", |
|
||||||
"elements": [ |
|
||||||
{ |
|
||||||
"type": "SINGLE", |
|
||||||
"filters": [], |
|
||||||
"versionCode": 1, |
|
||||||
"versionName": "1.0.0", |
|
||||||
"outputFile": "reader_app_1.0.0.apk" |
|
||||||
} |
|
||||||
] |
|
||||||
} |
|
Binary file not shown.
Before Width: | Height: | Size: 246 KiB |
@ -1,62 +0,0 @@ |
|||||||
[ |
|
||||||
{ |
|
||||||
"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}" |
|
||||||
} |
|
||||||
] |
|
@ -1,52 +0,0 @@ |
|||||||
[ |
|
||||||
{ |
|
||||||
"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 |
|
||||||
} |
|
||||||
] |
|
@ -1,26 +0,0 @@ |
|||||||
[ |
|
||||||
{ |
|
||||||
"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" |
|
||||||
} |
|
||||||
] |
|
Binary file not shown.
@ -1,12 +1,23 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||||
<litepal> |
<litepal> |
||||||
<dbname value="light_book" /> |
<dbname value="readDb" /> |
||||||
<version value="1" /> |
|
||||||
|
<version value="9" /> |
||||||
|
|
||||||
<list> |
<list> |
||||||
<mapping class="com.novel.read.data.db.entity.Book" /> |
<!--搜索记录表--> |
||||||
<mapping class="com.novel.read.data.db.entity.BookChapter" /> |
<mapping class="com.novel.read.model.db.SearchListTable"/> |
||||||
<mapping class="com.novel.read.data.db.entity.Bookmark" /> |
<!--收藏书籍表--> |
||||||
<mapping class="com.novel.read.data.db.entity.ReadRecord" /> |
<mapping class="com.novel.read.model.db.CollBookBean"/> |
||||||
<mapping class="com.novel.read.data.db.entity.SearchHistory" /> |
<!--章节表--> |
||||||
|
<mapping class="com.novel.read.model.db.BookChapterBean"/> |
||||||
|
<!--阅读记录表--> |
||||||
|
<mapping class="com.novel.read.model.db.BookRecordBean"/> |
||||||
|
<!--章节详情表--> |
||||||
|
<mapping class="com.novel.read.model.db.ChapterInfoBean" /> |
||||||
|
<!--章节详情表--> |
||||||
|
<mapping class="com.novel.read.model.db.DownloadTaskBean" /> |
||||||
|
<!--书签表--> |
||||||
|
<mapping class="com.novel.read.model.db.BookSignTable" /> |
||||||
</list> |
</list> |
||||||
<storage value="external" /> |
|
||||||
</litepal> |
</litepal> |
@ -1,138 +0,0 @@ |
|||||||
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.bumptech.glide.Glide |
|
||||||
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)) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
override fun onLowMemory() { |
|
||||||
super.onLowMemory() |
|
||||||
Glide.get(this).clearMemory() |
|
||||||
} |
|
||||||
|
|
||||||
override fun onTrimMemory(level: Int) { |
|
||||||
super.onTrimMemory(level) |
|
||||||
if (level == TRIM_MEMORY_UI_HIDDEN) { |
|
||||||
Glide.get(this).clearMemory() |
|
||||||
} |
|
||||||
Glide.get(this).trimMemory(level) |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
@ -0,0 +1,22 @@ |
|||||||
|
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 |
||||||
|
} |
@ -0,0 +1,205 @@ |
|||||||
|
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<RecommendBookResp.BookBean>() |
||||||
|
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()) |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,89 @@ |
|||||||
|
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<SearchResp.BookBean> = 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) |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,148 @@ |
|||||||
|
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) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,91 @@ |
|||||||
|
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<RankByUpdateResp.BookBean> = 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<RankByUpdateResp> { |
||||||
|
|
||||||
|
override fun onResponse(call: Call<RankByUpdateResp>, response: Response<RankByUpdateResp>) { |
||||||
|
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<RankByUpdateResp>, t: Throwable) { |
||||||
|
|
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,655 @@ |
|||||||
|
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<TxtChapter>() |
||||||
|
private lateinit var mCurrentChapter: TxtChapter //当前章节 |
||||||
|
private var currentChapter = 0 |
||||||
|
private lateinit var mMarkAdapter: MarkAdapter |
||||||
|
private val mMarks = ArrayList<BookSignTable>() |
||||||
|
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<TxtChapter>) { |
||||||
|
AccountManager.getInstance().getBookArticleDetail(mBookId, requestChapters) |
||||||
|
mHandler.sendEmptyMessage(WHAT_CATEGORY) |
||||||
|
} |
||||||
|
|
||||||
|
override fun onCategoryFinish(chapters: List<TxtChapter>) { |
||||||
|
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<BookChapterBean>() |
||||||
|
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<BookChapterBean>, 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 |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,62 @@ |
|||||||
|
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<Fragment>() |
||||||
|
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) |
||||||
|
} |
||||||
|
} |
||||||
|
}) |
||||||
|
|
||||||
|
} |
||||||
|
} |
@ -0,0 +1,255 @@ |
|||||||
|
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<String>() |
||||||
|
private lateinit var mHotAdapter: HotAdapter |
||||||
|
|
||||||
|
private var mHisList: MutableList<SearchListTable> = ArrayList() |
||||||
|
private lateinit var mHisAdapter: HistoryAdapter |
||||||
|
|
||||||
|
private val mSearchList = ArrayList<SearchResp.BookBean>() |
||||||
|
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) |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,152 @@ |
|||||||
|
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) |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,69 @@ |
|||||||
|
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<String>, |
||||||
|
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 |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,163 @@ |
|||||||
|
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<CollBookBean>) : RecyclerView.Adapter<RecyclerView.ViewHolder>() { |
||||||
|
private lateinit var mContext: Context |
||||||
|
|
||||||
|
private var mClickListener: OnItemClickListener? = null |
||||||
|
private var mEdit: Boolean = false |
||||||
|
|
||||||
|
val selectList: List<CollBookBean> |
||||||
|
get() { |
||||||
|
val collBookBeans = ArrayList<CollBookBean>() |
||||||
|
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 |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,126 @@ |
|||||||
|
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<SearchResp.BookBean>, recyclerView: RecyclerView) : RecyclerView.Adapter<RecyclerView.ViewHolder>() { |
||||||
|
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 |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,34 @@ |
|||||||
|
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<TxtChapter> { |
||||||
|
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<TxtChapter> onCreateViewHolder(int viewType) { |
||||||
|
return new CategoryHolder(); |
||||||
|
} |
||||||
|
|
||||||
|
public void setChapter(int pos){ |
||||||
|
currentSelected = pos; |
||||||
|
notifyDataSetChanged(); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,87 @@ |
|||||||
|
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<T> extends BaseAdapter { |
||||||
|
|
||||||
|
private List<T> mList = new ArrayList<T>(); |
||||||
|
|
||||||
|
@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<T> values){ |
||||||
|
mList.addAll(values); |
||||||
|
notifyDataSetChanged(); |
||||||
|
} |
||||||
|
|
||||||
|
public void removeItem(T value){ |
||||||
|
mList.remove(value); |
||||||
|
notifyDataSetChanged(); |
||||||
|
} |
||||||
|
|
||||||
|
public List<T> getItems(){ |
||||||
|
return Collections.unmodifiableList(mList); |
||||||
|
} |
||||||
|
|
||||||
|
public int getItemSize(){ |
||||||
|
return mList.size(); |
||||||
|
} |
||||||
|
|
||||||
|
public void refreshItems(List<T> 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<T> onCreateViewHolder(int viewType); |
||||||
|
} |
@ -0,0 +1,62 @@ |
|||||||
|
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<RecommendListResp.ListBean>) : RecyclerView.Adapter<EditRecommendAdapter.ViewHolder>() { |
||||||
|
|
||||||
|
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) |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,54 @@ |
|||||||
|
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<SearchListTable>) : |
||||||
|
RecyclerView.Adapter<HistoryAdapter.ViewHolder>() { |
||||||
|
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) |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,54 @@ |
|||||||
|
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<String>) : RecyclerView.Adapter<HotAdapter.ViewHolder>() { |
||||||
|
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) |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,58 @@ |
|||||||
|
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<RecommendListResp.ListBean>) : RecyclerView.Adapter<HumanAdapter.ViewHolder>() { |
||||||
|
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) |
||||||
|
|
||||||
|
} |
||||||
|
} |
@ -0,0 +1,15 @@ |
|||||||
|
package com.novel.read.adapter |
||||||
|
|
||||||
|
import android.view.View |
||||||
|
import android.view.ViewGroup |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by zlj |
||||||
|
*/ |
||||||
|
|
||||||
|
interface IViewHolder<T> { |
||||||
|
fun createItemView(parent: ViewGroup): View |
||||||
|
fun initView() |
||||||
|
fun onBind(data: T, pos: Int) |
||||||
|
fun onClick() |
||||||
|
} |
@ -0,0 +1,59 @@ |
|||||||
|
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<RecommendBookResp.BookBean>) : RecyclerView.Adapter<RecyclerView.ViewHolder>() { |
||||||
|
|
||||||
|
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) |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,71 @@ |
|||||||
|
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<BookSignTable>) : RecyclerView.Adapter<RecyclerView.ViewHolder>() { |
||||||
|
|
||||||
|
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) |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,54 @@ |
|||||||
|
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<Drawable>, private val mPageLoader: PageLoader) : |
||||||
|
RecyclerView.Adapter<PageStyleAdapter.PageHolder>() { |
||||||
|
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) |
||||||
|
|
||||||
|
} |
||||||
|
} |
@ -0,0 +1,59 @@ |
|||||||
|
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<RecommendListResp.ListBean>) : |
||||||
|
RecyclerView.Adapter<RankAdapter.ViewHolder>() { |
||||||
|
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) |
||||||
|
|
||||||
|
} |
||||||
|
} |
@ -0,0 +1,125 @@ |
|||||||
|
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<RankByUpdateResp.BookBean>, recyclerView: RecyclerView) : RecyclerView.Adapter<RecyclerView.ViewHolder>() { |
||||||
|
|
||||||
|
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 |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,173 @@ |
|||||||
|
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<SearchResp.BookBean>, recyclerView: RecyclerView) : |
||||||
|
RecyclerView.Adapter<RecyclerView.ViewHolder>() { |
||||||
|
|
||||||
|
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 |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,61 @@ |
|||||||
|
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<CategoryTypeResp.CategoryBean>) : RecyclerView.Adapter<RecyclerView.ViewHolder>() { |
||||||
|
|
||||||
|
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) |
||||||
|
|
||||||
|
} |
||||||
|
} |
@ -0,0 +1,40 @@ |
|||||||
|
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<T> implements IViewHolder<T> { |
||||||
|
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 extends View> V findById(int id){ |
||||||
|
return (V) view.findViewById(id); |
||||||
|
} |
||||||
|
|
||||||
|
protected Context getContext(){ |
||||||
|
return context; |
||||||
|
} |
||||||
|
|
||||||
|
protected View getItemView(){ |
||||||
|
return view; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onClick() { |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,22 @@ |
|||||||
|
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<Fragment>) : |
||||||
|
FragmentPagerAdapter(fm) { |
||||||
|
|
||||||
|
override fun getItem(position: Int): Fragment { |
||||||
|
return fragmentList[position] |
||||||
|
} |
||||||
|
|
||||||
|
override fun getCount(): Int { |
||||||
|
return fragmentList.size |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,50 @@ |
|||||||
|
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<TxtChapter> { |
||||||
|
|
||||||
|
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); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,6 @@ |
|||||||
|
package com.novel.read.adapter.holder |
||||||
|
|
||||||
|
import android.view.View |
||||||
|
import androidx.recyclerview.widget.RecyclerView |
||||||
|
|
||||||
|
class EmptyHolder(itemView: View) : RecyclerView.ViewHolder(itemView) |
@ -0,0 +1,34 @@ |
|||||||
|
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 |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -1,178 +0,0 @@ |
|||||||
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 androidx.viewbinding.ViewBinding |
|
||||||
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<VB : ViewBinding>( |
|
||||||
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() { |
|
||||||
|
|
||||||
protected val binding: VB by lazy { getViewBinding() } |
|
||||||
|
|
||||||
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)) |
|
||||||
} |
|
||||||
|
|
||||||
protected abstract fun getViewBinding(): VB |
|
||||||
|
|
||||||
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() |
|
||||||
super.onCreate(savedInstanceState) |
|
||||||
setContentView(binding.root) |
|
||||||
setupSystemBar() |
|
||||||
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) { |
|
||||||
findViewById<TitleBar>(R.id.title_bar) |
|
||||||
?.onMultiWindowModeChanged(isInMultiWindowMode, fullScreen) |
|
||||||
} |
|
||||||
onActivityCreated(savedInstanceState) |
|
||||||
observeLiveBus() |
|
||||||
} |
|
||||||
|
|
||||||
override fun onMultiWindowModeChanged(isInMultiWindowMode: Boolean, newConfig: Configuration?) { |
|
||||||
super.onMultiWindowModeChanged(isInMultiWindowMode, newConfig) |
|
||||||
findViewById<TitleBar>(R.id.title_bar) |
|
||||||
?.onMultiWindowModeChanged(isInMultiWindowMode, fullScreen) |
|
||||||
setupSystemBar() |
|
||||||
} |
|
||||||
|
|
||||||
override fun onConfigurationChanged(newConfig: Configuration) { |
|
||||||
super.onConfigurationChanged(newConfig) |
|
||||||
findViewById<TitleBar>(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() |
|
||||||
} |
|
||||||
} |
|
@ -1,41 +0,0 @@ |
|||||||
package com.novel.read.base |
|
||||||
|
|
||||||
import android.view.LayoutInflater |
|
||||||
import android.view.View |
|
||||||
import android.view.ViewGroup |
|
||||||
import androidx.viewbinding.ViewBinding |
|
||||||
import com.chad.library.adapter.base.BaseQuickAdapter |
|
||||||
import com.chad.library.adapter.base.BaseSectionQuickAdapter |
|
||||||
import com.chad.library.adapter.base.entity.SectionEntity |
|
||||||
import com.chad.library.adapter.base.viewholder.BaseViewHolder |
|
||||||
|
|
||||||
abstract class BaseBindingAdapter<T, VB : ViewBinding>(data: MutableList<T>? = null) : |
|
||||||
BaseQuickAdapter<T, VBViewHolder<VB>>(0, data) { |
|
||||||
|
|
||||||
abstract fun createViewBinding(inflater: LayoutInflater, parent: ViewGroup): VB |
|
||||||
|
|
||||||
override fun onCreateDefViewHolder(parent: ViewGroup, viewType: Int): VBViewHolder<VB> { |
|
||||||
val viewBinding = createViewBinding(LayoutInflater.from(parent.context), parent) |
|
||||||
return VBViewHolder(viewBinding, viewBinding.root) |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
class VBViewHolder<VB : ViewBinding>(val vb: VB, view: View) : BaseViewHolder(view) |
|
||||||
|
|
||||||
|
|
||||||
@JvmName("bind") |
|
||||||
fun <VB : ViewBinding> BaseViewHolder.withBinding(bind: (View) -> VB): BaseViewHolder = |
|
||||||
BaseViewHolderWithBinding(bind(itemView)) |
|
||||||
|
|
||||||
@JvmName("getBinding") |
|
||||||
@Suppress("UNCHECKED_CAST") |
|
||||||
fun <VB : ViewBinding> BaseViewHolder.getViewBinding(): VB { |
|
||||||
if (this is BaseViewHolderWithBinding<*>) { |
|
||||||
return binding as VB |
|
||||||
} else { |
|
||||||
throw IllegalStateException("The binding could not be found.") |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
class BaseViewHolderWithBinding<VB : ViewBinding>(val binding: VB) : BaseViewHolder(binding.root) |
|
@ -1,58 +0,0 @@ |
|||||||
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 <T> execute( |
|
||||||
scope: CoroutineScope = this, |
|
||||||
context: CoroutineContext = Dispatchers.IO, |
|
||||||
block: suspend CoroutineScope.() -> T |
|
||||||
) = Coroutine.async(scope, context) { block() } |
|
||||||
|
|
||||||
open fun observeLiveBus() { |
|
||||||
} |
|
||||||
} |
|
@ -1,96 +0,0 @@ |
|||||||
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<TitleBar>(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) { |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
@ -1,60 +0,0 @@ |
|||||||
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) |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
@ -1,26 +1,25 @@ |
|||||||
package com.novel.read.base |
package com.novel.read.base |
||||||
|
|
||||||
import android.app.Service |
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 |
|
||||||
|
|
||||||
abstract class BaseService : Service(), CoroutineScope by MainScope() { |
import io.reactivex.disposables.CompositeDisposable |
||||||
|
import io.reactivex.disposables.Disposable |
||||||
|
|
||||||
fun <T> execute( |
abstract class BaseService : Service() { |
||||||
scope: CoroutineScope = this, |
|
||||||
context: CoroutineContext = Dispatchers.IO, |
|
||||||
block: suspend CoroutineScope.() -> T |
|
||||||
) = Coroutine.async(scope, context) { block() } |
|
||||||
|
|
||||||
override fun onBind(intent: Intent?) = null |
private var mDisposable: CompositeDisposable? = null |
||||||
|
|
||||||
|
protected fun addDisposable(disposable: Disposable) { |
||||||
|
if (mDisposable == null) { |
||||||
|
mDisposable = CompositeDisposable() |
||||||
|
} |
||||||
|
mDisposable!!.add(disposable) |
||||||
|
} |
||||||
|
|
||||||
override fun onDestroy() { |
override fun onDestroy() { |
||||||
super.onDestroy() |
super.onDestroy() |
||||||
cancel() |
if (mDisposable != null) { |
||||||
|
mDisposable!!.dispose() |
||||||
|
} |
||||||
} |
} |
||||||
} |
} |
@ -1,154 +0,0 @@ |
|||||||
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<T> = 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<App>() } |
|
||||||
|
|
||||||
fun <T> execute( |
|
||||||
scope: CoroutineScope = this, |
|
||||||
context: CoroutineContext = Dispatchers.IO, |
|
||||||
block: suspend CoroutineScope.() -> T |
|
||||||
): Coroutine<T> { |
|
||||||
return Coroutine.async(scope, context) { block() } |
|
||||||
} |
|
||||||
|
|
||||||
fun <R> submit( |
|
||||||
scope: CoroutineScope = this, |
|
||||||
context: CoroutineContext = Dispatchers.IO, |
|
||||||
block: suspend CoroutineScope.() -> Deferred<R> |
|
||||||
): Coroutine<R> { |
|
||||||
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<Unit>, |
|
||||||
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<T> |
|
||||||
*/ |
|
||||||
protected fun <T> async(block: Block<T>): Deferred<T> { |
|
||||||
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) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
@ -0,0 +1,63 @@ |
|||||||
|
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 |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,78 @@ |
|||||||
|
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)) |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,59 @@ |
|||||||
|
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) |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
} |
@ -1,15 +0,0 @@ |
|||||||
package com.novel.read.base |
|
||||||
|
|
||||||
import androidx.lifecycle.ViewModel |
|
||||||
import androidx.viewbinding.ViewBinding |
|
||||||
import com.novel.read.constant.Theme |
|
||||||
|
|
||||||
abstract class VMBaseActivity<VB : ViewBinding,VM : ViewModel>( |
|
||||||
fullScreen: Boolean = true, |
|
||||||
theme: Theme = Theme.Auto, |
|
||||||
toolBarTheme: Theme = Theme.Auto |
|
||||||
) : BaseActivity<VB>(fullScreen, theme, toolBarTheme) { |
|
||||||
|
|
||||||
protected abstract val viewModel: VM |
|
||||||
|
|
||||||
} |
|
@ -1,9 +0,0 @@ |
|||||||
package com.novel.read.base |
|
||||||
|
|
||||||
import androidx.lifecycle.ViewModel |
|
||||||
|
|
||||||
abstract class VMBaseFragment<VM : ViewModel>(layoutID: Int) : BaseFragment(layoutID) { |
|
||||||
|
|
||||||
protected abstract val viewModel: VM |
|
||||||
|
|
||||||
} |
|
@ -1,73 +0,0 @@ |
|||||||
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 AppId = "20210306161" |
|
||||||
const val AppSecret = "c14f6a2b3dcah893a31b9i4f40f5cc08" |
|
||||||
|
|
||||||
const val channelIdDownload = "channel_download" |
|
||||||
const val channelIdReadAloud = "channel_read_aloud" |
|
||||||
|
|
||||||
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<String> by lazy { |
|
||||||
arrayListOf( |
|
||||||
"※", "@", "&", "|", "%", "/", ":", "[", "]", "{", "}", "<", ">", "\\", |
|
||||||
"$", "#", "!", ".", "href", "src", "textNodes", "xpath", "json", "css", |
|
||||||
"id", "class", "tag" |
|
||||||
) |
|
||||||
} |
|
||||||
|
|
||||||
const val notificationIdRead = 1144771 |
|
||||||
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" |
|
||||||
) |
|
||||||
} |
|
@ -1,16 +0,0 @@ |
|||||||
package com.novel.read.constant |
|
||||||
|
|
||||||
import java.util.regex.Pattern |
|
||||||
|
|
||||||
object AppPattern { |
|
||||||
val JS_PATTERN: Pattern = |
|
||||||
Pattern.compile("(<js>[\\w\\W]*?</js>|@js:[\\w\\W]*$)", Pattern.CASE_INSENSITIVE) |
|
||||||
val EXP_PATTERN: Pattern = Pattern.compile("\\{\\{([\\w\\W]*?)\\}\\}") |
|
||||||
val imgPattern: Pattern = |
|
||||||
Pattern.compile("<img .*?src.*?=.*?\"(.*?(?:,\\{.*\\})?)\".*?>", Pattern.CASE_INSENSITIVE) |
|
||||||
|
|
||||||
val nameRegex = Regex("\\s+作\\s*者.*") |
|
||||||
val authorRegex = Regex(".*?作\\s*?者[::]") |
|
||||||
val fileNameRegex = Regex("[\\\\/:*?\"<>|.]") |
|
||||||
val splitGroupRegex = Regex("[,;,;]") |
|
||||||
} |
|
@ -1,13 +0,0 @@ |
|||||||
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" |
|
||||||
} |
|
@ -1,28 +0,0 @@ |
|||||||
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" |
|
||||||
} |
|
@ -1,30 +0,0 @@ |
|||||||
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" |
|
||||||
|
|
||||||
} |
|
@ -1,23 +0,0 @@ |
|||||||
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 |
|
||||||
} |
|
@ -1,69 +0,0 @@ |
|||||||
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 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" |
|
||||||
|
|
||||||
} |
|
@ -1,7 +0,0 @@ |
|||||||
package com.novel.read.constant |
|
||||||
|
|
||||||
object Status { |
|
||||||
const val STOP = 0 |
|
||||||
const val PLAY = 1 |
|
||||||
const val PAUSE = 3 |
|
||||||
} |
|
@ -1,20 +0,0 @@ |
|||||||
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 |
|
||||||
|
|
||||||
} |
|
||||||
} |
|
@ -1,17 +0,0 @@ |
|||||||
# 存储数据用 |
|
||||||
* dao 数据操作 |
|
||||||
* entities 数据模型 |
|
||||||
* \Book 书籍信息 |
|
||||||
* \BookChapter 目录信息 |
|
||||||
* \BookGroup 书籍分组 |
|
||||||
* \Bookmark 书签 |
|
||||||
* \BookSource 书源 |
|
||||||
* \Cookie http cookie |
|
||||||
* \ReplaceRule 替换规则 |
|
||||||
* \RssArticle rss条目 |
|
||||||
* \RssReadRecord rss阅读记录 |
|
||||||
* \RssSource rss源 |
|
||||||
* \RssStar rss收藏 |
|
||||||
* \SearchBook 搜索结果 |
|
||||||
* \SearchKeyword 搜索关键字 |
|
||||||
* \TxtTocRule txt文件目录规则 |
|
@ -1,50 +0,0 @@ |
|||||||
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<Book> = 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<Book>?) { |
|
||||||
if (book != null && book.isNotEmpty()) { |
|
||||||
LitePal.saveAll(book) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
@ -1,60 +0,0 @@ |
|||||||
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 |
|
||||||
|
|
||||||
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!! |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
@ -1,39 +0,0 @@ |
|||||||
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<Bookmark>? = |
|
||||||
LitePal.where("bookId=?", bookId.toString()).find(Bookmark::class.java) |
|
||||||
|
|
||||||
fun liveDataSearch(bookId: String, key: String): List<Bookmark>? = |
|
||||||
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() |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
@ -1,48 +0,0 @@ |
|||||||
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<BookChapter>? = |
|
||||||
LitePal.where("bookId=?", bookId.toString()).find(BookChapter::class.java) |
|
||||||
|
|
||||||
fun liveDataSearch(bookId: String, key: String): List<BookChapter>? = |
|
||||||
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<BookChapter>? = |
|
||||||
LitePal.where("bookId=?", bookId.toString()).find(BookChapter::class.java) |
|
||||||
|
|
||||||
fun getChapterList(bookId: Long, start: Int, end: Int): List<BookChapter> = |
|
||||||
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<BookChapter>) { |
|
||||||
if (bookChapters.isNotEmpty()) { |
|
||||||
LitePal.deleteAll( |
|
||||||
BookChapter::class.java, |
|
||||||
"bookId=?", |
|
||||||
bookChapters[0].bookId.toString() |
|
||||||
) |
|
||||||
} |
|
||||||
LitePal.saveAll(bookChapters.toList()) |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
@ -1,23 +0,0 @@ |
|||||||
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<ReadRecord> { |
|
||||||
return LitePal.findAll(ReadRecord::class.java) |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
@ -1,19 +0,0 @@ |
|||||||
package com.novel.read.data.db |
|
||||||
|
|
||||||
import com.novel.read.data.db.entity.SearchHistory |
|
||||||
import org.litepal.LitePal |
|
||||||
|
|
||||||
class SearchHistoryDao { |
|
||||||
|
|
||||||
fun getListByTime(): MutableList<SearchHistory>? = |
|
||||||
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) |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
@ -1,52 +0,0 @@ |
|||||||
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) |
|
||||||
} |
|
@ -1,19 +0,0 @@ |
|||||||
package com.novel.read.data.db.entity |
|
||||||
|
|
||||||
import org.litepal.crud.LitePalSupport |
|
||||||
|
|
||||||
data class BookChapter( |
|
||||||
// val bookId: Int, |
|
||||||
// val chapterList: List<Chapter>, |
|
||||||
// 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() |
|
@ -1,16 +0,0 @@ |
|||||||
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 |
|
@ -1,10 +0,0 @@ |
|||||||
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 |
|
||||||
) |
|
@ -1,9 +0,0 @@ |
|||||||
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() |
|
@ -1,15 +0,0 @@ |
|||||||
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 |
|
@ -1,20 +0,0 @@ |
|||||||
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 |
|
||||||
) |
|
@ -1,33 +0,0 @@ |
|||||||
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 |
|
||||||
) |
|
@ -1,52 +0,0 @@ |
|||||||
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) |
|
||||||
} |
|
||||||
} |
|
@ -1,51 +0,0 @@ |
|||||||
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<BoyEndRank>):MultiItemEntity{ |
|
||||||
override val itemType: Int |
|
||||||
get() = LayoutType.BOY_END |
|
||||||
} |
|
@ -1,50 +0,0 @@ |
|||||||
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<BoyHotRank>) : MultiItemEntity { |
|
||||||
override val itemType: Int |
|
||||||
get() = LayoutType.BOY_HOT |
|
||||||
} |
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue