update pageview

pull/32/head
Administrator 5 years ago
parent e5f27fbe97
commit 17a90ab7eb
  1. 10
      app/src/main/java/io/legado/app/base/BaseViewModel.kt
  2. 3
      app/src/main/java/io/legado/app/ui/readbook/ReadBookActivity.kt
  3. 6
      app/src/main/java/io/legado/app/ui/readbook/ReadBookViewModel.kt
  4. 21
      app/src/main/java/io/legado/app/ui/widget/page/ContentView.kt
  5. 10
      app/src/main/java/io/legado/app/ui/widget/page/DataSource.kt
  6. 8
      app/src/main/java/io/legado/app/ui/widget/page/PageFactory.kt
  7. 73
      app/src/main/java/io/legado/app/ui/widget/page/PageView.kt
  8. 3
      app/src/main/java/io/legado/app/ui/widget/page/ScrollContentView.kt
  9. 32
      app/src/main/java/io/legado/app/ui/widget/page/TextPageFactory.kt
  10. 14
      app/src/main/java/io/legado/app/ui/widget/page/delegate/CoverPageDelegate.kt
  11. 48
      app/src/main/java/io/legado/app/ui/widget/page/delegate/PageDelegate.kt
  12. 22
      app/src/main/java/io/legado/app/ui/widget/page/delegate/SlidePageDelegate.kt
  13. 1
      app/src/main/res/layout/view_book_page.xml

@ -12,7 +12,7 @@ import org.jetbrains.anko.toast
open class BaseViewModel(application: Application) : AndroidViewModel(application), CoroutineScope by MainScope(),
AnkoLogger {
val context: Context = this.getApplication<App>()
val context: Context by lazy { this.getApplication<App>() }
fun <T> execute(scope: CoroutineScope = this, block: suspend CoroutineScope.() -> T): Coroutine<T> {
return Coroutine.async(scope) { block() }
@ -29,25 +29,25 @@ open class BaseViewModel(application: Application) : AndroidViewModel(applicatio
open fun toast(message: Int) {
launch {
getApplication<App>().toast(message)
context.toast(message)
}
}
open fun toast(message: CharSequence) {
launch {
getApplication<App>().toast(message)
context.toast(message)
}
}
open fun longToast(message: Int) {
launch {
getApplication<App>().toast(message)
context.toast(message)
}
}
open fun longToast(message: CharSequence) {
launch {
getApplication<App>().toast(message)
context.toast(message)
}
}
}

@ -51,7 +51,6 @@ class ReadBookActivity : VMBaseActivity<ReadBookViewModel>(R.layout.activity_rea
setSupportActionBar(toolbar)
initAnimation()
initView()
page_view.callBack = this
viewModel.callBack = this
viewModel.chapterMaxIndex.observe(this, Observer { bookLoadFinish() })
viewModel.bookData.observe(this, Observer { title_bar.title = it.name })
@ -242,7 +241,7 @@ class ReadBookActivity : VMBaseActivity<ReadBookViewModel>(R.layout.activity_rea
}
}
override fun loadContentFinish(bookChapter: BookChapter, content: String) {
override fun onLoadFinish(bookChapter: BookChapter, content: String) {
launch {
when (bookChapter.index) {
viewModel.durChapterIndex -> {

@ -80,7 +80,7 @@ class ReadBookViewModel(application: Application) : BaseViewModel(application) {
execute {
App.db.bookChapterDao().getChapter(book.bookUrl, index)?.let { chapter ->
BookHelp.getContent(book, chapter)?.let {
callBack?.loadContentFinish(chapter, it)
callBack?.onLoadFinish(chapter, it)
synchronized(loadingLock) {
loadingChapters.remove(index)
}
@ -118,7 +118,7 @@ class ReadBookViewModel(application: Application) : BaseViewModel(application) {
?.onSuccess(IO) { content ->
content?.let {
BookHelp.saveContent(book, chapter, it)
callBack?.loadContentFinish(chapter, it)
callBack?.onLoadFinish(chapter, it)
synchronized(loadingLock) {
loadingChapters.remove(chapter.index)
}
@ -140,6 +140,6 @@ class ReadBookViewModel(application: Application) : BaseViewModel(application) {
}
interface CallBack {
fun loadContentFinish(bookChapter: BookChapter, content: String)
fun onLoadFinish(bookChapter: BookChapter, content: String)
}
}

@ -1,18 +1,21 @@
package io.legado.app.ui.widget.page
import android.content.Context
import android.graphics.Color
import android.graphics.drawable.Drawable
import android.util.AttributeSet
import android.widget.FrameLayout
import androidx.appcompat.widget.AppCompatImageView
import io.legado.app.R
import io.legado.app.help.ImageLoader
import io.legado.app.utils.dp
import kotlinx.android.synthetic.main.view_book_page.view.*
import org.jetbrains.anko.horizontalPadding
import org.jetbrains.anko.matchParent
class ContentView : FrameLayout {
private val bgImage: AppCompatImageView = AppCompatImageView(context)
constructor(context: Context) : super(context)
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
@ -20,22 +23,16 @@ class ContentView : FrameLayout {
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
init {
addView(bgImage, LayoutParams(matchParent, matchParent))
inflate(context, R.layout.view_book_page, this)
setBackgroundColor(Color.WHITE)
upStyle()
}
fun upStyle() {
page_panel.horizontalPadding = 16.dp
}
fun setBg(bg: Drawable?) {
page_panel.background = bg
}
fun setBgColor(color: Int) {
page_panel.setBackgroundColor(color)
ImageLoader.load(context, R.drawable.bg1)
.centerCrop()
.setAsDrawable(bgImage)
}
fun upTime() {

@ -1,11 +1,17 @@
package io.legado.app.ui.widget.page
import io.legado.app.data.entities.BookChapter
interface DataSource {
fun isPrepared(): Boolean
fun getChapterPosition()
fun getChapter(position: Int): TextChapter?
fun getCurrentChapter(): TextChapter?
fun getNextChapter(): TextChapter?
fun getPreviousChapter(): TextChapter?
@ -13,4 +19,8 @@ interface DataSource {
fun hasNextChapter(): Boolean
fun hasPrevChapter(): Boolean
interface CallBack {
fun onLoadFinish(bookChapter: BookChapter, content: String)
}
}

@ -4,10 +4,18 @@ abstract class PageFactory<DATA>(protected val dataSource: DataSource) {
abstract fun pageAt(index: Int): DATA?
abstract fun moveToFirst()
abstract fun moveToNext():Boolean
abstract fun moveToPrevious(): Boolean
abstract fun nextPage(): DATA?
abstract fun previousPage(): DATA?
abstract fun currentPage(): DATA?
abstract fun hasNext(): Boolean
abstract fun hasPrev(): Boolean

@ -12,8 +12,9 @@ import io.legado.app.ui.widget.page.delegate.PageDelegate
class PageView(context: Context, attrs: AttributeSet) : FrameLayout(context, attrs), PageDelegate.PageInterface {
var callBack: CallBack? = null
var callback: CallBack? = null
private var pageDelegate: PageDelegate? = null
private var pageFactory: TextPageFactory? = null
var prevPage: ContentView? = null
var curPage: ContentView? = null
@ -30,6 +31,40 @@ class PageView(context: Context, attrs: AttributeSet) : FrameLayout(context, att
setWillNotDraw(false)
pageDelegate = CoverPageDelegate(this)
setPageFactory(TextPageFactory.create(object : DataSource {
override fun isPrepared(): Boolean {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
override fun getChapterPosition() {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
override fun getChapter(position: Int): TextChapter? {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
override fun getCurrentChapter(): TextChapter? {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
override fun getNextChapter(): TextChapter? {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
override fun getPreviousChapter(): TextChapter? {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
override fun hasNextChapter(): Boolean {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
override fun hasPrevChapter(): Boolean {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
}))
}
override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
@ -41,9 +76,7 @@ class PageView(context: Context, attrs: AttributeSet) : FrameLayout(context, att
override fun dispatchDraw(canvas: Canvas) {
super.dispatchDraw(canvas)
// bringChildToFront(prevPage)
pageDelegate?.onPerform(canvas)
pageDelegate?.onDraw(canvas)
}
override fun computeScroll() {
@ -56,7 +89,7 @@ class PageView(context: Context, attrs: AttributeSet) : FrameLayout(context, att
}
fun chapterLoadFinish(chapterOnDur: Int = 0) {
callBack?.let { cb ->
callback?.let { cb ->
when (chapterOnDur) {
0 -> {
cb.textChapter()?.let {
@ -89,8 +122,36 @@ class PageView(context: Context, attrs: AttributeSet) : FrameLayout(context, att
}
}
fun setPageFactory(factory: PageFactory<*>) {
fun fillPage(direction: PageDelegate.Direction) {
pageFactory?.let {
when (direction) {
PageDelegate.Direction.PREV -> {
it.moveToPrevious()
}
PageDelegate.Direction.NEXT -> {
it.moveToNext()
}
else -> {
}
}
prevPage?.setContent(it.previousPage()?.text)
curPage?.setContent(it.currentPage()?.text)
nextPage?.setContent(it.nextPage()?.text)
}
}
fun setPageFactory(factory: TextPageFactory) {
this.pageFactory = factory
//可做成异步回调
pageFactory?.let {
prevPage?.setContent(it.previousPage()?.text)
curPage?.setContent(it.currentPage()?.text)
nextPage?.setContent(it.nextPage()?.text)
}
}
override fun hasNext(): Boolean {

@ -0,0 +1,3 @@
package io.legado.app.ui.widget.page
class ScrollContentView

@ -22,12 +22,36 @@ class TextPageFactory private constructor(dataSource: DataSource) : PageFactory<
TODO("todo...")
}
override fun nextPage(): TextPage {
return TextPage(index.plus(1), "index:$index")
override fun moveToFirst() {
index = 0
}
override fun previousPage(): TextPage {
return TextPage(index.minus(1), "index:$index")
override fun moveToNext(): Boolean {
return if(hasNext()){
index = index.plus(1)
true
}else
false
}
override fun moveToPrevious(): Boolean {
return if(hasPrev()){
index = index.minus(1)
true
}else
false
}
override fun currentPage(): TextPage? {
return TextPage(index, "index:$index")
}
override fun nextPage(): TextPage? {
return TextPage(index + 1, "index:${index + 1}")
}
override fun previousPage(): TextPage? {
return TextPage(index - 1, "index:${index - 1}")
}

@ -24,7 +24,7 @@ class CoverPageDelegate(pageView: PageView) : PageDelegate(pageView) {
shadowDrawableL.gradientType = GradientDrawable.LINEAR_GRADIENT
}
override fun onStart() {
override fun onScrollStart() {
val distanceX: Float
when (direction) {
Direction.NEXT -> if (isCancel) {
@ -47,10 +47,18 @@ class CoverPageDelegate(pageView: PageView) : PageDelegate(pageView) {
start()
}
override fun onPerform(canvas: Canvas) {
override fun onScrollStop() {
if (!isCancel) {
pageView.fillPage(direction)
}
}
override fun onDraw(canvas: Canvas) {
val offsetX = touchX - startX
if(offsetX == 0.toFloat()) return
if ((direction == Direction.NEXT && offsetX > 0)
|| (direction == Direction.PREV && offsetX < 0)
) return
val distanceX = if (offsetX > 0) offsetX - viewWidth else offsetX + viewWidth
bitmap?.let {

@ -4,15 +4,14 @@ import android.graphics.Bitmap
import android.graphics.Canvas
import android.view.GestureDetector
import android.view.MotionEvent
import android.view.View
import android.widget.Scroller
import androidx.interpolator.view.animation.FastOutLinearInInterpolator
import io.legado.app.ui.widget.page.ContentView
import io.legado.app.ui.widget.page.PageView
import io.legado.app.utils.screenshot
import kotlinx.android.synthetic.main.view_book_page.view.*
import kotlin.math.abs
abstract class PageDelegate(private val pageView: PageView) {
abstract class PageDelegate(protected val pageView: PageView) {
//起始点
protected var startX: Float = 0.toFloat()
@ -21,8 +20,14 @@ abstract class PageDelegate(private val pageView: PageView) {
protected var touchX: Float = 0.toFloat()
protected var touchY: Float = 0.toFloat()
protected val view: View
get() = pageView.page_panel
protected val nextPage: ContentView?
get() = pageView.nextPage
protected val curPage: ContentView?
get() = pageView.curPage
protected val prevPage: ContentView?
get() = pageView.prevPage
protected var bitmap: Bitmap? = null
@ -58,6 +63,8 @@ abstract class PageDelegate(private val pageView: PageView) {
if (invalidate) {
invalidate()
}
onScroll()
}
fun setViewSize(width: Int, height: Int) {
@ -89,6 +96,7 @@ abstract class PageDelegate(private val pageView: PageView) {
} else if (isStarted) {
setTouchPoint(scroller.finalX.toFloat(), scroller.finalY.toFloat(), false)
stop()
onScrollStop()
}
}
@ -126,14 +134,16 @@ abstract class PageDelegate(private val pageView: PageView) {
return
}
}
onStart()
onScrollStart()
}
fun onTouch(event: MotionEvent): Boolean {
if (isStarted) return false
if (isMoved && event.action == MotionEvent.ACTION_UP) {
// 开启翻页效果
if (!noNext) {
onStart()
onScrollStart()
}
return true
}
@ -145,9 +155,15 @@ abstract class PageDelegate(private val pageView: PageView) {
return duration.toInt()
}
abstract fun onStart()
abstract fun onScrollStart()//scroller start
abstract fun onPerform(canvas: Canvas)
abstract fun onDraw(canvas: Canvas)//绘制
abstract fun onScrollStop()//scroller finish
open fun onScroll() {//移动contentView, slidePage
}
enum class Direction {
NONE, PREV, NEXT
@ -156,7 +172,7 @@ abstract class PageDelegate(private val pageView: PageView) {
private inner class GestureListener : GestureDetector.OnGestureListener {
override fun onDown(e: MotionEvent): Boolean {
abort()
// abort()
//是否移动
isMoved = false
//是否存在下一章
@ -185,21 +201,24 @@ abstract class PageDelegate(private val pageView: PageView) {
if (!hasNext) {
return true
}
//下一页截图
bitmap = nextPage?.screenshot()
} else {
val hasPrev = pageView.hasPrev()
if (!hasPrev) {
return true
}
//上一页截图
bitmap = prevPage?.screenshot()
}
setTouchPoint(x, y)
onScrollStart()
return true
}
override fun onScroll(e1: MotionEvent, e2: MotionEvent, distanceX: Float, distanceY: Float): Boolean {
if (!isMoved && abs(distanceX) > abs(distanceY)) {
//上一页或下一页截图,还未处理
if (distanceX < 0) {
bitmap = pageView.prevPage?.screenshot()
//上一页的参数配置
direction = Direction.PREV
//判断是否上一页存在
@ -209,8 +228,9 @@ abstract class PageDelegate(private val pageView: PageView) {
noNext = true
return true
}
//上一页截图
bitmap = prevPage?.screenshot()
} else {
bitmap = pageView.nextPage?.screenshot()
//进行下一页的配置
direction = Direction.NEXT
//判断是否下一页存在
@ -220,6 +240,8 @@ abstract class PageDelegate(private val pageView: PageView) {
noNext = true
return true
}
//下一页截图
bitmap = nextPage?.screenshot()
}
isMoved = true
}

@ -0,0 +1,22 @@
package io.legado.app.ui.widget.page.delegate
import android.graphics.Canvas
import io.legado.app.ui.widget.page.PageView
class SlidePageDelegate(pageView: PageView) : PageDelegate(pageView) {
override fun onScrollStart() {
}
override fun onDraw(canvas: Canvas) {
}
override fun onScroll() {
}
override fun onScrollStop() {
}
}

@ -4,7 +4,6 @@
android:id="@+id/page_panel"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/background"
android:orientation="vertical"
app:divider="@drawable/ic_divider"
app:showDividers="middle">

Loading…
Cancel
Save