1
0
mirror of https://github.com/fumiama/copymanga.git synced 2026-06-21 18:00:24 +08:00
优化
1. 主界面加载速度
This commit is contained in:
源文雨
2025-07-06 23:05:19 +09:00
parent 555d78a58f
commit dadcb1e729
15 changed files with 205 additions and 136 deletions

View File

@@ -2,7 +2,9 @@
<dictionary name="fumiama"> <dictionary name="fumiama">
<words> <words>
<w>copymanga</w> <w>copymanga</w>
<w>copymangaweb</w>
<w>dere</w> <w>dere</w>
<w>fileprovider</w>
<w>lowpan</w> <w>lowpan</w>
<w>pdwn</w> <w>pdwn</w>
<w>reilia</w> <w>reilia</w>

6
.idea/kotlinc.xml generated
View File

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="KotlinJpsPluginSettings">
<option name="version" value="2.1.0" />
</component>
</project>

View File

@@ -10,8 +10,8 @@ android {
applicationId "top.fumiama.copymangaweb" applicationId "top.fumiama.copymangaweb"
minSdkVersion 23 minSdkVersion 23
targetSdkVersion 36 targetSdkVersion 36
versionCode 15 versionCode 16
versionName '1.5.2' versionName '1.5.3'
resConfigs "zh", "zh-rCN" resConfigs "zh", "zh-rCN"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
@@ -97,7 +97,7 @@ if (propFile.canRead()){
dependencies { dependencies {
implementation fileTree(dir: "libs", include: ["*.jar"]) implementation fileTree(dir: "libs", include: ["*.jar"])
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3" implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.10.2'
implementation 'androidx.core:core-ktx:1.16.0' implementation 'androidx.core:core-ktx:1.16.0'
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.9.1' implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.9.1'
implementation 'androidx.constraintlayout:constraintlayout:2.2.1' implementation 'androidx.constraintlayout:constraintlayout:2.2.1'

View File

@@ -14,7 +14,7 @@ import android.widget.Toast
import android.widget.ToggleButton import android.widget.ToggleButton
import com.google.gson.Gson import com.google.gson.Gson
import top.fumiama.copymangaweb.R import top.fumiama.copymangaweb.R
import top.fumiama.copymangaweb.activity.MainActivity.Companion.mh import top.fumiama.copymangaweb.activity.MainActivity.Companion.wm
import top.fumiama.copymangaweb.activity.template.ToolsBoxActivity import top.fumiama.copymangaweb.activity.template.ToolsBoxActivity
import top.fumiama.copymangaweb.data.ComicStructure import top.fumiama.copymangaweb.data.ComicStructure
import top.fumiama.copymangaweb.databinding.ActivityDlBinding import top.fumiama.copymangaweb.databinding.ActivityDlBinding
@@ -51,7 +51,7 @@ class DlActivity : ToolsBoxActivity() {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
mBinding = ActivityDlBinding.inflate(layoutInflater) mBinding = ActivityDlBinding.inflate(layoutInflater)
setContentView(mBinding.root) setContentView(mBinding.root)
mh?.saveUrlsOnly = true wm?.get()?.saveUrlsOnly = true
mangaDlTools = MangaDlTools(this) mangaDlTools = MangaDlTools(this)
mBinding.dwh.apply { post { mBinding.dwh.apply { post {
settings.userAgentString = getString(R.string.pc_ua) settings.userAgentString = getString(R.string.pc_ua)
@@ -63,7 +63,7 @@ class DlActivity : ToolsBoxActivity() {
} }
override fun onDestroy() { override fun onDestroy() {
mh?.saveUrlsOnly = false wm?.get()?.saveUrlsOnly = false
wmdlt?.get()?.exit = true wmdlt?.get()?.exit = true
handler.removeCallbacksAndMessages(null) handler.removeCallbacksAndMessages(null)
super.onDestroy() super.onDestroy()

View File

@@ -62,7 +62,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 as Array<String> ViewMangaActivity.zipList = it.toList().toTypedArray()
ViewMangaActivity.cd = cd ViewMangaActivity.cd = cd
startActivity(Intent(this, ViewMangaActivity::class.java)) startActivity(Intent(this, ViewMangaActivity::class.java))
} }

View File

@@ -6,6 +6,7 @@ import android.net.Uri
import android.os.Bundle import android.os.Bundle
import android.os.Looper import android.os.Looper
import android.view.View import android.view.View
import android.view.WindowManager
import android.webkit.ValueCallback import android.webkit.ValueCallback
import android.webkit.WebView import android.webkit.WebView
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
@@ -14,9 +15,12 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import top.fumiama.copymangaweb.BuildConfig import top.fumiama.copymangaweb.BuildConfig
import top.fumiama.copymangaweb.R import top.fumiama.copymangaweb.R
import top.fumiama.copymangaweb.activity.DlActivity.Companion.json
import top.fumiama.copymangaweb.activity.template.ToolsBoxActivity import top.fumiama.copymangaweb.activity.template.ToolsBoxActivity
import top.fumiama.copymangaweb.activity.viewmodel.MainViewModel
import top.fumiama.copymangaweb.databinding.ActivityMainBinding import top.fumiama.copymangaweb.databinding.ActivityMainBinding
import top.fumiama.copymangaweb.handler.MainHandler import top.fumiama.copymangaweb.handler.MainHandler
import top.fumiama.copymangaweb.tool.MangaDlTools.Companion.wmdlt
import top.fumiama.copymangaweb.tool.SetDraggable import top.fumiama.copymangaweb.tool.SetDraggable
import top.fumiama.copymangaweb.tool.Updater import top.fumiama.copymangaweb.tool.Updater
import top.fumiama.copymangaweb.web.JS import top.fumiama.copymangaweb.web.JS
@@ -26,19 +30,23 @@ import java.lang.ref.WeakReference
class MainActivity: ToolsBoxActivity() { class MainActivity: ToolsBoxActivity() {
var uploadMessageAboveL: ValueCallback<Array<Uri>>? = null var uploadMessageAboveL: ValueCallback<Array<Uri>>? = null
var saveUrlsOnly = false
lateinit var mBinding: ActivityMainBinding lateinit var mBinding: ActivityMainBinding
private val mViewModel = MainViewModel()
@SuppressLint("JavascriptInterface") @SuppressLint("JavascriptInterface")
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
mBinding = ActivityMainBinding.inflate(layoutInflater) mBinding = ActivityMainBinding.inflate(layoutInflater)
mBinding.mainViewModel = mViewModel
mBinding.lifecycleOwner = this
setContentView(mBinding.root) setContentView(mBinding.root)
wm = WeakReference(this) wm = WeakReference(this)
mh = MainHandler(Looper.myLooper()!!) mh = MainHandler(Looper.myLooper()!!)
toolsBox.netInfo.let { toolsBox.netInfo.let {
if(it == "无网络" || it == "错误") { if(it == "无网络" || it == "错误") {
mh?.sendEmptyMessage(MainHandler.SET_FAB_TO_DOWNLOAD_LIST) setFab2DlList()
return@let return@let
} }
@@ -109,10 +117,41 @@ class MainActivity: ToolsBoxActivity() {
).check(BuildConfig.VERSION_CODE) ).check(BuildConfig.VERSION_CODE)
} }
fun onFabClicked(v: View){ fun loadHiddenUrl(u: String) {
mBinding.wh.apply { post { loadUrl(u) } }
}
fun updateLoadProgress(p: Int) {
lifecycleScope.launch { mViewModel.updateLoadProgress(p) }
}
fun setFab(content: String) {
json = content
lifecycleScope.launch {
withContext(Dispatchers.Main) {
mViewModel.showDlList.value = false
mViewModel.setFabVisibility(true)
}
}
}
fun setFab2DlList() {
lifecycleScope.launch {
withContext(Dispatchers.Main) {
mViewModel.showDlList.value = true
mViewModel.setFabVisibility(true)
}
}
}
fun hideFab() {
lifecycleScope.launch { mViewModel.setFabVisibility(false) }
}
fun onFabClicked(v: View) {
DlListActivity.currentDir = getExternalFilesDir("") DlListActivity.currentDir = getExternalFilesDir("")
startActivity( startActivity(
Intent(this, (if(mh?.showDlList == true) DlListActivity::class else DlActivity::class).java) Intent(this, (if(mViewModel.showDlList.value == true) DlListActivity::class else DlActivity::class).java)
.putExtra("title", "我的下载") .putExtra("title", "我的下载")
) )
} }
@@ -128,6 +167,26 @@ class MainActivity: ToolsBoxActivity() {
) )
} }
fun callViewManga(content: String) {
lifecycleScope.launch { withContext(Dispatchers.IO) {
val listChapter = content.split('\n')
if(!saveUrlsOnly) {
ViewMangaActivity.titleText = listChapter[0].substringBeforeLast(' ')
ViewMangaActivity.nextChapterUrl = listChapter[1].let { if(it == "null") null else it }
ViewMangaActivity.previousChapterUrl = listChapter[2].let { if(it == "null") null else it }
ViewMangaActivity.imgUrls = arrayOf()
for(i in 3 until listChapter.size) ViewMangaActivity.imgUrls += listChapter[i]
withContext(Dispatchers.Main) {
startActivity(Intent(this@MainActivity, ViewMangaActivity::class.java))
}
} else {
var imgs = arrayOf<String>()
for(i in 3 until listChapter.size) imgs += listChapter[i]
wmdlt?.get()?.setChapterImages(listChapter[0].substringAfterLast(' '), imgs)
}
} }
}
companion object { companion object {
const val FILE_CHOOSER_RESULT_CODE = 1 const val FILE_CHOOSER_RESULT_CODE = 1
var wm: WeakReference<MainActivity>? = null var wm: WeakReference<MainActivity>? = null

View File

@@ -0,0 +1,30 @@
package top.fumiama.copymangaweb.activity.viewmodel
import android.view.View
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
class MainViewModel: ViewModel() {
val progress = MutableLiveData(0)
val progressDuration = MutableLiveData(233L)
val progressVisibility = MutableLiveData(View.VISIBLE)
val fabVisibility = MutableLiveData(View.GONE)
val showDlList = MutableLiveData(false)
suspend fun updateLoadProgress(p: Int) = withContext(Dispatchers.Main) {
if(progress.value == 100 && p < 100) {
progress.value = 0
progressVisibility.value = View.VISIBLE
return@withContext
}
progress.value = p
}
suspend fun setFabVisibility(visible: Boolean) {
withContext(Dispatchers.Main) {
fabVisibility.value = if (visible) View.VISIBLE else View.GONE
}
}
}

View File

@@ -1,33 +1,19 @@
package top.fumiama.copymangaweb.handler package top.fumiama.copymangaweb.handler
import android.animation.ObjectAnimator
import android.app.Dialog import android.app.Dialog
import android.content.Intent
import android.os.Handler import android.os.Handler
import android.os.Looper import android.os.Looper
import android.os.Message import android.os.Message
import android.view.View
import android.widget.TextView import android.widget.TextView
import top.fumiama.copymangaweb.R import top.fumiama.copymangaweb.R
import top.fumiama.copymangaweb.activity.DlActivity.Companion.json
import top.fumiama.copymangaweb.activity.MainActivity.Companion.wm import top.fumiama.copymangaweb.activity.MainActivity.Companion.wm
import top.fumiama.copymangaweb.activity.ViewMangaActivity
import top.fumiama.copymangaweb.tool.MangaDlTools.Companion.wmdlt
class MainHandler(looper: Looper):Handler(looper) { class MainHandler(looper: Looper): Handler(looper) {
var saveUrlsOnly = false
var showDlList = false
private var dialog: Dialog? = null private var dialog: Dialog? = null
override fun handleMessage(msg: Message) { override fun handleMessage(msg: Message) {
super.handleMessage(msg) super.handleMessage(msg)
when(msg.what) { when(msg.what) {
LOAD_URL_IN_HIDDEN_WEB_VIEW -> loadUrlInHiddenWebView(msg.obj as String)
CALL_VIEW_MANGA -> callViewManga(msg.obj as String)
UPDATE_LOAD_PROGRESS -> updateLoadProgress(msg.arg1)
SET_FAB -> setFab(msg.obj as String)
HIDE_FAB -> hideFab()
SET_FAB_TO_DOWNLOAD_LIST -> setFab2DlList()
SHOW_LOADING_DIALOG -> { SHOW_LOADING_DIALOG -> {
wm?.get()?.apply { wm?.get()?.apply {
(dialog?:Dialog(this).also { (dialog?:Dialog(this).also {
@@ -48,52 +34,7 @@ class MainHandler(looper: Looper):Handler(looper) {
} }
} }
} }
private fun loadUrlInHiddenWebView(url: String) { wm?.get()?.mBinding?.wh?.apply { post { loadUrl(url) } } }
private fun callViewManga(content: String) = Thread{
val listChapter = content.split('\n')
if(!saveUrlsOnly) {
ViewMangaActivity.titleText = listChapter[0].substringBeforeLast(' ')
ViewMangaActivity.nextChapterUrl = listChapter[1].let { if(it == "null") null else it }
ViewMangaActivity.previousChapterUrl = listChapter[2].let { if(it == "null") null else it }
ViewMangaActivity.imgUrls = arrayOf()
for(i in 3 until listChapter.size) ViewMangaActivity.imgUrls += listChapter[i]
wm?.get()?.apply { runOnUiThread { startActivity(Intent(this, ViewMangaActivity::class.java)) } }
} else {
var imgs = arrayOf<String>()
for(i in 3 until listChapter.size) imgs += listChapter[i]
wmdlt?.get()?.setChapterImgs(listChapter[0].substringAfterLast(' '), imgs)
}
}.start()
private fun updateLoadProgress(p: Int) {
wm?.get()?.mBinding?.pw?.apply { post {
if(progress == 100 && p < 100) {
progress = 0
visibility = View.VISIBLE
}
ObjectAnimator.ofInt(this, "progress", progress, p).setDuration(233).start()
if(p == 100) postDelayed({ visibility = View.GONE }, 500)
} }
}
private fun showFab() { wm?.get()?.mBinding?.fab?.apply { post { visibility = View.VISIBLE } } }
private fun hideFab() { wm?.get()?.mBinding?.fab?.apply { post { visibility = View.GONE } } }
private fun setFab(content: String) {
//Log.d("MyMH", "Get chapter json: $content")
showDlList = false
json = content
showFab()
}
private fun setFab2DlList(){
showDlList = true
showFab()
}
companion object { companion object {
const val LOAD_URL_IN_HIDDEN_WEB_VIEW = 1
const val CALL_VIEW_MANGA = 2
const val UPDATE_LOAD_PROGRESS = 3
const val SET_FAB = 4
const val HIDE_FAB = 5
const val SET_FAB_TO_DOWNLOAD_LIST = 6
const val SHOW_LOADING_DIALOG = 7 const val SHOW_LOADING_DIALOG = 7
const val HIDE_LOADING_DIALOG = 8 const val HIDE_LOADING_DIALOG = 8
const val SET_LOADING_DIALOG_TEXT = 9 const val SET_LOADING_DIALOG_TEXT = 9

View File

@@ -41,7 +41,7 @@ class MangaDlTools(activity: DlActivity) {
} }
} }
fun setChapterImgs(hash: String, imgUrls: Array<String>){ fun setChapterImages(hash: String, imgUrls: Array<String>){
imgUrlsList?.set(p[hash].toInt(), imgUrls) imgUrlsList?.set(p[hash].toInt(), imgUrls)
sem.release() sem.release()
} }

View File

@@ -0,0 +1,30 @@
package top.fumiama.copymangaweb.view
import android.animation.ObjectAnimator
import android.view.View
import android.widget.ProgressBar
import androidx.core.animation.doOnEnd
import androidx.databinding.BindingAdapter
object BindingAdapters {
@JvmStatic
@BindingAdapter(
value = ["animateProgress", "animationDuration"],
requireAll = false
)
fun bindAnimateProgress(
view: ProgressBar,
progress: Int?,
duration: Long?
) {
if (progress == null) return
val dur = duration ?: 1000L
ObjectAnimator.ofInt(view, "progress", view.progress, progress).apply {
setDuration(dur)
start()
}.doOnEnd {
if (progress < 100) return@doOnEnd
view.apply { post { visibility = View.GONE } }
}
}
}

View File

@@ -3,9 +3,7 @@ package top.fumiama.copymangaweb.web
import android.util.Log import android.util.Log
import android.webkit.JavascriptInterface import android.webkit.JavascriptInterface
import top.fumiama.copymangaweb.R import top.fumiama.copymangaweb.R
import top.fumiama.copymangaweb.activity.MainActivity.Companion.mh
import top.fumiama.copymangaweb.activity.MainActivity.Companion.wm import top.fumiama.copymangaweb.activity.MainActivity.Companion.wm
import top.fumiama.copymangaweb.handler.MainHandler
class JS { class JS {
@JavascriptInterface @JavascriptInterface
@@ -16,14 +14,14 @@ class JS {
else -> "" else -> ""
} }
Log.d("MyJS", "Load comic: $u") Log.d("MyJS", "Load comic: $u")
mh?.obtainMessage(MainHandler.LOAD_URL_IN_HIDDEN_WEB_VIEW, u)?.sendToTarget() wm?.get()?.loadHiddenUrl(u)
} }
@JavascriptInterface @JavascriptInterface
fun hideFab() { fun hideFab() {
mh?.sendEmptyMessage(MainHandler.HIDE_FAB) wm?.get()?.hideFab()
} }
@JavascriptInterface @JavascriptInterface
fun enterProfile(){ fun enterProfile(){
mh?.sendEmptyMessage(MainHandler.SET_FAB_TO_DOWNLOAD_LIST) wm?.get()?.setFab2DlList()
} }
} }

View File

@@ -4,12 +4,13 @@ import android.util.Log
import android.webkit.JavascriptInterface import android.webkit.JavascriptInterface
import top.fumiama.copymangaweb.activity.DlActivity import top.fumiama.copymangaweb.activity.DlActivity
import top.fumiama.copymangaweb.activity.MainActivity.Companion.mh import top.fumiama.copymangaweb.activity.MainActivity.Companion.mh
import top.fumiama.copymangaweb.activity.MainActivity.Companion.wm
import top.fumiama.copymangaweb.handler.MainHandler import top.fumiama.copymangaweb.handler.MainHandler
class JSHidden { class JSHidden {
@JavascriptInterface @JavascriptInterface
fun loadChapter(listString: String){ fun loadChapter(listString: String){
mh?.obtainMessage(MainHandler.CALL_VIEW_MANGA, listString)?.sendToTarget() wm?.get()?.callViewManga(listString)
} }
@JavascriptInterface @JavascriptInterface
fun setTitle(title:String){ fun setTitle(title:String){
@@ -18,7 +19,7 @@ class JSHidden {
} }
@JavascriptInterface @JavascriptInterface
fun setFab(content: String){ fun setFab(content: String){
mh?.obtainMessage(MainHandler.SET_FAB, content)?.sendToTarget() wm?.get()?.setFab(content)
} }
@JavascriptInterface @JavascriptInterface
fun setLoadingDialog(display: Boolean) { fun setLoadingDialog(display: Boolean) {

View File

@@ -1,17 +1,18 @@
package top.fumiama.copymangaweb.web package top.fumiama.copymangaweb.web
import android.net.Uri import android.net.Uri
import android.webkit.* import android.webkit.JsPromptResult
import android.webkit.JsResult
import android.webkit.ValueCallback
import android.webkit.WebChromeClient import android.webkit.WebChromeClient
import top.fumiama.copymangaweb.activity.MainActivity.Companion.mh import android.webkit.WebView
import top.fumiama.copymangaweb.activity.MainActivity.Companion.wm import top.fumiama.copymangaweb.activity.MainActivity.Companion.wm
import top.fumiama.copymangaweb.handler.MainHandler
class WebChromeClient:WebChromeClient() { class WebChromeClient:WebChromeClient() {
override fun onProgressChanged(view: WebView?, newProgress: Int) { override fun onProgressChanged(view: WebView?, newProgress: Int) {
super.onProgressChanged(view, newProgress) super.onProgressChanged(view, newProgress)
//Log.d("MyWCC", "W progress: $newProgress") //Log.d("MyWCC", "W progress: $newProgress")
mh?.obtainMessage(MainHandler.UPDATE_LOAD_PROGRESS, newProgress, 0)?.sendToTarget() wm?.get()?.updateLoadProgress(newProgress)
} }
override fun onJsAlert( override fun onJsAlert(

View File

@@ -8,6 +8,11 @@ import android.webkit.WebResourceResponse
import android.webkit.WebView import android.webkit.WebView
import android.webkit.WebViewClient import android.webkit.WebViewClient
import android.widget.Toast import android.widget.Toast
import androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import top.fumiama.copymangaweb.R import top.fumiama.copymangaweb.R
import top.fumiama.copymangaweb.activity.MainActivity.Companion.wm import top.fumiama.copymangaweb.activity.MainActivity.Companion.wm
@@ -25,20 +30,18 @@ class WebViewClient(private val context: Context, jsFileName: String):WebViewCli
} }
override fun onPageFinished(view: WebView?, url: String?) { override fun onPageFinished(view: WebView?, url: String?) {
Thread { wm?.get()?.lifecycleScope?.launch {
Thread.sleep(500) withContext(Dispatchers.IO) {
wm?.get()?.runOnUiThread { delay(500)
view?.loadUrl(js) withContext(Dispatchers.Main) {
Log.d("MyWC", "Inject JS into: $url") view?.loadUrl(js)
super.onPageFinished(view, url) Log.d("MyWC", "Inject JS into: $url")
super.onPageFinished(view, url)
}
} }
}.start() }
} }
/*override fun onReceivedSslError(view: WebView?, handler: SslErrorHandler?, error: SslError?) {
handler?.proceed() // ignore ssl errors
}*/
override fun shouldInterceptRequest( override fun shouldInterceptRequest(
view: WebView?, view: WebView?,
request: WebResourceRequest? request: WebResourceRequest?

View File

@@ -1,44 +1,54 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" <layout 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"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools">
android:layout_width="match_parent" <data>
android:layout_height="match_parent"> <variable
name="mainViewModel"
<top.fumiama.copymangaweb.view.JSWebView type="top.fumiama.copymangaweb.activity.viewmodel.MainViewModel" />
android:id="@+id/wh" </data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" /> android:layout_height="match_parent">
<top.fumiama.copymangaweb.view.JSWebView <top.fumiama.copymangaweb.view.JSWebView
android:id="@+id/w" android:id="@+id/wh"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" /> android:layout_height="match_parent" />
<ProgressBar <top.fumiama.copymangaweb.view.JSWebView
android:id="@+id/pw" android:id="@+id/w"
style="?android:attr/progressBarStyleHorizontal" android:layout_width="match_parent"
android:layout_width="0dp" android:layout_height="match_parent" />
android:layout_height="2dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button <ProgressBar
android:id="@+id/fab" android:id="@+id/pw"
android:layout_width="64dp" style="?android:attr/progressBarStyleHorizontal"
android:layout_height="64dp" android:layout_width="0dp"
android:layout_marginEnd="24dp" android:layout_height="2dp"
android:alpha="0.8" android:visibility="@{mainViewModel.progressVisibility}"
android:background="@drawable/rndbg_round" app:animateProgress="@{mainViewModel.progress}"
android:foreground="@drawable/ic_dl" app:animationDuration="@{mainViewModel.progressDuration}"
android:foregroundGravity="center" app:layout_constraintEnd_toEndOf="parent"
android:onClick="onFabClicked" app:layout_constraintStart_toStartOf="parent"
android:visibility="gone" app:layout_constraintTop_toTopOf="parent" />
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@+id/w"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.275"
tools:visibility="visible" />
</androidx.constraintlayout.widget.ConstraintLayout> <Button
android:id="@+id/fab"
android:layout_width="64dp"
android:layout_height="64dp"
android:layout_marginEnd="24dp"
android:alpha="0.8"
android:background="@drawable/rndbg_round"
android:foreground="@drawable/ic_dl"
android:foregroundGravity="center"
android:onClick="onFabClicked"
android:visibility="@{mainViewModel.fabVisibility}"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@+id/w"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.275"
tools:visibility="visible" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>