Merge remote-tracking branch 'origin/master'

pull/1217/head
ag2s20150909 3 years ago
commit e4b7b3a30a
  1. 17
      .github/workflows/legado.yml
  2. 2
      app/build.gradle
  3. 2
      app/src/main/assets/epub/chapter.html
  4. 8
      app/src/main/assets/updateLog.md
  5. 4
      app/src/main/java/io/legado/app/App.kt
  6. 13
      app/src/main/java/io/legado/app/base/BaseActivity.kt
  7. 1
      app/src/main/java/io/legado/app/constant/EventBus.kt
  8. 2
      app/src/main/java/io/legado/app/constant/PreferKey.kt
  9. 3
      app/src/main/java/io/legado/app/data/dao/BookDao.kt
  10. 30
      app/src/main/java/io/legado/app/help/ThemeConfig.kt
  11. 25
      app/src/main/java/io/legado/app/service/AudioPlayService.kt
  12. 1
      app/src/main/java/io/legado/app/ui/association/ImportBookSourceDialog.kt
  13. 1
      app/src/main/java/io/legado/app/ui/association/ImportRssSourceDialog.kt
  14. 4
      app/src/main/java/io/legado/app/ui/book/audio/AudioPlayViewModel.kt
  15. 2
      app/src/main/java/io/legado/app/ui/book/cache/CacheActivity.kt
  16. 5
      app/src/main/java/io/legado/app/ui/book/changecover/ChangeCoverDialog.kt
  17. 5
      app/src/main/java/io/legado/app/ui/book/changesource/ChangeSourceAdapter.kt
  18. 16
      app/src/main/java/io/legado/app/ui/book/changesource/ChangeSourceDialog.kt
  19. 2
      app/src/main/java/io/legado/app/ui/book/group/GroupEdit.kt
  20. 6
      app/src/main/java/io/legado/app/ui/book/group/GroupManageDialog.kt
  21. 8
      app/src/main/java/io/legado/app/ui/book/group/GroupSelectDialog.kt
  22. 10
      app/src/main/java/io/legado/app/ui/book/info/BookInfoActivity.kt
  23. 14
      app/src/main/java/io/legado/app/ui/book/info/BookInfoViewModel.kt
  24. 1
      app/src/main/java/io/legado/app/ui/book/local/ImportBookActivity.kt
  25. 13
      app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt
  26. 1
      app/src/main/java/io/legado/app/ui/book/read/ReadBookBaseActivity.kt
  27. 4
      app/src/main/java/io/legado/app/ui/book/read/ReadBookViewModel.kt
  28. 7
      app/src/main/java/io/legado/app/ui/book/read/config/BgTextConfigDialog.kt
  29. 4
      app/src/main/java/io/legado/app/ui/book/read/config/PaddingConfigDialog.kt
  30. 4
      app/src/main/java/io/legado/app/ui/book/read/config/ReadAloudConfigDialog.kt
  31. 3
      app/src/main/java/io/legado/app/ui/book/read/config/SpeakEngineDialog.kt
  32. 6
      app/src/main/java/io/legado/app/ui/book/read/config/TocRegexDialog.kt
  33. 3
      app/src/main/java/io/legado/app/ui/book/read/page/PageView.kt
  34. 6
      app/src/main/java/io/legado/app/ui/book/read/page/provider/ChapterProvider.kt
  35. 2
      app/src/main/java/io/legado/app/ui/book/source/edit/BookSourceEditActivity.kt
  36. 6
      app/src/main/java/io/legado/app/ui/book/source/manage/BookSourceActivity.kt
  37. 16
      app/src/main/java/io/legado/app/ui/book/source/manage/GroupManageDialog.kt
  38. 6
      app/src/main/java/io/legado/app/ui/config/OtherConfigFragment.kt
  39. 102
      app/src/main/java/io/legado/app/ui/config/ThemeConfigFragment.kt
  40. 2
      app/src/main/java/io/legado/app/ui/config/ThemeListDialog.kt
  41. 2
      app/src/main/java/io/legado/app/ui/document/FilePickerDialog.kt
  42. 2
      app/src/main/java/io/legado/app/ui/main/MainViewModel.kt
  43. 6
      app/src/main/java/io/legado/app/ui/main/bookshelf/BaseBookshelfFragment.kt
  44. 2
      app/src/main/java/io/legado/app/ui/qrcode/QrCodeActivity.kt
  45. 12
      app/src/main/java/io/legado/app/ui/replace/GroupManageDialog.kt
  46. 1
      app/src/main/java/io/legado/app/ui/replace/ReplaceRuleActivity.kt
  47. 4
      app/src/main/java/io/legado/app/ui/replace/edit/ReplaceEditActivity.kt
  48. 1
      app/src/main/java/io/legado/app/ui/rss/read/ReadRssActivity.kt
  49. 2
      app/src/main/java/io/legado/app/ui/rss/source/edit/RssSourceEditActivity.kt
  50. 20
      app/src/main/java/io/legado/app/ui/rss/source/manage/GroupManageDialog.kt
  51. 1
      app/src/main/java/io/legado/app/ui/rss/source/manage/RssSourceActivity.kt
  52. 4
      app/src/main/java/io/legado/app/ui/widget/dialog/TextDialog.kt
  53. 4
      app/src/main/java/io/legado/app/ui/widget/dialog/TextListDialog.kt
  54. 2
      app/src/main/java/io/legado/app/ui/widget/font/FontSelectDialog.kt
  55. 4
      app/src/main/java/io/legado/app/ui/widget/prefs/IconListPreference.kt
  56. 27
      app/src/main/java/io/legado/app/utils/ActivityExtensions.kt
  57. 4
      app/src/main/java/io/legado/app/utils/BitmapUtils.kt
  58. 0
      app/src/main/java/io/legado/app/utils/JsonExtensions.kt
  59. 1
      app/src/main/res/layout-land/activity_book_info.xml
  60. 7
      app/src/main/res/layout/activity_book_info.xml
  61. 4
      app/src/main/res/layout/activity_chapter_list.xml
  62. 3
      app/src/main/res/layout/activity_import_book.xml
  63. 4
      app/src/main/res/layout/activity_main.xml
  64. 21
      app/src/main/res/layout/activity_replace_edit.xml
  65. 3
      app/src/main/res/layout/activity_replace_rule.xml
  66. 4
      app/src/main/res/layout/activity_rss_artivles.xml
  67. 12
      app/src/main/res/layout/activity_rss_source_edit.xml
  68. 3
      app/src/main/res/layout/activity_search_content.xml
  69. 6
      app/src/main/res/layout/dialog_bookmark.xml
  70. 34
      app/src/main/res/layout/dialog_bookshelf_config.xml
  71. 14
      app/src/main/res/layout/dialog_download_choice.xml
  72. 32
      app/src/main/res/layout/dialog_edit_text.xml
  73. 30
      app/src/main/res/layout/dialog_image_blurring.xml
  74. 7
      app/src/main/res/layout/dialog_recycler_view.xml
  75. 7
      app/src/main/res/layout/dialog_toc_regex_edit.xml
  76. 2
      app/src/main/res/layout/dialog_wait.xml
  77. 5
      app/src/main/res/menu/book_info.xml
  78. 1
      app/src/main/res/values-es-rES/strings.xml
  79. 1
      app/src/main/res/values-ja-rJP/strings.xml
  80. 1
      app/src/main/res/values-pt-rBR/strings.xml
  81. 4
      app/src/main/res/values-zh-rHK/arrays.xml
  82. 60
      app/src/main/res/values-zh-rHK/strings.xml
  83. 4
      app/src/main/res/values-zh-rTW/arrays.xml
  84. 10
      app/src/main/res/values-zh-rTW/strings.xml
  85. 4
      app/src/main/res/values-zh/strings.xml
  86. 4
      app/src/main/res/values/strings.xml
  87. 28
      app/src/main/res/xml/pref_config_theme.xml

@ -50,31 +50,38 @@ jobs:
echo "设置apk共存" echo "设置apk共存"
sed "s/'.release'/'.releaseA'/" $GITHUB_WORKSPACE/app/build.gradle -i sed "s/'.release'/'.releaseA'/" $GITHUB_WORKSPACE/app/build.gradle -i
sed 's/.release/.releaseA/' $GITHUB_WORKSPACE/app/google-services.json -i sed 's/.release/.releaseA/' $GITHUB_WORKSPACE/app/google-services.json -i
echo "统一版本号"
version=$(date -d "8 hour" -u +3.%y.%m%d%H%M)
sed "/def version/c def version = \"$version\"" $GITHUB_WORKSPACE/app/build.gradle -i
- name: Build With Gradle - name: Build With Gradle
run: | run: |
echo "开始进行release构建" echo "开始进行release构建"
chmod +x gradlew chmod +x gradlew
./gradlew assembleAppRelease --build-cache --parallel ./gradlew assembleAppRelease --build-cache --parallel
echo "开始进行cronet构建"
./gradlew assembleCronetRelease --build-cache --parallel
- name: Organize the files
run: |
mkdir -p ${{ github.workspace }}/apk/
cp -rf ${{ github.workspace }}/app/build/outputs/apk/*/*/*.apk ${{ github.workspace }}/apk/
- name: Upload App To Artifact - name: Upload App To Artifact
if: ${{ env.UPLOAD_ARTIFACT != 'false' }} if: ${{ env.UPLOAD_ARTIFACT != 'false' }}
uses: actions/upload-artifact@v2 uses: actions/upload-artifact@v2
with: with:
name: legado apk name: legado apk
path: ${{ github.workspace }}/app/build/outputs/apk/app/release/*.apk path: ${{ github.workspace }}/apk/*.apk
- name: Upload App To Lanzou - name: Upload App To Lanzou
if: ${{ env.ylogin }} if: ${{ env.ylogin }}
run: | run: |
path="$GITHUB_WORKSPACE/app/build/outputs/apk/app/release" path="$GITHUB_WORKSPACE/apk"
files=$(ls $path) files=$(ls $path)
for f in $files for f in $files
do do
if [[ $f == *"apk" ]]; then if [[ $f == *"apk" ]]; then
file=$f file=$f
echo "[$(date -u -d '+8 hour' '+%Y.%m.%d %H:%M:%S')] 文件:$file" echo "[$(date -u -d '+8 hour' '+%Y.%m.%d %H:%M:%S')] 文件:$file"
break python3 $GITHUB_WORKSPACE/.github/scripts/lzy_web.py "$path/$file" "$LANZOU_FOLDER_ID"
fi fi
done done
python3 $GITHUB_WORKSPACE/.github/scripts/lzy_web.py "$path/$file" "$LANZOU_FOLDER_ID"
echo "[$(date -u -d '+8 hour' '+%Y.%m.%d %H:%M:%S')] 分享链接: https://kunfei.lanzoux.com/b0f810h4b" echo "[$(date -u -d '+8 hour' '+%Y.%m.%d %H:%M:%S')] 分享链接: https://kunfei.lanzoux.com/b0f810h4b"

@ -198,7 +198,7 @@ dependencies {
implementation('org.nanohttpd:nanohttpd-apache-fileupload:2.3.1') implementation('org.nanohttpd:nanohttpd-apache-fileupload:2.3.1')
// //
implementation('com.github.jenly1314:zxing-lite:2.1.0') implementation('com.github.jenly1314:zxing-lite:2.1.1')
// //
implementation('com.jaredrummler:colorpicker:1.1.0') implementation('com.jaredrummler:colorpicker:1.1.0')

@ -10,6 +10,8 @@
<!--<div class="logo"> <!--<div class="logo">
<img alt="" class="logo" src="../Images/logo.png"/> <img alt="" class="logo" src="../Images/logo.png"/>
</div>--> </div>-->
<br/>
<br/>
<h2 class="head">{title}</h2> <h2 class="head">{title}</h2>
{content} {content}
</body> </body>

@ -2,7 +2,6 @@
* 关注公众号 **[开源阅读]** 菜单•软件下载 提前享受新版本。 * 关注公众号 **[开源阅读]** 菜单•软件下载 提前享受新版本。
* 关注合作公众号 **[小说拾遗]** 获取好看的小说。 * 关注合作公众号 **[小说拾遗]** 获取好看的小说。
* 旧版数据导入教程:先在旧版阅读(2.x)中进行备份,然后在新版阅读(3.x)【我的】->【备份与恢复】,选择【导入旧版本数据】。
## **必读** ## **必读**
@ -11,6 +10,13 @@
* 阅读只是一个转码工具,不提供内容,第一次安装app,需要自己手动导入书源,可以从公众号 **[开源阅读]**、QQ群、酷安评论里获取由书友制作分享的书源。 * 阅读只是一个转码工具,不提供内容,第一次安装app,需要自己手动导入书源,可以从公众号 **[开源阅读]**、QQ群、酷安评论里获取由书友制作分享的书源。
* 正文出现缺字漏字、内容缺失、排版错乱等情况,有可能是净化规则出现问题, 出现简体变化问题检查一下简繁转换是否关闭。 * 正文出现缺字漏字、内容缺失、排版错乱等情况,有可能是净化规则出现问题, 出现简体变化问题检查一下简繁转换是否关闭。
* 漫画源看书显示乱码,**阅读与其他软件的源并不通用**,请导入阅读的支持的漫画源! * 漫画源看书显示乱码,**阅读与其他软件的源并不通用**,请导入阅读的支持的漫画源!
* 关于最近版本有时候界面没有数据的问题是因为把LiveData组件换成了谷歌推荐的Flow组件导致的问题,正在查找解决办法
**2021/08/06**
1. 背景图片添加模糊设置
2. 书籍信息界面添加置顶操作
3. 自动翻页时屏幕常亮
**2021/08/02** **2021/08/02**

@ -86,8 +86,4 @@ class App : MultiDexApplication() {
} }
} }
companion object {
var navigationBarHeight = 0
}
} }

@ -2,6 +2,7 @@ package io.legado.app.base
import android.content.Context import android.content.Context
import android.content.res.Configuration import android.content.res.Configuration
import android.graphics.drawable.BitmapDrawable
import android.os.Build import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.util.AttributeSet import android.util.AttributeSet
@ -11,7 +12,6 @@ import android.view.View
import android.widget.FrameLayout import android.widget.FrameLayout
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.viewbinding.ViewBinding import androidx.viewbinding.ViewBinding
import io.legado.app.App
import io.legado.app.R import io.legado.app.R
import io.legado.app.constant.AppConst import io.legado.app.constant.AppConst
import io.legado.app.constant.PreferKey import io.legado.app.constant.PreferKey
@ -99,13 +99,6 @@ abstract class BaseActivity<VB : ViewBinding>(
observeLiveBus() observeLiveBus()
} }
override fun onWindowFocusChanged(hasFocus: Boolean) {
super.onWindowFocusChanged(hasFocus)
if (hasFocus) {
App.navigationBarHeight = navigationBarHeight
}
}
override fun onMultiWindowModeChanged(isInMultiWindowMode: Boolean, newConfig: Configuration?) { override fun onMultiWindowModeChanged(isInMultiWindowMode: Boolean, newConfig: Configuration?) {
super.onMultiWindowModeChanged(isInMultiWindowMode, newConfig) super.onMultiWindowModeChanged(isInMultiWindowMode, newConfig)
findViewById<TitleBar>(R.id.title_bar) findViewById<TitleBar>(R.id.title_bar)
@ -174,8 +167,8 @@ abstract class BaseActivity<VB : ViewBinding>(
} }
if (imageBg) { if (imageBg) {
try { try {
ThemeConfig.getBgImage(this)?.let { ThemeConfig.getBgImage(this, windowSize)?.let {
window.decorView.background = it window.decorView.background = BitmapDrawable(resources, it)
} }
} catch (e: OutOfMemoryError) { } catch (e: OutOfMemoryError) {
toastOnUi(e.localizedMessage) toastOnUi(e.localizedMessage)

@ -24,4 +24,5 @@ object EventBus {
const val CHECK_SOURCE = "checkSource" const val CHECK_SOURCE = "checkSource"
const val CHECK_SOURCE_DONE = "checkSourceDone" const val CHECK_SOURCE_DONE = "checkSourceDone"
const val TIP_COLOR = "tipColor" const val TIP_COLOR = "tipColor"
const val SOURCE_CHANGED = "sourceChanged"
} }

@ -91,11 +91,13 @@ object PreferKey {
const val cBackground = "colorBackground" const val cBackground = "colorBackground"
const val cBBackground = "colorBottomBackground" const val cBBackground = "colorBottomBackground"
const val bgImage = "backgroundImage" const val bgImage = "backgroundImage"
const val bgImageBlurring = "backgroundImageBlurring"
const val cNPrimary = "colorPrimaryNight" const val cNPrimary = "colorPrimaryNight"
const val cNAccent = "colorAccentNight" const val cNAccent = "colorAccentNight"
const val cNBackground = "colorBackgroundNight" const val cNBackground = "colorBackgroundNight"
const val cNBBackground = "colorBottomBackgroundNight" const val cNBBackground = "colorBottomBackgroundNight"
const val bgImageN = "backgroundImageNight" const val bgImageN = "backgroundImageNight"
const val bgImageNBlurring = "backgroundImageNightBlurring"
} }

@ -62,6 +62,9 @@ interface BookDao {
@get:Query("SELECT COUNT(*) FROM books") @get:Query("SELECT COUNT(*) FROM books")
val allBookCount: Int val allBookCount: Int
@get:Query("select min(`order`) from books")
val minOrder: Int
@get:Query("select max(`order`) from books") @get:Query("select max(`order`) from books")
val maxOrder: Int val maxOrder: Int

@ -1,9 +1,9 @@
package io.legado.app.help package io.legado.app.help
import android.content.Context import android.content.Context
import android.graphics.Bitmap
import android.graphics.Color import android.graphics.Color
import android.graphics.drawable.BitmapDrawable import android.util.DisplayMetrics
import android.graphics.drawable.Drawable
import androidx.annotation.Keep import androidx.annotation.Keep
import androidx.appcompat.app.AppCompatDelegate import androidx.appcompat.app.AppCompatDelegate
import io.legado.app.R import io.legado.app.R
@ -11,6 +11,7 @@ import io.legado.app.constant.EventBus
import io.legado.app.constant.PreferKey import io.legado.app.constant.PreferKey
import io.legado.app.constant.Theme import io.legado.app.constant.Theme
import io.legado.app.lib.theme.ThemeStore import io.legado.app.lib.theme.ThemeStore
import io.legado.app.ui.widget.image.CoverImageView
import io.legado.app.utils.* import io.legado.app.utils.*
import splitties.init.appCtx import splitties.init.appCtx
import java.io.File import java.io.File
@ -28,6 +29,7 @@ object ThemeConfig {
ReadBookConfig.upBg() ReadBookConfig.upBg()
applyTheme(context) applyTheme(context)
initNightMode() initNightMode()
CoverImageView.upDefaultCover()
postEvent(EventBus.RECREATE, "") postEvent(EventBus.RECREATE, "")
} }
@ -41,14 +43,26 @@ object ThemeConfig {
AppCompatDelegate.setDefaultNightMode(targetMode) AppCompatDelegate.setDefaultNightMode(targetMode)
} }
fun getBgImage(context: Context): Drawable? { fun getBgImage(context: Context, metrics: DisplayMetrics): Bitmap? {
val bgPath = when (Theme.getTheme()) { val bgCfg = when (Theme.getTheme()) {
Theme.Light -> context.getPrefString(PreferKey.bgImage) Theme.Light -> Pair(
Theme.Dark -> context.getPrefString(PreferKey.bgImageN) context.getPrefString(PreferKey.bgImage),
context.getPrefInt(PreferKey.bgImageBlurring, 0)
)
Theme.Dark -> Pair(
context.getPrefString(PreferKey.bgImageN),
context.getPrefInt(PreferKey.bgImageNBlurring, 0)
)
else -> null else -> null
} ?: return null
if (bgCfg.first.isNullOrBlank()) return null
val bgImage = BitmapUtils
.decodeBitmap(bgCfg.first!!, metrics.widthPixels, metrics.heightPixels)
?: return null
if (bgCfg.second == 0) {
return bgImage
} }
if (bgPath.isNullOrBlank()) return null return BitmapUtils.stackBlur(bgImage, bgCfg.second.toFloat())
return BitmapDrawable.createFromPath(bgPath)
} }
fun upConfig() { fun upConfig() {

@ -161,17 +161,22 @@ class AudioPlayService : BaseService(),
} }
private fun resume() { private fun resume() {
pause = false try {
if (!mediaPlayer.isPlaying) { pause = false
mediaPlayer.start() if (!mediaPlayer.isPlaying) {
mediaPlayer.seekTo(position) mediaPlayer.start()
mediaPlayer.seekTo(position)
}
handler.removeCallbacks(mpRunnable)
handler.postDelayed(mpRunnable, 1000)
upMediaSessionPlaybackState(PlaybackStateCompat.STATE_PLAYING)
AudioPlay.status = Status.PLAY
postEvent(EventBus.AUDIO_STATE, Status.PLAY)
upNotification()
} catch (e: Exception) {
e.printStackTrace()
stopSelf()
} }
handler.removeCallbacks(mpRunnable)
handler.postDelayed(mpRunnable, 1000)
upMediaSessionPlaybackState(PlaybackStateCompat.STATE_PLAYING)
AudioPlay.status = Status.PLAY
postEvent(EventBus.AUDIO_STATE, Status.PLAY)
upNotification()
} }
private fun adjustProgress(position: Int) { private fun adjustProgress(position: Int) {

@ -176,6 +176,7 @@ class ImportBookSourceDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickList
appDb.bookSourceDao.allGroup.forEach { group -> appDb.bookSourceDao.allGroup.forEach { group ->
groups.addAll(group.splitNotBlank(AppPattern.splitGroupRegex)) groups.addAll(group.splitNotBlank(AppPattern.splitGroupRegex))
} }
textInputLayout.setHint(R.string.group_name)
editView.setFilterValues(groups.toList()) editView.setFilterValues(groups.toList())
editView.dropDownHeight = 180.dp editView.dropDownHeight = 180.dp
} }

@ -172,6 +172,7 @@ class ImportRssSourceDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListe
appDb.rssSourceDao.allGroup.forEach { group -> appDb.rssSourceDao.allGroup.forEach { group ->
groups.addAll(group.splitNotBlank(AppPattern.splitGroupRegex)) groups.addAll(group.splitNotBlank(AppPattern.splitGroupRegex))
} }
textInputLayout.setHint(R.string.group_name)
editView.setFilterValues(groups.toList()) editView.setFilterValues(groups.toList())
editView.dropDownHeight = 180.dp editView.dropDownHeight = 180.dp
} }

@ -4,12 +4,14 @@ import android.app.Application
import android.content.Intent import android.content.Intent
import io.legado.app.R import io.legado.app.R
import io.legado.app.base.BaseViewModel import io.legado.app.base.BaseViewModel
import io.legado.app.constant.EventBus
import io.legado.app.data.appDb import io.legado.app.data.appDb
import io.legado.app.data.entities.Book import io.legado.app.data.entities.Book
import io.legado.app.data.entities.BookChapter import io.legado.app.data.entities.BookChapter
import io.legado.app.help.BookHelp import io.legado.app.help.BookHelp
import io.legado.app.model.webBook.WebBook import io.legado.app.model.webBook.WebBook
import io.legado.app.service.help.AudioPlay import io.legado.app.service.help.AudioPlay
import io.legado.app.utils.postEvent
import io.legado.app.utils.toastOnUi import io.legado.app.utils.toastOnUi
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
@ -98,6 +100,8 @@ class AudioPlayViewModel(application: Application) : BaseViewModel(application)
} else { } else {
loadChapterList(book1) { upChangeDurChapterIndex(book1, oldTocSize, it) } loadChapterList(book1) { upChangeDurChapterIndex(book1, oldTocSize, it) }
} }
}.onFinally {
postEvent(EventBus.SOURCE_CHANGED, book1.bookUrl)
} }
} }

@ -298,6 +298,7 @@ class CacheActivity : VMBaseActivity<ActivityCacheBookBinding, CacheViewModel>()
private fun alertExportFileName() { private fun alertExportFileName() {
alert(R.string.export_file_name) { alert(R.string.export_file_name) {
val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply { val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply {
textInputLayout.hint = "file name js"
editView.setText(AppConfig.bookExportFileName) editView.setText(AppConfig.bookExportFileName)
} }
customView { alertBinding.root } customView { alertBinding.root }
@ -317,6 +318,7 @@ class CacheActivity : VMBaseActivity<ActivityCacheBookBinding, CacheViewModel>()
private fun showCharsetConfig() { private fun showCharsetConfig() {
alert(R.string.set_charset) { alert(R.string.set_charset) {
val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply { val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply {
textInputLayout.hint = "charset name"
editView.setFilterValues(charsets) editView.setFilterValues(charsets)
editView.setText(AppConfig.exportCharset) editView.setText(AppConfig.exportCharset)
} }

@ -14,9 +14,8 @@ import io.legado.app.base.BaseDialogFragment
import io.legado.app.databinding.DialogChangeCoverBinding import io.legado.app.databinding.DialogChangeCoverBinding
import io.legado.app.lib.theme.primaryColor import io.legado.app.lib.theme.primaryColor
import io.legado.app.utils.applyTint import io.legado.app.utils.applyTint
import io.legado.app.utils.getSize
import io.legado.app.utils.viewbindingdelegate.viewBinding import io.legado.app.utils.viewbindingdelegate.viewBinding
import io.legado.app.utils.windowSize
class ChangeCoverDialog : BaseDialogFragment(), class ChangeCoverDialog : BaseDialogFragment(),
@ -45,7 +44,7 @@ class ChangeCoverDialog : BaseDialogFragment(),
override fun onStart() { override fun onStart() {
super.onStart() super.onStart()
val dm = requireActivity().getSize() val dm = requireActivity().windowSize
dialog?.window?.setLayout((dm.widthPixels * 0.9).toInt(), (dm.heightPixels * 0.9).toInt()) dialog?.window?.setLayout((dm.widthPixels * 0.9).toInt(), (dm.heightPixels * 0.9).toInt())
} }

@ -62,6 +62,11 @@ class ChangeSourceAdapter(
when (it) { when (it) {
"name" -> tvOrigin.text = item.originName "name" -> tvOrigin.text = item.originName
"latest" -> tvLast.text = item.getDisplayLastChapterTitle() "latest" -> tvLast.text = item.getDisplayLastChapterTitle()
"upCurSource" -> if (callBack.bookUrl == item.bookUrl) {
ivChecked.visible()
} else {
ivChecked.invisible()
}
} }
} }
} }

@ -4,6 +4,7 @@ import android.os.Bundle
import android.view.* import android.view.*
import androidx.appcompat.widget.SearchView import androidx.appcompat.widget.SearchView
import androidx.appcompat.widget.Toolbar import androidx.appcompat.widget.Toolbar
import androidx.core.os.bundleOf
import androidx.fragment.app.FragmentManager import androidx.fragment.app.FragmentManager
import androidx.fragment.app.viewModels import androidx.fragment.app.viewModels
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
@ -11,6 +12,7 @@ import androidx.recyclerview.widget.RecyclerView
import io.legado.app.R import io.legado.app.R
import io.legado.app.base.BaseDialogFragment import io.legado.app.base.BaseDialogFragment
import io.legado.app.constant.AppPattern import io.legado.app.constant.AppPattern
import io.legado.app.constant.EventBus
import io.legado.app.constant.PreferKey import io.legado.app.constant.PreferKey
import io.legado.app.data.appDb import io.legado.app.data.appDb
import io.legado.app.data.entities.Book import io.legado.app.data.entities.Book
@ -53,7 +55,7 @@ class ChangeSourceDialog : BaseDialogFragment(),
override fun onStart() { override fun onStart() {
super.onStart() super.onStart()
val dm = requireActivity().getSize() val dm = requireActivity().windowSize
dialog?.window?.setLayout((dm.widthPixels * 0.9).toInt(), (dm.heightPixels * 0.9).toInt()) dialog?.window?.setLayout((dm.widthPixels * 0.9).toInt(), (dm.heightPixels * 0.9).toInt())
} }
@ -218,12 +220,12 @@ class ChangeSourceDialog : BaseDialogFragment(),
} }
override fun deleteSource(searchBook: SearchBook) { override fun deleteSource(searchBook: SearchBook) {
viewModel.del(searchBook)
if (bookUrl == searchBook.bookUrl) { if (bookUrl == searchBook.bookUrl) {
viewModel.firstSourceOrNull(searchBook)?.let { viewModel.firstSourceOrNull(searchBook)?.let {
changeSource(it) changeSource(it)
} }
} }
viewModel.del(searchBook)
} }
private fun changeSource(searchBook: SearchBook) { private fun changeSource(searchBook: SearchBook) {
@ -259,6 +261,16 @@ class ChangeSourceDialog : BaseDialogFragment(),
} }
} }
override fun observeLiveBus() {
observeEvent<String>(EventBus.SOURCE_CHANGED) {
adapter.notifyItemRangeChanged(
0,
adapter.itemCount,
bundleOf(Pair("upCurSource", bookUrl))
)
}
}
interface CallBack { interface CallBack {
val oldBook: Book? val oldBook: Book?
fun changeTo(book: Book) fun changeTo(book: Book)

@ -15,7 +15,7 @@ object GroupEdit {
fun show(context: Context, layoutInflater: LayoutInflater, bookGroup: BookGroup) = context.run { fun show(context: Context, layoutInflater: LayoutInflater, bookGroup: BookGroup) = context.run {
alert(title = getString(R.string.group_edit)) { alert(title = getString(R.string.group_edit)) {
val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply { val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply {
editView.setHint(R.string.group_name) textInputLayout.setHint(R.string.group_name)
editView.setText(bookGroup.groupName) editView.setText(bookGroup.groupName)
} }
if (bookGroup.groupId >= 0) { if (bookGroup.groupId >= 0) {

@ -28,10 +28,10 @@ import io.legado.app.lib.theme.primaryColor
import io.legado.app.ui.widget.recycler.ItemTouchCallback import io.legado.app.ui.widget.recycler.ItemTouchCallback
import io.legado.app.ui.widget.recycler.VerticalDivider import io.legado.app.ui.widget.recycler.VerticalDivider
import io.legado.app.utils.applyTint import io.legado.app.utils.applyTint
import io.legado.app.utils.getSize
import io.legado.app.utils.requestInputMethod import io.legado.app.utils.requestInputMethod
import io.legado.app.utils.viewbindingdelegate.viewBinding import io.legado.app.utils.viewbindingdelegate.viewBinding
import io.legado.app.utils.visible import io.legado.app.utils.visible
import io.legado.app.utils.windowSize
import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@ -43,7 +43,7 @@ class GroupManageDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener
override fun onStart() { override fun onStart() {
super.onStart() super.onStart()
val dm = requireActivity().getSize() val dm = requireActivity().windowSize
dialog?.window?.setLayout((dm.widthPixels * 0.9).toInt(), (dm.heightPixels * 0.9).toInt()) dialog?.window?.setLayout((dm.widthPixels * 0.9).toInt(), (dm.heightPixels * 0.9).toInt())
} }
@ -103,7 +103,7 @@ class GroupManageDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener
private fun addGroup() { private fun addGroup() {
alert(title = getString(R.string.add_group)) { alert(title = getString(R.string.add_group)) {
val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply { val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply {
editView.setHint(R.string.group_name) textInputLayout.setHint(R.string.group_name)
} }
customView { alertBinding.root } customView { alertBinding.root }
yesButton { yesButton {

@ -29,9 +29,9 @@ import io.legado.app.lib.theme.primaryColor
import io.legado.app.ui.widget.recycler.ItemTouchCallback import io.legado.app.ui.widget.recycler.ItemTouchCallback
import io.legado.app.ui.widget.recycler.VerticalDivider import io.legado.app.ui.widget.recycler.VerticalDivider
import io.legado.app.utils.applyTint import io.legado.app.utils.applyTint
import io.legado.app.utils.getSize
import io.legado.app.utils.requestInputMethod import io.legado.app.utils.requestInputMethod
import io.legado.app.utils.viewbindingdelegate.viewBinding import io.legado.app.utils.viewbindingdelegate.viewBinding
import io.legado.app.utils.windowSize
import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@ -61,7 +61,7 @@ class GroupSelectDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener
override fun onStart() { override fun onStart() {
super.onStart() super.onStart()
val dm = requireActivity().getSize() val dm = requireActivity().windowSize
dialog?.window?.setLayout((dm.widthPixels * 0.9).toInt(), (dm.heightPixels * 0.9).toInt()) dialog?.window?.setLayout((dm.widthPixels * 0.9).toInt(), (dm.heightPixels * 0.9).toInt())
} }
@ -125,7 +125,7 @@ class GroupSelectDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener
private fun addGroup() { private fun addGroup() {
alert(title = getString(R.string.add_group)) { alert(title = getString(R.string.add_group)) {
val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply { val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply {
editView.setHint(R.string.group_name) textInputLayout.setHint(R.string.group_name)
} }
customView { alertBinding.root } customView { alertBinding.root }
yesButton { yesButton {
@ -143,7 +143,7 @@ class GroupSelectDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener
private fun editGroup(bookGroup: BookGroup) { private fun editGroup(bookGroup: BookGroup) {
alert(title = getString(R.string.group_edit)) { alert(title = getString(R.string.group_edit)) {
val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply { val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply {
editView.setHint(R.string.group_name) textInputLayout.setHint(R.string.group_name)
editView.setText(bookGroup.groupName) editView.setText(bookGroup.groupName)
} }
customView { alertBinding.root } customView { alertBinding.root }

@ -15,6 +15,7 @@ import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions
import com.bumptech.glide.request.RequestOptions.bitmapTransform import com.bumptech.glide.request.RequestOptions.bitmapTransform
import io.legado.app.R import io.legado.app.R
import io.legado.app.base.VMBaseActivity import io.legado.app.base.VMBaseActivity
import io.legado.app.constant.AppConst
import io.legado.app.constant.BookType import io.legado.app.constant.BookType
import io.legado.app.constant.Theme import io.legado.app.constant.Theme
import io.legado.app.data.appDb import io.legado.app.data.appDb
@ -36,6 +37,7 @@ import io.legado.app.ui.book.read.ReadBookActivity
import io.legado.app.ui.book.search.SearchActivity import io.legado.app.ui.book.search.SearchActivity
import io.legado.app.ui.book.source.edit.BookSourceEditActivity import io.legado.app.ui.book.source.edit.BookSourceEditActivity
import io.legado.app.ui.book.toc.TocActivityResult import io.legado.app.ui.book.toc.TocActivityResult
import io.legado.app.ui.login.SourceLoginActivity
import io.legado.app.ui.widget.image.CoverImageView import io.legado.app.ui.widget.image.CoverImageView
import io.legado.app.utils.* import io.legado.app.utils.*
import io.legado.app.utils.viewbindingdelegate.viewBinding import io.legado.app.utils.viewbindingdelegate.viewBinding
@ -151,6 +153,14 @@ class BookInfoActivity :
viewModel.loadBookInfo(it, false) viewModel.loadBookInfo(it, false)
} }
} }
R.id.menu_login -> viewModel.bookSource?.let {
startActivity<SourceLoginActivity> {
putExtra("sourceUrl", it.bookSourceUrl)
putExtra("loginUrl", it.loginUrl)
putExtra("userAgent", it.getHeaderMap()[AppConst.UA_NAME])
}
}
R.id.menu_top -> viewModel.topBook()
R.id.menu_copy_book_url -> viewModel.bookData.value?.bookUrl?.let { R.id.menu_copy_book_url -> viewModel.bookData.value?.bookUrl?.let {
sendToClip(it) sendToClip(it)
} ?: toastOnUi(R.string.no_book) } ?: toastOnUi(R.string.no_book)

@ -5,6 +5,7 @@ import android.content.Intent
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import io.legado.app.R import io.legado.app.R
import io.legado.app.base.BaseViewModel import io.legado.app.base.BaseViewModel
import io.legado.app.constant.EventBus
import io.legado.app.data.appDb import io.legado.app.data.appDb
import io.legado.app.data.entities.Book import io.legado.app.data.entities.Book
import io.legado.app.data.entities.BookChapter import io.legado.app.data.entities.BookChapter
@ -13,6 +14,7 @@ import io.legado.app.help.BookHelp
import io.legado.app.model.localBook.LocalBook import io.legado.app.model.localBook.LocalBook
import io.legado.app.model.webBook.WebBook import io.legado.app.model.webBook.WebBook
import io.legado.app.service.help.ReadBook import io.legado.app.service.help.ReadBook
import io.legado.app.utils.postEvent
import io.legado.app.utils.toastOnUi import io.legado.app.utils.toastOnUi
import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.Dispatchers.IO
@ -167,6 +169,8 @@ class BookInfoViewModel(application: Application) : BaseViewModel(application) {
upChangeDurChapterIndex(newBook, oldTocSize, it) upChangeDurChapterIndex(newBook, oldTocSize, it)
} }
} }
}.onFinally {
postEvent(EventBus.SOURCE_CHANGED, newBook.bookUrl)
} }
} }
@ -192,6 +196,16 @@ class BookInfoViewModel(application: Application) : BaseViewModel(application) {
} }
} }
fun topBook() {
execute {
bookData.value?.let { book ->
val minOrder = appDb.bookDao.minOrder
book.order = minOrder - 1
appDb.bookDao.update(book)
}
}
}
fun saveBook(success: (() -> Unit)? = null) { fun saveBook(success: (() -> Unit)? = null) {
execute { execute {
bookData.value?.let { book -> bookData.value?.let { book ->

@ -280,6 +280,7 @@ class ImportBookActivity : VMBaseActivity<ActivityImportBookBinding, ImportBookV
private fun alertImportFileName() { private fun alertImportFileName() {
alert(R.string.import_file_name) { alert(R.string.import_file_name) {
val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply { val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply {
textInputLayout.hint = "js"
editView.setText(AppConfig.bookImportFileName) editView.setText(AppConfig.bookImportFileName)
} }
customView { alertBinding.root } customView { alertBinding.root }

@ -150,6 +150,7 @@ class ReadBookActivity : ReadBookBaseActivity(),
override fun onWindowFocusChanged(hasFocus: Boolean) { override fun onWindowFocusChanged(hasFocus: Boolean) {
super.onWindowFocusChanged(hasFocus) super.onWindowFocusChanged(hasFocus)
binding.readView.upStyle()
upSystemUiVisibility() upSystemUiVisibility()
} }
@ -686,6 +687,8 @@ class ReadBookActivity : ReadBookBaseActivity(),
binding.readView.upContent(1) binding.readView.upContent(1)
autoPagePlus() autoPagePlus()
binding.readMenu.setAutoPage(true) binding.readMenu.setAutoPage(true)
screenTimeOut = -1L
screenOffTimerStart()
} }
} }
@ -694,14 +697,15 @@ class ReadBookActivity : ReadBookBaseActivity(),
mHandler.removeCallbacks(autoPageRunnable) mHandler.removeCallbacks(autoPageRunnable)
binding.readView.upContent() binding.readView.upContent()
binding.readMenu.setAutoPage(false) binding.readMenu.setAutoPage(false)
upScreenTimeOut()
} }
private fun autoPagePlus() { private fun autoPagePlus() {
var delayMillis = ReadBookConfig.autoReadSpeed * 1000L / binding.readView.height var delayMillis = ReadBookConfig.autoReadSpeed * 1000L / binding.readView.height
var scrollOffset = 1 var scrollOffset = 1
if (delayMillis < 20) { if (delayMillis < 20) {
var delayInt=delayMillis.toInt() var delayInt = delayMillis.toInt()
if(delayInt==0)delayInt =1 if (delayInt == 0) delayInt = 1
scrollOffset = 20 / delayInt scrollOffset = 20 / delayInt
delayMillis = 20 delayMillis = 20
} }
@ -970,9 +974,8 @@ class ReadBookActivity : ReadBookBaseActivity(),
} }
private fun upScreenTimeOut() { private fun upScreenTimeOut() {
getPrefString(PreferKey.keepLight)?.let { val keepLightPrefer = getPrefString(PreferKey.keepLight)?.toInt() ?: 0
screenTimeOut = it.toLong() * 1000 screenTimeOut = keepLightPrefer * 1000L
}
screenOffTimerStart() screenOffTimerStart()
} }

@ -202,6 +202,7 @@ abstract class ReadBookBaseActivity :
fun showCharsetConfig() { fun showCharsetConfig() {
alert(R.string.set_charset) { alert(R.string.set_charset) {
val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply { val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply {
textInputLayout.hint = "charset"
editView.setFilterValues(charsets) editView.setFilterValues(charsets)
editView.setText(ReadBook.book?.charset) editView.setText(ReadBook.book?.charset)
} }

@ -5,6 +5,7 @@ import android.content.Intent
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import io.legado.app.R import io.legado.app.R
import io.legado.app.base.BaseViewModel import io.legado.app.base.BaseViewModel
import io.legado.app.constant.EventBus
import io.legado.app.data.appDb import io.legado.app.data.appDb
import io.legado.app.data.entities.Book import io.legado.app.data.entities.Book
import io.legado.app.data.entities.BookChapter import io.legado.app.data.entities.BookChapter
@ -20,6 +21,7 @@ import io.legado.app.service.BaseReadAloudService
import io.legado.app.service.help.ReadAloud import io.legado.app.service.help.ReadAloud
import io.legado.app.service.help.ReadBook import io.legado.app.service.help.ReadBook
import io.legado.app.utils.msg import io.legado.app.utils.msg
import io.legado.app.utils.postEvent
import io.legado.app.utils.toastOnUi import io.legado.app.utils.toastOnUi
import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.Dispatchers.Main import kotlinx.coroutines.Dispatchers.Main
@ -207,6 +209,8 @@ class ReadBookViewModel(application: Application) : BaseViewModel(application) {
upChangeDurChapterIndex(newBook, oldTocSize, it) upChangeDurChapterIndex(newBook, oldTocSize, it)
} }
} }
}.onFinally {
postEvent(EventBus.SOURCE_CHANGED, newBook.bookUrl)
} }
} }

@ -47,12 +47,12 @@ class BgTextConfigDialog : BaseDialogFragment() {
private var secondaryTextColor = 0 private var secondaryTextColor = 0
private val importFormNet = "网络导入" private val importFormNet = "网络导入"
private val selectBgImage = registerForActivityResult(ActivityResultContracts.GetContent()) { private val selectBgImage = registerForActivityResult(ActivityResultContracts.GetContent()) {
it ?: return@registerForActivityResult
setBgFromUri(it) setBgFromUri(it)
} }
private val selectExportDir = registerForActivityResult(FilePicker()) { private val selectExportDir = registerForActivityResult(FilePicker()) {
it?.let { it ?: return@registerForActivityResult
exportConfig(it) exportConfig(it)
}
} }
private val selectImportDoc = registerForActivityResult(FilePicker()) { private val selectImportDoc = registerForActivityResult(FilePicker()) {
it ?: return@registerForActivityResult it ?: return@registerForActivityResult
@ -142,6 +142,7 @@ class BgTextConfigDialog : BaseDialogFragment() {
binding.ivEdit.setOnClickListener { binding.ivEdit.setOnClickListener {
alert(R.string.style_name) { alert(R.string.style_name) {
val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply { val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply {
textInputLayout.hint = "name"
editView.setText(ReadBookConfig.durConfig.name) editView.setText(ReadBookConfig.durConfig.name)
} }
customView { alertBinding.root } customView { alertBinding.root }

@ -11,9 +11,9 @@ import io.legado.app.base.BaseDialogFragment
import io.legado.app.constant.EventBus import io.legado.app.constant.EventBus
import io.legado.app.databinding.DialogReadPaddingBinding import io.legado.app.databinding.DialogReadPaddingBinding
import io.legado.app.help.ReadBookConfig import io.legado.app.help.ReadBookConfig
import io.legado.app.utils.getSize
import io.legado.app.utils.postEvent import io.legado.app.utils.postEvent
import io.legado.app.utils.viewbindingdelegate.viewBinding import io.legado.app.utils.viewbindingdelegate.viewBinding
import io.legado.app.utils.windowSize
class PaddingConfigDialog : BaseDialogFragment() { class PaddingConfigDialog : BaseDialogFragment() {
@ -21,7 +21,7 @@ class PaddingConfigDialog : BaseDialogFragment() {
override fun onStart() { override fun onStart() {
super.onStart() super.onStart()
val dm = requireActivity().getSize() val dm = requireActivity().windowSize
dialog?.window?.let { dialog?.window?.let {
it.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND) it.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND)
val attr = it.attributes val attr = it.attributes

@ -19,8 +19,8 @@ import io.legado.app.lib.theme.backgroundColor
import io.legado.app.service.BaseReadAloudService import io.legado.app.service.BaseReadAloudService
import io.legado.app.service.help.ReadAloud import io.legado.app.service.help.ReadAloud
import io.legado.app.utils.getPrefLong import io.legado.app.utils.getPrefLong
import io.legado.app.utils.getSize
import io.legado.app.utils.postEvent import io.legado.app.utils.postEvent
import io.legado.app.utils.windowSize
import splitties.init.appCtx import splitties.init.appCtx
class ReadAloudConfigDialog : DialogFragment() { class ReadAloudConfigDialog : DialogFragment() {
@ -28,7 +28,7 @@ class ReadAloudConfigDialog : DialogFragment() {
override fun onStart() { override fun onStart() {
super.onStart() super.onStart()
val dm = requireActivity().getSize() val dm = requireActivity().windowSize
dialog?.window?.let { dialog?.window?.let {
it.setBackgroundDrawableResource(R.color.transparent) it.setBackgroundDrawableResource(R.color.transparent)
it.setLayout((dm.widthPixels * 0.9).toInt(), ViewGroup.LayoutParams.WRAP_CONTENT) it.setLayout((dm.widthPixels * 0.9).toInt(), ViewGroup.LayoutParams.WRAP_CONTENT)

@ -54,7 +54,7 @@ class SpeakEngineDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener
override fun onStart() { override fun onStart() {
super.onStart() super.onStart()
val dm = requireActivity().getSize() val dm = requireActivity().windowSize
dialog?.window?.setLayout((dm.widthPixels * 0.9).toInt(), (dm.heightPixels * 0.9).toInt()) dialog?.window?.setLayout((dm.widthPixels * 0.9).toInt(), (dm.heightPixels * 0.9).toInt())
} }
@ -134,6 +134,7 @@ class SpeakEngineDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener
?.toMutableList() ?: mutableListOf() ?.toMutableList() ?: mutableListOf()
alert(R.string.import_on_line) { alert(R.string.import_on_line) {
val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply { val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply {
textInputLayout.hint = "url"
editView.setFilterValues(cacheUrls) editView.setFilterValues(cacheUrls)
editView.delCallBack = { editView.delCallBack = {
cacheUrls.remove(it) cacheUrls.remove(it)

@ -45,7 +45,7 @@ class TocRegexDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener {
override fun onStart() { override fun onStart() {
super.onStart() super.onStart()
val dm = requireActivity().getSize() val dm = requireActivity().windowSize
dialog?.window?.setLayout((dm.widthPixels * 0.9).toInt(), (dm.heightPixels * 0.8).toInt()) dialog?.window?.setLayout((dm.widthPixels * 0.9).toInt(), (dm.heightPixels * 0.8).toInt())
} }
@ -135,8 +135,8 @@ class TocRegexDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener {
cacheUrls.add(0, defaultUrl) cacheUrls.add(0, defaultUrl)
} }
requireContext().alert(titleResource = R.string.import_on_line) { requireContext().alert(titleResource = R.string.import_on_line) {
val alertBinding = DialogEditTextBinding.inflate(layoutInflater) val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply {
alertBinding.apply { textInputLayout.hint = "url"
editView.setFilterValues(cacheUrls) editView.setFilterValues(cacheUrls)
editView.delCallBack = { editView.delCallBack = {
cacheUrls.remove(it) cacheUrls.remove(it)

@ -7,7 +7,6 @@ import android.view.LayoutInflater
import android.widget.FrameLayout import android.widget.FrameLayout
import androidx.core.view.isGone import androidx.core.view.isGone
import androidx.core.view.isInvisible import androidx.core.view.isInvisible
import io.legado.app.App
import io.legado.app.R import io.legado.app.R
import io.legado.app.base.BaseActivity import io.legado.app.base.BaseActivity
import io.legado.app.constant.AppConst.timeFormat import io.legado.app.constant.AppConst.timeFormat
@ -85,7 +84,7 @@ class PageView(context: Context) : FrameLayout(context) {
vwTopDivider.visible(it.showHeaderLine) vwTopDivider.visible(it.showHeaderLine)
vwBottomDivider.visible(it.showFooterLine) vwBottomDivider.visible(it.showFooterLine)
pageNvBar.layoutParams = pageNvBar.layoutParams.apply { pageNvBar.layoutParams = pageNvBar.layoutParams.apply {
height = if (it.hideNavigationBar) 0 else App.navigationBarHeight height = if (it.hideNavigationBar) 0 else activity?.navigationBarHeight ?: 0
} }
} }
contentTextView.upVisibleRect() contentTextView.upVisibleRect()

@ -343,8 +343,10 @@ object ChapterProvider {
} }
x = x1 x = x1
} }
val words1 = words.copyOfRange(bodyIndent.length, words.size) if (words.size > bodyIndent.length) {
addCharsToLineMiddle(textLine, words1, textPaint, desiredWidth, x, srcList) val words1 = words.copyOfRange(bodyIndent.length, words.size)
addCharsToLineMiddle(textLine, words1, textPaint, desiredWidth, x, srcList)
}
} }
/** /**

@ -444,7 +444,7 @@ class BookSourceEditActivity :
val rect = Rect() val rect = Rect()
// 获取当前页面窗口的显示范围 // 获取当前页面窗口的显示范围
window.decorView.getWindowVisibleDisplayFrame(rect) window.decorView.getWindowVisibleDisplayFrame(rect)
val screenHeight = this@BookSourceEditActivity.getSize().heightPixels val screenHeight = this@BookSourceEditActivity.windowSize.heightPixels
val keyboardHeight = screenHeight - rect.bottom // 输入法的高度 val keyboardHeight = screenHeight - rect.bottom // 输入法的高度
val preShowing = mIsSoftKeyBoardShowing val preShowing = mIsSoftKeyBoardShowing
if (abs(keyboardHeight) > screenHeight / 5) { if (abs(keyboardHeight) > screenHeight / 5) {

@ -327,6 +327,7 @@ class BookSourceActivity : VMBaseActivity<ActivityBookSourceBinding, BookSourceV
private fun checkSource() { private fun checkSource() {
alert(titleResource = R.string.search_book_key) { alert(titleResource = R.string.search_book_key) {
val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply { val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply {
textInputLayout.hint = "search word"
editView.setText(CheckSource.keyword) editView.setText(CheckSource.keyword)
} }
customView { alertBinding.root } customView { alertBinding.root }
@ -346,7 +347,7 @@ class BookSourceActivity : VMBaseActivity<ActivityBookSourceBinding, BookSourceV
private fun selectionAddToGroups() { private fun selectionAddToGroups() {
alert(titleResource = R.string.add_group) { alert(titleResource = R.string.add_group) {
val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply { val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply {
editView.setHint(R.string.group_name) textInputLayout.setHint(R.string.group_name)
editView.setFilterValues(groups.toList()) editView.setFilterValues(groups.toList())
editView.dropDownHeight = 180.dp editView.dropDownHeight = 180.dp
} }
@ -366,7 +367,7 @@ class BookSourceActivity : VMBaseActivity<ActivityBookSourceBinding, BookSourceV
private fun selectionRemoveFromGroups() { private fun selectionRemoveFromGroups() {
alert(titleResource = R.string.remove_group) { alert(titleResource = R.string.remove_group) {
val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply { val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply {
editView.setHint(R.string.group_name) textInputLayout.setHint(R.string.group_name)
editView.setFilterValues(groups.toList()) editView.setFilterValues(groups.toList())
editView.dropDownHeight = 180.dp editView.dropDownHeight = 180.dp
} }
@ -400,6 +401,7 @@ class BookSourceActivity : VMBaseActivity<ActivityBookSourceBinding, BookSourceV
?.toMutableList() ?: mutableListOf() ?.toMutableList() ?: mutableListOf()
alert(titleResource = R.string.import_on_line) { alert(titleResource = R.string.import_on_line) {
val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply { val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply {
textInputLayout.hint = "url"
editView.setFilterValues(cacheUrls) editView.setFilterValues(cacheUrls)
editView.delCallBack = { editView.delCallBack = {
cacheUrls.remove(it) cacheUrls.remove(it)

@ -24,10 +24,10 @@ import io.legado.app.lib.theme.backgroundColor
import io.legado.app.lib.theme.primaryColor import io.legado.app.lib.theme.primaryColor
import io.legado.app.ui.widget.recycler.VerticalDivider import io.legado.app.ui.widget.recycler.VerticalDivider
import io.legado.app.utils.applyTint import io.legado.app.utils.applyTint
import io.legado.app.utils.getSize
import io.legado.app.utils.requestInputMethod import io.legado.app.utils.requestInputMethod
import io.legado.app.utils.splitNotBlank import io.legado.app.utils.splitNotBlank
import io.legado.app.utils.viewbindingdelegate.viewBinding import io.legado.app.utils.viewbindingdelegate.viewBinding
import io.legado.app.utils.windowSize
import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@ -39,7 +39,7 @@ class GroupManageDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener
override fun onStart() { override fun onStart() {
super.onStart() super.onStart()
val dm = requireActivity().getSize() val dm = requireActivity().windowSize
dialog?.window?.setLayout((dm.widthPixels * 0.9).toInt(), (dm.heightPixels * 0.9).toInt()) dialog?.window?.setLayout((dm.widthPixels * 0.9).toInt(), (dm.heightPixels * 0.9).toInt())
} }
@ -87,8 +87,9 @@ class GroupManageDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener
@SuppressLint("InflateParams") @SuppressLint("InflateParams")
private fun addGroup() { private fun addGroup() {
alert(title = getString(R.string.add_group)) { alert(title = getString(R.string.add_group)) {
val alertBinding = DialogEditTextBinding.inflate(layoutInflater) val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply {
alertBinding.editView.setHint(R.string.group_name) textInputLayout.setHint(R.string.group_name)
}
customView { alertBinding.root } customView { alertBinding.root }
yesButton { yesButton {
alertBinding.editView.text?.toString()?.let { alertBinding.editView.text?.toString()?.let {
@ -104,9 +105,10 @@ class GroupManageDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener
@SuppressLint("InflateParams") @SuppressLint("InflateParams")
private fun editGroup(group: String) { private fun editGroup(group: String) {
alert(title = getString(R.string.group_edit)) { alert(title = getString(R.string.group_edit)) {
val alertBinding = DialogEditTextBinding.inflate(layoutInflater) val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply {
alertBinding.editView.setHint(R.string.group_name) textInputLayout.setHint(R.string.group_name)
alertBinding.editView.setText(group) editView.setText(group)
}
customView { alertBinding.root } customView { alertBinding.root }
yesButton { yesButton {
viewModel.upGroup(group, alertBinding.editView.text?.toString()) viewModel.upGroup(group, alertBinding.editView.text?.toString())

@ -144,8 +144,10 @@ class OtherConfigFragment : BasePreferenceFragment(),
@SuppressLint("InflateParams") @SuppressLint("InflateParams")
private fun showUserAgentDialog() { private fun showUserAgentDialog() {
alert("UserAgent") { alert("UserAgent") {
val alertBinding = DialogEditTextBinding.inflate(layoutInflater) val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply {
alertBinding.editView.setText(AppConfig.userAgent) textInputLayout.hint = "UserAgent"
editView.setText(AppConfig.userAgent)
}
customView { alertBinding.root } customView { alertBinding.root }
okButton { okButton {
val userAgent = alertBinding.editView.text?.toString() val userAgent = alertBinding.editView.text?.toString()

@ -9,6 +9,7 @@ import android.view.Menu
import android.view.MenuInflater import android.view.MenuInflater
import android.view.MenuItem import android.view.MenuItem
import android.view.View import android.view.View
import android.widget.SeekBar
import androidx.documentfile.provider.DocumentFile import androidx.documentfile.provider.DocumentFile
import androidx.preference.Preference import androidx.preference.Preference
import io.legado.app.R import io.legado.app.R
@ -17,6 +18,7 @@ import io.legado.app.constant.AppConst
import io.legado.app.constant.EventBus import io.legado.app.constant.EventBus
import io.legado.app.constant.PreferKey import io.legado.app.constant.PreferKey
import io.legado.app.databinding.DialogEditTextBinding import io.legado.app.databinding.DialogEditTextBinding
import io.legado.app.databinding.DialogImageBlurringBinding
import io.legado.app.help.AppConfig import io.legado.app.help.AppConfig
import io.legado.app.help.LauncherIconHelp import io.legado.app.help.LauncherIconHelp
import io.legado.app.help.ThemeConfig import io.legado.app.help.ThemeConfig
@ -28,6 +30,7 @@ import io.legado.app.lib.theme.ATH
import io.legado.app.ui.widget.image.CoverImageView import io.legado.app.ui.widget.image.CoverImageView
import io.legado.app.ui.widget.number.NumberPickerDialog import io.legado.app.ui.widget.number.NumberPickerDialog
import io.legado.app.ui.widget.prefs.ColorPreference import io.legado.app.ui.widget.prefs.ColorPreference
import io.legado.app.ui.widget.seekbar.SeekBarChangeListener
import io.legado.app.utils.* import io.legado.app.utils.*
import java.io.File import java.io.File
@ -134,7 +137,10 @@ class ThemeConfigFragment : BasePreferenceFragment(),
PreferKey.cNBBackground -> { PreferKey.cNBBackground -> {
upTheme(true) upTheme(true)
} }
PreferKey.defaultCover, PreferKey.defaultCoverDark -> { PreferKey.bgImage,
PreferKey.bgImageN,
PreferKey.defaultCover,
PreferKey.defaultCoverDark -> {
upPreferenceSummary(key, getPrefString(key)) upPreferenceSummary(key, getPrefString(key))
} }
} }
@ -158,31 +164,9 @@ class ThemeConfigFragment : BasePreferenceFragment(),
recreateActivities() recreateActivities()
} }
"themeList" -> ThemeListDialog().show(childFragmentManager, "themeList") "themeList" -> ThemeListDialog().show(childFragmentManager, "themeList")
"saveDayTheme", "saveNightTheme" -> saveThemeAlert(key) "saveDayTheme", "saveNightTheme" -> alertSaveTheme(key)
PreferKey.bgImage -> if (getPrefString(PreferKey.bgImage).isNullOrEmpty()) { PreferKey.bgImage -> selectBgAction(false)
selectImage.launch(requestCodeBgLight) PreferKey.bgImageN -> selectBgAction(true)
} else {
selector(items = arrayListOf("删除图片", "选择图片")) { _, i ->
if (i == 0) {
removePref(PreferKey.bgImage)
upTheme(false)
} else {
selectImage.launch(requestCodeBgLight)
}
}
}
PreferKey.bgImageN -> if (getPrefString(PreferKey.bgImageN).isNullOrEmpty()) {
selectImage.launch(requestCodeBgDark)
} else {
selector(items = arrayListOf("删除图片", "选择图片")) { _, i ->
if (i == 0) {
removePref(PreferKey.bgImageN)
upTheme(true)
} else {
selectImage.launch(requestCodeBgDark)
}
}
}
PreferKey.defaultCover -> if (getPrefString(PreferKey.defaultCover).isNullOrEmpty()) { PreferKey.defaultCover -> if (getPrefString(PreferKey.defaultCover).isNullOrEmpty()) {
selectImage.launch(requestCodeCover) selectImage.launch(requestCodeCover)
} else { } else {
@ -211,9 +195,11 @@ class ThemeConfigFragment : BasePreferenceFragment(),
} }
@SuppressLint("InflateParams") @SuppressLint("InflateParams")
private fun saveThemeAlert(key: String) { private fun alertSaveTheme(key: String) {
alert(R.string.theme_name) { alert(R.string.theme_name) {
val alertBinding = DialogEditTextBinding.inflate(layoutInflater) val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply {
textInputLayout.hint = "name"
}
customView { alertBinding.root } customView { alertBinding.root }
okButton { okButton {
alertBinding.editView.text?.toString()?.let { themeName -> alertBinding.editView.text?.toString()?.let { themeName ->
@ -231,6 +217,64 @@ class ThemeConfigFragment : BasePreferenceFragment(),
}.show() }.show()
} }
private fun selectBgAction(isNight: Boolean) {
val bgKey = if (isNight) PreferKey.bgImageN else PreferKey.bgImage
val blurringKey = if (isNight) PreferKey.bgImageNBlurring else PreferKey.bgImageBlurring
val actions = arrayListOf(
getString(R.string.background_image_blurring),
getString(R.string.select_image)
)
if (!getPrefString(bgKey).isNullOrEmpty()) {
actions.add(getString(R.string.delete))
}
selector(items = actions) { _, i ->
when (i) {
0 -> alertImageBlurring(blurringKey) {
upTheme(isNight)
}
1 -> {
if (isNight) {
selectImage.launch(requestCodeBgDark)
} else {
selectImage.launch(requestCodeBgLight)
}
}
2 -> {
removePref(bgKey)
upTheme(isNight)
}
}
}
}
private fun alertImageBlurring(preferKey: String, success: () -> Unit) {
alert(R.string.background_image_blurring) {
val alertBinding = DialogImageBlurringBinding.inflate(layoutInflater).apply {
getPrefInt(preferKey, 0).let {
seekBar.progress = it
textViewValue.text = it.toString()
}
seekBar.setOnSeekBarChangeListener(object : SeekBarChangeListener {
override fun onProgressChanged(
seekBar: SeekBar,
progress: Int,
fromUser: Boolean
) {
textViewValue.text = progress.toString()
}
})
}
customView { alertBinding.root }
okButton {
alertBinding.seekBar.progress.let {
putPrefInt(preferKey, it)
success.invoke()
}
}
noButton()
}.show()
}
private fun upTheme(isNightTheme: Boolean) { private fun upTheme(isNightTheme: Boolean) {
if (AppConfig.isNightTheme == isNightTheme) { if (AppConfig.isNightTheme == isNightTheme) {
listView.post { listView.post {
@ -272,7 +316,6 @@ class ThemeConfigFragment : BasePreferenceFragment(),
}.getOrNull()?.let { byteArray -> }.getOrNull()?.let { byteArray ->
file.writeBytes(byteArray) file.writeBytes(byteArray)
putPrefString(preferenceKey, file.absolutePath) putPrefString(preferenceKey, file.absolutePath)
upPreferenceSummary(preferenceKey, file.absolutePath)
success() success()
} ?: toastOnUi("获取文件出错") } ?: toastOnUi("获取文件出错")
} }
@ -291,7 +334,6 @@ class ThemeConfigFragment : BasePreferenceFragment(),
file = FileUtils.createFileIfNotExist(file, preferenceKey, imgFile.name) file = FileUtils.createFileIfNotExist(file, preferenceKey, imgFile.name)
file.writeBytes(imgFile.readBytes()) file.writeBytes(imgFile.readBytes())
putPrefString(preferenceKey, file.absolutePath) putPrefString(preferenceKey, file.absolutePath)
upPreferenceSummary(preferenceKey, file.absolutePath)
success() success()
} }
} }

@ -26,7 +26,7 @@ class ThemeListDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener {
override fun onStart() { override fun onStart() {
super.onStart() super.onStart()
val dm = requireActivity().getSize() val dm = requireActivity().windowSize
dialog?.window?.setLayout((dm.widthPixels * 0.9).toInt(), (dm.heightPixels * 0.9).toInt()) dialog?.window?.setLayout((dm.widthPixels * 0.9).toInt(), (dm.heightPixels * 0.9).toInt())
} }

@ -76,7 +76,7 @@ class FilePickerDialog : DialogFragment(),
override fun onStart() { override fun onStart() {
super.onStart() super.onStart()
val dm = requireActivity().getSize() val dm = requireActivity().windowSize
dialog?.window?.setLayout((dm.widthPixels * 0.9).toInt(), (dm.heightPixels * 0.8).toInt()) dialog?.window?.setLayout((dm.widthPixels * 0.9).toInt(), (dm.heightPixels * 0.8).toInt())
} }

@ -12,7 +12,6 @@ import io.legado.app.help.DefaultData
import io.legado.app.help.LocalConfig import io.legado.app.help.LocalConfig
import io.legado.app.model.webBook.WebBook import io.legado.app.model.webBook.WebBook
import io.legado.app.service.help.CacheBook import io.legado.app.service.help.CacheBook
import io.legado.app.utils.FileUtils
import io.legado.app.utils.postEvent import io.legado.app.utils.postEvent
import kotlinx.coroutines.asCoroutineDispatcher import kotlinx.coroutines.asCoroutineDispatcher
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
@ -143,7 +142,6 @@ class MainViewModel(application: Application) : BaseViewModel(application) {
fun postLoad() { fun postLoad() {
execute { execute {
FileUtils.deleteFile(FileUtils.getPath(context.cacheDir, "Fonts"))
if (appDb.httpTTSDao.count == 0) { if (appDb.httpTTSDao.count == 0) {
DefaultData.httpTTS.let { DefaultData.httpTTS.let {
appDb.httpTTSDao.insert(*it.toTypedArray()) appDb.httpTTSDao.insert(*it.toTypedArray())

@ -65,7 +65,9 @@ abstract class BaseBookshelfFragment(layoutId: Int) : VMBaseFragment<BookshelfVi
@SuppressLint("InflateParams") @SuppressLint("InflateParams")
fun addBookByUrl() { fun addBookByUrl() {
alert(titleResource = R.string.add_book_url) { alert(titleResource = R.string.add_book_url) {
val alertBinding = DialogEditTextBinding.inflate(layoutInflater) val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply {
textInputLayout.hint = "url"
}
customView { alertBinding.root } customView { alertBinding.root }
okButton { okButton {
alertBinding.editView.text?.toString()?.let { alertBinding.editView.text?.toString()?.let {
@ -122,7 +124,7 @@ abstract class BaseBookshelfFragment(layoutId: Int) : VMBaseFragment<BookshelfVi
private fun importBookshelfAlert(groupId: Long) { private fun importBookshelfAlert(groupId: Long) {
alert(titleResource = R.string.import_bookshelf) { alert(titleResource = R.string.import_bookshelf) {
val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply { val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply {
editView.hint = "url/json" textInputLayout.hint = "url/json"
} }
customView { alertBinding.root } customView { alertBinding.root }
okButton { okButton {

@ -20,7 +20,7 @@ class QrCodeActivity : BaseActivity<ActivityQrcodeCaptureBinding>(), OnScanResul
override val binding by viewBinding(ActivityQrcodeCaptureBinding::inflate) override val binding by viewBinding(ActivityQrcodeCaptureBinding::inflate)
private val selectQrImage = registerForActivityResult(ActivityResultContracts.GetContent()) { private val selectQrImage = registerForActivityResult(ActivityResultContracts.GetContent()) {
it.readBytes(this)?.let { bytes -> it?.readBytes(this)?.let { bytes ->
val bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.size) val bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.size)
onScanResultCallback(QRCodeUtils.parseCodeResult(bitmap)) onScanResultCallback(QRCodeUtils.parseCodeResult(bitmap))
} }

@ -36,7 +36,7 @@ class GroupManageDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener
override fun onStart() { override fun onStart() {
super.onStart() super.onStart()
val dm = requireActivity().getSize() val dm = requireActivity().windowSize
dialog?.window?.setLayout((dm.widthPixels * 0.9).toInt(), (dm.heightPixels * 0.9).toInt()) dialog?.window?.setLayout((dm.widthPixels * 0.9).toInt(), (dm.heightPixels * 0.9).toInt())
} }
@ -88,12 +88,10 @@ class GroupManageDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener
@SuppressLint("InflateParams") @SuppressLint("InflateParams")
private fun addGroup() { private fun addGroup() {
alert(title = getString(R.string.add_group)) { alert(title = getString(R.string.add_group)) {
val alertBinding = DialogEditTextBinding.inflate(layoutInflater) val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply {
customView { textInputLayout.setHint(R.string.group_name)
alertBinding.apply {
editView.hint = "分组名称"
}.root
} }
customView { alertBinding.root }
yesButton { yesButton {
alertBinding.editView.text?.toString()?.let { alertBinding.editView.text?.toString()?.let {
if (it.isNotBlank()) { if (it.isNotBlank()) {
@ -109,7 +107,7 @@ class GroupManageDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener
private fun editGroup(group: String) { private fun editGroup(group: String) {
alert(title = getString(R.string.group_edit)) { alert(title = getString(R.string.group_edit)) {
val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply { val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply {
editView.hint = "分组名称" textInputLayout.setHint(R.string.group_name)
editView.setText(group) editView.setText(group)
} }
customView { alertBinding.root } customView { alertBinding.root }

@ -255,6 +255,7 @@ class ReplaceRuleActivity : VMBaseActivity<ActivityReplaceRuleBinding, ReplaceRu
?.toMutableList() ?: mutableListOf() ?.toMutableList() ?: mutableListOf()
alert(titleResource = R.string.import_replace_rule_on_line) { alert(titleResource = R.string.import_replace_rule_on_line) {
val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply { val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply {
textInputLayout.hint = "url"
editView.setFilterValues(cacheUrls) editView.setFilterValues(cacheUrls)
editView.delCallBack = { editView.delCallBack = {
cacheUrls.remove(it) cacheUrls.remove(it)

@ -19,9 +19,9 @@ import io.legado.app.databinding.ActivityReplaceEditBinding
import io.legado.app.lib.dialogs.selector import io.legado.app.lib.dialogs.selector
import io.legado.app.ui.widget.KeyboardToolPop import io.legado.app.ui.widget.KeyboardToolPop
import io.legado.app.ui.widget.dialog.TextDialog import io.legado.app.ui.widget.dialog.TextDialog
import io.legado.app.utils.getSize
import io.legado.app.utils.toastOnUi import io.legado.app.utils.toastOnUi
import io.legado.app.utils.viewbindingdelegate.viewBinding import io.legado.app.utils.viewbindingdelegate.viewBinding
import io.legado.app.utils.windowSize
import kotlin.math.abs import kotlin.math.abs
/** /**
@ -166,7 +166,7 @@ class ReplaceEditActivity :
val rect = Rect() val rect = Rect()
// 获取当前页面窗口的显示范围 // 获取当前页面窗口的显示范围
window.decorView.getWindowVisibleDisplayFrame(rect) window.decorView.getWindowVisibleDisplayFrame(rect)
val screenHeight = this.getSize().heightPixels val screenHeight = this.windowSize.heightPixels
val keyboardHeight = screenHeight - rect.bottom // 输入法的高度 val keyboardHeight = screenHeight - rect.bottom // 输入法的高度
val preShowing = mIsSoftKeyBoardShowing val preShowing = mIsSoftKeyBoardShowing
if (abs(keyboardHeight) > screenHeight / 5) { if (abs(keyboardHeight) > screenHeight / 5) {

@ -43,6 +43,7 @@ class ReadRssActivity : VMBaseActivity<ActivityRssReadBinding, ReadRssViewModel>
private var customWebViewCallback: WebChromeClient.CustomViewCallback? = null private var customWebViewCallback: WebChromeClient.CustomViewCallback? = null
private var webPic: String? = null private var webPic: String? = null
private val saveImage = registerForActivityResult(FilePicker()) { private val saveImage = registerForActivityResult(FilePicker()) {
it ?: return@registerForActivityResult
ACache.get(this).put(imagePathKey, it.toString()) ACache.get(this).put(imagePathKey, it.toString())
viewModel.saveImage(webPic, it.toString()) viewModel.saveImage(webPic, it.toString())
} }

@ -256,7 +256,7 @@ class RssSourceEditActivity :
val rect = Rect() val rect = Rect()
// 获取当前页面窗口的显示范围 // 获取当前页面窗口的显示范围
window.decorView.getWindowVisibleDisplayFrame(rect) window.decorView.getWindowVisibleDisplayFrame(rect)
val screenHeight = this@RssSourceEditActivity.getSize().heightPixels val screenHeight = this@RssSourceEditActivity.windowSize.heightPixels
val keyboardHeight = screenHeight - rect.bottom // 输入法的高度 val keyboardHeight = screenHeight - rect.bottom // 输入法的高度
val preShowing = mIsSoftKeyBoardShowing val preShowing = mIsSoftKeyBoardShowing
if (abs(keyboardHeight) > screenHeight / 5) { if (abs(keyboardHeight) > screenHeight / 5) {

@ -37,7 +37,7 @@ class GroupManageDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener
override fun onStart() { override fun onStart() {
super.onStart() super.onStart()
val dm = requireActivity().getSize() val dm = requireActivity().windowSize
dialog?.window?.setLayout((dm.widthPixels * 0.9).toInt(), (dm.heightPixels * 0.9).toInt()) dialog?.window?.setLayout((dm.widthPixels * 0.9).toInt(), (dm.heightPixels * 0.9).toInt())
} }
@ -89,12 +89,10 @@ class GroupManageDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener
@SuppressLint("InflateParams") @SuppressLint("InflateParams")
private fun addGroup() { private fun addGroup() {
alert(title = getString(R.string.add_group)) { alert(title = getString(R.string.add_group)) {
val alertBinding = DialogEditTextBinding.inflate(layoutInflater) val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply {
customView { textInputLayout.setHint(R.string.group_name)
alertBinding.apply {
editView.setHint(R.string.group_name)
}.root
} }
customView { alertBinding.root }
yesButton { yesButton {
alertBinding.editView.text?.toString()?.let { alertBinding.editView.text?.toString()?.let {
if (it.isNotBlank()) { if (it.isNotBlank()) {
@ -109,13 +107,11 @@ class GroupManageDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener
@SuppressLint("InflateParams") @SuppressLint("InflateParams")
private fun editGroup(group: String) { private fun editGroup(group: String) {
alert(title = getString(R.string.group_edit)) { alert(title = getString(R.string.group_edit)) {
val alertBinding = DialogEditTextBinding.inflate(layoutInflater) val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply {
customView { textInputLayout.setHint(R.string.group_name)
alertBinding.apply { editView.setText(group)
editView.setHint(R.string.group_name)
editView.setText(group)
}.root
} }
customView { alertBinding.root }
yesButton { yesButton {
viewModel.upGroup(group, alertBinding.editView.text?.toString()) viewModel.upGroup(group, alertBinding.editView.text?.toString())
} }

@ -263,6 +263,7 @@ class RssSourceActivity : VMBaseActivity<ActivityRssSourceBinding, RssSourceView
?.toMutableList() ?: mutableListOf() ?.toMutableList() ?: mutableListOf()
alert(titleResource = R.string.import_on_line) { alert(titleResource = R.string.import_on_line) {
val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply { val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply {
textInputLayout.hint = "url"
editView.setFilterValues(cacheUrls) editView.setFilterValues(cacheUrls)
editView.delCallBack = { editView.delCallBack = {
cacheUrls.remove(it) cacheUrls.remove(it)

@ -8,8 +8,8 @@ import androidx.fragment.app.FragmentManager
import io.legado.app.R import io.legado.app.R
import io.legado.app.base.BaseDialogFragment import io.legado.app.base.BaseDialogFragment
import io.legado.app.databinding.DialogTextViewBinding import io.legado.app.databinding.DialogTextViewBinding
import io.legado.app.utils.getSize
import io.legado.app.utils.viewbindingdelegate.viewBinding import io.legado.app.utils.viewbindingdelegate.viewBinding
import io.legado.app.utils.windowSize
import io.noties.markwon.Markwon import io.noties.markwon.Markwon
import io.noties.markwon.ext.tables.TablePlugin import io.noties.markwon.ext.tables.TablePlugin
import io.noties.markwon.html.HtmlPlugin import io.noties.markwon.html.HtmlPlugin
@ -49,7 +49,7 @@ class TextDialog : BaseDialogFragment() {
override fun onStart() { override fun onStart() {
super.onStart() super.onStart()
val dm = requireActivity().getSize() val dm = requireActivity().windowSize
dialog?.window?.setLayout((dm.widthPixels * 0.9).toInt(), (dm.heightPixels * 0.9).toInt()) dialog?.window?.setLayout((dm.widthPixels * 0.9).toInt(), (dm.heightPixels * 0.9).toInt())
} }

@ -13,8 +13,8 @@ import io.legado.app.base.adapter.ItemViewHolder
import io.legado.app.base.adapter.RecyclerAdapter import io.legado.app.base.adapter.RecyclerAdapter
import io.legado.app.databinding.DialogRecyclerViewBinding import io.legado.app.databinding.DialogRecyclerViewBinding
import io.legado.app.databinding.ItemLogBinding import io.legado.app.databinding.ItemLogBinding
import io.legado.app.utils.getSize
import io.legado.app.utils.viewbindingdelegate.viewBinding import io.legado.app.utils.viewbindingdelegate.viewBinding
import io.legado.app.utils.windowSize
class TextListDialog : BaseDialogFragment() { class TextListDialog : BaseDialogFragment() {
@ -35,7 +35,7 @@ class TextListDialog : BaseDialogFragment() {
override fun onStart() { override fun onStart() {
super.onStart() super.onStart()
val dm = requireActivity().getSize() val dm = requireActivity().windowSize
dialog?.window?.setLayout((dm.widthPixels * 0.9).toInt(), (dm.heightPixels * 0.9).toInt()) dialog?.window?.setLayout((dm.widthPixels * 0.9).toInt(), (dm.heightPixels * 0.9).toInt())
} }

@ -65,7 +65,7 @@ class FontSelectDialog : BaseDialogFragment(),
override fun onStart() { override fun onStart() {
super.onStart() super.onStart()
val dm = requireActivity().getSize() val dm = requireActivity().windowSize
dialog?.window?.setLayout((dm.widthPixels * 0.9).toInt(), (dm.heightPixels * 0.9).toInt()) dialog?.window?.setLayout((dm.widthPixels * 0.9).toInt(), (dm.heightPixels * 0.9).toInt())
} }

@ -21,8 +21,8 @@ import io.legado.app.databinding.DialogRecyclerViewBinding
import io.legado.app.databinding.ItemIconPreferenceBinding import io.legado.app.databinding.ItemIconPreferenceBinding
import io.legado.app.lib.theme.primaryColor import io.legado.app.lib.theme.primaryColor
import io.legado.app.utils.getCompatDrawable import io.legado.app.utils.getCompatDrawable
import io.legado.app.utils.getSize
import io.legado.app.utils.viewbindingdelegate.viewBinding import io.legado.app.utils.viewbindingdelegate.viewBinding
import io.legado.app.utils.windowSize
class IconListPreference(context: Context, attrs: AttributeSet) : ListPreference(context, attrs) { class IconListPreference(context: Context, attrs: AttributeSet) : ListPreference(context, attrs) {
@ -131,7 +131,7 @@ class IconListPreference(context: Context, attrs: AttributeSet) : ListPreference
override fun onStart() { override fun onStart() {
super.onStart() super.onStart()
val dm = requireActivity().getSize() val dm = requireActivity().windowSize
dialog?.window?.setLayout( dialog?.window?.setLayout(
(dm.widthPixels * 0.8).toInt(), (dm.widthPixels * 0.8).toInt(),
ViewGroup.LayoutParams.WRAP_CONTENT ViewGroup.LayoutParams.WRAP_CONTENT

@ -6,20 +6,21 @@ import android.util.DisplayMetrics
import android.view.WindowInsets import android.view.WindowInsets
import android.view.WindowMetrics import android.view.WindowMetrics
fun Activity.getSize(): DisplayMetrics { val Activity.windowSize: DisplayMetrics
val displayMetrics = DisplayMetrics() get() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { val displayMetrics = DisplayMetrics()
val windowMetrics: WindowMetrics = windowManager.currentWindowMetrics if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
val insets = windowMetrics.windowInsets val windowMetrics: WindowMetrics = windowManager.currentWindowMetrics
.getInsetsIgnoringVisibility(WindowInsets.Type.systemBars()) val insets = windowMetrics.windowInsets
displayMetrics.widthPixels = windowMetrics.bounds.width() - insets.left - insets.right .getInsetsIgnoringVisibility(WindowInsets.Type.systemBars())
displayMetrics.heightPixels = windowMetrics.bounds.height() - insets.top - insets.bottom displayMetrics.widthPixels = windowMetrics.bounds.width() - insets.left - insets.right
} else { displayMetrics.heightPixels = windowMetrics.bounds.height() - insets.top - insets.bottom
@Suppress("DEPRECATION") } else {
windowManager.defaultDisplay.getMetrics(displayMetrics) @Suppress("DEPRECATION")
windowManager.defaultDisplay.getMetrics(displayMetrics)
}
return displayMetrics
} }
return displayMetrics
}
/** /**
* 该方法需要在View完全被绘制出来之后调用否则判断不了 * 该方法需要在View完全被绘制出来之后调用否则判断不了

@ -249,7 +249,7 @@ object BitmapUtils {
/** /**
* 高斯模糊 * 高斯模糊
*/ */
fun stackBlur(srcBitmap: Bitmap?): Bitmap? { fun stackBlur(srcBitmap: Bitmap?, radius: Float = 8f): Bitmap? {
if (srcBitmap == null) return null if (srcBitmap == null) return null
val rs = RenderScript.create(appCtx) val rs = RenderScript.create(appCtx)
val blurredBitmap = srcBitmap.copy(Config.ARGB_8888, true) val blurredBitmap = srcBitmap.copy(Config.ARGB_8888, true)
@ -268,7 +268,7 @@ object BitmapUtils {
script.setInput(input) script.setInput(input)
//设置模糊半径 //设置模糊半径
script.setRadius(8f) script.setRadius(radius)
//启动 ScriptIntrinsicBlur //启动 ScriptIntrinsicBlur
script.forEach(output) script.forEach(output)

@ -362,6 +362,7 @@
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
android:clickable="true" android:clickable="true"
android:focusable="true" android:focusable="true"
android:minHeight="48dp"
android:paddingLeft="8dp" android:paddingLeft="8dp"
android:paddingBottom="8dp" android:paddingBottom="8dp"
android:text="@string/book_intro" android:text="@string/book_intro"

@ -333,16 +333,17 @@
<io.legado.app.ui.widget.text.ScrollTextView <io.legado.app.ui.widget.text.ScrollTextView
android:id="@+id/tv_intro" android:id="@+id/tv_intro"
android:layout_marginTop="8dp"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:clickable="true" android:clickable="true"
android:focusable="true" android:focusable="true"
android:minHeight="48dp"
android:paddingLeft="8dp"
android:paddingBottom="8dp"
android:text="@string/book_intro" android:text="@string/book_intro"
android:textColor="@color/secondaryText" android:textColor="@color/secondaryText"
android:textSize="14sp" android:textSize="14sp"
android:paddingLeft="8dp"
android:paddingBottom="8dp"
android:visibility="visible" android:visibility="visible"
tools:ignore="RtlHardcoded,RtlSymmetry" /> tools:ignore="RtlHardcoded,RtlSymmetry" />

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:orientation="vertical"> android:orientation="vertical">
@ -15,6 +16,7 @@
<androidx.viewpager.widget.ViewPager <androidx.viewpager.widget.ViewPager
android:id="@+id/view_pager" android:id="@+id/view_pager"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" /> android:layout_height="match_parent"
tools:ignore="SpeakableTextPresentCheck" />
</LinearLayout> </LinearLayout>

@ -69,7 +69,8 @@
<io.legado.app.ui.widget.recycler.scroller.FastScrollRecyclerView <io.legado.app.ui.widget.recycler.scroller.FastScrollRecyclerView
android:id="@+id/recycler_view" android:id="@+id/recycler_view"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" /> android:layout_height="match_parent"
tools:ignore="SpeakableTextPresentCheck" />
<TextView <TextView
android:id="@+id/tv_empty_msg" android:id="@+id/tv_empty_msg"

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:orientation="vertical"> android:orientation="vertical">
@ -9,7 +10,8 @@
android:id="@+id/view_pager_main" android:id="@+id/view_pager_main"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="0dp" android:layout_height="0dp"
android:layout_weight="1" /> android:layout_weight="1"
tools:ignore="SpeakableTextPresentCheck" />
<com.google.android.material.bottomnavigation.BottomNavigationView <com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/bottom_navigation_view" android:id="@+id/bottom_navigation_view"

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/root_view" android:id="@+id/root_view"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
@ -35,7 +36,8 @@
<io.legado.app.ui.widget.text.EditText <io.legado.app.ui.widget.text.EditText
android:id="@+id/et_name" android:id="@+id/et_name"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" /> android:layout_height="wrap_content"
tools:ignore="SpeakableTextPresentCheck,TouchTargetSizeCheck" />
</io.legado.app.ui.widget.text.TextInputLayout> </io.legado.app.ui.widget.text.TextInputLayout>
<io.legado.app.ui.widget.text.TextInputLayout <io.legado.app.ui.widget.text.TextInputLayout
@ -47,7 +49,8 @@
<io.legado.app.ui.widget.text.EditText <io.legado.app.ui.widget.text.EditText
android:id="@+id/et_group" android:id="@+id/et_group"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" /> android:layout_height="wrap_content"
tools:ignore="SpeakableTextPresentCheck,TouchTargetSizeCheck" />
</io.legado.app.ui.widget.text.TextInputLayout> </io.legado.app.ui.widget.text.TextInputLayout>
<io.legado.app.ui.widget.text.TextInputLayout <io.legado.app.ui.widget.text.TextInputLayout
@ -59,7 +62,8 @@
<io.legado.app.ui.widget.text.EditText <io.legado.app.ui.widget.text.EditText
android:id="@+id/et_replace_rule" android:id="@+id/et_replace_rule"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" /> android:layout_height="wrap_content"
tools:ignore="SpeakableTextPresentCheck,TouchTargetSizeCheck" />
</io.legado.app.ui.widget.text.TextInputLayout> </io.legado.app.ui.widget.text.TextInputLayout>
<LinearLayout <LinearLayout
@ -73,14 +77,15 @@
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="1" android:layout_weight="1"
android:text="@string/use_regex" /> android:text="@string/use_regex"
tools:ignore="TouchTargetSizeCheck" />
<ImageView <ImageView
android:id="@+id/iv_help" android:id="@+id/iv_help"
android:layout_width="24dp" android:layout_width="24dp"
android:layout_height="24dp" android:layout_height="24dp"
android:src="@drawable/ic_help" android:src="@drawable/ic_help"
app:tint="@color/secondaryText" app:tint="@color/primaryText"
android:contentDescription="@string/help" /> android:contentDescription="@string/help" />
</LinearLayout> </LinearLayout>
@ -94,7 +99,8 @@
<io.legado.app.ui.widget.text.EditText <io.legado.app.ui.widget.text.EditText
android:id="@+id/et_replace_to" android:id="@+id/et_replace_to"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" /> android:layout_height="wrap_content"
tools:ignore="SpeakableTextPresentCheck,TouchTargetSizeCheck" />
</io.legado.app.ui.widget.text.TextInputLayout> </io.legado.app.ui.widget.text.TextInputLayout>
<io.legado.app.ui.widget.text.TextInputLayout <io.legado.app.ui.widget.text.TextInputLayout
@ -106,7 +112,8 @@
<io.legado.app.ui.widget.text.EditText <io.legado.app.ui.widget.text.EditText
android:id="@+id/et_scope" android:id="@+id/et_scope"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" /> android:layout_height="wrap_content"
tools:ignore="SpeakableTextPresentCheck,TouchTargetSizeCheck" />
</io.legado.app.ui.widget.text.TextInputLayout> </io.legado.app.ui.widget.text.TextInputLayout>
</LinearLayout> </LinearLayout>

@ -23,7 +23,8 @@
<io.legado.app.ui.widget.recycler.scroller.FastScrollRecyclerView <io.legado.app.ui.widget.recycler.scroller.FastScrollRecyclerView
android:id="@+id/recycler_view" android:id="@+id/recycler_view"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" /> android:layout_height="match_parent"
tools:ignore="SpeakableTextPresentCheck" />
</FrameLayout> </FrameLayout>

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
@ -19,6 +20,7 @@
<androidx.viewpager.widget.ViewPager <androidx.viewpager.widget.ViewPager
android:id="@+id/view_pager" android:id="@+id/view_pager"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" /> android:layout_height="wrap_content"
tools:ignore="SpeakableTextPresentCheck" />
</LinearLayout> </LinearLayout>

@ -34,14 +34,16 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:checked="true" android:checked="true"
android:text="@string/is_enable" /> android:text="@string/is_enable"
tools:ignore="TouchTargetSizeCheck" />
<io.legado.app.lib.theme.view.ATECheckBox <io.legado.app.lib.theme.view.ATECheckBox
android:id="@+id/cb_single_url" android:id="@+id/cb_single_url"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:checked="false" android:checked="false"
android:text="@string/single_url" /> android:text="@string/single_url"
tools:ignore="TouchTargetSizeCheck" />
</LinearLayout> </LinearLayout>
@ -64,14 +66,16 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:checked="false" android:checked="false"
android:text="@string/enable_js" /> android:text="@string/enable_js"
tools:ignore="TouchTargetSizeCheck" />
<io.legado.app.lib.theme.view.ATECheckBox <io.legado.app.lib.theme.view.ATECheckBox
android:id="@+id/cb_enable_base_url" android:id="@+id/cb_enable_base_url"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:checked="false" android:checked="false"
android:text="@string/load_with_base_url" /> android:text="@string/load_with_base_url"
tools:ignore="TouchTargetSizeCheck" />
</LinearLayout> </LinearLayout>

@ -25,7 +25,8 @@
android:layout_height="0dp" android:layout_height="0dp"
android:overScrollMode="never" android:overScrollMode="never"
app:layout_constraintBottom_toTopOf="@+id/ll_search_base_info" app:layout_constraintBottom_toTopOf="@+id/ll_search_base_info"
app:layout_constraintTop_toBottomOf="@id/refresh_progress_bar" /> app:layout_constraintTop_toBottomOf="@id/refresh_progress_bar"
tools:ignore="SpeakableTextPresentCheck" />
<LinearLayout <LinearLayout
android:id="@+id/ll_search_base_info" android:id="@+id/ll_search_base_info"

@ -43,7 +43,8 @@
android:id="@+id/edit_book_text" android:id="@+id/edit_book_text"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:hint="@string/content" /> android:hint="@string/content"
tools:ignore="SpeakableTextPresentCheck,TouchTargetSizeCheck" />
</io.legado.app.ui.widget.text.TextInputLayout> </io.legado.app.ui.widget.text.TextInputLayout>
@ -56,7 +57,8 @@
android:id="@+id/edit_content" android:id="@+id/edit_content"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:hint="@string/note_content" /> android:hint="@string/note_content"
tools:ignore="SpeakableTextPresentCheck,TouchTargetSizeCheck" />
</io.legado.app.ui.widget.text.TextInputLayout> </io.legado.app.ui.widget.text.TextInputLayout>

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:padding="16dp" android:padding="16dp"
@ -31,7 +32,8 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:entries="@array/group_style" android:entries="@array/group_style"
app:theme="@style/Spinner" /> app:theme="@style/Spinner"
tools:ignore="TouchTargetSizeCheck" />
</LinearLayout> </LinearLayout>
@ -51,27 +53,32 @@
<RadioButton <RadioButton
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/layout_list" /> android:text="@string/layout_list"
tools:ignore="TouchTargetSizeCheck" />
<RadioButton <RadioButton
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/layout_grid3" /> android:text="@string/layout_grid3"
tools:ignore="TouchTargetSizeCheck" />
<RadioButton <RadioButton
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/layout_grid4" /> android:text="@string/layout_grid4"
tools:ignore="TouchTargetSizeCheck" />
<RadioButton <RadioButton
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/layout_grid5" /> android:text="@string/layout_grid5"
tools:ignore="TouchTargetSizeCheck" />
<RadioButton <RadioButton
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/layout_grid6" /> android:text="@string/layout_grid6"
tools:ignore="TouchTargetSizeCheck" />
</RadioGroup> </RadioGroup>
</LinearLayout> </LinearLayout>
@ -84,8 +91,9 @@
android:padding="6dp" android:padding="6dp"
android:text="@string/show_unread" android:text="@string/show_unread"
app:layout_constraintLeft_toRightOf="@+id/ll_layout" app:layout_constraintLeft_toRightOf="@+id/ll_layout"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
app:layout_constraintRight_toRightOf="parent" /> tools:ignore="TouchTargetSizeCheck" />
<LinearLayout <LinearLayout
android:id="@+id/ll_sort" android:id="@+id/ll_sort"
@ -112,22 +120,26 @@
<RadioButton <RadioButton
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/bookshelf_px_0" /> android:text="@string/bookshelf_px_0"
tools:ignore="TouchTargetSizeCheck" />
<RadioButton <RadioButton
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/bookshelf_px_1" /> android:text="@string/bookshelf_px_1"
tools:ignore="TouchTargetSizeCheck" />
<RadioButton <RadioButton
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/bookshelf_px_2" /> android:text="@string/bookshelf_px_2"
tools:ignore="TouchTargetSizeCheck" />
<RadioButton <RadioButton
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/bookshelf_px_3" /> android:text="@string/bookshelf_px_3"
tools:ignore="TouchTargetSizeCheck" />
</RadioGroup> </RadioGroup>

@ -4,10 +4,10 @@
android:id="@+id/ll_content" android:id="@+id/ll_content"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:padding="16dp"
android:background="@color/background" android:background="@color/background"
android:gravity="center" android:gravity="center"
android:orientation="horizontal"> android:orientation="horizontal"
android:padding="16dp">
<View <View
android:layout_width="0dp" android:layout_width="0dp"
@ -30,6 +30,8 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center_vertical" android:layout_gravity="center_vertical"
android:background="@drawable/bg_edit" android:background="@drawable/bg_edit"
android:hint="@string/start"
android:importantForAutofill="no"
android:inputType="number" android:inputType="number"
android:lines="1" android:lines="1"
android:maxLength="5" android:maxLength="5"
@ -40,7 +42,8 @@
android:paddingBottom="4dp" android:paddingBottom="4dp"
android:textColor="@color/primaryText" android:textColor="@color/primaryText"
android:textCursorDrawable="@drawable/shape_text_cursor" android:textCursorDrawable="@drawable/shape_text_cursor"
android:textSize="14sp" /> android:textSize="14sp"
tools:ignore="TouchTargetSizeCheck" />
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
@ -58,6 +61,8 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center_vertical" android:layout_gravity="center_vertical"
android:background="@drawable/bg_edit" android:background="@drawable/bg_edit"
android:hint="@string/end"
android:importantForAutofill="no"
android:inputType="number" android:inputType="number"
android:lines="1" android:lines="1"
android:maxLength="5" android:maxLength="5"
@ -68,7 +73,8 @@
android:paddingBottom="4dp" android:paddingBottom="4dp"
android:textColor="@color/primaryText" android:textColor="@color/primaryText"
android:textCursorDrawable="@drawable/shape_text_cursor" android:textCursorDrawable="@drawable/shape_text_cursor"
android:textSize="14sp" /> android:textSize="14sp"
tools:ignore="TouchTargetSizeCheck,SpeakableTextPresentCheck" />
<View <View
android:layout_width="0dp" android:layout_width="0dp"

@ -1,18 +1,24 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<ScrollView <androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="20dp"
android:paddingRight="20dp"
android:paddingTop="12dp"
android:overScrollMode="ifContentScrolls">
<io.legado.app.ui.widget.text.TextInputLayout
android:id="@+id/text_input_layout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="wrap_content">
android:layout_marginTop="48dp"
android:layout_marginBottom="48dp"
android:overScrollMode="ifContentScrolls">
<io.legado.app.ui.widget.text.AutoCompleteTextView <io.legado.app.ui.widget.text.AutoCompleteTextView
android:id="@+id/edit_view" android:id="@+id/edit_view"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginStart="20dp"
android:layout_marginEnd="20dp"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"/> android:layout_height="wrap_content"
</ScrollView> tools:ignore="SpeakableTextPresentCheck,TouchTargetSizeCheck" />
</io.legado.app.ui.widget.text.TextInputLayout>
</androidx.core.widget.NestedScrollView>

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="10dp">
<TextView
android:id="@+id/text_view_value"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="6dp"
android:layout_gravity="center_horizontal"
android:textColor="@color/primaryText"
android:textSize="17sp" />
<androidx.appcompat.widget.AppCompatSeekBar
android:id="@+id/seek_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="6dp"
android:max="25" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="6dp"
android:text="@string/background_image_hint" />
</LinearLayout>

@ -23,7 +23,8 @@
android:id="@+id/recycler_view" android:id="@+id/recycler_view"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:scrollbars="none" /> android:scrollbars="none"
tools:ignore="SpeakableTextPresentCheck" />
<io.legado.app.ui.widget.anima.RotateLoading <io.legado.app.ui.widget.anima.RotateLoading
android:id="@+id/rotate_loading" android:id="@+id/rotate_loading"
@ -61,6 +62,10 @@
android:visibility="gone" android:visibility="gone"
tools:ignore="RtlHardcoded" /> tools:ignore="RtlHardcoded" />
<Space
android:layout_width="0dp"
android:layout_height="0dp" />
<LinearLayout <LinearLayout
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical" android:orientation="vertical"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
@ -15,7 +16,8 @@
<io.legado.app.ui.widget.text.EditText <io.legado.app.ui.widget.text.EditText
android:id="@+id/tv_rule_name" android:id="@+id/tv_rule_name"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" /> android:layout_height="wrap_content"
tools:ignore="SpeakableTextPresentCheck,TouchTargetSizeCheck" />
</io.legado.app.ui.widget.text.TextInputLayout> </io.legado.app.ui.widget.text.TextInputLayout>
@ -27,7 +29,8 @@
<io.legado.app.ui.widget.text.EditText <io.legado.app.ui.widget.text.EditText
android:id="@+id/tv_rule_regex" android:id="@+id/tv_rule_regex"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" /> android:layout_height="wrap_content"
tools:ignore="SpeakableTextPresentCheck,TouchTargetSizeCheck" />
</io.legado.app.ui.widget.text.TextInputLayout> </io.legado.app.ui.widget.text.TextInputLayout>

@ -20,6 +20,6 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:padding="6dp" android:padding="6dp"
android:gravity="center" android:gravity="center"
android:text="执行中......" android:text="@string/loading"
android:textColor="@color/primaryText" /> android:textColor="@color/primaryText" />
</LinearLayout> </LinearLayout>

@ -24,6 +24,11 @@
android:title="@string/login" android:title="@string/login"
app:showAsAction="never" /> app:showAsAction="never" />
<item
android:id="@+id/menu_top"
android:title="@string/to_top"
app:showAsAction="never" />
<item <item
android:id="@+id/menu_copy_book_url" android:id="@+id/menu_copy_book_url"
android:title="@string/copy_book_url" android:title="@string/copy_book_url"

@ -847,4 +847,5 @@
<string name="null_url">URL nula</string> <string name="null_url">URL nula</string>
<string name="dict">字典</string> <string name="dict">字典</string>
<string name="unknown_error">未知错误</string> <string name="unknown_error">未知错误</string>
<string name="end">end</string>
</resources> </resources>

@ -847,4 +847,5 @@
<string name="null_url">url为空</string> <string name="null_url">url为空</string>
<string name="dict">字典</string> <string name="dict">字典</string>
<string name="unknown_error">未知错误</string> <string name="unknown_error">未知错误</string>
<string name="end">end</string>
</resources> </resources>

@ -847,4 +847,5 @@
<string name="null_url">Nenhuma url</string> <string name="null_url">Nenhuma url</string>
<string name="dict">Dicionários</string> <string name="dict">Dicionários</string>
<string name="unknown_error">未知错误</string> <string name="unknown_error">未知错误</string>
<string name="end">end</string>
</resources> </resources>

@ -7,8 +7,8 @@
</string-array> </string-array>
<string-array name="group_style"> <string-array name="group_style">
<item>标签</item> <item>標籤</item>
<item>文件</item> <item>文件</item>
</string-array> </string-array>
<string-array name="theme_mode"> <string-array name="theme_mode">

@ -343,7 +343,7 @@
<string name="pt_show_all_find">顯示所有發現</string> <string name="pt_show_all_find">顯示所有發現</string>
<string name="ps_show_all_find">關閉則只顯示勾選源的發現</string> <string name="ps_show_all_find">關閉則只顯示勾選源的發現</string>
<string name="update_toc">更新目錄</string> <string name="update_toc">更新目錄</string>
<string name="txt_toc_regex">Txt目錄正則</string> <string name="txt_toc_regex">TXT目錄正則</string>
<string name="set_charset">設置編碼</string> <string name="set_charset">設置編碼</string>
<string name="swap_sort">倒序-順序</string> <string name="swap_sort">倒序-順序</string>
<string name="sort">排序</string> <string name="sort">排序</string>
@ -405,7 +405,7 @@
<string name="book_url_pattern">書籍 URL 正則 (bookUrlPattern)</string> <string name="book_url_pattern">書籍 URL 正則 (bookUrlPattern)</string>
<string name="rule_book_info_init">預處理規則 (bookInfoInit)</string> <string name="rule_book_info_init">預處理規則 (bookInfoInit)</string>
<string name="rule_toc_url">目錄 URL 規則 (tocUrl)</string> <string name="rule_toc_url">目錄 URL 規則 (tocUrl)</string>
<string name="rule_can_re_name">许修改书名作者(canReName)</string> <string name="rule_can_re_name">許修改書名作者 (canReName)</string>
<string name="rule_next_toc_url">目錄下一頁規則 (nextTocUrl)</string> <string name="rule_next_toc_url">目錄下一頁規則 (nextTocUrl)</string>
<string name="rule_chapter_list">目錄列表規則 (chapterList)</string> <string name="rule_chapter_list">目錄列表規則 (chapterList)</string>
<string name="rule_chapter_name">章節名稱規則 (ChapterName)</string> <string name="rule_chapter_name">章節名稱規則 (ChapterName)</string>
@ -414,7 +414,7 @@
<string name="rule_update_time">更新時間 (ChapterInfo)</string> <string name="rule_update_time">更新時間 (ChapterInfo)</string>
<string name="rule_book_content">正文規則 (content)</string> <string name="rule_book_content">正文規則 (content)</string>
<string name="rule_next_content">正文下一頁 URL 規則 (nextContentUrl)</string> <string name="rule_next_content">正文下一頁 URL 規則 (nextContentUrl)</string>
<string name="rule_web_js">WebViewJs(webJs)</string> <string name="rule_web_js">WebViewJs (webJs)</string>
<string name="rule_source_regex">資源正則 (sourceRegex)</string> <string name="rule_source_regex">資源正則 (sourceRegex)</string>
<string name="source_icon">圖標 (sourceIcon)</string> <string name="source_icon">圖標 (sourceIcon)</string>
<string name="r_articles">列表規則 (ruleArticles)</string> <string name="r_articles">列表規則 (ruleArticles)</string>
@ -672,10 +672,10 @@
<string name="contributors">開發人員</string> <string name="contributors">開發人員</string>
<string name="contact">聯繫我們</string> <string name="contact">聯繫我們</string>
<string name="license">開源許可</string> <string name="license">開源許可</string>
<string name="follow_official_account">關注公</string> <string name="follow_official_account">關注公</string>
<string name="wechat">WeChat</string> <string name="wechat">WeChat</string>
<string name="thanks">你的支持是我更新的動力</string> <string name="thanks">你的支持是我更新的動力</string>
<string name="about_official_account">众号[开源阅读]</string> <string name="about_official_account">眾號[开源阅读]</string>
<string name="source_auto_changing">正在自動換源</string> <string name="source_auto_changing">正在自動換源</string>
<string name="click_to_apply">點擊加入</string> <string name="click_to_apply">點擊加入</string>
<string name="middle"></string> <string name="middle"></string>
@ -716,46 +716,46 @@
<string name="already_in_download">該書已在下載列表</string> <string name="already_in_download">該書已在下載列表</string>
<string name="click_to_open">點擊打開</string> <string name="click_to_open">點擊打開</string>
<string name="follow_public_account_summary">關注[legado-top]點擊廣告支持我</string> <string name="follow_public_account_summary">關注[legado-top]點擊廣告支持我</string>
<string name="weChat_appreciation_code">微信赞赏码</string> <string name="weChat_appreciation_code">微信讚賞碼</string>
<string name="alipay">支付寶</string> <string name="alipay">支付寶</string>
<string name="alipay_red_envelope_search_code">支付寶紅包搜索碼</string> <string name="alipay_red_envelope_search_code">支付寶紅包搜索碼</string>
<string name="alipay_red_envelope_copy">537954522 點擊複製</string> <string name="alipay_red_envelope_copy">537954522 點擊複製</string>
<string name="alipay_red_envelope_qr_code">支付寶紅包二維碼</string> <string name="alipay_red_envelope_qr_code">支付寶紅包二維碼</string>
<string name="alipay_payment_qr_code">支付寶收款二維碼</string> <string name="alipay_payment_qr_code">支付寶收款二維碼</string>
<string name="qq_collection_qr_code">QQ收款二維碼</string> <string name="qq_collection_qr_code">QQ收款二維碼</string>
<string name="contributors_summary">gedoor,Invinciblelee等,详情请在github中查看</string> <string name="contributors_summary">gedoor,Invinciblelee等,詳情請在github中查看</string>
<string name="clear_cache_summary">清除已下載書籍和字體緩存</string> <string name="clear_cache_summary">清除已下載書籍和字體緩存</string>
<string name="default_cover">默認封面</string> <string name="default_cover">默認封面</string>
<string name="restore_ignore">恢復忽略列表</string> <string name="restore_ignore">恢復忽略列表</string>
<string name="restore_ignore_summary">恢復時忽略一些內容不恢復,方便不同手機配置不同</string> <string name="restore_ignore_summary">恢復時忽略一些內容不恢復,方便不同手機配置不同</string>
<string name="read_config">閱讀界面設置</string> <string name="read_config">閱讀界面設置</string>
<string name="rule_image_style">图片样式(imageStyle)</string> <string name="rule_image_style">圖片樣式 (imageStyle)</string>
<string name="rule_replace_regex">换规则(replaceRegex)</string> <string name="rule_replace_regex">換規則 (replaceRegex)</string>
<string name="group_name">分組名稱</string> <string name="group_name">分組名稱</string>
<string name="note_content">備註內容</string> <string name="note_content">備註內容</string>
<string name="replace_enable_default_t">认启用替换净</string> <string name="replace_enable_default_t">認啟用替換淨</string>
<string name="replace_enable_default_s">新加入书架的书是否启用替换净</string> <string name="replace_enable_default_s">新加入書架的書是否啟用替換淨</string>
<string name="select_restore_file">选择恢复文件</string> <string name="select_restore_file">選擇恢復文件</string>
<string name="day_background_too_dark">白天背景不能太暗</string> <string name="day_background_too_dark">白天背景不能太暗</string>
<string name="day_bottom_bar_too_dark">白天底不能太暗</string> <string name="day_bottom_bar_too_dark">白天底不能太暗</string>
<string name="night_background_too_light">背景不能太亮</string> <string name="night_background_too_light">背景不能太亮</string>
<string name="night_bottom_bar_too_light">间底栏不能太亮</string> <string name="night_bottom_bar_too_light">間底欄不能太亮</string>
<string name="accent_background_diff">强调色不能和背景颜色相似</string> <string name="accent_background_diff">強調色不能和背景顏色相似</string>
<string name="accent_text_diff">强调色不能和文字颜色相似</string> <string name="accent_text_diff">強調色不能和文字顏色相似</string>
<string name="wrong_format">格式不對</string> <string name="wrong_format">格式不對</string>
<string name="error">錯誤</string> <string name="error">錯誤</string>
<string name="show_brightness_view">顯示亮度調節控制項</string> <string name="show_brightness_view">顯示亮度調節控制項</string>
<string name="language">語言</string> <string name="language">語言</string>
<string name="import_rss_source">匯入訂閱源</string> <string name="import_rss_source">匯入訂閱源</string>
<string name="donate_summary">您嘅支援我更新嘅動力</string> <string name="donate_summary">您嘅支援我更新嘅動力</string>
<string name="about_summary">众号[开源阅读软件]</string> <string name="about_summary">眾號[开源阅读软件]</string>
<string name="read_record">閲讀記錄</string> <string name="read_record">閲讀記錄</string>
<string name="read_record_summary">閱讀時間記錄</string> <string name="read_record_summary">閱讀時間記錄</string>
<string name="local_tts">本地TTS</string> <string name="local_tts">本地TTS</string>
<string name="thread_count">線程數</string> <string name="thread_count">線程數</string>
<string name="all_read_time">總閲讀時間</string> <string name="all_read_time">總閲讀時間</string>
<string name="un_select_all">全部唔要</string> <string name="un_select_all">全部唔要</string>
<string name="delete_all">除所有</string> <string name="delete_all">除所有</string>
<string name="import_str">導入</string> <string name="import_str">導入</string>
<string name="export_str">導出</string> <string name="export_str">導出</string>
<string name="save_theme_config">儲存主題配置</string> <string name="save_theme_config">儲存主題配置</string>
@ -789,7 +789,7 @@
<string name="non_action">無操作</string> <string name="non_action">無操作</string>
<string name="body_title">正文標題</string> <string name="body_title">正文標題</string>
<string name="show_hide">顯示/隱藏</string> <string name="show_hide">顯示/隱藏</string>
<string name="header_footer">页眉<![CDATA[&]]>页脚</string> <string name="header_footer">頁眉<![CDATA[&]]>頁腳</string>
<string name="rule_subscription">規則訂閱</string> <string name="rule_subscription">規則訂閱</string>
<string name="rule_sub_empty_msg">添加大佬們提供的規則匯入地址 添加後點擊可匯入規則</string> <string name="rule_sub_empty_msg">添加大佬們提供的規則匯入地址 添加後點擊可匯入規則</string>
<string name="get_book_progress">拉取雲端進度</string> <string name="get_book_progress">拉取雲端進度</string>
@ -804,6 +804,9 @@
<string name="pre_download_s">預先下載%s章正文</string> <string name="pre_download_s">預先下載%s章正文</string>
<string name="is_enabled">係咪啟用</string> <string name="is_enabled">係咪啟用</string>
<string name="background_image">背景圖片</string> <string name="background_image">背景圖片</string>
<string name="background_image_blurring">背景圖片虛化</string>
<string name="background_image_blurring_radius">虛化半徑</string>
<string name="background_image_hint">0為停用,啓用範圍1~25\n半徑數值越大,虛化效果越高</string>
<string name="export_folder">導出資料夾</string> <string name="export_folder">導出資料夾</string>
<string name="export_charset">導出編碼</string> <string name="export_charset">導出編碼</string>
<string name="export_to_web_dav">導出到WebDav</string> <string name="export_to_web_dav">導出到WebDav</string>
@ -836,14 +839,15 @@
<string name="hide_when_status_bar_show">狀態欄顯示時隱藏</string> <string name="hide_when_status_bar_show">狀態欄顯示時隱藏</string>
<string name="diy_source_group">自訂源分組</string> <string name="diy_source_group">自訂源分組</string>
<string name="diy_edit_source_group">輸入自訂源分組名稱</string> <string name="diy_edit_source_group">輸入自訂源分組名稱</string>
<string name="reverse_toc">转目录</string> <string name="reverse_toc">轉目錄</string>
<string name="show_discovery">显示发现</string> <string name="show_discovery">顯示發現</string>
<string name="style"></string> <string name="style"></string>
<string name="group_style">组样</string> <string name="group_style">組樣</string>
<string name="export_file_name">出文件名</string> <string name="export_file_name">出文件名</string>
<string name="reset">重置</string> <string name="reset">重置</string>
<string name="null_url">url</string> <string name="null_url">url</string>
<string name="dict">字典</string> <string name="dict">字典</string>
<string name="unknown_error">未知错误</string> <string name="unknown_error">未知錯誤</string>
<string name="end">end</string>
</resources> </resources>

@ -6,8 +6,8 @@
</string-array> </string-array>
<string-array name="group_style"> <string-array name="group_style">
<item>标签</item> <item>標籤</item>
<item>文件</item> <item>文件</item>
</string-array> </string-array>
<string-array name="text_suffix"> <string-array name="text_suffix">

@ -345,7 +345,7 @@
<string name="pt_show_all_find">顯示所有發現</string> <string name="pt_show_all_find">顯示所有發現</string>
<string name="ps_show_all_find">關閉則只顯示勾選源的發現</string> <string name="ps_show_all_find">關閉則只顯示勾選源的發現</string>
<string name="update_toc">更新目錄</string> <string name="update_toc">更新目錄</string>
<string name="txt_toc_regex">Txt目錄正則</string> <string name="txt_toc_regex">TXT目錄正則</string>
<string name="set_charset">設定編碼</string> <string name="set_charset">設定編碼</string>
<string name="swap_sort">倒序-順序</string> <string name="swap_sort">倒序-順序</string>
<string name="sort">排序</string> <string name="sort">排序</string>
@ -807,6 +807,9 @@
<string name="pre_download_s">預先下載%s章正文</string> <string name="pre_download_s">預先下載%s章正文</string>
<string name="is_enabled">是否啟用</string> <string name="is_enabled">是否啟用</string>
<string name="background_image">背景圖片</string> <string name="background_image">背景圖片</string>
<string name="background_image_blurring">背景圖片虛化</string>
<string name="background_image_blurring_radius">虛化半徑</string>
<string name="background_image_hint">0為停用,啓用範圍1~25\n半徑數值越大,虛化效果越高</string>
<string name="export_folder">匯出資料夾</string> <string name="export_folder">匯出資料夾</string>
<string name="export_charset">匯出編碼</string> <string name="export_charset">匯出編碼</string>
<string name="export_to_web_dav">匯出到WebDav</string> <string name="export_to_web_dav">匯出到WebDav</string>
@ -843,8 +846,9 @@
<string name="group_style">分組樣式</string> <string name="group_style">分組樣式</string>
<string name="export_file_name">匯出檔案名</string> <string name="export_file_name">匯出檔案名</string>
<string name="reset">重設</string> <string name="reset">重設</string>
<string name="null_url">url</string> <string name="null_url">url</string>
<string name="dict">字典</string> <string name="dict">字典</string>
<string name="unknown_error">未知错误</string> <string name="unknown_error">未知錯誤</string>
<string name="end">end</string>
</resources> </resources>

@ -807,6 +807,9 @@
<string name="pre_download_s">预先下载%s章正文</string> <string name="pre_download_s">预先下载%s章正文</string>
<string name="is_enabled">是否启用</string> <string name="is_enabled">是否启用</string>
<string name="background_image">背景图片</string> <string name="background_image">背景图片</string>
<string name="background_image_blurring">背景图片虚化</string>
<string name="background_image_blurring_radius">虚化半径</string>
<string name="background_image_hint">0为停用,启用范围1~25\n半径数值越大,虚化效果越高</string>
<string name="export_folder">导出文件夹</string> <string name="export_folder">导出文件夹</string>
<string name="export_charset">导出编码</string> <string name="export_charset">导出编码</string>
<string name="export_to_web_dav">导出到WebDav</string> <string name="export_to_web_dav">导出到WebDav</string>
@ -847,5 +850,6 @@
<string name="dict">字典</string> <string name="dict">字典</string>
<string name="unknown_error">未知错误</string> <string name="unknown_error">未知错误</string>
<string name="autobackup_fail">自动备份失败</string> <string name="autobackup_fail">自动备份失败</string>
<string name="end">结束</string>
</resources> </resources>

@ -807,6 +807,9 @@
<string name="pre_download_s">Download %s chapters in advance</string> <string name="pre_download_s">Download %s chapters in advance</string>
<string name="is_enabled">Is enabled</string> <string name="is_enabled">Is enabled</string>
<string name="background_image">Background image</string> <string name="background_image">Background image</string>
<string name="background_image_blurring">Background image blurring</string>
<string name="background_image_blurring_radius">Blurring radius</string>
<string name="background_image_hint">Disabled when 0, enable range from 1 to 25\nThe greater the radius, the stronger the effect of blurring</string>
<string name="copy_book_url">Copy book URL</string> <string name="copy_book_url">Copy book URL</string>
<string name="copy_toc_url">Copy chapters URL</string> <string name="copy_toc_url">Copy chapters URL</string>
<string name="export_folder">Export folder</string> <string name="export_folder">Export folder</string>
@ -849,5 +852,6 @@
<string name="dict">字典</string> <string name="dict">字典</string>
<string name="unknown_error">未知错误</string> <string name="unknown_error">未知错误</string>
<string name="autobackup_fail">Autobackup failed</string> <string name="autobackup_fail">Autobackup failed</string>
<string name="end">end</string>
</resources> </resources>

@ -82,10 +82,6 @@
app:cpv_dialogType="preset" app:cpv_dialogType="preset"
app:iconSpaceReserved="false" /> app:iconSpaceReserved="false" />
<io.legado.app.ui.widget.prefs.Preference
android:key="backgroundImage"
android:title="@string/background_image" />
<io.legado.app.ui.widget.prefs.ColorPreference <io.legado.app.ui.widget.prefs.ColorPreference
android:defaultValue="@color/md_grey_200" android:defaultValue="@color/md_grey_200"
android:key="colorBottomBackground" android:key="colorBottomBackground"
@ -96,12 +92,13 @@
app:cpv_dialogType="preset" app:cpv_dialogType="preset"
app:iconSpaceReserved="false" /> app:iconSpaceReserved="false" />
<io.legado.app.ui.widget.prefs.Preference
android:key="backgroundImage"
android:title="@string/background_image" />
<io.legado.app.ui.widget.prefs.Preference <io.legado.app.ui.widget.prefs.Preference
android:key="defaultCover" android:key="defaultCover"
android:title="@string/default_cover" android:title="@string/default_cover" />
app:allowDividerAbove="false"
app:allowDividerBelow="false"
app:iconSpaceReserved="false" />
<io.legado.app.ui.widget.prefs.Preference <io.legado.app.ui.widget.prefs.Preference
android:key="saveDayTheme" android:key="saveDayTheme"
@ -145,10 +142,6 @@
app:cpv_dialogType="preset" app:cpv_dialogType="preset"
app:iconSpaceReserved="false" /> app:iconSpaceReserved="false" />
<io.legado.app.ui.widget.prefs.Preference
android:key="backgroundImageNight"
android:title="@string/background_image" />
<io.legado.app.ui.widget.prefs.ColorPreference <io.legado.app.ui.widget.prefs.ColorPreference
android:defaultValue="@color/md_grey_800" android:defaultValue="@color/md_grey_800"
android:key="colorBottomBackgroundNight" android:key="colorBottomBackgroundNight"
@ -157,17 +150,20 @@
app:cpv_dialogType="preset" app:cpv_dialogType="preset"
app:iconSpaceReserved="false" /> app:iconSpaceReserved="false" />
<io.legado.app.ui.widget.prefs.Preference
android:key="backgroundImageNight"
android:title="@string/background_image" />
<io.legado.app.ui.widget.prefs.Preference <io.legado.app.ui.widget.prefs.Preference
android:key="defaultCoverDark" android:key="defaultCoverDark"
android:title="@string/default_cover" android:title="@string/default_cover" />
app:allowDividerAbove="false"
app:allowDividerBelow="false"
app:iconSpaceReserved="false" />
<io.legado.app.ui.widget.prefs.Preference <io.legado.app.ui.widget.prefs.Preference
android:key="saveNightTheme" android:key="saveNightTheme"
android:summary="@string/save_night_theme_summary" android:summary="@string/save_night_theme_summary"
android:title="@string/save_theme_config" android:title="@string/save_theme_config"
app:allowDividerAbove="false"
app:allowDividerBelow="false"
app:iconSpaceReserved="false" /> app:iconSpaceReserved="false" />
</io.legado.app.ui.widget.prefs.PreferenceCategory> </io.legado.app.ui.widget.prefs.PreferenceCategory>

Loading…
Cancel
Save