feat: 优化代码

pull/103/head
kunfei 5 years ago
parent 81e6931668
commit 7ae49cc342
  1. 58
      app/src/main/java/io/legado/app/ui/book/read/page/PageView.kt
  2. 4
      app/src/main/java/io/legado/app/ui/book/read/page/delegate/CoverPageDelegate.kt
  3. 8
      app/src/main/java/io/legado/app/ui/book/read/page/delegate/HorizontalPageDelegate.kt
  4. 18
      app/src/main/java/io/legado/app/ui/book/read/page/delegate/PageDelegate.kt
  5. 12
      app/src/main/java/io/legado/app/ui/book/read/page/delegate/ScrollPageDelegate.kt
  6. 4
      app/src/main/java/io/legado/app/ui/book/read/page/delegate/SimulationPageDelegate.kt
  7. 4
      app/src/main/java/io/legado/app/ui/book/read/page/delegate/SlidePageDelegate.kt
  8. 863
      app/src/main/java/io/legado/app/ui/book/read/page/delegate/TestDelegate.kt

@ -22,9 +22,9 @@ class PageView(context: Context, attrs: AttributeSet) :
var pageFactory: TextPageFactory? = null var pageFactory: TextPageFactory? = null
private var pageDelegate: PageDelegate? = null private var pageDelegate: PageDelegate? = null
var prevPage: ContentView? = null var prevPage: ContentView
var curPage: ContentView? = null var curPage: ContentView
var nextPage: ContentView? = null var nextPage: ContentView
init { init {
callBack = activity as? CallBack callBack = activity as? CallBack
@ -38,7 +38,7 @@ class PageView(context: Context, attrs: AttributeSet) :
setWillNotDraw(false) setWillNotDraw(false)
pageFactory = TextPageFactory(this) pageFactory = TextPageFactory(this)
upPageAnim(context.getPrefInt(PreferKey.pageAnim)) upPageAnim(context.getPrefInt(PreferKey.pageAnim))
curPage?.callBack = this curPage.callBack = this
} }
override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) { override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
@ -75,14 +75,14 @@ class PageView(context: Context, attrs: AttributeSet) :
pageFactory?.moveToPrevious() pageFactory?.moveToPrevious()
upContent() upContent()
if (isScrollDelegate) { if (isScrollDelegate) {
curPage?.scrollToBottom() curPage.scrollToBottom()
} }
} }
PageDelegate.Direction.NEXT -> { PageDelegate.Direction.NEXT -> {
pageFactory?.moveToNext() pageFactory?.moveToNext()
upContent() upContent()
if (isScrollDelegate) { if (isScrollDelegate) {
curPage?.scrollTo(0) curPage.scrollTo(0)
} }
} }
else -> Unit else -> Unit
@ -105,19 +105,19 @@ class PageView(context: Context, attrs: AttributeSet) :
fun upContent(position: Int = 0) { fun upContent(position: Int = 0) {
pageFactory?.let { pageFactory?.let {
when (position) { when (position) {
-1 -> prevPage?.setContent(it.previousPage()) -1 -> prevPage.setContent(it.previousPage())
1 -> nextPage?.setContent(it.nextPage()) 1 -> nextPage.setContent(it.nextPage())
else -> { else -> {
curPage?.setContent(it.currentPage()) curPage.setContent(it.currentPage())
nextPage?.setContent(it.nextPage()) nextPage.setContent(it.nextPage())
prevPage?.setContent(it.previousPage()) prevPage.setContent(it.previousPage())
if (isScrollDelegate) { if (isScrollDelegate) {
curPage?.scrollTo(ReadBook.textChapter()?.getStartLine(ReadBook.durChapterPos())) curPage.scrollTo(ReadBook.textChapter()?.getStartLine(ReadBook.durChapterPos()))
} }
} }
} }
if (isScrollDelegate) { if (isScrollDelegate) {
prevPage?.scrollToBottom() prevPage.scrollToBottom()
} }
} }
callBack?.screenOffTimerStart() callBack?.screenOffTimerStart()
@ -127,7 +127,7 @@ class PageView(context: Context, attrs: AttributeSet) :
if (noAnim) { if (noAnim) {
if (isScrollDelegate) { if (isScrollDelegate) {
ReadBook.textChapter()?.let { ReadBook.textChapter()?.let {
curPage?.scrollTo(it.getStartLine(pageIndex - 1)) curPage.scrollTo(it.getStartLine(pageIndex - 1))
} }
} else { } else {
fillPage(PageDelegate.Direction.PREV) fillPage(PageDelegate.Direction.PREV)
@ -139,7 +139,7 @@ class PageView(context: Context, attrs: AttributeSet) :
if (noAnim) { if (noAnim) {
if (isScrollDelegate) { if (isScrollDelegate) {
ReadBook.textChapter()?.let { ReadBook.textChapter()?.let {
curPage?.scrollTo(it.getStartLine(pageIndex + 1)) curPage.scrollTo(it.getStartLine(pageIndex + 1))
} }
} else { } else {
fillPage(PageDelegate.Direction.NEXT) fillPage(PageDelegate.Direction.NEXT)
@ -148,30 +148,30 @@ class PageView(context: Context, attrs: AttributeSet) :
} }
fun upStyle() { fun upStyle() {
curPage?.upStyle() curPage.upStyle()
prevPage?.upStyle() prevPage.upStyle()
nextPage?.upStyle() nextPage.upStyle()
} }
fun upBg() { fun upBg() {
ReadBookConfig.bg ?: let { ReadBookConfig.bg ?: let {
ReadBookConfig.upBg() ReadBookConfig.upBg()
} }
curPage?.setBg(ReadBookConfig.bg) curPage.setBg(ReadBookConfig.bg)
prevPage?.setBg(ReadBookConfig.bg) prevPage.setBg(ReadBookConfig.bg)
nextPage?.setBg(ReadBookConfig.bg) nextPage.setBg(ReadBookConfig.bg)
} }
fun upTime() { fun upTime() {
curPage?.upTime() curPage.upTime()
prevPage?.upTime() prevPage.upTime()
nextPage?.upTime() nextPage.upTime()
} }
fun upBattery(battery: Int) { fun upBattery(battery: Int) {
curPage?.upBattery(battery) curPage.upBattery(battery)
prevPage?.upBattery(battery) prevPage.upBattery(battery)
nextPage?.upBattery(battery) nextPage.upBattery(battery)
} }
fun upSelectAble() { fun upSelectAble() {
@ -219,7 +219,7 @@ class PageView(context: Context, attrs: AttributeSet) :
if (isScrollDelegate) { if (isScrollDelegate) {
ReadBook.textChapter()?.let { ReadBook.textChapter()?.let {
val pageIndex = it.getPageIndex(line) val pageIndex = it.getPageIndex(line)
curPage?.setPageIndex(pageIndex) curPage.setPageIndex(pageIndex)
callBack?.setPageIndex(pageIndex) callBack?.setPageIndex(pageIndex)
} }
} }
@ -229,7 +229,7 @@ class PageView(context: Context, attrs: AttributeSet) :
if (isScrollDelegate) { if (isScrollDelegate) {
ReadBook.textChapter()?.let { ReadBook.textChapter()?.let {
callBack?.setPageIndex(it.lastIndex()) callBack?.setPageIndex(it.lastIndex())
curPage?.setPageIndex(it.lastIndex()) curPage.setPageIndex(it.lastIndex())
} }
} }
} }

@ -43,7 +43,7 @@ class CoverPageDelegate(pageView: PageView) : HorizontalPageDelegate(pageView) {
} }
override fun onScrollStop() { override fun onScrollStop() {
curPage?.x = 0.toFloat() curPage.x = 0.toFloat()
if (!isCancel) { if (!isCancel) {
pageView.fillPage(direction) pageView.fillPage(direction)
} }
@ -62,7 +62,7 @@ class CoverPageDelegate(pageView: PageView) : HorizontalPageDelegate(pageView) {
bitmapMatrix.setTranslate(distanceX, 0.toFloat()) bitmapMatrix.setTranslate(distanceX, 0.toFloat())
canvas.drawBitmap(it, bitmapMatrix, null) canvas.drawBitmap(it, bitmapMatrix, null)
} else if (direction == Direction.NEXT) { } else if (direction == Direction.NEXT) {
curPage?.translationX = offsetX curPage.translationX = offsetX
} }
addShadow(distanceX.toInt(), canvas) addShadow(distanceX.toInt(), canvas)
} }

@ -17,7 +17,7 @@ abstract class HorizontalPageDelegate(pageView: PageView) : PageDelegate(pageVie
): Boolean { ): Boolean {
if (!isMoved) { if (!isMoved) {
val event = e1.toAction(MotionEvent.ACTION_UP) val event = e1.toAction(MotionEvent.ACTION_UP)
curPage?.dispatchTouchEvent(event) curPage.dispatchTouchEvent(event)
event.recycle() event.recycle()
if (abs(distanceX) > abs(distanceY)) { if (abs(distanceX) > abs(distanceY)) {
if (distanceX < 0) { if (distanceX < 0) {
@ -27,7 +27,7 @@ abstract class HorizontalPageDelegate(pageView: PageView) : PageDelegate(pageVie
return true return true
} }
//上一页截图 //上一页截图
bitmap = prevPage?.screenshot() bitmap = prevPage.screenshot()
} else { } else {
//如果不存在表示没有下一页了 //如果不存在表示没有下一页了
if (!hasNext()) { if (!hasNext()) {
@ -35,7 +35,7 @@ abstract class HorizontalPageDelegate(pageView: PageView) : PageDelegate(pageVie
return true return true
} }
//下一页截图 //下一页截图
bitmap = nextPage?.screenshot() bitmap = nextPage.screenshot()
} }
isMoved = true isMoved = true
} }
@ -50,7 +50,7 @@ abstract class HorizontalPageDelegate(pageView: PageView) : PageDelegate(pageVie
} }
override fun upSelectAble() { override fun upSelectAble() {
pageView.curPage?.contentTextView()?.apply { pageView.curPage.contentTextView()?.apply {
if (context.getPrefBoolean(PreferKey.selectText)) { if (context.getPrefBoolean(PreferKey.selectText)) {
setTextIsSelectable(true) setTextIsSelectable(true)
} else { } else {

@ -30,13 +30,13 @@ abstract class PageDelegate(protected val pageView: PageView) {
protected var touchX: Float = 0.toFloat() protected var touchX: Float = 0.toFloat()
protected var touchY: Float = 0.toFloat() protected var touchY: Float = 0.toFloat()
protected val nextPage: ContentView? protected val nextPage: ContentView
get() = pageView.nextPage get() = pageView.nextPage
protected val curPage: ContentView? protected val curPage: ContentView
get() = pageView.curPage get() = pageView.curPage
protected val prevPage: ContentView? protected val prevPage: ContentView
get() = pageView.prevPage get() = pageView.prevPage
protected var bitmap: Bitmap? = null protected var bitmap: Bitmap? = null
@ -184,12 +184,12 @@ abstract class PageDelegate(protected val pageView: PageView) {
@CallSuper @CallSuper
open fun onTouch(event: MotionEvent): Boolean { open fun onTouch(event: MotionEvent): Boolean {
if (isStarted) return false if (isStarted) return false
if (curPage?.isTextSelected() == true) { if (curPage.isTextSelected()) {
curPage?.dispatchTouchEvent(event) curPage.dispatchTouchEvent(event)
return true return true
} }
if (event.action == MotionEvent.ACTION_DOWN) { if (event.action == MotionEvent.ACTION_DOWN) {
curPage?.let { curPage.let {
it.contentTextView()?.let { contentTextView -> it.contentTextView()?.let { contentTextView ->
atTop = contentTextView.atTop() atTop = contentTextView.atTop()
atBottom = contentTextView.atBottom() atBottom = contentTextView.atBottom()
@ -197,7 +197,7 @@ abstract class PageDelegate(protected val pageView: PageView) {
it.dispatchTouchEvent(event) it.dispatchTouchEvent(event)
} }
} else if (event.action == MotionEvent.ACTION_UP) { } else if (event.action == MotionEvent.ACTION_UP) {
curPage?.dispatchTouchEvent(event) curPage.dispatchTouchEvent(event)
if (isMoved) { if (isMoved) {
// 开启翻页效果 // 开启翻页效果
if (!noNext) onScrollStart() if (!noNext) onScrollStart()
@ -266,13 +266,13 @@ abstract class PageDelegate(protected val pageView: PageView) {
return true return true
} }
//下一页截图 //下一页截图
nextPage?.screenshot() nextPage.screenshot()
} else { } else {
if (!hasPrev()) { if (!hasPrev()) {
return true return true
} }
//上一页截图 //上一页截图
prevPage?.screenshot() prevPage.screenshot()
} }
setTouchPoint(x, y) setTouchPoint(x, y)
onScrollStart() onScrollStart()

@ -81,7 +81,7 @@ class ScrollPageDelegate(pageView: PageView) : PageDelegate(pageView) {
if (distanceY < 0) { if (distanceY < 0) {
if (atTop) { if (atTop) {
val event = e1.toAction(MotionEvent.ACTION_UP) val event = e1.toAction(MotionEvent.ACTION_UP)
curPage?.dispatchTouchEvent(event) curPage.dispatchTouchEvent(event)
event.recycle() event.recycle()
//如果上一页不存在 //如果上一页不存在
if (!hasPrev()) { if (!hasPrev()) {
@ -89,12 +89,12 @@ class ScrollPageDelegate(pageView: PageView) : PageDelegate(pageView) {
return true return true
} }
//上一页截图 //上一页截图
bitmap = prevPage?.screenshot() bitmap = prevPage.screenshot()
} }
} else { } else {
if (atBottom) { if (atBottom) {
val event = e1.toAction(MotionEvent.ACTION_UP) val event = e1.toAction(MotionEvent.ACTION_UP)
curPage?.dispatchTouchEvent(event) curPage.dispatchTouchEvent(event)
event.recycle() event.recycle()
//如果不存在表示没有下一页了 //如果不存在表示没有下一页了
if (!hasNext()) { if (!hasNext()) {
@ -102,14 +102,14 @@ class ScrollPageDelegate(pageView: PageView) : PageDelegate(pageView) {
return true return true
} }
//下一页截图 //下一页截图
bitmap = nextPage?.screenshot() bitmap = nextPage.screenshot()
} }
} }
isMoved = true isMoved = true
} }
if ((atTop && direction != Direction.PREV) || (atBottom && direction != Direction.NEXT) || direction == Direction.NONE) { if ((atTop && direction != Direction.PREV) || (atBottom && direction != Direction.NEXT) || direction == Direction.NONE) {
//传递触摸事件到textView //传递触摸事件到textView
curPage?.dispatchTouchEvent(e2) curPage.dispatchTouchEvent(e2)
} }
if (isMoved) { if (isMoved) {
isCancel = if (direction == Direction.NEXT) distanceY < 0 else distanceY > 0 isCancel = if (direction == Direction.NEXT) distanceY < 0 else distanceY > 0
@ -121,7 +121,7 @@ class ScrollPageDelegate(pageView: PageView) : PageDelegate(pageView) {
} }
override fun upSelectAble() { override fun upSelectAble() {
pageView.curPage?.contentTextView()?.apply { pageView.curPage.contentTextView()?.apply {
if (context.getPrefBoolean(PreferKey.selectText)) { if (context.getPrefBoolean(PreferKey.selectText)) {
setTextIsSelectable(true) setTextIsSelectable(true)
} else { } else {

@ -4,6 +4,7 @@ import android.graphics.*
import android.graphics.drawable.GradientDrawable import android.graphics.drawable.GradientDrawable
import android.os.Build import android.os.Build
import io.legado.app.ui.book.read.page.PageView import io.legado.app.ui.book.read.page.PageView
import io.legado.app.utils.screenshot
import kotlin.math.* import kotlin.math.*
class SimulationPageDelegate(pageView: PageView) : HorizontalPageDelegate(pageView) { class SimulationPageDelegate(pageView: PageView) : HorizontalPageDelegate(pageView) {
@ -57,6 +58,9 @@ class SimulationPageDelegate(pageView: PageView) : HorizontalPageDelegate(pageVi
private val mPaint: Paint = Paint() private val mPaint: Paint = Paint()
private var curBitmap: Bitmap? = curPage.screenshot()
init { init {
mMaxLength = hypot(pageView.width.toDouble(), pageView.height.toDouble()).toFloat() mMaxLength = hypot(pageView.width.toDouble(), pageView.height.toDouble()).toFloat()
mPaint.style = Paint.Style.FILL mPaint.style = Paint.Style.FILL

@ -53,11 +53,11 @@ class SlidePageDelegate(pageView: PageView) : HorizontalPageDelegate(pageView) {
|| (direction == Direction.PREV && offsetX < 0) || (direction == Direction.PREV && offsetX < 0)
) return ) return
curPage?.translationX = offsetX curPage.translationX = offsetX
} }
override fun onScrollStop() { override fun onScrollStop() {
curPage?.x = 0.toFloat() curPage.x = 0.toFloat()
if (!isCancel) { if (!isCancel) {
pageView.fillPage(direction) pageView.fillPage(direction)

@ -1,863 +0,0 @@
package io.legado.app.ui.book.read.page.delegate
import android.graphics.*
import android.graphics.drawable.GradientDrawable
import android.os.Trace
import android.view.MotionEvent
import io.legado.app.ui.book.read.page.PageView
import io.legado.app.utils.screenshot
import kotlin.math.hypot
class TestDelegate(pageView: PageView) : HorizontalPageDelegate(pageView) {
private var pointPaint //绘制各标识点的画笔
: Paint? = null
private var bgPaint //背景画笔
: Paint? = null
private var pathAPaint //绘制A区域画笔
: Paint? = null
private var pathBPaint //绘制B区域画笔
: Paint? = null
private var pathCPaint //绘制C区域画笔
: Paint? = null
private var textPaint //绘制文字画笔
: Paint? = null
private var pathCContentPaint //绘制C区域内容画笔
: Paint? = null
private var a: MyPoint? = null
private var f: MyPoint? = null
private var g: MyPoint? = null
private var e: MyPoint? = null
private var h: MyPoint? = null
private var c: MyPoint? = null
private var j: MyPoint? = null
private var b: MyPoint? = null
private var k: MyPoint? = null
private var d: MyPoint? = null
private var i: MyPoint? = null
private var pathA: Path? = null
private var pathB: Path? = null
private var pathC: Path? = null
private var defaultWidth = 0 //默认宽度 = 0
private var defaultHeight = 0 //默认高度 = 0
var lPathAShadowDis = 0f //A区域左阴影矩形短边长度参考值
var rPathAShadowDis = 0f //A区域右阴影矩形短边长度参考值
private val mMatrixArray = floatArrayOf(0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 1.0f)
private var mMatrix: Matrix? = null
private var style: String? = null
private var drawableLeftTopRight: GradientDrawable? = null
private var drawableLeftLowerRight: GradientDrawable? = null
private var drawableRightTopRight: GradientDrawable? = null
private var drawableRightLowerRight: GradientDrawable? = null
private var drawableHorizontalLowerRight: GradientDrawable? = null
private var drawableBTopRight: GradientDrawable? = null
private var drawableBLowerRight: GradientDrawable? = null
private var drawableCTopRight: GradientDrawable? = null
private var drawableCLowerRight: GradientDrawable? = null
private val pathAContentBitmap
get() = pageView.prevPage?.screenshot()
private val pathBContentBitmap //B区域内容Bitmap
get() = pageView.curPage?.screenshot()
private val pathCContentBitmap //C区域内容Bitmap
get() = pageView.nextPage?.screenshot()
init {
defaultWidth = 600
defaultHeight = 1000
a = MyPoint()
f = MyPoint()
g = MyPoint()
e = MyPoint()
h = MyPoint()
c = MyPoint()
j = MyPoint()
b = MyPoint()
k = MyPoint()
d = MyPoint()
i = MyPoint()
pointPaint = Paint()
pointPaint!!.color = Color.RED
pointPaint!!.textSize = 25f
pointPaint!!.style = Paint.Style.STROKE
bgPaint = Paint()
bgPaint!!.color = Color.GREEN
pathAPaint = Paint()
pathAPaint!!.color = Color.GREEN
pathAPaint!!.isAntiAlias = true //设置抗锯齿
pathBPaint = Paint()
pathBPaint!!.color = Color.GREEN
pathBPaint!!.isAntiAlias = true //设置抗锯齿
// pathBPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_ATOP));我们不需要单独绘制path了,记得注释掉
pathCPaint = Paint()
pathCPaint!!.color = Color.YELLOW
pathCPaint!!.isAntiAlias = true //设置抗锯齿
// pathCPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_ATOP));
// pathCPaint.setStyle(Paint.Style.STROKE);
pathCContentPaint = Paint()
pathCContentPaint!!.color = Color.YELLOW
pathCContentPaint!!.isAntiAlias = true //设置抗锯齿
textPaint = Paint()
textPaint!!.color = Color.BLACK
textPaint!!.textAlign = Paint.Align.CENTER
textPaint!!.isSubpixelText = true //设置自像素。如果该项为true,将有助于文本在LCD屏幕上的显示效果。
textPaint!!.textSize = 30f
pathA = Path()
pathB = Path()
pathC = Path()
style = STYLE_LOWER_RIGHT
mMatrix = Matrix()
createGradientDrawable()
}
private fun drawPathAContentBitmap(
bitmap: Bitmap?,
pathPaint: Paint?
) {
val mCanvas = Canvas(bitmap!!)
//下面开始绘制区域内的内容...
mCanvas.drawPath(pathDefault!!, pathPaint!!)
mCanvas.drawText(
"这是在A区域的内容...AAAA",
viewWidth - 260.toFloat(),
viewHeight - 100.toFloat(),
textPaint!!
)
//结束绘制区域内的内容...
}
private fun drawPathBContentBitmap(
bitmap: Bitmap?,
pathPaint: Paint?
) {
val mCanvas = Canvas(bitmap!!)
//下面开始绘制区域内的内容...
mCanvas.drawPath(pathDefault!!, pathPaint!!)
mCanvas.drawText(
"这是在B区域的内容...BBBB",
viewWidth - 260.toFloat(),
viewHeight - 100.toFloat(),
textPaint!!
)
//结束绘制区域内的内容...
}
override fun onDraw(canvas: Canvas) {
canvas.drawColor(Color.YELLOW)
if (a!!.x == -1f && a!!.y == -1f) {
drawPathAContent(canvas, pathDefault)
} else {
if (f!!.x == viewWidth.toFloat() && f!!.y == 0f) {
drawPathAContent(canvas, pathAFromTopRight)
drawPathCContent(canvas, pathAFromTopRight)
drawPathBContent(canvas, pathAFromTopRight)
} else if (f!!.x == viewWidth.toFloat() && f!!.y == viewHeight.toFloat()) {
beginTrace("drawPathA")
drawPathAContent(canvas, pathAFromLowerRight)
endTrace()
beginTrace("drawPathC")
drawPathCContent(canvas, pathAFromLowerRight)
endTrace()
beginTrace("drawPathB")
drawPathBContent(canvas, pathAFromLowerRight)
endTrace()
}
}
}
private fun beginTrace(tag: String) {
Trace.beginSection(tag)
}
private fun endTrace() {
Trace.endSection()
}
override fun onScroll() {
if (style == STYLE_TOP_RIGHT) {
setTouchPoint(touchX, touchY, STYLE_TOP_RIGHT)
} else {
setTouchPoint(touchX, touchY, STYLE_LOWER_RIGHT)
}
}
override fun onTouch(event: MotionEvent): Boolean {
when (event.action) {
MotionEvent.ACTION_DOWN -> {
val x: Float = event.x
val y: Float = event.y
if (x <= viewWidth / 3) { //左
style = STYLE_LEFT
setTouchPoint(x, y, style)
} else if (x > viewWidth / 3 && y <= viewHeight / 3) { //上
style = STYLE_TOP_RIGHT
setTouchPoint(x, y, style)
} else if (x > viewWidth * 2 / 3 && y > viewHeight / 3 && y <= viewHeight * 2 / 3) { //右
style = STYLE_RIGHT
setTouchPoint(x, y, style)
} else if (x > viewWidth / 3 && y > viewHeight * 2 / 3) { //下
style = STYLE_LOWER_RIGHT
setTouchPoint(x, y, style)
} else if (x > viewWidth / 3 && x < viewWidth * 2 / 3 && y > viewHeight / 3 && y < viewHeight * 2 / 3) { //中
style = STYLE_MIDDLE
}
}
MotionEvent.ACTION_MOVE -> setTouchPoint(event.x, event.y, style)
MotionEvent.ACTION_UP -> startCancelAnim()
}
return super.onTouch(event)
}
/**
* 取消翻页动画,计算滑动位置与时间
*/
fun startCancelAnim() {
val dx: Int
val dy: Int
//让a滑动到f点所在位置,留出1像素是为了防止当a和f重叠时出现View闪烁的情况
if (style == STYLE_TOP_RIGHT) {
dx = (viewWidth - 1 - a!!.x).toInt()
dy = (1 - a!!.y).toInt()
} else {
dx = (viewWidth - 1 - a!!.x).toInt()
dy = (viewHeight - 1 - a!!.y).toInt()
}
}
override fun onScrollStart() {
val distanceX: Float
when (direction) {
Direction.NEXT -> distanceX =
if (isCancel) {
var dis = viewWidth - startX + touchX
if (dis > viewWidth) {
dis = viewWidth.toFloat()
}
viewWidth - dis
} else {
-(touchX + (viewWidth - startX))
}
else -> distanceX =
if (isCancel) {
-(touchX - startX)
} else {
viewWidth - (touchX - startX)
}
}
startScroll(touchX.toInt(), 0, distanceX.toInt(), 0)
}
override fun onScrollStop() {
}
/**
* 设置触摸点
* @param x
* @param y
* @param style
*/
fun setTouchPoint(x: Float, y: Float, style: String?) {
val touchPoint: MyPoint
a!!.x = x
a!!.y = y
this.style = style
when (style) {
STYLE_TOP_RIGHT -> {
f!!.x = viewWidth.toFloat()
f!!.y = 0f
calcPointsXY(a, f)
touchPoint = MyPoint(x, y)
if (calcPointCX(touchPoint, f) < 0) { //如果c点x坐标小于0则重新测量a点坐标
calcPointAByTouchPoint()
calcPointsXY(a, f)
}
pageView.postInvalidate()
}
STYLE_LEFT, STYLE_RIGHT -> {
a!!.y = viewHeight - 1.toFloat()
f!!.x = viewWidth.toFloat()
f!!.y = viewHeight.toFloat()
calcPointsXY(a, f)
pageView.postInvalidate()
}
STYLE_LOWER_RIGHT -> {
f!!.x = viewWidth.toFloat()
f!!.y = viewHeight.toFloat()
calcPointsXY(a, f)
touchPoint = MyPoint(x, y)
if (calcPointCX(touchPoint, f) < 0) { //如果c点x坐标小于0则重新测量a点坐标
calcPointAByTouchPoint()
calcPointsXY(a, f)
}
pageView.postInvalidate()
}
else -> {
}
}
}
/**
* 如果c点x坐标小于0,根据触摸点重新测量a点坐标
*/
private fun calcPointAByTouchPoint() {
val w0 = viewWidth - c!!.x
val w1 = Math.abs(f!!.x - a!!.x)
val w2 = viewWidth * w1 / w0
a!!.x = Math.abs(f!!.x - w2)
val h1 = Math.abs(f!!.y - a!!.y)
val h2 = w2 * h1 / w1
a!!.y = Math.abs(f!!.y - h2)
}
/**
* 回到默认状态
*/
fun setDefaultPath() {
a!!.x = -1f
a!!.y = -1f
pageView.postInvalidate()
}
/**
* 初始化各区域阴影GradientDrawable
*/
private fun createGradientDrawable() {
var deepColor = 0x33333333
var lightColor = 0x01333333
var gradientColors = intArrayOf(lightColor, deepColor) //渐变颜色数组
drawableLeftTopRight =
GradientDrawable(GradientDrawable.Orientation.LEFT_RIGHT, gradientColors)
drawableLeftTopRight!!.gradientType = GradientDrawable.LINEAR_GRADIENT
drawableLeftLowerRight =
GradientDrawable(GradientDrawable.Orientation.RIGHT_LEFT, gradientColors)
drawableLeftLowerRight!!.gradientType = GradientDrawable.LINEAR_GRADIENT
deepColor = 0x22333333
lightColor = 0x01333333
gradientColors = intArrayOf(deepColor, lightColor, lightColor)
drawableRightTopRight =
GradientDrawable(GradientDrawable.Orientation.BOTTOM_TOP, gradientColors)
drawableRightTopRight!!.gradientType = GradientDrawable.LINEAR_GRADIENT
drawableRightLowerRight =
GradientDrawable(GradientDrawable.Orientation.TOP_BOTTOM, gradientColors)
drawableRightLowerRight!!.gradientType = GradientDrawable.LINEAR_GRADIENT
deepColor = 0x44333333
lightColor = 0x01333333
gradientColors = intArrayOf(lightColor, deepColor) //渐变颜色数组
drawableHorizontalLowerRight =
GradientDrawable(GradientDrawable.Orientation.LEFT_RIGHT, gradientColors)
drawableHorizontalLowerRight!!.gradientType = GradientDrawable.LINEAR_GRADIENT
deepColor = 0x55111111
lightColor = 0x00111111
gradientColors = intArrayOf(deepColor, lightColor) //渐变颜色数组
drawableBTopRight =
GradientDrawable(GradientDrawable.Orientation.LEFT_RIGHT, gradientColors)
drawableBTopRight!!.gradientType = GradientDrawable.LINEAR_GRADIENT //线性渐变
drawableBLowerRight =
GradientDrawable(GradientDrawable.Orientation.RIGHT_LEFT, gradientColors)
drawableBLowerRight!!.gradientType = GradientDrawable.LINEAR_GRADIENT
deepColor = 0x55333333
lightColor = 0x00333333
gradientColors = intArrayOf(lightColor, deepColor) //渐变颜色数组
drawableCTopRight =
GradientDrawable(GradientDrawable.Orientation.LEFT_RIGHT, gradientColors)
drawableCTopRight!!.gradientType = GradientDrawable.LINEAR_GRADIENT
drawableCLowerRight =
GradientDrawable(GradientDrawable.Orientation.RIGHT_LEFT, gradientColors)
drawableCLowerRight!!.gradientType = GradientDrawable.LINEAR_GRADIENT
}
/**
* 绘制A区域内容
* @param canvas
* @param pathA
*/
private fun drawPathAContent(
canvas: Canvas,
pathA: Path?
) {
canvas.save()
canvas.clipPath(pathA!!, Region.Op.INTERSECT) //对绘制内容进行裁剪,取和A区域的交集
canvas.drawBitmap(pathAContentBitmap!!, 0f, 0f, null)
if (style == STYLE_LEFT || style == STYLE_RIGHT) {
drawPathAHorizontalShadow(canvas, pathA)
} else {
drawPathALeftShadow(canvas, pathA)
drawPathARightShadow(canvas, pathA)
}
canvas.restore()
}
/**
* 绘制A区域左阴影
* @param canvas
*/
private fun drawPathALeftShadow(
canvas: Canvas,
pathA: Path?
) {
canvas.restore()
canvas.save()
val left: Int
val right: Int
val top = e!!.y.toInt()
val bottom = (e!!.y + viewHeight).toInt()
val gradientDrawable: GradientDrawable?
if (style == STYLE_TOP_RIGHT) {
gradientDrawable = drawableLeftTopRight
left = (e!!.x - lPathAShadowDis / 2).toInt()
right = e!!.x.toInt()
} else {
gradientDrawable = drawableLeftLowerRight
left = e!!.x.toInt()
right = (e!!.x + lPathAShadowDis / 2).toInt()
}
val mPath = Path()
mPath.moveTo(a!!.x - Math.max(rPathAShadowDis, lPathAShadowDis) / 2, a!!.y)
mPath.lineTo(d!!.x, d!!.y)
mPath.lineTo(e!!.x, e!!.y)
mPath.lineTo(a!!.x, a!!.y)
mPath.close()
canvas.clipPath(pathA!!)
canvas.clipPath(mPath, Region.Op.INTERSECT)
val mDegrees = Math.toDegrees(
Math.atan2(
e!!.x - a!!.x.toDouble(),
a!!.y - e!!.y.toDouble()
)
).toFloat()
canvas.rotate(mDegrees, e!!.x, e!!.y)
gradientDrawable!!.setBounds(left, top, right, bottom)
gradientDrawable.draw(canvas)
}
/**
* 绘制A区域右阴影
* @param canvas
*/
private fun drawPathARightShadow(
canvas: Canvas,
pathA: Path?
) {
canvas.restore()
canvas.save()
val viewDiagonalLength = Math.hypot(
viewWidth.toDouble(),
viewHeight.toDouble()
).toFloat() //view对角线长度
val left = h!!.x.toInt()
val right = (h!!.x + viewDiagonalLength * 10).toInt() //需要足够长的长度
val top: Int
val bottom: Int
val gradientDrawable: GradientDrawable?
if (style == STYLE_TOP_RIGHT) {
gradientDrawable = drawableRightTopRight
top = (h!!.y - rPathAShadowDis / 2).toInt()
bottom = h!!.y.toInt()
} else {
gradientDrawable = drawableRightLowerRight
top = h!!.y.toInt()
bottom = (h!!.y + rPathAShadowDis / 2).toInt()
}
gradientDrawable!!.setBounds(left, top, right, bottom)
val mPath = Path()
mPath.moveTo(a!!.x - Math.max(rPathAShadowDis, lPathAShadowDis) / 2, a!!.y)
// mPath.lineTo(i.x,i.y);
mPath.lineTo(h!!.x, h!!.y)
mPath.lineTo(a!!.x, a!!.y)
mPath.close()
canvas.clipPath(pathA!!)
canvas.clipPath(mPath, Region.Op.INTERSECT)
val mDegrees = Math.toDegrees(
Math.atan2(
a!!.y - h!!.y.toDouble(),
a!!.x - h!!.x.toDouble()
)
).toFloat()
canvas.rotate(mDegrees, h!!.x, h!!.y)
gradientDrawable.draw(canvas)
}
/**
* 绘制A区域水平翻页阴影
* @param canvas
*/
private fun drawPathAHorizontalShadow(
canvas: Canvas,
pathA: Path?
) {
canvas.restore()
canvas.save()
canvas.clipPath(pathA!!, Region.Op.INTERSECT)
val maxShadowWidth = 30 //阴影矩形最大的宽度
val left =
(a!!.x - Math.min(maxShadowWidth.toFloat(), rPathAShadowDis / 2)).toInt()
val right = a!!.x.toInt()
val top = 0
val bottom = viewHeight
val gradientDrawable = drawableHorizontalLowerRight
gradientDrawable!!.setBounds(left, top, right, bottom)
val mDegrees = Math.toDegrees(
Math.atan2(
f!!.x - a!!.x.toDouble(),
f!!.y - h!!.y.toDouble()
)
).toFloat()
canvas.rotate(mDegrees, a!!.x, a!!.y)
gradientDrawable.draw(canvas)
}
/**
* 绘制默认的界面
* @return
*/
private val pathDefault: Path?
private get() {
pathA!!.reset()
pathA!!.lineTo(0f, viewHeight.toFloat())
pathA!!.lineTo(viewWidth.toFloat(), viewHeight.toFloat())
pathA!!.lineTo(viewWidth.toFloat(), 0f)
pathA!!.close()
return pathA
}//移动到c点
//从c到b画贝塞尔曲线,控制点为e
//移动到a点
//移动到k点
//从k到j画贝塞尔曲线,控制点为h
//移动到右下角
//移动到左下角
/**
* 获取f点在右上角的pathA
* @return
*/
private val pathAFromTopRight: Path?
private get() {
pathA!!.reset()
pathA!!.lineTo(c!!.x, c!!.y) //移动到c点
pathA!!.quadTo(e!!.x, e!!.y, b!!.x, b!!.y) //从c到b画贝塞尔曲线,控制点为e
pathA!!.lineTo(a!!.x, a!!.y) //移动到a点
pathA!!.lineTo(k!!.x, k!!.y) //移动到k点
pathA!!.quadTo(h!!.x, h!!.y, j!!.x, j!!.y) //从k到j画贝塞尔曲线,控制点为h
pathA!!.lineTo(viewWidth.toFloat(), viewHeight.toFloat()) //移动到右下角
pathA!!.lineTo(0f, viewHeight.toFloat()) //移动到左下角
pathA!!.close()
return pathA
}//移动到左下角
//移动到c点
//从c到b画贝塞尔曲线,控制点为e
//移动到a点
//移动到k点
//从k到j画贝塞尔曲线,控制点为h
//移动到右上角
//闭合区域
/**
* 获取f点在右下角的pathA
* @return
*/
private val pathAFromLowerRight: Path?
private get() {
pathA!!.reset()
pathA!!.lineTo(0f, viewHeight.toFloat()) //移动到左下角
pathA!!.lineTo(c!!.x, c!!.y) //移动到c点
pathA!!.quadTo(e!!.x, e!!.y, b!!.x, b!!.y) //从c到b画贝塞尔曲线,控制点为e
pathA!!.lineTo(a!!.x, a!!.y) //移动到a点
pathA!!.lineTo(k!!.x, k!!.y) //移动到k点
pathA!!.quadTo(h!!.x, h!!.y, j!!.x, j!!.y) //从k到j画贝塞尔曲线,控制点为h
pathA!!.lineTo(viewWidth.toFloat(), 0f) //移动到右上角
pathA!!.close() //闭合区域
return pathA
}
/**
* 绘制B区域内容
* @param canvas
* @param pathA
*/
private fun drawPathBContent(
canvas: Canvas,
pathA: Path?
) {
canvas.save()
canvas.clipPath(pathA!!) //裁剪出A区域
canvas.clipPath(getPathC()!!, Region.Op.INTERSECT) //裁剪出A和C区域的全集
canvas.clipPath(
getPathB()!!,
Region.Op.DIFFERENCE
) //裁剪出B区域中不同于与AC区域的部分
canvas.drawBitmap(pathBContentBitmap!!, 0f, 0f, null)
drawPathBShadow(canvas)
canvas.restore()
}
/**
* 绘制B区域阴影阴影左深右浅
* @param canvas
*/
private fun drawPathBShadow(canvas: Canvas) {
val deepOffset = 0 //深色端的偏移值
val lightOffset = 0 //浅色端的偏移值
val aTof = Math.hypot(
(a!!.x - f!!.x).toDouble(),
(a!!.y - f!!.y).toDouble()
).toFloat() //a到f的距离
val viewDiagonalLength = Math.hypot(
viewWidth.toDouble(),
viewHeight.toDouble()
).toFloat() //对角线长度
val left: Int
val right: Int
val top = c!!.y.toInt()
val bottom = (viewDiagonalLength + c!!.y).toInt()
val gradientDrawable: GradientDrawable?
if (style == STYLE_TOP_RIGHT) { //f点在右上角
//从左向右线性渐变
gradientDrawable = drawableBTopRight
left = (c!!.x - deepOffset).toInt() //c点位于左上角
right = (c!!.x + aTof / 4 + lightOffset).toInt()
} else { //从右向左线性渐变
gradientDrawable = drawableBLowerRight
left = (c!!.x - aTof / 4 - lightOffset).toInt() //c点位于左下角
right = (c!!.x + deepOffset).toInt()
}
gradientDrawable!!.setBounds(left, top, right, bottom) //设置阴影矩形
val rotateDegrees = Math.toDegrees(
Math.atan2(
e!!.x - f!!.x.toDouble(),
h!!.y - f!!.y.toDouble()
)
).toFloat() //旋转角度
canvas.rotate(rotateDegrees, c!!.x, c!!.y) //以c为中心点旋转
gradientDrawable.draw(canvas)
}
/**
* 绘制区域B
* @return
*/
private fun getPathB(): Path? {
pathB!!.reset()
pathB!!.lineTo(0f, viewHeight.toFloat()) //移动到左下角
pathB!!.lineTo(viewWidth.toFloat(), viewHeight.toFloat()) //移动到右下角
pathB!!.lineTo(viewWidth.toFloat(), 0f) //移动到右上角
pathB!!.close() //闭合区域
return pathB
}
/**
* 绘制C区域内容
* @param canvas
* @param pathA
*/
private fun drawPathCContent(
canvas: Canvas,
pathA: Path?
) {
canvas.save()
canvas.clipPath(pathA!!)
canvas.clipPath(getPathC()!!, Region.Op.DIFFERENCE) //裁剪出C区域不同于A区域的部分
// canvas.drawPath(getPathC(),pathCPaint);
val eh =
hypot(f!!.x - e!!.x.toDouble(), h!!.y - f!!.y.toDouble()).toFloat()
val sin0 = (f!!.x - e!!.x) / eh
val cos0 = (h!!.y - f!!.y) / eh
//设置翻转和旋转矩阵
mMatrixArray[0] = -(1 - 2 * sin0 * sin0)
mMatrixArray[1] = 2 * sin0 * cos0
mMatrixArray[3] = 2 * sin0 * cos0
mMatrixArray[4] = 1 - 2 * sin0 * sin0
mMatrix!!.reset()
mMatrix!!.setValues(mMatrixArray) //翻转和旋转
mMatrix!!.preTranslate(-e!!.x, -e!!.y) //沿当前XY轴负方向位移得到 矩形A₃B₃C₃D₃
mMatrix!!.postTranslate(e!!.x, e!!.y) //沿原XY轴方向位移得到 矩形A4 B4 C4 D4
canvas.drawBitmap(pathCContentBitmap!!, mMatrix!!, null)
drawPathCShadow(canvas)
canvas.restore()
}
/**
* 绘制C区域阴影阴影左浅右深
* @param canvas
*/
private fun drawPathCShadow(canvas: Canvas) {
val deepOffset = 1 //深色端的偏移值
val lightOffset = -30 //浅色端的偏移值
val viewDiagonalLength = Math.hypot(
viewWidth.toDouble(),
viewHeight.toDouble()
).toFloat() //view对角线长度
val midpoint_ce = (c!!.x + e!!.x).toInt() / 2 //ce中点
val midpoint_jh = (j!!.y + h!!.y).toInt() / 2 //jh中点
val minDisToControlPoint = Math.min(
Math.abs(midpoint_ce - e!!.x),
Math.abs(midpoint_jh - h!!.y)
) //中点到控制点的最小值
val left: Int
val right: Int
val top = c!!.y.toInt()
val bottom = (viewDiagonalLength + c!!.y).toInt()
val gradientDrawable: GradientDrawable?
if (style == STYLE_TOP_RIGHT) {
gradientDrawable = drawableCTopRight
left = (c!!.x - lightOffset).toInt()
right = (c!!.x + minDisToControlPoint + deepOffset).toInt()
} else {
gradientDrawable = drawableCLowerRight
left = (c!!.x - minDisToControlPoint - deepOffset).toInt()
right = (c!!.x + lightOffset).toInt()
}
gradientDrawable!!.setBounds(left, top, right, bottom)
val mDegrees = Math.toDegrees(
Math.atan2(
e!!.x - f!!.x.toDouble(),
h!!.y - f!!.y.toDouble()
)
).toFloat()
canvas.rotate(mDegrees, c!!.x, c!!.y)
gradientDrawable.draw(canvas)
}
/**
* 绘制区域C
* @return
*/
private fun getPathC(): Path? {
pathC!!.reset()
pathC!!.moveTo(i!!.x, i!!.y) //移动到i点
pathC!!.lineTo(d!!.x, d!!.y) //移动到d点
pathC!!.lineTo(b!!.x, b!!.y) //移动到b点
pathC!!.lineTo(a!!.x, a!!.y) //移动到a点
pathC!!.lineTo(k!!.x, k!!.y) //移动到k点
pathC!!.close() //闭合区域
return pathC
}
/**
* 计算各点坐标
* @param a
* @param f
*/
private fun calcPointsXY(a: MyPoint?, f: MyPoint?) {
g!!.x = (a!!.x + f!!.x) / 2
g!!.y = (a.y + f.y) / 2
e!!.x = g!!.x - (f.y - g!!.y) * (f.y - g!!.y) / (f.x - g!!.x)
e!!.y = f.y
h!!.x = f.x
h!!.y = g!!.y - (f.x - g!!.x) * (f.x - g!!.x) / (f.y - g!!.y)
c!!.x = e!!.x - (f.x - e!!.x) / 2
c!!.y = f.y
j!!.x = f.x
j!!.y = h!!.y - (f.y - h!!.y) / 2
b = getIntersectionPoint(a, e, c, j)
k = getIntersectionPoint(a, h, c, j)
d!!.x = (c!!.x + 2 * e!!.x + b!!.x) / 4
d!!.y = (2 * e!!.y + c!!.y + b!!.y) / 4
i!!.x = (j!!.x + 2 * h!!.x + k!!.x) / 4
i!!.y = (2 * h!!.y + j!!.y + k!!.y) / 4
//计算d点到ae的距离
val lA = a.y - e!!.y
val lB = e!!.x - a.x
val lC = a.x * e!!.y - e!!.x * a.y
lPathAShadowDis = Math.abs(
(lA * d!!.x + lB * d!!.y + lC) / Math.hypot(
lA.toDouble(),
lB.toDouble()
).toFloat()
)
//计算i点到ah的距离
val rA = a.y - h!!.y
val rB = h!!.x - a.x
val rC = a.x * h!!.y - h!!.x * a.y
rPathAShadowDis = Math.abs(
(rA * i!!.x + rB * i!!.y + rC) / Math.hypot(
rA.toDouble(),
rB.toDouble()
).toFloat()
)
}
/**
* 计算两线段相交点坐标
* @param lineOne_My_pointOne
* @param lineOne_My_pointTwo
* @param lineTwo_My_pointOne
* @param lineTwo_My_pointTwo
* @return 返回该点
*/
private fun getIntersectionPoint(
lineOne_My_pointOne: MyPoint?,
lineOne_My_pointTwo: MyPoint?,
lineTwo_My_pointOne: MyPoint?,
lineTwo_My_pointTwo: MyPoint?
): MyPoint {
val x1: Float
val y1: Float
val x2: Float
val y2: Float
val x3: Float
val y3: Float
val x4: Float
val y4: Float
x1 = lineOne_My_pointOne!!.x
y1 = lineOne_My_pointOne.y
x2 = lineOne_My_pointTwo!!.x
y2 = lineOne_My_pointTwo.y
x3 = lineTwo_My_pointOne!!.x
y3 = lineTwo_My_pointOne.y
x4 = lineTwo_My_pointTwo!!.x
y4 = lineTwo_My_pointTwo.y
val pointX =
(((x1 - x2) * (x3 * y4 - x4 * y3) - (x3 - x4) * (x1 * y2 - x2 * y1))
/ ((x3 - x4) * (y1 - y2) - (x1 - x2) * (y3 - y4)))
val pointY =
(((y1 - y2) * (x3 * y4 - x4 * y3) - (x1 * y2 - x2 * y1) * (y3 - y4))
/ ((y1 - y2) * (x3 - x4) - (x1 - x2) * (y3 - y4)))
return MyPoint(pointX, pointY)
}
/**
* 计算C点的X值
* @param a
* @param f
* @return
*/
private fun calcPointCX(a: MyPoint, f: MyPoint?): Float {
val g: MyPoint
val e: MyPoint
g = MyPoint()
e = MyPoint()
g.x = (a.x + f!!.x) / 2
g.y = (a.y + f.y) / 2
e.x = g.x - (f.y - g.y) * (f.y - g.y) / (f.x - g.x)
e.y = f.y
return e.x - (f.x - e.x) / 2
}
fun getViewWidth(): Float {
return viewWidth.toFloat()
}
fun getViewHeight(): Float {
return viewHeight.toFloat()
}
internal inner class MyPoint {
var x = 0f
var y = 0f
constructor() {}
constructor(x: Float, y: Float) {
this.x = x
this.y = y
}
}
companion object {
const val STYLE_LEFT = "STYLE_LEFT" //点击左边区域
const val STYLE_RIGHT = "STYLE_RIGHT" //点击右边区域
const val STYLE_MIDDLE = "STYLE_MIDDLE" //点击中间区域
const val STYLE_TOP_RIGHT = "STYLE_TOP_RIGHT" //f点在右上角
const val STYLE_LOWER_RIGHT = "STYLE_LOWER_RIGHT" //f点在右下角
}
}
Loading…
Cancel
Save