使用ProgressBar

This commit is contained in:
HapeLee
2025-09-05 03:38:27 +08:00
parent 3b10cb7ad7
commit ee703523de
24 changed files with 54 additions and 463 deletions
@@ -21,6 +21,7 @@ import io.legato.kazusa.utils.buildMainHandler
import io.legato.kazusa.utils.canRead import io.legato.kazusa.utils.canRead
import io.legato.kazusa.utils.checkWrite import io.legato.kazusa.utils.checkWrite
import io.legato.kazusa.utils.getFile import io.legato.kazusa.utils.getFile
import io.legato.kazusa.utils.gone
import io.legato.kazusa.utils.isContentScheme import io.legato.kazusa.utils.isContentScheme
import io.legato.kazusa.utils.readUri import io.legato.kazusa.utils.readUri
import io.legato.kazusa.utils.showDialogFragment import io.legato.kazusa.utils.showDialogFragment
@@ -28,6 +29,7 @@ import io.legato.kazusa.utils.startActivity
import io.legato.kazusa.utils.startActivityForBook import io.legato.kazusa.utils.startActivityForBook
import io.legato.kazusa.utils.toastOnUi import io.legato.kazusa.utils.toastOnUi
import io.legato.kazusa.utils.viewbindingdelegate.viewBinding import io.legato.kazusa.utils.viewbindingdelegate.viewBinding
import io.legato.kazusa.utils.visible
import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
@@ -216,7 +216,7 @@ class ChangeChapterSourceDialog() : BaseDialogFragment(R.layout.dialog_chapter_c
private fun initLiveData() { private fun initLiveData() {
viewModel.searchStateData.observe(viewLifecycleOwner) { viewModel.searchStateData.observe(viewLifecycleOwner) {
binding.refreshProgressBar.isAutoLoading = it binding.refreshProgressBar.isVisible = it
if (it) { if (it) {
startStopMenuItem?.let { item -> startStopMenuItem?.let { item ->
item.setIcon(R.drawable.ic_stop_black_24dp) item.setIcon(R.drawable.ic_stop_black_24dp)
@@ -1,5 +1,6 @@
package io.legato.kazusa.ui.book.import.local package io.legato.kazusa.ui.book.import.local
//import io.legado.app.lib.theme.backgroundColor
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.net.Uri import android.net.Uri
import android.os.Bundle import android.os.Bundle
@@ -8,6 +9,8 @@ import android.view.MenuItem
import androidx.activity.addCallback import androidx.activity.addCallback
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.appcompat.widget.PopupMenu import androidx.appcompat.widget.PopupMenu
import androidx.core.net.toUri
import androidx.core.view.isVisible
import androidx.documentfile.provider.DocumentFile import androidx.documentfile.provider.DocumentFile
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
@@ -19,7 +22,6 @@ import io.legato.kazusa.help.config.AppConfig
import io.legato.kazusa.lib.dialogs.alert import io.legato.kazusa.lib.dialogs.alert
import io.legato.kazusa.lib.permission.Permissions import io.legato.kazusa.lib.permission.Permissions
import io.legato.kazusa.lib.permission.PermissionsCompat import io.legato.kazusa.lib.permission.PermissionsCompat
//import io.legado.app.lib.theme.backgroundColor
import io.legato.kazusa.ui.book.import.BaseImportBookActivity import io.legato.kazusa.ui.book.import.BaseImportBookActivity
import io.legato.kazusa.ui.file.HandleFileContract import io.legato.kazusa.ui.file.HandleFileContract
import io.legato.kazusa.ui.widget.SelectActionBar import io.legato.kazusa.ui.widget.SelectActionBar
@@ -38,7 +40,6 @@ import kotlinx.coroutines.flow.conflate
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import java.io.File import java.io.File
import androidx.core.net.toUri
/** /**
* 导入本地书籍界面 * 导入本地书籍界面
@@ -252,12 +253,12 @@ class ImportBookActivity : BaseImportBookActivity<ImportBookViewModel>(),
viewModel.rootDoc?.let { doc -> viewModel.rootDoc?.let { doc ->
adapter.clearItems() adapter.clearItems()
val lastDoc = viewModel.subDocs.lastOrNull() ?: doc val lastDoc = viewModel.subDocs.lastOrNull() ?: doc
binding.refreshProgressBar.isAutoLoading = true binding.refreshProgressBar.isVisible = true
scanDocJob?.cancel() scanDocJob?.cancel()
scanDocJob = lifecycleScope.launch(IO) { scanDocJob = lifecycleScope.launch(IO) {
viewModel.scanDoc(lastDoc) viewModel.scanDoc(lastDoc)
withContext(Main) { withContext(Main) {
binding.refreshProgressBar.isAutoLoading = false binding.refreshProgressBar.isVisible = false
} }
} }
} }
@@ -9,6 +9,7 @@ import android.view.SubMenu
import androidx.activity.addCallback import androidx.activity.addCallback
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.core.view.isGone import androidx.core.view.isGone
import androidx.core.view.isVisible
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import io.legato.kazusa.R import io.legato.kazusa.R
@@ -59,7 +60,7 @@ class RemoteBookActivity : BaseImportBookActivity<RemoteBookViewModel>(),
initEvent() initEvent()
launch { launch {
viewModel.dataFlow.conflate().collect { sortedRemoteBooks -> viewModel.dataFlow.conflate().collect { sortedRemoteBooks ->
binding.refreshProgressBar.isAutoLoading = false binding.refreshProgressBar.isVisible = false
binding.tvEmptyMsg.isGone = sortedRemoteBooks.isNotEmpty() binding.tvEmptyMsg.isGone = sortedRemoteBooks.isNotEmpty()
adapter.setItems(sortedRemoteBooks) adapter.setItems(sortedRemoteBooks)
delay(500) delay(500)
@@ -151,11 +152,11 @@ class RemoteBookActivity : BaseImportBookActivity<RemoteBookViewModel>(),
@SuppressLint("NotifyDataSetChanged") @SuppressLint("NotifyDataSetChanged")
override fun onClickSelectBarMainAction() { override fun onClickSelectBarMainAction() {
binding.refreshProgressBar.isAutoLoading = true binding.refreshProgressBar.isVisible = true
viewModel.addToBookshelf(adapter.selected) { viewModel.addToBookshelf(adapter.selected) {
adapter.selected.clear() adapter.selected.clear()
adapter.notifyDataSetChanged() adapter.notifyDataSetChanged()
binding.refreshProgressBar.isAutoLoading = false binding.refreshProgressBar.isVisible = false
} }
} }
@@ -184,7 +185,7 @@ class RemoteBookActivity : BaseImportBookActivity<RemoteBookViewModel>(),
viewModel.loadRemoteBookList( viewModel.loadRemoteBookList(
viewModel.dirList.lastOrNull()?.path viewModel.dirList.lastOrNull()?.path
) { ) {
binding.refreshProgressBar.isAutoLoading = it binding.refreshProgressBar.isVisible = it
} }
} }
@@ -247,9 +248,9 @@ class RemoteBookActivity : BaseImportBookActivity<RemoteBookViewModel>(),
override fun addToBookShelfAgain(remoteBook: RemoteBook) { override fun addToBookShelfAgain(remoteBook: RemoteBook) {
alert(getString(R.string.sure), "是否重新加入书架?") { alert(getString(R.string.sure), "是否重新加入书架?") {
yesButton { yesButton {
binding.refreshProgressBar.isAutoLoading = true binding.refreshProgressBar.isVisible = true
viewModel.addToBookshelf(hashSetOf(remoteBook)) { viewModel.addToBookshelf(hashSetOf(remoteBook)) {
binding.refreshProgressBar.isAutoLoading = false binding.refreshProgressBar.isVisible = false
} }
} }
noButton() noButton()
@@ -1,5 +1,6 @@
package io.legato.kazusa.ui.book.read package io.legato.kazusa.ui.book.read
//import io.legado.app.lib.theme.primaryColor
import android.app.Application import android.app.Application
import android.content.DialogInterface import android.content.DialogInterface
import android.os.Bundle import android.os.Bundle
@@ -20,13 +21,13 @@ import io.legato.kazusa.help.book.ContentProcessor
import io.legato.kazusa.help.book.isLocal import io.legato.kazusa.help.book.isLocal
import io.legato.kazusa.help.coroutine.Coroutine import io.legato.kazusa.help.coroutine.Coroutine
import io.legato.kazusa.lib.dialogs.alert import io.legato.kazusa.lib.dialogs.alert
//import io.legado.app.lib.theme.primaryColor
import io.legato.kazusa.model.ReadBook import io.legato.kazusa.model.ReadBook
import io.legato.kazusa.model.webBook.WebBook import io.legato.kazusa.model.webBook.WebBook
import io.legato.kazusa.utils.applyTint import io.legato.kazusa.utils.gone
import io.legato.kazusa.utils.sendToClip import io.legato.kazusa.utils.sendToClip
import io.legato.kazusa.utils.setLayout import io.legato.kazusa.utils.setLayout
import io.legato.kazusa.utils.viewbindingdelegate.viewBinding import io.legato.kazusa.utils.viewbindingdelegate.viewBinding
import io.legato.kazusa.utils.visible
import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
@@ -10,6 +10,7 @@ import android.widget.EditText
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.appcompat.widget.SearchView import androidx.appcompat.widget.SearchView
import androidx.core.view.allViews import androidx.core.view.allViews
import androidx.core.view.isVisible
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import io.legato.kazusa.R import io.legato.kazusa.R
import io.legato.kazusa.base.VMBaseActivity import io.legato.kazusa.base.VMBaseActivity
@@ -210,7 +211,7 @@ class SearchContentActivity :
viewModel.searchResultList.clear() viewModel.searchResultList.clear()
viewModel.searchResultCounts = 0 viewModel.searchResultCounts = 0
viewModel.lastQuery = query viewModel.lastQuery = query
binding.refreshProgressBar.isAutoLoading = true binding.refreshProgressBar.isVisible = true
binding.fbStop.visible() binding.fbStop.visible()
searchJob = lifecycleScope.launch(IO) { searchJob = lifecycleScope.launch(IO) {
initJob?.join() initJob?.join()
@@ -246,7 +247,7 @@ class SearchContentActivity :
} }
binding.tvCurrentSearchInfo.post { binding.tvCurrentSearchInfo.post {
binding.fbStop.invisible() binding.fbStop.invisible()
binding.refreshProgressBar.isAutoLoading = false binding.refreshProgressBar.isVisible = false
} }
} }
} }
@@ -19,11 +19,13 @@ import io.legato.kazusa.lib.dialogs.selector
import io.legato.kazusa.ui.qrcode.QrCodeResult import io.legato.kazusa.ui.qrcode.QrCodeResult
import io.legato.kazusa.ui.widget.dialog.TextDialog import io.legato.kazusa.ui.widget.dialog.TextDialog
import io.legato.kazusa.utils.applyNavigationBarPadding import io.legato.kazusa.utils.applyNavigationBarPadding
import io.legato.kazusa.utils.gone
import io.legato.kazusa.utils.launch import io.legato.kazusa.utils.launch
import io.legato.kazusa.utils.showDialogFragment import io.legato.kazusa.utils.showDialogFragment
import io.legato.kazusa.utils.showHelp import io.legato.kazusa.utils.showHelp
import io.legato.kazusa.utils.toastOnUi import io.legato.kazusa.utils.toastOnUi
import io.legato.kazusa.utils.viewbindingdelegate.viewBinding import io.legato.kazusa.utils.viewbindingdelegate.viewBinding
import io.legato.kazusa.utils.visible
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import splitties.views.onClick import splitties.views.onClick
import splitties.views.onLongClick import splitties.views.onLongClick
@@ -218,7 +218,7 @@ class WebViewActivity : VMBaseActivity<ActivityWebViewBinding, WebViewModel>() {
override fun onProgressChanged(view: WebView?, newProgress: Int) { override fun onProgressChanged(view: WebView?, newProgress: Int) {
super.onProgressChanged(view, newProgress) super.onProgressChanged(view, newProgress)
binding.progressBar.setDurProgress(newProgress) binding.progressBar.setProgress(newProgress)
binding.progressBar.gone(newProgress == 100) binding.progressBar.gone(newProgress == 100)
} }
@@ -135,7 +135,7 @@ class WebViewLoginFragment : BaseFragment(R.layout.fragment_web_view_login) {
override fun onProgressChanged(view: WebView?, newProgress: Int) { override fun onProgressChanged(view: WebView?, newProgress: Int) {
super.onProgressChanged(view, newProgress) super.onProgressChanged(view, newProgress)
binding.progressBar.setDurProgress(newProgress) binding.progressBar.setProgress(newProgress)
binding.progressBar.gone(newProgress == 100) binding.progressBar.gone(newProgress == 100)
} }
@@ -359,7 +359,7 @@ class ReadRssActivity : VMBaseActivity<ActivityRssReadBinding, ReadRssViewModel>
override fun onProgressChanged(view: WebView?, newProgress: Int) { override fun onProgressChanged(view: WebView?, newProgress: Int) {
super.onProgressChanged(view, newProgress) super.onProgressChanged(view, newProgress)
binding.progressBar.setDurProgress(newProgress) binding.progressBar.setProgress(newProgress)
binding.progressBar.gone(newProgress == 100) binding.progressBar.gone(newProgress == 100)
} }
@@ -17,6 +17,7 @@ import io.legato.kazusa.utils.gone
import io.legato.kazusa.utils.showDialogFragment import io.legato.kazusa.utils.showDialogFragment
import io.legato.kazusa.utils.toastOnUi import io.legato.kazusa.utils.toastOnUi
import io.legato.kazusa.utils.viewbindingdelegate.viewBinding import io.legato.kazusa.utils.viewbindingdelegate.viewBinding
import io.legato.kazusa.utils.visible
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@@ -1,195 +0,0 @@
package io.legato.kazusa.ui.widget.anima
import android.content.Context
import android.graphics.Canvas
import android.graphics.Paint
import android.graphics.Rect
import android.graphics.RectF
import android.os.Looper
import android.util.AttributeSet
import android.view.View
import io.legato.kazusa.R
@Suppress("unused", "MemberVisibilityCanBePrivate")
class RefreshProgressBar @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null
) : View(context, attrs) {
private var a = 1
private var durProgress = 0
private var secondDurProgress = 0
var maxProgress = 100
var secondMaxProgress = 100
var bgColor = 0x00000000
var secondColor = -0x3e3e3f
var fontColor = -0xc9c9ca
var speed = 2
var secondFinalProgress = 0
private set
private var paint: Paint = Paint()
private val bgRect = Rect()
private val secondRect = Rect()
private val fontRectF = RectF()
var isAutoLoading: Boolean = false
set(loading) {
field = loading
if (!loading) {
secondDurProgress = 0
secondFinalProgress = 0
}
maxProgress = 0
invalidate()
}
init {
paint.style = Paint.Style.FILL
val a = context.obtainStyledAttributes(attrs, R.styleable.RefreshProgressBar)
speed = a.getDimensionPixelSize(R.styleable.RefreshProgressBar_speed, speed)
maxProgress = a.getInt(R.styleable.RefreshProgressBar_max_progress, maxProgress)
durProgress = a.getInt(R.styleable.RefreshProgressBar_dur_progress, durProgress)
secondDurProgress = a.getDimensionPixelSize(
R.styleable.RefreshProgressBar_second_dur_progress,
secondDurProgress
)
secondFinalProgress = secondDurProgress
secondMaxProgress = a.getDimensionPixelSize(
R.styleable.RefreshProgressBar_second_max_progress,
secondMaxProgress
)
bgColor = a.getColor(R.styleable.RefreshProgressBar_bg_color, bgColor)
secondColor = a.getColor(R.styleable.RefreshProgressBar_second_color, secondColor)
fontColor = a.getColor(R.styleable.RefreshProgressBar_font_color, fontColor)
a.recycle()
}
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
paint.color = bgColor
bgRect.set(0, 0, measuredWidth, measuredHeight)
canvas.drawRect(bgRect, paint)
if (secondDurProgress > 0 && secondMaxProgress > 0) {
var secondDur = secondDurProgress
if (secondDur > secondMaxProgress) {
secondDur = secondMaxProgress
}
paint.color = secondColor
val tempW =
(measuredWidth.toFloat() * 1.0f * (secondDur * 1.0f / secondMaxProgress)).toInt()
secondRect.set(
measuredWidth / 2 - tempW / 2,
0,
measuredWidth / 2 + tempW / 2,
measuredHeight
)
canvas.drawRect(secondRect, paint)
}
if (durProgress > 0 && maxProgress > 0) {
paint.color = fontColor
fontRectF.set(
0f,
0f,
measuredWidth.toFloat() * 1.0f * (durProgress * 1.0f / maxProgress),
measuredHeight.toFloat()
)
canvas.drawRect(fontRectF, paint)
}
if (this.isAutoLoading) {
if (secondDurProgress >= secondMaxProgress) {
a = -1
} else if (secondDurProgress <= 0) {
a = 1
}
secondDurProgress += a * speed
if (secondDurProgress < 0)
secondDurProgress = 0
else if (secondDurProgress > secondMaxProgress)
secondDurProgress = secondMaxProgress
secondFinalProgress = secondDurProgress
invalidate()
} else {
if (secondDurProgress != secondFinalProgress) {
if (secondDurProgress > secondFinalProgress) {
secondDurProgress -= speed
if (secondDurProgress < secondFinalProgress) {
secondDurProgress = secondFinalProgress
}
} else {
secondDurProgress += speed
if (secondDurProgress > secondFinalProgress) {
secondDurProgress = secondFinalProgress
}
}
this.invalidate()
}
}
}
fun getDurProgress(): Int {
return durProgress
}
fun setDurProgress(durProgress: Int) {
var durProgress1 = durProgress
if (durProgress1 < 0) {
durProgress1 = 0
}
if (durProgress1 > maxProgress) {
durProgress1 = maxProgress
}
this.durProgress = durProgress1
if (Looper.myLooper() == Looper.getMainLooper()) {
this.invalidate()
} else {
this.postInvalidate()
}
}
fun getSecondDurProgress(): Int {
return secondDurProgress
}
fun setSecondDurProgress(secondDur: Int) {
this.secondDurProgress = secondDur
this.secondFinalProgress = secondDurProgress
if (Looper.myLooper() == Looper.getMainLooper()) {
this.invalidate()
} else {
this.postInvalidate()
}
}
fun setSecondDurProgressWithAnim(secondDur: Int) {
var secondDur1 = secondDur
if (secondDur1 < 0) {
secondDur1 = 0
}
if (secondDur1 > secondMaxProgress) {
secondDur1 = secondMaxProgress
}
this.secondFinalProgress = secondDur1
if (Looper.myLooper() == Looper.getMainLooper()) {
this.invalidate()
} else {
this.postInvalidate()
}
}
fun clean() {
durProgress = 0
secondDurProgress = 0
secondFinalProgress = 0
if (Looper.myLooper() == Looper.getMainLooper()) {
this.invalidate()
} else {
this.postInvalidate()
}
}
}
@@ -1,228 +0,0 @@
package io.legato.kazusa.ui.widget.anima
import android.animation.Animator
import android.animation.AnimatorListenerAdapter
import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.RectF
import android.util.AttributeSet
import android.view.View
import io.legato.kazusa.R
//import io.legado.app.lib.theme.accentColor
import io.legato.kazusa.utils.dpToPx
/**
* RotateLoading
* Created by Victor on 2015/4/28.
*/
@Suppress("MemberVisibilityCanBePrivate")
class RotateLoading @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null
) : View(context, attrs) {
private var mPaint: Paint
private var loadingRectF: RectF? = null
private var shadowRectF: RectF? = null
private var topDegree = 10
private var bottomDegree = 190
private var arc: Float = 0.toFloat()
private var thisWidth: Int = 0
private var changeBigger = true
private var shadowPosition: Int = 0
private var hideMode = GONE
var isStarted = false
private set
var loadingColor: Int = 0
set(value) {
field = value
invalidate()
}
private var speedOfDegree: Int = 0
private var speedOfArc: Float = 0.toFloat()
private val shown = Runnable { this.startInternal() }
private val hidden = Runnable { this.stopInternal() }
init {
//loadingColor = context.accentColor
thisWidth = DEFAULT_WIDTH.dpToPx()
shadowPosition = DEFAULT_SHADOW_POSITION.dpToPx()
speedOfDegree = DEFAULT_SPEED_OF_DEGREE
if (null != attrs) {
val typedArray = context.obtainStyledAttributes(attrs, R.styleable.RotateLoading)
loadingColor =
typedArray.getColor(R.styleable.RotateLoading_loading_color, loadingColor)
thisWidth = typedArray.getDimensionPixelSize(
R.styleable.RotateLoading_loading_width,
DEFAULT_WIDTH.dpToPx()
)
shadowPosition = typedArray.getInt(
R.styleable.RotateLoading_shadow_position,
DEFAULT_SHADOW_POSITION
)
speedOfDegree =
typedArray.getInt(R.styleable.RotateLoading_loading_speed, DEFAULT_SPEED_OF_DEGREE)
typedArray.recycle()
}
speedOfArc = (speedOfDegree / 4).toFloat()
mPaint = Paint()
mPaint.color = loadingColor
mPaint.isAntiAlias = true
mPaint.style = Paint.Style.STROKE
mPaint.strokeWidth = thisWidth.toFloat()
mPaint.strokeCap = Paint.Cap.ROUND
}
override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
super.onSizeChanged(w, h, oldw, oldh)
arc = 10f
loadingRectF =
RectF(
(2 * thisWidth).toFloat(),
(2 * thisWidth).toFloat(),
(w - 2 * thisWidth).toFloat(),
(h - 2 * thisWidth).toFloat()
)
shadowRectF = RectF(
(2 * thisWidth + shadowPosition).toFloat(),
(2 * thisWidth + shadowPosition).toFloat(),
(w - 2 * thisWidth + shadowPosition).toFloat(),
(h - 2 * thisWidth + shadowPosition).toFloat()
)
}
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
if (!isStarted) {
return
}
mPaint.color = Color.parseColor("#1a000000")
shadowRectF?.let {
canvas.drawArc(it, topDegree.toFloat(), arc, false, mPaint)
canvas.drawArc(it, bottomDegree.toFloat(), arc, false, mPaint)
}
mPaint.color = loadingColor
loadingRectF?.let {
canvas.drawArc(it, topDegree.toFloat(), arc, false, mPaint)
canvas.drawArc(it, bottomDegree.toFloat(), arc, false, mPaint)
}
topDegree += speedOfDegree
bottomDegree += speedOfDegree
if (topDegree > 360) {
topDegree -= 360
}
if (bottomDegree > 360) {
bottomDegree -= 360
}
if (changeBigger) {
if (arc < 160) {
arc += speedOfArc
invalidate()
}
} else {
if (arc > speedOfDegree) {
arc -= 2 * speedOfArc
invalidate()
}
}
if (arc >= 160 || arc <= 10) {
changeBigger = !changeBigger
invalidate()
}
}
override fun onAttachedToWindow() {
super.onAttachedToWindow()
if (visibility == VISIBLE) {
startInternal()
}
}
override fun onDetachedFromWindow() {
super.onDetachedFromWindow()
isStarted = false
animate().cancel()
removeCallbacks(shown)
removeCallbacks(hidden)
}
fun visible() {
removeCallbacks(shown)
removeCallbacks(hidden)
post(shown)
}
fun inVisible() {
hideMode = INVISIBLE
removeCallbacks(shown)
removeCallbacks(hidden)
stopInternal()
}
fun gone() {
hideMode = GONE
removeCallbacks(shown)
removeCallbacks(hidden)
stopInternal()
}
private fun startInternal() {
startAnimator()
isStarted = true
invalidate()
}
private fun stopInternal() {
stopAnimator()
invalidate()
}
private fun startAnimator() {
animate().cancel()
animate().scaleX(1.0f)
.scaleY(1.0f)
.setListener(object : AnimatorListenerAdapter() {
override fun onAnimationStart(animation: Animator) {
visibility = VISIBLE
}
})
.start()
}
private fun stopAnimator() {
animate().cancel()
isStarted = false
this.visibility = hideMode
}
companion object {
private const val DEFAULT_WIDTH = 6
private const val DEFAULT_SHADOW_POSITION = 2
private const val DEFAULT_SPEED_OF_DEGREE = 10
}
}
@@ -45,10 +45,11 @@
tools:ignore="UnusedAttribute" /> tools:ignore="UnusedAttribute" />
</LinearLayout> </LinearLayout>
<io.legato.kazusa.ui.widget.anima.RefreshProgressBar <com.google.android.material.progressindicator.LinearProgressIndicator
android:id="@+id/refresh_progress_bar" android:id="@+id/refresh_progress_bar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="2dp" android:layout_height="wrap_content"
android:indeterminate="true"
app:layout_constraintTop_toBottomOf="@id/lay_top" /> app:layout_constraintTop_toBottomOf="@id/lay_top" />
<FrameLayout <FrameLayout
@@ -24,11 +24,11 @@
app:layout_constraintTop_toBottomOf="@+id/title_bar" app:layout_constraintTop_toBottomOf="@+id/title_bar"
app:layout_constraintBottom_toBottomOf="parent" /> app:layout_constraintBottom_toBottomOf="parent" />
<io.legato.kazusa.ui.widget.anima.RefreshProgressBar <com.google.android.material.progressindicator.LinearProgressIndicator
android:id="@+id/progress_bar" android:id="@+id/progress_bar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="1dp" android:layout_height="wrap_content"
app:max_progress="100" android:progress="100"
app:layout_constraintTop_toTopOf="@id/web_view" /> app:layout_constraintTop_toTopOf="@id/web_view" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
@@ -13,10 +13,11 @@
app:contentInsetRight="24dp" app:contentInsetRight="24dp"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
<io.legato.kazusa.ui.widget.anima.RefreshProgressBar <com.google.android.material.progressindicator.LinearProgressIndicator
android:id="@+id/refresh_progress_bar" android:id="@+id/refresh_progress_bar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="2dp" android:layout_height="wrap_content"
android:indeterminate="true"
app:layout_constraintTop_toBottomOf="@id/title_bar" /> app:layout_constraintTop_toBottomOf="@id/title_bar" />
<io.legato.kazusa.ui.widget.recycler.scroller.FastScrollRecyclerView <io.legato.kazusa.ui.widget.recycler.scroller.FastScrollRecyclerView
@@ -25,7 +25,7 @@
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@+id/title_bar" /> app:layout_constraintTop_toBottomOf="@+id/title_bar" />
<io.legato.kazusa.ui.widget.anima.RotateLoading <com.google.android.material.loadingindicator.LoadingIndicator
android:id="@+id/rotate_loading" android:id="@+id/rotate_loading"
android:layout_width="36dp" android:layout_width="36dp"
android:layout_height="36dp" android:layout_height="36dp"
@@ -5,7 +5,7 @@
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="@color/transparent50"> android:background="@color/transparent50">
<io.legato.kazusa.ui.widget.anima.RotateLoading <com.google.android.material.loadingindicator.LoadingIndicator
android:id="@+id/rotate_loading" android:id="@+id/rotate_loading"
android:layout_width="36dp" android:layout_width="36dp"
android:layout_height="36dp" android:layout_height="36dp"
@@ -24,11 +24,12 @@
app:layout_constraintTop_toBottomOf="@+id/title_bar" app:layout_constraintTop_toBottomOf="@+id/title_bar"
app:layout_constraintBottom_toBottomOf="parent" /> app:layout_constraintBottom_toBottomOf="parent" />
<io.legato.kazusa.ui.widget.anima.RefreshProgressBar <com.google.android.material.progressindicator.LinearProgressIndicator
android:id="@+id/progress_bar" android:id="@+id/progress_bar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="1dp" android:layout_height="wrap_content"
app:max_progress="100" android:indeterminate="false"
android:progress="100"
app:layout_constraintTop_toTopOf="@id/web_view" /> app:layout_constraintTop_toTopOf="@id/web_view" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
@@ -16,10 +16,11 @@
app:fitStatusBar="false" app:fitStatusBar="false"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
<io.legato.kazusa.ui.widget.anima.RefreshProgressBar <com.google.android.material.progressindicator.LinearProgressIndicator
android:id="@+id/refresh_progress_bar" android:id="@+id/refresh_progress_bar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="2dp" android:layout_height="wrap_content"
android:indeterminate="true"
app:layout_constraintTop_toBottomOf="@+id/tool_bar" /> app:layout_constraintTop_toBottomOf="@+id/tool_bar" />
<io.legato.kazusa.ui.widget.recycler.scroller.FastScrollRecyclerView <io.legato.kazusa.ui.widget.recycler.scroller.FastScrollRecyclerView
@@ -106,7 +107,7 @@
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@+id/fl_hide_toc" /> app:layout_constraintTop_toBottomOf="@+id/fl_hide_toc" />
<io.legato.kazusa.ui.widget.anima.RotateLoading <com.google.android.material.loadingindicator.LoadingIndicator
android:id="@+id/loading_toc" android:id="@+id/loading_toc"
android:layout_width="48dp" android:layout_width="48dp"
android:layout_height="48dp" android:layout_height="48dp"
@@ -23,7 +23,7 @@
app:layout_constraintTop_toBottomOf="@+id/tool_bar" app:layout_constraintTop_toBottomOf="@+id/tool_bar"
app:layout_constraintBottom_toBottomOf="parent" /> app:layout_constraintBottom_toBottomOf="parent" />
<io.legato.kazusa.ui.widget.anima.RotateLoading <com.google.android.material.loadingindicator.LoadingIndicator
android:id="@+id/rl_loading" android:id="@+id/rl_loading"
android:layout_width="60dp" android:layout_width="60dp"
android:layout_height="60dp" android:layout_height="60dp"
@@ -29,7 +29,7 @@
android:scrollbars="none" android:scrollbars="none"
tools:ignore="SpeakableTextPresentCheck" /> tools:ignore="SpeakableTextPresentCheck" />
<io.legato.kazusa.ui.widget.anima.RotateLoading <com.google.android.material.loadingindicator.LoadingIndicator
android:id="@+id/rotate_loading" android:id="@+id/rotate_loading"
android:layout_width="36dp" android:layout_width="36dp"
android:layout_height="36dp" android:layout_height="36dp"
@@ -20,11 +20,11 @@
app:layout_constraintTop_toBottomOf="@+id/title_bar" app:layout_constraintTop_toBottomOf="@+id/title_bar"
app:layout_constraintBottom_toBottomOf="parent" /> app:layout_constraintBottom_toBottomOf="parent" />
<io.legato.kazusa.ui.widget.anima.RefreshProgressBar <com.google.android.material.progressindicator.LinearProgressIndicator
android:id="@+id/progress_bar" android:id="@+id/progress_bar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="1dp" android:layout_height="wrap_content"
app:max_progress="100" android:progress="100"
app:layout_constraintTop_toTopOf="@id/web_view" /> app:layout_constraintTop_toTopOf="@id/web_view" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
@@ -2,10 +2,11 @@
<merge xmlns:android="http://schemas.android.com/apk/res/android" <merge 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">
<io.legato.kazusa.ui.widget.anima.RefreshProgressBar <com.google.android.material.progressindicator.LinearProgressIndicator
android:id="@+id/refresh_progress_bar" android:id="@+id/refresh_progress_bar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="2dp" android:layout_height="wrap_content"
android:indeterminate="true"
app:layout_constraintTop_toBottomOf="@id/title_bar" /> app:layout_constraintTop_toBottomOf="@id/title_bar" />
<androidx.recyclerview.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView