阅读动画

This commit is contained in:
HapeLee
2025-11-13 23:54:00 +08:00
parent 3cda129ec9
commit 6147d243cc
4 changed files with 18 additions and 36 deletions
@@ -10,7 +10,6 @@ import android.view.ViewConfiguration
import androidx.core.app.ActivityOptionsCompat
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.doOnPreDraw
import androidx.core.view.isGone
import androidx.fragment.app.activityViewModels
import androidx.lifecycle.Lifecycle
@@ -116,10 +115,6 @@ class BooksFragment() : BaseFragment(R.layout.fragment_books),
private var enableRefresh = true
override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) {
postponeEnterTransition()
view.doOnPreDraw {
startPostponedEnterTransition()
}
arguments?.let {
position = it.getInt("position", 0)
groupId = it.getLong("groupId", -1)
@@ -248,11 +243,10 @@ class BooksFragment() : BaseFragment(R.layout.fragment_books),
).catch {
AppLog.put("书架更新出错", it)
}.conflate().flowOn(Dispatchers.Default).collect { list ->
if (view == null) return@collect
binding.emptyView.isGone = list.isNotEmpty()
binding.refreshLayout.isEnabled = enableRefresh && list.isNotEmpty()
booksAdapter.setItems(list)
delay(500)
delay(100)
}
}
}
@@ -11,7 +11,6 @@ import androidx.appcompat.widget.SearchView
import androidx.core.app.ActivityOptionsCompat
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.doOnPreDraw
import androidx.core.view.isGone
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
@@ -52,7 +51,6 @@ import io.legado.app.utils.showDialogFragment
import io.legado.app.utils.viewbindingdelegate.viewBinding
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.conflate
import kotlinx.coroutines.flow.flowOn
@@ -120,10 +118,6 @@ class BookshelfFragment2() : BaseBookshelfFragment(R.layout.fragment_bookshelf2)
override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) {
setSupportToolbar(binding.topBar)
postponeEnterTransition()
view.doOnPreDraw {
startPostponedEnterTransition()
}
initRecyclerView()
initBookGroupData()
initAllBooksData()
@@ -305,11 +299,10 @@ class BookshelfFragment2() : BaseBookshelfFragment(R.layout.fragment_bookshelf2)
).catch {
AppLog.put("书架更新出错", it)
}.conflate().flowOn(Dispatchers.Default).collect { list ->
if (view == null) return@collect
binding.emptyView.isGone = list.isNotEmpty()
binding.refreshLayout.isEnabled = enableRefresh && list.isNotEmpty()
books = list
booksAdapter.updateItems()
delay(500)
binding.emptyView.isGone = getItemCount() > 0
binding.refreshLayout.isEnabled = enableRefresh && getItemCount() > 0
}
}
}
@@ -12,6 +12,13 @@ import io.legado.app.data.entities.Book
abstract class BaseBooksAdapter<VB : ViewBinding>(context: Context) :
DiffRecyclerAdapter<Book, VB>(context) {
init {
setHasStableIds(true)
}
override fun getItemId(position: Int): Long {
return getItems()[position].bookUrl.hashCode().toLong()
}
override val keepScrollPosition = true
override val diffItemCallback: DiffUtil.ItemCallback<Book> =
@@ -11,6 +11,7 @@ import kotlinx.coroutines.flow.FlowCollector
import kotlinx.coroutines.flow.buffer
import kotlinx.coroutines.flow.callbackFlow
import kotlinx.coroutines.flow.channelFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.conflate
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.firstOrNull
@@ -235,29 +236,16 @@ fun <T> Flow<T>.flowWithLifecycleAndDatabaseChange(
fun <T> Flow<T>.flowWithLifecycleAndDatabaseChangeFirst(
lifecycle: Lifecycle,
minActiveState: Lifecycle.State = Lifecycle.State.STARTED,
minActiveState: Lifecycle.State = Lifecycle.State.RESUMED,
table: String
): Flow<T> = callbackFlow {
var update = 0
val isActive = lifecycle.currentState.isAtLeast(minActiveState)
val channel = appDb.invalidationTracker
.createFlow(table, emitInitialState = isActive)
val invalidationFlow = appDb.invalidationTracker
.createFlow(table, emitInitialState = true)
.conflate()
.onEach { update++ }
.produceIn(this)
if (!isActive) {
firstOrNull()?.let {
send(it)
}
}
lifecycle.repeatOnLifecycle(minActiveState) {
if (update == 0) {
channel.receive()
}
this@flowWithLifecycleAndDatabaseChangeFirst.collect {
update = 0
send(it)
}
combine(this@flowWithLifecycleAndDatabaseChangeFirst, invalidationFlow) { data, _ -> data }
.collect { send(it) }
}
close()
}