1
0
mirror of https://github.com/fumiama/copymanga.git synced 2026-06-28 23:00:28 +08:00
1. 更改 加载图片占位
2. 修复 重复写入info
3. 更改 长按删除提示语
4. 增加 翻到上一章时置于末页
5. 优化 浏览漫画性能
This commit is contained in:
fumiama
2021-01-09 14:39:37 +08:00
parent 36ea5cc149
commit 5bbe768882
13 changed files with 344 additions and 562 deletions

9
.idea/dictionaries/rumia.xml generated Normal file
View File

@@ -0,0 +1,9 @@
<component name="ProjectDictionaryState">
<dictionary name="rumia">
<words>
<w>cdwn</w>
<w>manga</w>
<w>rmrf</w>
</words>
</dictionary>
</component>

View File

@@ -11,8 +11,8 @@ android {
applicationId "top.fumiama.copymanga" applicationId "top.fumiama.copymanga"
minSdkVersion 23 minSdkVersion 23
targetSdkVersion 30 targetSdkVersion 30
versionCode 9 versionCode 10
versionName '1.3.1' versionName '1.3.2'
resConfigs "zh", "zh-rCN" resConfigs "zh", "zh-rCN"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"

View File

@@ -25,6 +25,7 @@ import top.fumiama.copymanga.handler.DlHandler
import top.fumiama.copymanga.tool.MangaDlTools import top.fumiama.copymanga.tool.MangaDlTools
import top.fumiama.copymanga.tool.MangaDlTools.Companion.wmdlt import top.fumiama.copymanga.tool.MangaDlTools.Companion.wmdlt
import top.fumiama.copymanga.tool.ToolsBox import top.fumiama.copymanga.tool.ToolsBox
import top.fumiama.copymanga.view.ChapterToggleButton
import top.fumiama.copymanga.view.LazyScrollView import top.fumiama.copymanga.view.LazyScrollView
import java.io.File import java.io.File
import java.lang.Thread.sleep import java.lang.Thread.sleep
@@ -41,17 +42,14 @@ class DlActivity : Activity() {
var haveDlStarted = false var haveDlStarted = false
private var btnNumPerRow = 4 private var btnNumPerRow = 4
private lateinit var ltbtn: View private lateinit var ltbtn: View
var tbtnlist: List<ToggleButton> = arrayListOf() var tbtnlist: Array<ChapterToggleButton> = arrayOf()
var tbtnUrlList = arrayListOf<String>()
private val handler = DlHandler(this, Looper.myLooper()!!) private val handler = DlHandler(this, Looper.myLooper()!!)
private var btnw = 0 private var btnw = 0
private var cdwnWidth = 0 private var cdwnWidth = 0
private var canDl = false private var canDl = false
private lateinit var toolsBox: ToolsBox private lateinit var toolsBox: ToolsBox
lateinit var mangaDlTools: MangaDlTools private lateinit var mangaDlTools: MangaDlTools
var multiSelect = false var multiSelect = false
private var zipArrayList: Array<String> = arrayOf()
@ExperimentalStdlibApi @ExperimentalStdlibApi
@SuppressLint("SetTextI18n") @SuppressLint("SetTextI18n")
@@ -85,14 +83,14 @@ class DlActivity : Activity() {
private fun fillChapters() { private fun fillChapters() {
mangaDlTools.allocateChapterUrls(checkedChapter) mangaDlTools.allocateChapterUrls(checkedChapter)
for (i in tbtnlist.indices) { for (i in tbtnlist) {
if (tbtnlist[i].isChecked) mangaDlTools.dlChapterUrl(tbtnUrlList[i]) if (i.isChecked) mangaDlTools.dlChapterUrl(i.url.toString())
} }
} }
private fun dlThead(dlMethod: (i: ToggleButton) -> Unit) { private fun dlThread(dlMethod: (i: ChapterToggleButton) -> Unit) {
sleep(10000) sleep(10000)
for (i in tbtnlist.listIterator()) { for (i in tbtnlist) {
if (i.isChecked) dlMethod(i) if (i.isChecked) dlMethod(i)
if (!canDl) { if (!canDl) {
checkedChapter -= dldChapter checkedChapter -= dldChapter
@@ -139,7 +137,7 @@ class DlActivity : Activity() {
handler.sendEmptyMessage(9) //set dl card color to red handler.sendEmptyMessage(9) //set dl card color to red
Toast.makeText(this, "十秒后开始下载...", Toast.LENGTH_SHORT).show() Toast.makeText(this, "十秒后开始下载...", Toast.LENGTH_SHORT).show()
fillChapters() fillChapters()
Thread { dlThead { downloadChapterPages(it) } }.start() Thread { dlThread { downloadChapterPages(it) } }.start()
} }
} }
} }
@@ -157,6 +155,7 @@ class DlActivity : Activity() {
} }
private fun analyzeStructure() { private fun analyzeStructure() {
ViewMangaActivity.zipList = arrayOf()
Gson().fromJson(json?.reader(), Array<ComicStructure>::class.java)?.let { Gson().fromJson(json?.reader(), Array<ComicStructure>::class.java)?.let {
for (group in it) { for (group in it) {
val tc = layoutInflater.inflate(R.layout.line_caption, ldwn, false) val tc = layoutInflater.inflate(R.layout.line_caption, ldwn, false)
@@ -182,21 +181,21 @@ class DlActivity : Activity() {
val mangaHome = File("${getExternalFilesDir("")}/$comicName") val mangaHome = File("${getExternalFilesDir("")}/$comicName")
val jsonFile = File(mangaHome, "info.bin") val jsonFile = File(mangaHome, "info.bin")
if(!mangaHome.exists()) mangaHome.mkdirs() if(!mangaHome.exists()) mangaHome.mkdirs()
json?.let { jsonFile.writeText(it) } if(!(jsonFile.exists() && intent.getBooleanExtra("callFromDlList", false))) json?.let { jsonFile.writeText(it) }
} }
@ExperimentalStdlibApi @ExperimentalStdlibApi
private fun downloadChapterPages(i: ToggleButton) { private fun downloadChapterPages(i: ChapterToggleButton) {
mangaDlTools.onDownloadedListener = mangaDlTools.onDownloadedListener =
object : MangaDlTools.OnDownloadedListener { object : MangaDlTools.OnDownloadedListener {
override fun handleMessage(succeed: Boolean) { override fun handleMessage(succeed: Boolean) {
handler.obtainMessage(if (succeed) 1 else -1, tbtnlist.indexOf(i), 0) handler.obtainMessage(if (succeed) 1 else -1, i.index, 0)
.sendToTarget() .sendToTarget()
} }
override fun handleMessage(succeed: Boolean, pageNow: Int) { override fun handleMessage(succeed: Boolean, pageNow: Int) {
handler.obtainMessage( handler.obtainMessage(
5, 5,
tbtnlist.indexOf(i), i.index,
pageNow, pageNow,
succeed succeed
).sendToTarget() ).sendToTarget()
@@ -204,16 +203,18 @@ class DlActivity : Activity() {
override fun handleMessage(pageNow: Int){ override fun handleMessage(pageNow: Int){
handler.obtainMessage( handler.obtainMessage(
10, 10,
tbtnlist.indexOf(i), i.index,
pageNow pageNow
).sendToTarget() ).sendToTarget()
} }
} }
i.hash?.let {
mangaDlTools.dlChapterAndPackIntoZip( mangaDlTools.dlChapterAndPackIntoZip(
File("${getExternalFilesDir("")}/$comicName/${i.hint}/${i.textOn}.zip"), File("${getExternalFilesDir("")}/$comicName/${i.hint}/${i.textOn}.zip"),
tbtnUrlList[tbtnlist.indexOf(i)].substringAfterLast("/") it
) )
} }
}
@SuppressLint("SetTextI18n") @SuppressLint("SetTextI18n")
fun addTbtn(title: String, url: String, caption: String) { fun addTbtn(title: String, url: String, caption: String) {
@@ -224,11 +225,12 @@ class DlActivity : Activity() {
isNewTitle = false isNewTitle = false
} }
val tbv = layoutInflater.inflate(R.layout.button_tbutton, ltbtn.ltbtn, false) val tbv = layoutInflater.inflate(R.layout.button_tbutton, ltbtn.ltbtn, false)
tbv.tbtn.index = tbtnlist.size
tbtnlist += tbv.tbtn tbtnlist += tbv.tbtn
tbv.tbtn.url = url
tbtncnt++ tbtncnt++
tbtnUrlList.add(url) val zipPosition = ViewMangaActivity.zipList?.size
val zipPosition = zipArrayList.size ViewMangaActivity.zipList = ViewMangaActivity.zipList?.plus("$title.zip")
zipArrayList += "$title.zip"
tbv.tbtn.textOff = title tbv.tbtn.textOff = title
tbv.tbtn.textOn = title tbv.tbtn.textOn = title
tbv.tbtn.text = title tbv.tbtn.text = title
@@ -251,7 +253,7 @@ class DlActivity : Activity() {
else tdwn.text = "$dldChapter/${--checkedChapter}" else tdwn.text = "$dldChapter/${--checkedChapter}"
}else if(it.tbtn.isChecked){ }else if(it.tbtn.isChecked){
it.tbtn.isChecked = false it.tbtn.isChecked = false
callVM(title, zipf, zipPosition) zipPosition?.let { callVM(title, zipf, it) }
} }
} }
tbv.tbtn.setOnLongClickListener { tbv.tbtn.setOnLongClickListener {
@@ -289,7 +291,7 @@ class DlActivity : Activity() {
private fun callVM(titleText: String, zipFile: File, zipPosition:Int){ private fun callVM(titleText: String, zipFile: File, zipPosition:Int){
ViewMangaActivity.titleText = titleText ViewMangaActivity.titleText = titleText
ViewMangaActivity.zipFile = zipFile ViewMangaActivity.zipFile = zipFile
ViewMangaActivity.zipList = zipArrayList //ViewMangaActivity.zipList = zipArrayList
ViewMangaActivity.zipPosition = zipPosition ViewMangaActivity.zipPosition = zipPosition
ViewMangaActivity.cd = zipFile.parentFile ViewMangaActivity.cd = zipFile.parentFile
startActivity(Intent(this, ViewMangaActivity::class.java)) startActivity(Intent(this, ViewMangaActivity::class.java))

View File

@@ -57,7 +57,7 @@ class DlListActivity:Activity() {
ViewMangaActivity.zipFile = chosenFile ViewMangaActivity.zipFile = chosenFile
ViewMangaActivity.titleText = it[position] ViewMangaActivity.titleText = it[position]
ViewMangaActivity.zipPosition = position ViewMangaActivity.zipPosition = position
ViewMangaActivity.zipList = it ViewMangaActivity.zipList = it as Array<String>
ViewMangaActivity.cd = cd ViewMangaActivity.cd = cd
startActivity(Intent(this, ViewMangaActivity::class.java)) startActivity(Intent(this, ViewMangaActivity::class.java))
} }
@@ -66,8 +66,8 @@ class DlListActivity:Activity() {
mylv.setOnItemLongClickListener { _, _, position, _ -> mylv.setOnItemLongClickListener { _, _, position, _ ->
val chosenFile = File(cd, it[position]) val chosenFile = File(cd, it[position])
AlertDialog.Builder(this) AlertDialog.Builder(this)
.setIcon(R.drawable.ic_launcher_foreground).setMessage("是否在此执行删除/查错?") .setIcon(R.drawable.ic_launcher_foreground).setMessage("在此执行删除/查错?")
.setTitle("提示").setPositiveButton(android.R.string.ok){ _, _ -> .setTitle("提示").setPositiveButton("删除"){ _, _ ->
if(chosenFile.exists()) handler?.obtainMessage(2, chosenFile)?.sendToTarget() //call rmrf if(chosenFile.exists()) handler?.obtainMessage(2, chosenFile)?.sendToTarget() //call rmrf
handler?.obtainMessage(3, cd)?.sendToTarget() //call scanFile handler?.obtainMessage(3, cd)?.sendToTarget() //call scanFile
}.setNegativeButton(android.R.string.cancel){_, _ ->} }.setNegativeButton(android.R.string.cancel){_, _ ->}
@@ -97,7 +97,10 @@ class DlListActivity:Activity() {
private fun callDownloadActivity(jsonFile: File){ private fun callDownloadActivity(jsonFile: File){
DlActivity.json = jsonFile.readText() DlActivity.json = jsonFile.readText()
DlActivity.comicName = jsonFile.parentFile?.name?:"Null" DlActivity.comicName = jsonFile.parentFile?.name?:"Null"
startActivity(Intent(this, DlActivity::class.java)) startActivity(
Intent(this, DlActivity::class.java)
.putExtra("callFromDlList", true)
)
} }
private fun findNullWebpZipFileInDir(f: File){ private fun findNullWebpZipFileInDir(f: File){

View File

@@ -26,7 +26,7 @@ class MainActivity: Activity() {
setContentView(R.layout.activity_main) setContentView(R.layout.activity_main)
wm = WeakReference(this) wm = WeakReference(this)
mh = MainHandler(Looper.getMainLooper()) mh = MainHandler(Looper.myLooper()!!)
toolsBox = ToolsBox(wm as WeakReference<Any>) toolsBox = ToolsBox(wm as WeakReference<Any>)
toolsBox?.netinfo?.let { toolsBox?.netinfo?.let {
if(it == "无网络" || it == "错误"){ if(it == "无网络" || it == "错误"){

View File

@@ -5,10 +5,7 @@ import android.annotation.SuppressLint
import android.app.Activity import android.app.Activity
import android.graphics.Bitmap import android.graphics.Bitmap
import android.graphics.BitmapFactory import android.graphics.BitmapFactory
import android.os.Build import android.os.*
import android.os.Bundle
import android.os.Handler
import android.os.Message
import android.util.Log import android.util.Log
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
@@ -105,6 +102,13 @@ class ViewMangaActivity : Activity() {
} }
try { try {
prepareItems() prepareItems()
if(pn > 0) {
pageNum = pn
pn = -1
}else if(pn == -2){
pageNum = count
pn = -1
}
} catch (e: Exception) { } catch (e: Exception) {
e.printStackTrace() e.printStackTrace()
toolsBox.toastError("准备控件错误") toolsBox.toastError("准备控件错误")
@@ -152,7 +156,11 @@ class ViewMangaActivity : Activity() {
private fun loadOneImg() { private fun loadOneImg() {
if(dlZip2View) onei.setImageBitmap(getImgBitmap(currentItem)) if(dlZip2View) onei.setImageBitmap(getImgBitmap(currentItem))
else Glide.with(this@ViewMangaActivity).load(imgUrls[currentItem]).placeholder(R.drawable.bg_comment).into(onei) else Glide.with(this@ViewMangaActivity)
.load(imgUrls[currentItem])
.placeholder(R.drawable.ic_dl)
.dontAnimate()
.into(onei)
updateSeekBar() updateSeekBar()
} }
@@ -338,7 +346,7 @@ class ViewMangaActivity : Activity() {
//Glide.with(this@ViewMangaActivity).load(it).placeholder(R.drawable.bg_comment).into(holder.itemView.onei) //Glide.with(this@ViewMangaActivity).load(it).placeholder(R.drawable.bg_comment).into(holder.itemView.onei)
holder.itemView.onei.setImageBitmap(it) holder.itemView.onei.setImageBitmap(it)
} }
else Glide.with(this@ViewMangaActivity).load(imgUrls[pos]).placeholder(R.drawable.bg_comment).timeout(10000).into(holder.itemView.onei) else Glide.with(this@ViewMangaActivity).load(imgUrls[pos]).placeholder(R.drawable.ic_dl).dontAnimate().timeout(10000).into(holder.itemView.onei)
} }
override fun getItemCount(): Int { override fun getItemCount(): Int {
@@ -377,7 +385,7 @@ class ViewMangaActivity : Activity() {
class MyHandler( class MyHandler(
private val infcard: View, private val infcard: View,
private val toolsBox: ToolsBox private val toolsBox: ToolsBox
) : Handler() { ) : Handler(Looper.myLooper()!!) {
private var infcShowed = false private var infcShowed = false
private var delta = -1f private var delta = -1f
get() { get() {
@@ -429,7 +437,8 @@ class ViewMangaActivity : Activity() {
var nextChapterUrl: String? = null var nextChapterUrl: String? = null
var previousChapterUrl: String? = null var previousChapterUrl: String? = null
var zipPosition = 0 var zipPosition = 0
var zipList: Array<out String>? = null var zipList: Array<String>? = null
var cd: File? = null var cd: File? = null
var pn = -1
} }
} }

View File

@@ -48,7 +48,7 @@ class DlHandler(activity: DlActivity, looper: Looper) : Handler(looper) {
d?.pdwn?.progress = 0 d?.pdwn?.progress = 0
val selectDownloaded = d?.multiSelect?:false val selectDownloaded = d?.multiSelect?:false
if (d?.haveSElectAll == true) { if (d?.haveSElectAll == true) {
d?.tbtnlist?.listIterator()?.forEach { i -> d?.tbtnlist?.forEach { i ->
if(i.freezesText) i.setBackgroundResource(R.drawable.rndbg_checked) else i.setBackgroundResource(R.drawable.toggle_button) if(i.freezesText) i.setBackgroundResource(R.drawable.rndbg_checked) else i.setBackgroundResource(R.drawable.toggle_button)
i.isChecked = false i.isChecked = false
} }
@@ -62,7 +62,7 @@ class DlHandler(activity: DlActivity, looper: Looper) : Handler(looper) {
i.isChecked = true i.isChecked = true
it.checkedChapter++ it.checkedChapter++
} }
for (i in it.tbtnlist.listIterator()) { for (i in it.tbtnlist) {
if(selectDownloaded) checkBtn(i, it) if(selectDownloaded) checkBtn(i, it)
else if(!i.freezesText) checkBtn(i, it) else if(!i.freezesText) checkBtn(i, it)
} }
@@ -90,7 +90,7 @@ class DlHandler(activity: DlActivity, looper: Looper) : Handler(looper) {
} }
private fun setSize(pageNow: Int, tbtnNo: Int){ private fun setSize(pageNow: Int, tbtnNo: Int){
if(refreshSize || size == 0) { if(refreshSize || size == 0) {
size = d?.tbtnUrlList?.get(tbtnNo)?.let { wmdlt?.get()?.getImgsCountByHash(it.substringAfterLast("/")) }?:0 size = d?.tbtnlist?.get(tbtnNo)?.hash?.let { wmdlt?.get()?.getImgsCountByHash(it) }?:0
refreshSize = false refreshSize = false
}else if(pageNow == size) refreshSize = true }else if(pageNow == size) refreshSize = true
} }

View File

@@ -28,9 +28,9 @@ class MainHandler(looper: Looper):Handler(looper) {
} }
private fun loadUrlInHiddenWebView(url: String){wm?.get()?.wh?.loadUrl(url)} private fun loadUrlInHiddenWebView(url: String){wm?.get()?.wh?.loadUrl(url)}
private fun callViewManga(content: String){ private fun callViewManga(content: String){
val listChapter = content.split("\n") val listChapter = content.split('\n')
if(!saveUrlsOnly) { if(!saveUrlsOnly) {
ViewMangaActivity.titleText = listChapter[0].substringBeforeLast(" ") ViewMangaActivity.titleText = listChapter[0].substringBeforeLast(' ')
ViewMangaActivity.nextChapterUrl = listChapter[1].let { if(it == "null") null else it } ViewMangaActivity.nextChapterUrl = listChapter[1].let { if(it == "null") null else it }
ViewMangaActivity.previousChapterUrl = listChapter[2].let { if(it == "null") null else it } ViewMangaActivity.previousChapterUrl = listChapter[2].let { if(it == "null") null else it }
ViewMangaActivity.imgUrls = arrayOf() ViewMangaActivity.imgUrls = arrayOf()
@@ -39,7 +39,7 @@ class MainHandler(looper: Looper):Handler(looper) {
} else{ } else{
var imgs = arrayOf<String>() var imgs = arrayOf<String>()
for(i in 3 until listChapter.size) imgs += listChapter[i] for(i in 3 until listChapter.size) imgs += listChapter[i]
wmdlt?.get()?.setChapterImgs(listChapter[0].substringAfterLast(" "), imgs) wmdlt?.get()?.setChapterImgs(listChapter[0].substringAfterLast(' '), imgs)
} }
} }
private fun updateLoadProgress(progress: Int){ private fun updateLoadProgress(progress: Int){

View File

@@ -1,7 +1,6 @@
package top.fumiama.copymanga.tool package top.fumiama.copymanga.tool
import android.content.Intent import android.content.Intent
import android.util.Log
import android.widget.Toast import android.widget.Toast
import kotlinx.android.synthetic.main.activity_main.* import kotlinx.android.synthetic.main.activity_main.*
import top.fumiama.copymanga.activity.MainActivity.Companion.wm import top.fumiama.copymanga.activity.MainActivity.Companion.wm
@@ -21,9 +20,6 @@ class PagesManager(w: WeakReference<ViewMangaActivity>) {
private fun judgeNext() = v?.pageNum?:0 < v?.count?:0 private fun judgeNext() = v?.pageNum?:0 < v?.count?:0
@ExperimentalStdlibApi @ExperimentalStdlibApi
private fun toPage(goNext:Boolean){ private fun toPage(goNext:Boolean){
val chapterUrl = if(goNext) ViewMangaActivity.nextChapterUrl else ViewMangaActivity.previousChapterUrl
val newZipPosition = ViewMangaActivity.zipPosition + (if(goNext) 1 else -1)
val hint = if(goNext) "" else ""
if (v?.clicked == false) { if (v?.clicked == false) {
if (if(goNext)judgeNext() else judgePrevious()) { if (if(goNext)judgeNext() else judgePrevious()) {
if(goNext) { if(goNext) {
@@ -33,33 +29,42 @@ class PagesManager(w: WeakReference<ViewMangaActivity>) {
v.scrollBack() v.scrollBack()
isEndL = false isEndL = false
} }
} else if (chapterUrl != null) { } else {
val chapterUrl = if(goNext) ViewMangaActivity.nextChapterUrl else ViewMangaActivity.previousChapterUrl
if (chapterUrl != null) {
if (if(goNext)isEndR else isEndL) { if (if(goNext)isEndR else isEndL) {
if(!goNext) ViewMangaActivity.pn = -2
wm?.get()?.w?.loadUrl("javascript:invoke.clickClass(\"comicControlBottomTopClick\",${if(goNext)1 else 0});") wm?.get()?.w?.loadUrl("javascript:invoke.clickClass(\"comicControlBottomTopClick\",${if(goNext)1 else 0});")
v.tt.canDo = false v.tt.canDo = false
v.finish() v.finish()
} else doubleTapToast(hint, goNext) } else doubleTapToast(goNext)
} else if(v.dlZip2View && newZipPosition >= 0 && newZipPosition < ViewMangaActivity.zipList?.size?:0){ } else {
val newZipPosition = ViewMangaActivity.zipPosition + (if(goNext) 1 else -1)
if(v.dlZip2View && newZipPosition >= 0 && newZipPosition < ViewMangaActivity.zipList?.size?:0){
if (if(goNext)isEndR else isEndL){ if (if(goNext)isEndR else isEndL){
if(!goNext) ViewMangaActivity.pn = -2
ViewMangaActivity.zipPosition = newZipPosition ViewMangaActivity.zipPosition = newZipPosition
ViewMangaActivity.titleText = ViewMangaActivity.zipList?.get(newZipPosition) ?: "null" ViewMangaActivity.titleText = ViewMangaActivity.zipList?.get(newZipPosition) ?: "null"
ViewMangaActivity.zipFile = File(ViewMangaActivity.cd, ViewMangaActivity.titleText) ViewMangaActivity.zipFile = File(ViewMangaActivity.cd, ViewMangaActivity.titleText)
v.startActivity(Intent(v, ViewMangaActivity::class.java)) v.startActivity(Intent(v, ViewMangaActivity::class.java))
v.tt.canDo = false v.tt.canDo = false
v.finish() v.finish()
}else doubleTapToast(hint, goNext) }else doubleTapToast(goNext)
} }
else Toast.makeText( else Toast.makeText(
v.applicationContext, v.applicationContext,
"已经到头了~", "已经到头了~",
Toast.LENGTH_SHORT Toast.LENGTH_SHORT
).show() ).show()
}
}
} else v?.hideObjs() } else v?.hideObjs()
} }
fun manageInfo(){ fun manageInfo(){
if (v?.clicked == false) v.showObjs() else v?.hideObjs() if (v?.clicked == false) v.showObjs() else v?.hideObjs()
} }
private fun doubleTapToast(hint: String, goNext: Boolean){ private fun doubleTapToast(goNext: Boolean){
val hint = if(goNext) "" else ""
Toast.makeText( Toast.makeText(
v?.applicationContext, v?.applicationContext,
"再次按下加载${hint}一章", "再次按下加载${hint}一章",

View File

@@ -0,0 +1,23 @@
package top.fumiama.copymanga.view
import android.content.Context
import android.util.AttributeSet
import android.widget.ToggleButton
class ChapterToggleButton: ToggleButton {
constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int): super(context, attrs, defStyleAttr)
constructor(context: Context?, attrs: AttributeSet?): super(context, attrs)
constructor(context: Context?): super(context, null)
var url: CharSequence? = null
val hash get() = url?.toString()?.substringAfterLast('/')
var caption: CharSequence? = null
var index: Int = 0
var chapterName: CharSequence = "null"
set(value) {
textOn = value
textOff = value
text = value
field = value
}
}

View File

@@ -117,34 +117,44 @@ class ScaleImageView : ImageView {
* @return 如果传了matrix参数则将matrix填充后返回,否则new一个填充返回 * @return 如果传了matrix参数则将matrix填充后返回,否则new一个填充返回
*/ */
private fun getInnerMatrix(matrix: Matrix?): Matrix { private fun getInnerMatrix(matrix: Matrix?): Matrix {
var matrix = matrix val m = matrix?:Matrix().let {
if (matrix == null) { it.reset()
matrix = Matrix() it
} else {
matrix.reset()
} }
if (isReady) { if (isReady) {
val imgX = drawable.intrinsicWidth.toFloat()
val imgY = drawable.intrinsicHeight.toFloat()
//原图大小 //原图大小
val tempSrc = MathUtils.rectFTake( val tempSrc = rectFTake(0f, 0f, imgX, imgY)
0f, //layoutParams.height = (imgY / imgX * width + 0.5).toInt()
0f, //invalidate()
drawable.intrinsicWidth.toFloat(),
drawable.intrinsicHeight.toFloat()
)
//控件大小 //控件大小
val tempDst = MathUtils.rectFTake( val tempDst = rectFTake(0f, 0f, width.toFloat(), height.toFloat())
0f, //计算fit center矩阵
0f, m.setRectToRect(tempSrc, tempDst, Matrix.ScaleToFit.CENTER)
width.toFloat(), //释放临时对象
height.toFloat() rectFGiven(tempDst)
) rectFGiven(tempSrc)
}
return m
}
fun setHeight2FitImgWidth(){
matrix.reset()
val imgX = drawable.intrinsicWidth.toFloat()
val imgY = drawable.intrinsicHeight.toFloat()
//Log.d("MySIV", "ix: $imgX, iy: $imgY, w: $width, h: $height")
//原图大小
val tempSrc = rectFTake(0f, 0f, imgX, imgY)
layoutParams.height = (imgY / imgX * width + 0.5).toInt()
invalidate()
//控件大小
val tempDst = rectFTake(0f, 0f, width.toFloat(), height.toFloat())
//计算fit center矩阵 //计算fit center矩阵
matrix.setRectToRect(tempSrc, tempDst, Matrix.ScaleToFit.CENTER) matrix.setRectToRect(tempSrc, tempDst, Matrix.ScaleToFit.CENTER)
//释放临时对象 //释放临时对象
MathUtils.rectFGiven(tempDst) rectFGiven(tempDst)
MathUtils.rectFGiven(tempSrc) rectFGiven(tempSrc)
}
return matrix
} }
/** /**
@@ -161,11 +171,10 @@ class ScaleImageView : ImageView {
*/ */
private fun getCurrentImageMatrix(matrix: Matrix): Matrix { private fun getCurrentImageMatrix(matrix: Matrix): Matrix {
//获取内部变换矩阵 //获取内部变换矩阵
var matrix = matrix val m = getInnerMatrix(matrix)
matrix = getInnerMatrix(matrix)
//乘上外部变换矩阵 //乘上外部变换矩阵
matrix.postConcat(mOuterMatrix) m.postConcat(mOuterMatrix)
return matrix return m
} }
/** /**
@@ -179,26 +188,20 @@ class ScaleImageView : ImageView {
* @see .getCurrentImageMatrix * @see .getCurrentImageMatrix
*/ */
private fun getImageBound(rectF: RectF?): RectF { private fun getImageBound(rectF: RectF?): RectF {
var rectF = rectF var rf = rectF
if (rectF == null) { if (rf == null) rf = RectF() else rf.setEmpty()
rectF = RectF() if (isReady) {
} else {
rectF.setEmpty()
}
return if (!isReady) {
rectF
} else {
//申请一个空matrix //申请一个空matrix
val matrix = MathUtils.matrixTake() val matrix = matrixTake()
//获取当前总变换矩阵 //获取当前总变换矩阵
getCurrentImageMatrix(matrix) getCurrentImageMatrix(matrix)
//对原图矩形进行变换得到当前显示矩形 //对原图矩形进行变换得到当前显示矩形
rectF[0f, 0f, drawable.intrinsicWidth.toFloat()] = drawable.intrinsicHeight.toFloat() rf[0f, 0f, drawable.intrinsicWidth.toFloat()] = drawable.intrinsicHeight.toFloat()
matrix.mapRect(rectF) matrix.mapRect(rf)
//释放临时matrix //释放临时matrix
MathUtils.matrixGiven(matrix) matrixGiven(matrix)
rectF
} }
return rf
} }
/** /**
@@ -508,11 +511,9 @@ class ScaleImageView : ImageView {
outerScale: Float outerScale: Float
): Float { ): Float {
val currentScale = innerScale * outerScale val currentScale = innerScale * outerScale
return if (currentScale < maxScale) { Log.d("MySIV", "current scale: $currentScale, max scale: $maxScale")
maxScale return if (currentScale < maxScale * 0.9f) maxScale
} else { else innerScale
innerScale
}
} }
////////////////////////////////初始化//////////////////////////////// ////////////////////////////////初始化////////////////////////////////
@@ -520,10 +521,7 @@ class ScaleImageView : ImageView {
initView() initView()
} }
constructor(context: Context?, attrs: AttributeSet?) : super( constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs) {
context,
attrs
) {
initView() initView()
} }
@@ -548,9 +546,9 @@ class ScaleImageView : ImageView {
try { try {
//在绘制前设置变换矩阵 //在绘制前设置变换矩阵
if (isReady) { if (isReady) {
val matrix = MathUtils.matrixTake() val matrix = matrixTake()
imageMatrix = getCurrentImageMatrix(matrix) imageMatrix = getCurrentImageMatrix(matrix)
MathUtils.matrixGiven(matrix) matrixGiven(matrix)
} }
//对图像做遮罩处理 //对图像做遮罩处理
if (mMask != null) { if (mMask != null) {
@@ -563,7 +561,7 @@ class ScaleImageView : ImageView {
} }
}catch (e:Exception){ }catch (e:Exception){
e.printStackTrace() e.printStackTrace()
ViewMangaActivity.va?.get()?.toolsBox?.toastError("图片加载错误", false) ViewMangaActivity.va?.get()?.toolsBox?.toastError("图片加载错误,请尝试下载后使用较低图片质量查看", false)
} }
} }
////////////////////////////////有效性判断//////////////////////////////// ////////////////////////////////有效性判断////////////////////////////////
@@ -576,75 +574,6 @@ class ScaleImageView : ImageView {
*/ */
private val isReady: Boolean private val isReady: Boolean
get() = drawable != null && drawable.intrinsicWidth > 0 && drawable.intrinsicHeight > 0 && width > 0 && height > 0 get() = drawable != null && drawable.intrinsicWidth > 0 && drawable.intrinsicHeight > 0 && width > 0 && height > 0
////////////////////////////////mask动画处理////////////////////////////////
/**
* mask修改的动画
*
* 和图片的动画相互独立.
*
@see .zoomMaskTo
*/
//private var mMaskAnimator: MaskAnimator? = null
/**
* mask变换动画
*
* 将mask从一个rect动画到另外一个rect
private inner class MaskAnimator(start: RectF, end: RectF, duration: Long) :
ValueAnimator(), AnimatorUpdateListener {
/**
* 开始mask
*/
private val mStart = FloatArray(4)
/**
* 结束mask
*/
private val mEnd = FloatArray(4)
/**
* 中间结果mask
*/
private val mResult = FloatArray(4)
override fun onAnimationUpdate(animation: ValueAnimator) {
//获取动画进度,0-1范围
val value = animation.animatedValue as Float
//根据进度对起点终点之间做插值
for (i in 0..3) {
mResult[i] = mStart[i] + (mEnd[i] - mStart[i]) * value
}
//期间mask有可能被置空了,所以判断一下
if (mMask == null) {
mMask = RectF()
}
//设置新的mask并绘制
mMask!![mResult[0], mResult[1], mResult[2]] = mResult[3]
invalidate()
}
/**
* 创建mask变换动画
*
@param start 动画起始状态
@param end 动画终点状态
@param duration 动画持续时间
*/
init {
setFloatValues(0f, 1f)
setDuration(duration)
addUpdateListener(this)
//将起点终点拷贝到数组方便计算
mStart[0] = start.left
mStart[1] = start.top
mStart[2] = start.right
mStart[3] = start.bottom
mEnd[0] = end.left
mEnd[1] = end.top
mEnd[2] = end.right
mEnd[3] = end.bottom
}
}*/
////////////////////////////////手势动画处理//////////////////////////////// ////////////////////////////////手势动画处理////////////////////////////////
/** /**
* 在单指模式下: * 在单指模式下:
@@ -766,14 +695,14 @@ class ScaleImageView : ImageView {
} }
}) })
private val isBig: Boolean private val isBig: Boolean
get() = MathUtils.getMatrixScale(mOuterMatrix)[0] > 1f get() = getMatrixScale(mOuterMatrix)[0] > 1f
@ExperimentalStdlibApi @ExperimentalStdlibApi
@SuppressLint("ClickableViewAccessibility") @SuppressLint("ClickableViewAccessibility")
override fun onTouchEvent(event: MotionEvent): Boolean { override fun onTouchEvent(event: MotionEvent): Boolean {
super.onTouchEvent(event) super.onTouchEvent(event)
val action = event.action and MotionEvent.ACTION_MASK val action = event.action and MotionEvent.ACTION_MASK
Log.d("MySi", "Outer Scale: ${MathUtils.getMatrixScale(mOuterMatrix)[0]}") Log.d("MySi", "Outer Scale: ${getMatrixScale(mOuterMatrix)[0]}")
//最后一个点抬起或者取消,结束所有模式 //最后一个点抬起或者取消,结束所有模式
if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) { if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
//如果之前是缩放模式,还需要触发一下缩放结束动画 //如果之前是缩放模式,还需要触发一下缩放结束动画
@@ -829,14 +758,14 @@ class ScaleImageView : ImageView {
//在缩放模式下移动 //在缩放模式下移动
} else if (pinchMode == PINCH_MODE_SCALE && event.pointerCount > 1) { } else if (pinchMode == PINCH_MODE_SCALE && event.pointerCount > 1) {
//两个缩放点间的距离 //两个缩放点间的距离
val distance = MathUtils.getDistance( val distance = getDistance(
event.getX(0), event.getX(0),
event.getY(0), event.getY(0),
event.getX(1), event.getX(1),
event.getY(1) event.getY(1)
) )
//保存缩放点中点 //保存缩放点中点
val lineCenter = MathUtils.getCenterPoint( val lineCenter = getCenterPoint(
event.getX(0), event.getX(0),
event.getY(0), event.getY(0),
event.getX(1), event.getX(1),
@@ -869,7 +798,7 @@ class ScaleImageView : ImageView {
return false return false
} }
//原图方框 //原图方框
val bound = MathUtils.rectFTake() val bound = rectFTake()
getImageBound(bound) getImageBound(bound)
//控件大小 //控件大小
val displayWidth = width.toFloat() val displayWidth = width.toFloat()
@@ -927,7 +856,7 @@ class ScaleImageView : ImageView {
//触发重绘 //触发重绘
//检查是否有变化 //检查是否有变化
} }
MathUtils.rectFGiven(bound) rectFGiven(bound)
//应用移动变换 //应用移动变换
mOuterMatrix.postTranslate(xDiff, yDiff) mOuterMatrix.postTranslate(xDiff, yDiff)
dispatchOuterMatrixChanged() dispatchOuterMatrixChanged()
@@ -959,13 +888,13 @@ class ScaleImageView : ImageView {
//但是有可能外部设定了不规范的值. //但是有可能外部设定了不规范的值.
//但是后续的scale操作会将xy不等的缩放值纠正,改成和x方向相同 //但是后续的scale操作会将xy不等的缩放值纠正,改成和x方向相同
mScaleBase = mScaleBase =
MathUtils.getMatrixScale(mOuterMatrix)[0] / MathUtils.getDistance(x1, y1, x2, y2) getMatrixScale(mOuterMatrix)[0] / getDistance(x1, y1, x2, y2)
//两手指的中点在屏幕上落在了图片的某个点上,图片上的这个点在经过总矩阵变换后和手指中点相同 //两手指的中点在屏幕上落在了图片的某个点上,图片上的这个点在经过总矩阵变换后和手指中点相同
//现在我们需要得到图片上这个点在图片是fit center状态下在屏幕上的位置 //现在我们需要得到图片上这个点在图片是fit center状态下在屏幕上的位置
//因为后续的计算都是基于图片是fit center状态下进行变换 //因为后续的计算都是基于图片是fit center状态下进行变换
//所以需要把两手指中点除以外层变换矩阵得到mScaleCenter //所以需要把两手指中点除以外层变换矩阵得到mScaleCenter
val center = MathUtils.inverseMatrixPoint( val center = inverseMatrixPoint(
MathUtils.getCenterPoint( getCenterPoint(
x1, x1,
y1, y1,
x2, x2,
@@ -998,14 +927,14 @@ class ScaleImageView : ImageView {
} }
//计算图片从fit center状态到目标状态的缩放比例 //计算图片从fit center状态到目标状态的缩放比例
val scale = scaleBase * distance val scale = scaleBase * distance
val matrix = MathUtils.matrixTake() val matrix = matrixTake()
//按照图片缩放中心缩放,并且让缩放中心在缩放点中点上 //按照图片缩放中心缩放,并且让缩放中心在缩放点中点上
matrix.postScale(scale, scale, scaleCenter.x, scaleCenter.y) matrix.postScale(scale, scale, scaleCenter.x, scaleCenter.y)
//让图片的缩放中点跟随手指缩放中点 //让图片的缩放中点跟随手指缩放中点
matrix.postTranslate(lineCenter.x - scaleCenter.x, lineCenter.y - scaleCenter.y) matrix.postTranslate(lineCenter.x - scaleCenter.x, lineCenter.y - scaleCenter.y)
//应用变换 //应用变换
mOuterMatrix.set(matrix) mOuterMatrix.set(matrix)
MathUtils.matrixGiven(matrix) matrixGiven(matrix)
dispatchOuterMatrixChanged() dispatchOuterMatrixChanged()
//重绘 //重绘
invalidate() invalidate()
@@ -1029,11 +958,11 @@ class ScaleImageView : ImageView {
return return
} }
//获取第一层变换矩阵 //获取第一层变换矩阵
val innerMatrix = MathUtils.matrixTake() val innerMatrix = matrixTake()
getInnerMatrix(innerMatrix) getInnerMatrix(innerMatrix)
//当前总的缩放比例 //当前总的缩放比例
val innerScale = MathUtils.getMatrixScale(innerMatrix)[0] val innerScale = getMatrixScale(innerMatrix)[0]
val outerScale = MathUtils.getMatrixScale(mOuterMatrix)[0] val outerScale = getMatrixScale(mOuterMatrix)[0]
val currentScale = innerScale * outerScale val currentScale = innerScale * outerScale
//控件大小 //控件大小
val displayWidth = width.toFloat() val displayWidth = width.toFloat()
@@ -1043,6 +972,7 @@ class ScaleImageView : ImageView {
//接下来要放大的大小 //接下来要放大的大小
var nextScale = calculateNextScale(innerScale, outerScale) var nextScale = calculateNextScale(innerScale, outerScale)
//如果接下来放大大于最大值或者小于fit center值则取边界 //如果接下来放大大于最大值或者小于fit center值则取边界
Log.d("MySIV", "Next scale: $nextScale, Max scale: $maxScale, Inner scale: $innerScale")
if (nextScale > maxScale) { if (nextScale > maxScale) {
nextScale = maxScale nextScale = maxScale
} }
@@ -1050,15 +980,15 @@ class ScaleImageView : ImageView {
nextScale = innerScale nextScale = innerScale
} }
//开始计算缩放动画的结果矩阵 //开始计算缩放动画的结果矩阵
val animEnd = MathUtils.matrixTake(mOuterMatrix) val animEnd = matrixTake(mOuterMatrix)
//计算还需缩放的倍数 //计算还需缩放的倍数
animEnd.postScale(nextScale / currentScale, nextScale / currentScale, x, y) animEnd.postScale(nextScale / currentScale, nextScale / currentScale, x, y)
//将放大点移动到控件中心 //将放大点移动到控件中心
animEnd.postTranslate(displayWidth / 2f - x, displayHeight / 2f - y) animEnd.postTranslate(displayWidth / 2f - x, displayHeight / 2f - y)
//得到放大之后的图片方框 //得到放大之后的图片方框
val testMatrix = MathUtils.matrixTake(innerMatrix) val testMatrix = matrixTake(innerMatrix)
testMatrix.postConcat(animEnd) testMatrix.postConcat(animEnd)
val testBound = MathUtils.rectFTake( val testBound = rectFTake(
0f, 0f,
0f, 0f,
drawable.intrinsicWidth.toFloat(), drawable.intrinsicWidth.toFloat(),
@@ -1106,10 +1036,10 @@ class ScaleImageView : ImageView {
mScaleAnimator = ScaleAnimator(mOuterMatrix, animEnd) mScaleAnimator = ScaleAnimator(mOuterMatrix, animEnd)
mScaleAnimator!!.start() mScaleAnimator!!.start()
//清理临时变量 //清理临时变量
MathUtils.rectFGiven(testBound) rectFGiven(testBound)
MathUtils.matrixGiven(testMatrix) matrixGiven(testMatrix)
MathUtils.matrixGiven(animEnd) matrixGiven(animEnd)
MathUtils.matrixGiven(innerMatrix) matrixGiven(innerMatrix)
} }
/** /**
@@ -1125,13 +1055,13 @@ class ScaleImageView : ImageView {
//是否修正了位置 //是否修正了位置
var change = false var change = false
//获取图片整体的变换矩阵 //获取图片整体的变换矩阵
val currentMatrix = MathUtils.matrixTake() val currentMatrix = matrixTake()
getCurrentImageMatrix(currentMatrix) getCurrentImageMatrix(currentMatrix)
//整体缩放比例 //整体缩放比例
val currentScale = val currentScale =
MathUtils.getMatrixScale(currentMatrix)[0] getMatrixScale(currentMatrix)[0]
//第二层缩放比例 //第二层缩放比例
val outerScale = MathUtils.getMatrixScale(mOuterMatrix)[0] val outerScale = getMatrixScale(mOuterMatrix)[0]
//控件大小 //控件大小
val displayWidth = width.toFloat() val displayWidth = width.toFloat()
val displayHeight = height.toFloat() val displayHeight = height.toFloat()
@@ -1155,9 +1085,9 @@ class ScaleImageView : ImageView {
change = true change = true
} }
//尝试根据缩放点进行缩放修正 //尝试根据缩放点进行缩放修正
val testMatrix = MathUtils.matrixTake(currentMatrix) val testMatrix = matrixTake(currentMatrix)
testMatrix.postScale(scalePost, scalePost, mLastMovePoint.x, mLastMovePoint.y) testMatrix.postScale(scalePost, scalePost, mLastMovePoint.x, mLastMovePoint.y)
val testBound = MathUtils.rectFTake( val testBound = rectFTake(
0f, 0f,
0f, 0f,
drawable.intrinsicWidth.toFloat(), drawable.intrinsicWidth.toFloat(),
@@ -1215,7 +1145,7 @@ class ScaleImageView : ImageView {
//只有有执行修正才执行动画 //只有有执行修正才执行动画
if (change) { if (change) {
//计算结束矩阵 //计算结束矩阵
val animEnd = MathUtils.matrixTake(mOuterMatrix) val animEnd = matrixTake(mOuterMatrix)
animEnd.postScale(scalePost, scalePost, mLastMovePoint.x, mLastMovePoint.y) animEnd.postScale(scalePost, scalePost, mLastMovePoint.x, mLastMovePoint.y)
animEnd.postTranslate(postX, postY) animEnd.postTranslate(postX, postY)
//清理当前可能正在执行的动画 //清理当前可能正在执行的动画
@@ -1224,12 +1154,12 @@ class ScaleImageView : ImageView {
mScaleAnimator = ScaleAnimator(mOuterMatrix, animEnd) mScaleAnimator = ScaleAnimator(mOuterMatrix, animEnd)
mScaleAnimator!!.start() mScaleAnimator!!.start()
//清理临时变量 //清理临时变量
MathUtils.matrixGiven(animEnd) matrixGiven(animEnd)
} }
//清理临时变量 //清理临时变量
MathUtils.rectFGiven(testBound) rectFGiven(testBound)
MathUtils.matrixGiven(testMatrix) matrixGiven(testMatrix)
MathUtils.matrixGiven(currentMatrix) matrixGiven(currentMatrix)
} }
/** /**
@@ -1288,7 +1218,7 @@ class ScaleImageView : ImageView {
mVector[0] *= FLING_DAMPING_FACTOR mVector[0] *= FLING_DAMPING_FACTOR
mVector[1] *= FLING_DAMPING_FACTOR mVector[1] *= FLING_DAMPING_FACTOR
//速度太小或者不能移动了就结束 //速度太小或者不能移动了就结束
if (!result || MathUtils.getDistance( if (!result || getDistance(
0f, 0f,
0f, 0f,
mVector[0], mVector[0],
@@ -1496,7 +1426,7 @@ class ScaleImageView : ImageView {
/** /**
* 数学计算工具类 * 数学计算工具类
*/ */
object MathUtils { companion object {
/** /**
* 矩阵对象池 * 矩阵对象池
*/ */
@@ -1505,9 +1435,7 @@ class ScaleImageView : ImageView {
/** /**
* 获取矩阵对象 * 获取矩阵对象
*/ */
fun matrixTake(): Matrix { fun matrixTake() = mMatrixPool.take()!!
return mMatrixPool.take()!!
}
/** /**
* 获取某个矩阵的copy * 获取某个矩阵的copy
@@ -1653,192 +1581,6 @@ class ScaleImageView : ImageView {
FloatArray(2) FloatArray(2)
} }
} }
/**
* 计算两个矩形之间的变换矩阵
*
* unknownMatrix.mapRect(to, from)
* 已知from矩形和to矩形,求unknownMatrix
*
@param from
@param to
@param result unknownMatrix
fun calculateRectTranslateMatrix(
from: RectF?,
to: RectF?,
result: Matrix?
) {
if (from == null || to == null || result == null) {
return
}
if (from.width() == 0f || from.height() == 0f) {
return
}
result.reset()
result.postTranslate(-from.left, -from.top)
result.postScale(to.width() / from.width(), to.height() / from.height())
result.postTranslate(to.left, to.top)
}*/
/**
* 计算图片在某个ImageView中的显示矩形
*
@param container ImageView的Rect
@param srcWidth 图片的宽度
@param srcHeight 图片的高度
@param scaleType 图片在ImageView中的ScaleType
@param result 图片应该在ImageView中展示的矩形
fun calculateScaledRectInContainer(
container: RectF?,
srcWidth: Float,
srcHeight: Float,
scaleType: ScaleType?,
result: RectF?
) {
var scaleType = scaleType
if (container == null || result == null) {
return
}
if (srcWidth == 0f || srcHeight == 0f) {
return
}
//默认scaleType为fit center
if (scaleType == null) {
scaleType = ScaleType.FIT_CENTER
}
result.setEmpty()
if (ScaleType.FIT_XY == scaleType) {
result.set(container)
} else if (ScaleType.CENTER == scaleType) {
val matrix = matrixTake()
val rect = rectFTake(0f, 0f, srcWidth, srcHeight)
matrix.setTranslate(
(container.width() - srcWidth) * 0.5f,
(container.height() - srcHeight) * 0.5f
)
matrix.mapRect(result, rect)
rectFGiven(rect)
matrixGiven(matrix)
result.left += container.left
result.right += container.left
result.top += container.top
result.bottom += container.top
} else if (ScaleType.CENTER_CROP == scaleType) {
val matrix = matrixTake()
val rect = rectFTake(0f, 0f, srcWidth, srcHeight)
val scale: Float
var dx = 0f
var dy = 0f
if (srcWidth * container.height() > container.width() * srcHeight) {
scale = container.height() / srcHeight
dx = (container.width() - srcWidth * scale) * 0.5f
} else {
scale = container.width() / srcWidth
dy = (container.height() - srcHeight * scale) * 0.5f
}
matrix.setScale(scale, scale)
matrix.postTranslate(dx, dy)
matrix.mapRect(result, rect)
rectFGiven(rect)
matrixGiven(matrix)
result.left += container.left
result.right += container.left
result.top += container.top
result.bottom += container.top
} else if (ScaleType.CENTER_INSIDE == scaleType) {
val matrix = matrixTake()
val rect = rectFTake(0f, 0f, srcWidth, srcHeight)
val scale: Float
val dx: Float
val dy: Float
scale = if (srcWidth <= container.width() && srcHeight <= container.height()) {
1f
} else {
Math.min(
container.width() / srcWidth,
container.height() / srcHeight
)
}
dx = (container.width() - srcWidth * scale) * 0.5f
dy = (container.height() - srcHeight * scale) * 0.5f
matrix.setScale(scale, scale)
matrix.postTranslate(dx, dy)
matrix.mapRect(result, rect)
rectFGiven(rect)
matrixGiven(matrix)
result.left += container.left
result.right += container.left
result.top += container.top
result.bottom += container.top
} else if (ScaleType.FIT_CENTER == scaleType) {
val matrix = matrixTake()
val rect = rectFTake(0f, 0f, srcWidth, srcHeight)
val tempSrc = rectFTake(0f, 0f, srcWidth, srcHeight)
val tempDst = rectFTake(
0f,
0f,
container.width(),
container.height()
)
matrix.setRectToRect(tempSrc, tempDst, Matrix.ScaleToFit.CENTER)
matrix.mapRect(result, rect)
rectFGiven(tempDst)
rectFGiven(tempSrc)
rectFGiven(rect)
matrixGiven(matrix)
result.left += container.left
result.right += container.left
result.top += container.top
result.bottom += container.top
} else if (ScaleType.FIT_START == scaleType) {
val matrix = matrixTake()
val rect = rectFTake(0f, 0f, srcWidth, srcHeight)
val tempSrc = rectFTake(0f, 0f, srcWidth, srcHeight)
val tempDst = rectFTake(
0f,
0f,
container.width(),
container.height()
)
matrix.setRectToRect(tempSrc, tempDst, Matrix.ScaleToFit.START)
matrix.mapRect(result, rect)
rectFGiven(tempDst)
rectFGiven(tempSrc)
rectFGiven(rect)
matrixGiven(matrix)
result.left += container.left
result.right += container.left
result.top += container.top
result.bottom += container.top
} else if (ScaleType.FIT_END == scaleType) {
val matrix = matrixTake()
val rect = rectFTake(0f, 0f, srcWidth, srcHeight)
val tempSrc = rectFTake(0f, 0f, srcWidth, srcHeight)
val tempDst = rectFTake(
0f,
0f,
container.width(),
container.height()
)
matrix.setRectToRect(tempSrc, tempDst, Matrix.ScaleToFit.END)
matrix.mapRect(result, rect)
rectFGiven(tempDst)
rectFGiven(tempSrc)
rectFGiven(rect)
matrixGiven(matrix)
result.left += container.left
result.right += container.left
result.top += container.top
result.bottom += container.top
} else {
result.set(container)
}
}*/
}
companion object {
////////////////////////////////配置参数//////////////////////////////// ////////////////////////////////配置参数////////////////////////////////
/** /**
* 图片缩放动画时间 * 图片缩放动画时间

File diff suppressed because one or more lines are too long

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<ToggleButton xmlns:android="http://schemas.android.com/apk/res/android" <top.fumiama.copymanga.view.ChapterToggleButton xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/tbtn" android:id="@+id/tbtn"
android:layout_width="64dp" android:layout_width="64dp"