每本书可以单独设置翻页动画,在菜单里

pull/443/head
gedoor 4 years ago
parent c68923b728
commit 703e503810
  1. 22
      app/src/main/java/io/legado/app/data/entities/Book.kt
  2. 4
      app/src/main/java/io/legado/app/help/ContentHelp.kt
  3. 3
      app/src/main/java/io/legado/app/help/ReadBookConfig.kt
  4. 14
      app/src/main/java/io/legado/app/lib/dialogs/AndroidSelectors.kt
  5. 13
      app/src/main/java/io/legado/app/service/help/ReadBook.kt
  6. 21
      app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt
  7. 14
      app/src/main/java/io/legado/app/ui/book/read/ReadBookActivityHelp.kt
  8. 10
      app/src/main/java/io/legado/app/ui/book/read/config/ReadStyleDialog.kt
  9. 13
      app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt
  10. 36
      app/src/main/java/io/legado/app/ui/book/read/page/PageView.kt
  11. 14
      app/src/main/res/menu/read_book.xml
  12. 4
      app/src/main/res/values-night/strings.xml
  13. 1
      app/src/main/res/values-zh-rHK/strings.xml
  14. 1
      app/src/main/res/values-zh-rTW/strings.xml
  15. 1
      app/src/main/res/values-zh/strings.xml
  16. 1
      app/src/main/res/values/strings.xml

@ -114,7 +114,7 @@ data class Book(
return charset(charset ?: "UTF-8") return charset(charset ?: "UTF-8")
} }
fun rConfig(): ReadConfig { private fun config(): ReadConfig {
if (readConfig == null) { if (readConfig == null) {
readConfig = ReadConfig() readConfig = ReadConfig()
} }
@ -122,11 +122,27 @@ data class Book(
} }
fun setUseReplaceRule(useReplaceRule: Boolean) { fun setUseReplaceRule(useReplaceRule: Boolean) {
rConfig().useReplaceRule = useReplaceRule config().useReplaceRule = useReplaceRule
} }
fun getUseReplaceRule(): Boolean { fun getUseReplaceRule(): Boolean {
return rConfig().useReplaceRule return config().useReplaceRule
}
fun getReSegment(): Boolean {
return config().reSegment
}
fun setReSegment(reSegment: Boolean) {
config().reSegment = reSegment
}
fun getPageAnim(): Int {
return config().pageAnim
}
fun setPageAnim(pageAnim: Int) {
config().pageAnim = pageAnim
} }
fun getFolderName(): String { fun getFolderName(): String {

@ -14,9 +14,8 @@ object ContentHelp {
* @param chapterName 标题 * @param chapterName 标题
* @return * @return
*/ */
fun lightNovelParagraph2(content: String, chapterName: String): String { fun reSegment(content: String, chapterName: String): String {
var content1 = content var content1 = content
if (true) {
val content2: String val content2: String
val chapterNameLength = chapterName.trim { it <= ' ' }.length val chapterNameLength = chapterName.trim { it <= ' ' }.length
content2 = if (chapterNameLength > 1) { content2 = if (chapterNameLength > 1) {
@ -80,7 +79,6 @@ object ContentHelp {
.replace("[::][”“\"\\s]+".toRegex(), ":“") .replace("[::][”“\"\\s]+".toRegex(), ":“")
.replace("\n[\"“”]([^\n\"“”]+)([,:,:][\"”“])([^\n\"“”]+)".toRegex(), "\n$1:“$3") .replace("\n[\"“”]([^\n\"“”]+)([,:,:][\"”“])([^\n\"“”]+)".toRegex(), "\n$1:“$3")
.replace("\n(\\s*)".toRegex(), "\n")) .replace("\n(\\s*)".toRegex(), "\n"))
}
return content1 return content1
} }

@ -96,7 +96,6 @@ object ReadBookConfig {
bgMeanColor = color bgMeanColor = color
} }
} }
isScroll = pageAnim == 3
} }
fun save() { fun save() {
@ -154,7 +153,6 @@ object ReadBookConfig {
App.INSTANCE.putPrefBoolean(PreferKey.shareLayout, value) App.INSTANCE.putPrefBoolean(PreferKey.shareLayout, value)
} }
} }
var isScroll = pageAnim == 3
val clickTurnPage get() = App.INSTANCE.getPrefBoolean(PreferKey.clickTurnPage, true) val clickTurnPage get() = App.INSTANCE.getPrefBoolean(PreferKey.clickTurnPage, true)
val textFullJustify get() = App.INSTANCE.getPrefBoolean(PreferKey.textFullJustify, true) val textFullJustify get() = App.INSTANCE.getPrefBoolean(PreferKey.textFullJustify, true)
val textBottomJustify get() = App.INSTANCE.getPrefBoolean(PreferKey.textBottomJustify, true) val textBottomJustify get() = App.INSTANCE.getPrefBoolean(PreferKey.textBottomJustify, true)
@ -167,7 +165,6 @@ object ReadBookConfig {
get() = config.curPageAnim() get() = config.curPageAnim()
set(value) { set(value) {
config.setCurPageAnim(value) config.setCurPageAnim(value)
isScroll = pageAnim == 3
} }
var textFont: String var textFont: String

@ -42,3 +42,17 @@ fun Context.selector(
show().applyTint() show().applyTint()
} }
} }
fun Context.selector(
titleSource: Int? = null,
items: List<CharSequence>,
onClick: (DialogInterface, Int) -> Unit
) {
with(AndroidAlertBuilder(this)) {
if (titleSource != null) {
this.title = getString(titleSource)
}
items(items, onClick)
show().applyTint()
}
}

@ -11,6 +11,7 @@ import io.legado.app.data.entities.ReadRecord
import io.legado.app.help.AppConfig import io.legado.app.help.AppConfig
import io.legado.app.help.BookHelp import io.legado.app.help.BookHelp
import io.legado.app.help.IntentDataHelp import io.legado.app.help.IntentDataHelp
import io.legado.app.help.ReadBookConfig
import io.legado.app.help.coroutine.Coroutine import io.legado.app.help.coroutine.Coroutine
import io.legado.app.model.webBook.WebBook import io.legado.app.model.webBook.WebBook
import io.legado.app.service.BaseReadAloudService import io.legado.app.service.BaseReadAloudService
@ -57,6 +58,7 @@ object ReadBook {
curTextChapter = null curTextChapter = null
nextTextChapter = null nextTextChapter = null
titleDate.postValue(book.name) titleDate.postValue(book.name)
callBack?.upPageAnim()
upWebBook(book) upWebBook(book)
ImageProvider.clearAllCache() ImageProvider.clearAllCache()
synchronized(this) { synchronized(this) {
@ -431,6 +433,16 @@ object ReadBook {
private val imageStyle get() = webBook?.bookSource?.ruleContent?.imageStyle private val imageStyle get() = webBook?.bookSource?.ruleContent?.imageStyle
fun pageAnim(): Int {
book?.let {
return if (it.getPageAnim() < 0)
ReadBookConfig.pageAnim
else
it.getPageAnim()
}
return ReadBookConfig.pageAnim
}
fun setCharset(charset: String) { fun setCharset(charset: String) {
book?.let { book?.let {
it.charset = charset it.charset = charset
@ -460,6 +472,7 @@ object ReadBook {
fun upView() fun upView()
fun pageChanged() fun pageChanged()
fun contentLoadFinish() fun contentLoadFinish()
fun upPageAnim()
} }
} }

@ -91,7 +91,7 @@ class ReadBookActivity : VMBaseActivity<ReadBookViewModel>(R.layout.activity_boo
override val scope: CoroutineScope get() = this override val scope: CoroutineScope get() = this
override val isInitFinish: Boolean get() = viewModel.isInitFinish override val isInitFinish: Boolean get() = viewModel.isInitFinish
override val isScroll: Boolean get() = page_view.isScroll
private val mHandler = Handler() private val mHandler = Handler()
private val keepScreenRunnable: Runnable = private val keepScreenRunnable: Runnable =
Runnable { ReadBookActivityHelp.keepScreenOn(window, false) } Runnable { ReadBookActivityHelp.keepScreenOn(window, false) }
@ -228,8 +228,9 @@ class ReadBookActivity : VMBaseActivity<ReadBookViewModel>(R.layout.activity_boo
R.id.menu_group_text -> item.isVisible = book.isLocalTxt() R.id.menu_group_text -> item.isVisible = book.isLocalTxt()
R.id.menu_group_login -> R.id.menu_group_login ->
item.isVisible = !ReadBook.webBook?.bookSource?.loginUrl.isNullOrEmpty() item.isVisible = !ReadBook.webBook?.bookSource?.loginUrl.isNullOrEmpty()
else -> if (item.itemId == R.id.menu_enable_replace) { else -> when (item.itemId) {
item.isChecked = book.getUseReplaceRule() R.id.menu_enable_replace -> item.isChecked = book.getUseReplaceRule()
R.id.menu_re_segment -> item.isChecked = book.getReSegment()
} }
} }
} }
@ -267,6 +268,14 @@ class ReadBookActivity : VMBaseActivity<ReadBookViewModel>(R.layout.activity_boo
menu?.findItem(R.id.menu_enable_replace)?.isChecked = it.getUseReplaceRule() menu?.findItem(R.id.menu_enable_replace)?.isChecked = it.getUseReplaceRule()
onReplaceRuleSave() onReplaceRuleSave()
} }
R.id.menu_re_segment -> ReadBook.book?.let {
it.setReSegment(!it.getReSegment())
menu?.findItem(R.id.menu_re_segment)?.isChecked = it.getReSegment()
ReadBook.loadContent(false)
}
R.id.menu_page_anim -> ReadBookActivityHelp.showPageAnimConfig(this) {
page_view.upPageAnim()
}
R.id.menu_book_info -> ReadBook.book?.let { R.id.menu_book_info -> ReadBook.book?.let {
startActivity<BookInfoActivity>( startActivity<BookInfoActivity>(
Pair("name", it.name), Pair("name", it.name),
@ -582,6 +591,12 @@ class ReadBookActivity : VMBaseActivity<ReadBookViewModel>(R.layout.activity_boo
} }
} }
override fun upPageAnim() {
launch {
page_view.upPageAnim()
}
}
/** /**
* 页面改变 * 页面改变
*/ */

@ -189,6 +189,20 @@ object ReadBookActivityHelp {
}.show().applyTint() }.show().applyTint()
} }
fun showPageAnimConfig(context: Context, success: () -> Unit) = with(context) {
val items = arrayListOf<String>()
items.add(getString(R.string.btn_default_s))
items.add(getString(R.string.page_anim_cover))
items.add(getString(R.string.page_anim_slide))
items.add(getString(R.string.page_anim_simulation))
items.add(getString(R.string.page_anim_scroll))
items.add(getString(R.string.page_anim_none))
selector(R.string.page_anim, items) { _, i ->
ReadBook.book?.setPageAnim(i - 1)
success()
}
}
fun isPrevKey(context: Context, keyCode: Int): Boolean { fun isPrevKey(context: Context, keyCode: Int): Boolean {
val prevKeysStr = context.getPrefString(PreferKey.prevKeys) val prevKeysStr = context.getPrefString(PreferKey.prevKeys)
return prevKeysStr?.split(",")?.contains(keyCode.toString()) ?: false return prevKeysStr?.split(",")?.contains(keyCode.toString()) ?: false

@ -17,6 +17,7 @@ import io.legado.app.lib.dialogs.selector
import io.legado.app.lib.theme.accentColor import io.legado.app.lib.theme.accentColor
import io.legado.app.lib.theme.bottomBackground import io.legado.app.lib.theme.bottomBackground
import io.legado.app.lib.theme.getPrimaryTextColor import io.legado.app.lib.theme.getPrimaryTextColor
import io.legado.app.service.help.ReadBook
import io.legado.app.ui.book.read.ReadBookActivity import io.legado.app.ui.book.read.ReadBookActivity
import io.legado.app.ui.widget.font.FontSelectDialog import io.legado.app.ui.widget.font.FontSelectDialog
import io.legado.app.utils.* import io.legado.app.utils.*
@ -138,6 +139,7 @@ class ReadStyleDialog : BaseDialogFragment(), FontSelectDialog.CallBack {
TipConfigDialog().show(childFragmentManager, "tipConfigDialog") TipConfigDialog().show(childFragmentManager, "tipConfigDialog")
} }
rg_page_anim.onCheckedChange { _, checkedId -> rg_page_anim.onCheckedChange { _, checkedId ->
ReadBook.book?.setPageAnim(-1)
ReadBookConfig.pageAnim = rg_page_anim.getIndexById(checkedId) ReadBookConfig.pageAnim = rg_page_anim.getIndexById(checkedId)
callBack?.page_view?.upPageAnim() callBack?.page_view?.upPageAnim()
} }
@ -216,10 +218,12 @@ class ReadStyleDialog : BaseDialogFragment(), FontSelectDialog.CallBack {
} }
private fun upView() { private fun upView() {
ReadBookConfig.let { ReadBook.pageAnim().let {
if (it.pageAnim >= 0 && it.pageAnim < rg_page_anim.childCount) { if (it >= 0 && it < rg_page_anim.childCount) {
rg_page_anim.check(rg_page_anim[it.pageAnim].id) rg_page_anim.check(rg_page_anim[it].id)
}
} }
ReadBookConfig.let {
dsb_text_size.progress = it.textSize - 5 dsb_text_size.progress = it.textSize - 5
dsb_text_letter_spacing.progress = (it.letterSpacing * 100).toInt() + 50 dsb_text_letter_spacing.progress = (it.letterSpacing * 100).toInt() + 50
dsb_line_size.progress = it.lineSpacingExtra dsb_line_size.progress = it.lineSpacingExtra

@ -86,7 +86,7 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
textPage.textLines.forEach { textLine -> textPage.textLines.forEach { textLine ->
draw(canvas, textLine, relativeOffset) draw(canvas, textLine, relativeOffset)
} }
if (!ReadBookConfig.isScroll) return if (!callBack.isScroll) return
//滚动翻页 //滚动翻页
if (!pageFactory.hasNext()) return if (!pageFactory.hasNext()) return
val nextPage = relativePage(1) val nextPage = relativePage(1)
@ -215,7 +215,7 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
relativeOffset = relativeOffset(relativePos) relativeOffset = relativeOffset(relativePos)
if (relativePos > 0) { if (relativePos > 0) {
//滚动翻页 //滚动翻页
if (!ReadBookConfig.isScroll) return if (!callBack.isScroll) return
if (relativeOffset >= ChapterProvider.visibleHeight) return if (relativeOffset >= ChapterProvider.visibleHeight) return
} }
val page = relativePage(relativePos) val page = relativePage(relativePos)
@ -252,7 +252,7 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
relativeOffset = relativeOffset(relativePos) relativeOffset = relativeOffset(relativePos)
if (relativePos > 0) { if (relativePos > 0) {
//滚动翻页 //滚动翻页
if (!ReadBookConfig.isScroll) return if (!callBack.isScroll) return
if (relativeOffset >= ChapterProvider.visibleHeight) return if (relativeOffset >= ChapterProvider.visibleHeight) return
} }
for ((lineIndex, textLine) in relativePage(relativePos).textLines.withIndex()) { for ((lineIndex, textLine) in relativePage(relativePos).textLines.withIndex()) {
@ -295,7 +295,7 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
relativeOffset = relativeOffset(relativePos) relativeOffset = relativeOffset(relativePos)
if (relativePos > 0) { if (relativePos > 0) {
//滚动翻页 //滚动翻页
if (!ReadBookConfig.isScroll) return if (!callBack.isScroll) return
if (relativeOffset >= ChapterProvider.visibleHeight) return if (relativeOffset >= ChapterProvider.visibleHeight) return
} }
Log.e("y", "$y") Log.e("y", "$y")
@ -358,7 +358,7 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
} }
private fun upSelectChars() { private fun upSelectChars() {
val last = if (ReadBookConfig.isScroll) 2 else 0 val last = if (callBack.isScroll) 2 else 0
for (relativePos in 0..last) { for (relativePos in 0..last) {
for ((lineIndex, textLine) in relativePage(relativePos).textLines.withIndex()) { for ((lineIndex, textLine) in relativePage(relativePos).textLines.withIndex()) {
for ((charIndex, textChar) in textLine.textChars.withIndex()) { for ((charIndex, textChar) in textLine.textChars.withIndex()) {
@ -397,7 +397,7 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
} }
fun cancelSelect() { fun cancelSelect() {
val last = if (ReadBookConfig.isScroll) 2 else 0 val last = if (callBack.isScroll) 2 else 0
for (relativePos in 0..last) { for (relativePos in 0..last) {
relativePage(relativePos).textLines.forEach { textLine -> relativePage(relativePos).textLines.forEach { textLine ->
textLine.textChars.forEach { textLine.textChars.forEach {
@ -499,5 +499,6 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
val headerHeight: Int val headerHeight: Int
val pageFactory: TextPageFactory val pageFactory: TextPageFactory
val scope: CoroutineScope val scope: CoroutineScope
val isScroll: Boolean
} }
} }

@ -29,7 +29,13 @@ class PageView(context: Context, attrs: AttributeSet) :
val callBack: CallBack get() = activity as CallBack val callBack: CallBack get() = activity as CallBack
var pageFactory: TextPageFactory = TextPageFactory(this) var pageFactory: TextPageFactory = TextPageFactory(this)
var pageDelegate: PageDelegate? = null var pageDelegate: PageDelegate? = null
private set(value) {
field?.onDestroy()
field = null
field = value
upContent()
}
var isScroll = ReadBook.pageAnim() == 3
var prevPage: ContentView = ContentView(context) var prevPage: ContentView = ContentView(context)
var curPage: ContentView = ContentView(context) var curPage: ContentView = ContentView(context)
var nextPage: ContentView = ContentView(context) var nextPage: ContentView = ContentView(context)
@ -304,20 +310,28 @@ class PageView(context: Context, attrs: AttributeSet) :
} }
fun upPageAnim() { fun upPageAnim() {
pageDelegate?.onDestroy() isScroll = ReadBook.pageAnim() == 3
pageDelegate = null when (ReadBook.pageAnim()) {
pageDelegate = when (ReadBookConfig.pageAnim) { 0 -> if (pageDelegate !is CoverPageDelegate) {
0 -> CoverPageDelegate(this) pageDelegate = CoverPageDelegate(this)
1 -> SlidePageDelegate(this) }
2 -> SimulationPageDelegate(this) 1 -> if (pageDelegate !is SlidePageDelegate) {
3 -> ScrollPageDelegate(this) pageDelegate = SlidePageDelegate(this)
else -> NoAnimPageDelegate(this) }
2 -> if (pageDelegate !is SimulationPageDelegate) {
pageDelegate = SimulationPageDelegate(this)
}
3 -> if (pageDelegate !is ScrollPageDelegate) {
pageDelegate = ScrollPageDelegate(this)
}
else -> if (pageDelegate !is NoAnimPageDelegate) {
pageDelegate = NoAnimPageDelegate(this)
}
} }
upContent()
} }
override fun upContent(relativePosition: Int, resetPageOffset: Boolean) { override fun upContent(relativePosition: Int, resetPageOffset: Boolean) {
if (ReadBookConfig.isScroll && !callBack.isAutoPage) { if (isScroll && !callBack.isAutoPage) {
curPage.setContent(pageFactory.currentPage, resetPageOffset) curPage.setContent(pageFactory.currentPage, resetPageOffset)
} else { } else {
curPage.resetPageOffset() curPage.resetPageOffset()

@ -70,6 +70,12 @@
android:title="@string/copy_text" android:title="@string/copy_text"
app:showAsAction="ifRoom" /> app:showAsAction="ifRoom" />
<item
android:id="@+id/menu_page_anim"
android:icon="@drawable/ic_auto_page"
android:title="@string/page_anim"
app:showAsAction="never" />
<item <item
android:id="@+id/menu_enable_replace" android:id="@+id/menu_enable_replace"
android:icon="@drawable/ic_find_replace" android:icon="@drawable/ic_find_replace"
@ -78,6 +84,14 @@
android:checked="true" android:checked="true"
app:showAsAction="never" /> app:showAsAction="never" />
<item
android:id="@+id/menu_re_segment"
android:icon="@drawable/ic_toc"
android:title="@string/re_segment"
android:checkable="true"
android:checked="false"
app:showAsAction="never" />
<item <item
android:id="@+id/menu_update_toc" android:id="@+id/menu_update_toc"
android:icon="@drawable/ic_update" android:icon="@drawable/ic_update"

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
</resources>

@ -773,5 +773,6 @@
<string name="theme_name">主题名称</string> <string name="theme_name">主题名称</string>
<string name="auto_clear_expired">自动清除过期搜索数据</string> <string name="auto_clear_expired">自动清除过期搜索数据</string>
<string name="auto_clear_expired_summary">超过一天的搜索数据</string> <string name="auto_clear_expired_summary">超过一天的搜索数据</string>
<string name="re_segment">重新分段</string>
</resources> </resources>

@ -773,5 +773,6 @@
<string name="theme_name">主题名称</string> <string name="theme_name">主题名称</string>
<string name="auto_clear_expired">自动清除过期搜索数据</string> <string name="auto_clear_expired">自动清除过期搜索数据</string>
<string name="auto_clear_expired_summary">超过一天的搜索数据</string> <string name="auto_clear_expired_summary">超过一天的搜索数据</string>
<string name="re_segment">重新分段</string>
</resources> </resources>

@ -776,5 +776,6 @@
<string name="theme_name">主题名称</string> <string name="theme_name">主题名称</string>
<string name="auto_clear_expired">自动清除过期搜索数据</string> <string name="auto_clear_expired">自动清除过期搜索数据</string>
<string name="auto_clear_expired_summary">超过一天的搜索数据</string> <string name="auto_clear_expired_summary">超过一天的搜索数据</string>
<string name="re_segment">重新分段</string>
</resources> </resources>

@ -779,5 +779,6 @@
<string name="theme_name">主题名称</string> <string name="theme_name">主题名称</string>
<string name="auto_clear_expired">自动清除过期搜索数据</string> <string name="auto_clear_expired">自动清除过期搜索数据</string>
<string name="auto_clear_expired_summary">超过一天的搜索数据</string> <string name="auto_clear_expired_summary">超过一天的搜索数据</string>
<string name="re_segment">重新分段</string>
</resources> </resources>

Loading…
Cancel
Save