feat: 优化代码

pull/103/head
kunfei 5 years ago
parent a9532cf248
commit ecfc0ea844
  1. 863
      app/src/main/java/io/legado/app/ui/book/read/page/delegate/TestDelegate.kt
  2. 64
      app/src/main/res/layout/dialog_read_padding.xml
  3. 5
      app/src/main/res/layout/view_detail_seek_bar.xml
  4. 8
      app/src/main/res/values/strings.xml

@ -0,0 +1,863 @@
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点在右下角
}
}

@ -35,4 +35,68 @@
app:title="@string/padding_right"
app:max="100" />
<View
android:layout_width="match_parent"
android:layout_height="10dp" />
<io.legado.app.ui.widget.DetailSeekBar
android:id="@+id/dsb_header_padding_top"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:title="@string/header_padding_top"
app:max="100" />
<io.legado.app.ui.widget.DetailSeekBar
android:id="@+id/dsb_header_padding_bottom"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:title="@string/header_padding_bottom"
app:max="100" />
<io.legado.app.ui.widget.DetailSeekBar
android:id="@+id/dsb_header_padding_left"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:title="@string/header_padding_left"
app:max="100" />
<io.legado.app.ui.widget.DetailSeekBar
android:id="@+id/dsb_header_padding_right"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:title="@string/header_padding_right"
app:max="100" />
<View
android:layout_width="match_parent"
android:layout_height="10dp" />
<io.legado.app.ui.widget.DetailSeekBar
android:id="@+id/dsb_footer_padding_top"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:title="@string/footer_padding_top"
app:max="100" />
<io.legado.app.ui.widget.DetailSeekBar
android:id="@+id/dsb_footer_padding_bottom"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:title="@string/footer_padding_bottom"
app:max="100" />
<io.legado.app.ui.widget.DetailSeekBar
android:id="@+id/dsb_footer_padding_left"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:title="@string/footer_padding_left"
app:max="100" />
<io.legado.app.ui.widget.DetailSeekBar
android:id="@+id/dsb_footer_padding_right"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:title="@string/footer_padding_right"
app:max="100" />
</LinearLayout>

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="horizontal"
android:gravity="center">
@ -43,6 +43,7 @@
android:layout_height="wrap_content"
android:gravity="right"
android:singleLine="true"
tools:ignore="RtlHardcoded" />
android:text="0"
tools:ignore="HardcodedText,RtlHardcoded" />
</LinearLayout>

@ -284,6 +284,14 @@
<string name="padding_bottom">下边距</string>
<string name="padding_left">左边距</string>
<string name="padding_right">右边距</string>
<string name="header_padding_top">页眉上</string>
<string name="header_padding_bottom">页眉下</string>
<string name="header_padding_left">页眉左</string>
<string name="header_padding_right">页眉右</string>
<string name="footer_padding_top">页脚上</string>
<string name="footer_padding_bottom">页脚下</string>
<string name="footer_padding_left">页脚左</string>
<string name="footer_padding_right">页脚右</string>
<string name="check_book_source">校验书源</string>
<string name="check_select_source">校验所选</string>
<string name="progress_show">进度 %d/%d</string>

Loading…
Cancel
Save