From ed891c3e2b73fc47d9403c4bdf2ffc9de67dd6f5 Mon Sep 17 00:00:00 2001 From: gedoor Date: Tue, 20 Jul 2021 21:03:42 +0800 Subject: [PATCH] =?UTF-8?q?=E9=87=87=E7=94=A8Flow?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle | 1 + .../java/io/legado/app/data/dao/BookDao.kt | 16 ++-- .../io/legado/app/data/dao/BookSourceDao.kt | 24 +++--- .../ui/book/arrange/ArrangeBookActivity.kt | 28 ++++--- .../legado/app/ui/book/cache/CacheActivity.kt | 47 ++++++----- .../book/changesource/ChangeSourceDialog.kt | 16 ++-- .../app/ui/book/local/ImportBookActivity.kt | 13 ++- .../app/ui/book/search/SearchActivity.kt | 55 ++++++------ .../book/source/manage/BookSourceActivity.kt | 83 ++++++++++--------- .../book/source/manage/GroupManageDialog.kt | 23 ++--- .../bookshelf/style1/books/BooksFragment.kt | 24 +++--- .../bookshelf/style2/BookshelfFragment2.kt | 23 ++--- .../app/ui/main/explore/ExploreFragment.kt | 70 ++++++++-------- 13 files changed, 228 insertions(+), 195 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 08c49ef61..2fd7672db 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -169,6 +169,7 @@ dependencies { //room def room_version = '2.3.0' implementation("androidx.room:room-runtime:$room_version") + implementation("androidx.room:room-ktx:$room_version") kapt("androidx.room:room-compiler:$room_version") testImplementation("androidx.room:room-testing:$room_version") diff --git a/app/src/main/java/io/legado/app/data/dao/BookDao.kt b/app/src/main/java/io/legado/app/data/dao/BookDao.kt index 9a2a5a0db..e541bf37e 100644 --- a/app/src/main/java/io/legado/app/data/dao/BookDao.kt +++ b/app/src/main/java/io/legado/app/data/dao/BookDao.kt @@ -1,33 +1,33 @@ package io.legado.app.data.dao -import androidx.lifecycle.LiveData import androidx.room.* import io.legado.app.constant.BookType import io.legado.app.data.entities.Book +import kotlinx.coroutines.flow.Flow @Dao interface BookDao { @Query("SELECT * FROM books order by durChapterTime desc") - fun observeAll(): LiveData> + fun observeAll(): Flow> @Query("SELECT * FROM books WHERE type = ${BookType.audio}") - fun observeAudio(): LiveData> + fun observeAudio(): Flow> @Query("SELECT * FROM books WHERE origin = '${BookType.local}'") - fun observeLocal(): LiveData> + fun observeLocal(): Flow> @Query("select * from books where type != ${BookType.audio} and origin != '${BookType.local}' and ((SELECT sum(groupId) FROM book_groups where groupId > 0) & `group`) = 0") - fun observeNoGroup(): LiveData> + fun observeNoGroup(): Flow> @Query("SELECT bookUrl FROM books WHERE origin = '${BookType.local}'") - fun observeLocalUri(): LiveData> + fun observeLocalUri(): Flow> @Query("SELECT * FROM books WHERE (`group` & :group) > 0") - fun observeByGroup(group: Long): LiveData> + fun observeByGroup(group: Long): Flow> @Query("SELECT * FROM books WHERE name like '%'||:key||'%' or author like '%'||:key||'%'") - fun liveDataSearch(key: String): LiveData> + fun liveDataSearch(key: String): Flow> @Query("SELECT * FROM books WHERE (`group` & :group) > 0") fun getBooksByGroup(group: Long): List diff --git a/app/src/main/java/io/legado/app/data/dao/BookSourceDao.kt b/app/src/main/java/io/legado/app/data/dao/BookSourceDao.kt index a9d113098..7bc28742d 100644 --- a/app/src/main/java/io/legado/app/data/dao/BookSourceDao.kt +++ b/app/src/main/java/io/legado/app/data/dao/BookSourceDao.kt @@ -1,14 +1,14 @@ package io.legado.app.data.dao -import androidx.lifecycle.LiveData import androidx.room.* import io.legado.app.data.entities.BookSource +import kotlinx.coroutines.flow.Flow @Dao interface BookSourceDao { @Query("select * from book_sources order by customOrder asc") - fun liveDataAll(): LiveData> + fun liveDataAll(): Flow> @Query( """ @@ -20,19 +20,19 @@ interface BookSourceDao { order by customOrder asc """ ) - fun liveDataSearch(searchKey: String): LiveData> + fun liveDataSearch(searchKey: String): Flow> @Query("select * from book_sources where bookSourceGroup like :searchKey order by customOrder asc") - fun liveDataGroupSearch(searchKey: String): LiveData> + fun liveDataGroupSearch(searchKey: String): Flow> @Query("select * from book_sources where enabled = 1 order by customOrder asc") - fun liveDataEnabled(): LiveData> + fun liveDataEnabled(): Flow> @Query("select * from book_sources where enabled = 0 order by customOrder asc") - fun liveDataDisabled(): LiveData> + fun liveDataDisabled(): Flow> @Query("select * from book_sources where enabledExplore = 1 and trim(exploreUrl) <> '' order by customOrder asc") - fun liveExplore(): LiveData> + fun liveExplore(): Flow> @Query( """ @@ -43,7 +43,7 @@ interface BookSourceDao { order by customOrder asc """ ) - fun liveExplore(key: String): LiveData> + fun liveExplore(key: String): Flow> @Query( """ @@ -54,13 +54,13 @@ interface BookSourceDao { order by customOrder asc """ ) - fun liveGroupExplore(key: String): LiveData> + fun liveGroupExplore(key: String): Flow> @Query("select distinct bookSourceGroup from book_sources where trim(bookSourceGroup) <> ''") - fun liveGroup(): LiveData> + fun liveGroup(): Flow> @Query("select distinct bookSourceGroup from book_sources where enabled = 1 and trim(bookSourceGroup) <> ''") - fun liveGroupEnabled(): LiveData> + fun liveGroupEnabled(): Flow> @Query( """ @@ -70,7 +70,7 @@ interface BookSourceDao { and trim(bookSourceGroup) <> '' """ ) - fun liveExploreGroup(): LiveData> + fun liveExploreGroup(): Flow> @Query("select * from book_sources where bookSourceGroup like '%' || :group || '%'") fun getByGroup(group: String): List diff --git a/app/src/main/java/io/legado/app/ui/book/arrange/ArrangeBookActivity.kt b/app/src/main/java/io/legado/app/ui/book/arrange/ArrangeBookActivity.kt index 63268b2d9..2495f36f0 100644 --- a/app/src/main/java/io/legado/app/ui/book/arrange/ArrangeBookActivity.kt +++ b/app/src/main/java/io/legado/app/ui/book/arrange/ArrangeBookActivity.kt @@ -28,6 +28,8 @@ import io.legado.app.utils.cnCompare import io.legado.app.utils.getPrefInt import io.legado.app.utils.viewbindingdelegate.viewBinding import kotlinx.coroutines.Dispatchers.IO +import kotlinx.coroutines.Job +import kotlinx.coroutines.flow.collect import kotlinx.coroutines.launch import kotlinx.coroutines.withContext @@ -45,7 +47,7 @@ class ArrangeBookActivity : VMBaseActivity>? = null - private var booksLiveData: LiveData>? = null + private var booksFlowJob: Job? = null private var menu: Menu? = null private var groupId: Long = -1 @@ -118,26 +120,26 @@ class ArrangeBookActivity : VMBaseActivity appDb.bookDao.observeAll() AppConst.bookGroupLocalId -> appDb.bookDao.observeLocal() AppConst.bookGroupAudioId -> appDb.bookDao.observeAudio() AppConst.bookGroupNoneId -> appDb.bookDao.observeNoGroup() else -> appDb.bookDao.observeByGroup(groupId) - } - booksLiveData?.observe(this, { list -> - val books = when (getPrefInt(PreferKey.bookshelfSort)) { - 1 -> list.sortedByDescending { it.latestChapterTime } - 2 -> list.sortedWith { o1, o2 -> - o1.name.cnCompare(o2.name) + }.collect { list -> + val books = when (getPrefInt(PreferKey.bookshelfSort)) { + 1 -> list.sortedByDescending { it.latestChapterTime } + 2 -> list.sortedWith { o1, o2 -> + o1.name.cnCompare(o2.name) + } + 3 -> list.sortedBy { it.order } + else -> list.sortedByDescending { it.durChapterTime } } - 3 -> list.sortedBy { it.order } - else -> list.sortedByDescending { it.durChapterTime } + adapter.setItems(books) } - adapter.setItems(books) - }) + } } override fun onCompatOptionsItemSelected(item: MenuItem): Boolean { diff --git a/app/src/main/java/io/legado/app/ui/book/cache/CacheActivity.kt b/app/src/main/java/io/legado/app/ui/book/cache/CacheActivity.kt index 5a3822c1d..8d24c807b 100644 --- a/app/src/main/java/io/legado/app/ui/book/cache/CacheActivity.kt +++ b/app/src/main/java/io/legado/app/ui/book/cache/CacheActivity.kt @@ -31,6 +31,8 @@ import io.legado.app.utils.* import io.legado.app.utils.viewbindingdelegate.viewBinding import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers.IO +import kotlinx.coroutines.Job +import kotlinx.coroutines.flow.collect import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import java.util.concurrent.ConcurrentHashMap @@ -45,7 +47,7 @@ class CacheActivity : VMBaseActivity() private val exportBookPathKey = "exportBookPath" lateinit var adapter: CacheAdapter private var groupLiveData: LiveData>? = null - private var booksLiveData: LiveData>? = null + private var booksFlowJob: Job? = null private var menu: Menu? = null private var exportPosition = -1 private val groupList: ArrayList = arrayListOf() @@ -147,29 +149,30 @@ class CacheActivity : VMBaseActivity() } private fun initBookData() { - booksLiveData?.removeObservers(this) - booksLiveData = when (groupId) { - AppConst.bookGroupAllId -> appDb.bookDao.observeAll() - AppConst.bookGroupLocalId -> appDb.bookDao.observeLocal() - AppConst.bookGroupAudioId -> appDb.bookDao.observeAudio() - AppConst.bookGroupNoneId -> appDb.bookDao.observeNoGroup() - else -> appDb.bookDao.observeByGroup(groupId) - } - booksLiveData?.observe(this, { list -> - val booksDownload = list.filter { - it.isOnLineTxt() - } - val books = when (getPrefInt(PreferKey.bookshelfSort)) { - 1 -> booksDownload.sortedByDescending { it.latestChapterTime } - 2 -> booksDownload.sortedWith { o1, o2 -> - o1.name.cnCompare(o2.name) + booksFlowJob?.cancel() + booksFlowJob = launch { + when (groupId) { + AppConst.bookGroupAllId -> appDb.bookDao.observeAll() + AppConst.bookGroupLocalId -> appDb.bookDao.observeLocal() + AppConst.bookGroupAudioId -> appDb.bookDao.observeAudio() + AppConst.bookGroupNoneId -> appDb.bookDao.observeNoGroup() + else -> appDb.bookDao.observeByGroup(groupId) + }.collect { list -> + val booksDownload = list.filter { + it.isOnLineTxt() + } + val books = when (getPrefInt(PreferKey.bookshelfSort)) { + 1 -> booksDownload.sortedByDescending { it.latestChapterTime } + 2 -> booksDownload.sortedWith { o1, o2 -> + o1.name.cnCompare(o2.name) + } + 3 -> booksDownload.sortedBy { it.order } + else -> booksDownload.sortedByDescending { it.durChapterTime } } - 3 -> booksDownload.sortedBy { it.order } - else -> booksDownload.sortedByDescending { it.durChapterTime } + adapter.setItems(books) + initCacheSize(books) } - adapter.setItems(books) - initCacheSize(books) - }) + } } private fun initGroupData() { diff --git a/app/src/main/java/io/legado/app/ui/book/changesource/ChangeSourceDialog.kt b/app/src/main/java/io/legado/app/ui/book/changesource/ChangeSourceDialog.kt index e83118039..969217fd8 100644 --- a/app/src/main/java/io/legado/app/ui/book/changesource/ChangeSourceDialog.kt +++ b/app/src/main/java/io/legado/app/ui/book/changesource/ChangeSourceDialog.kt @@ -22,6 +22,8 @@ import io.legado.app.ui.book.source.manage.BookSourceActivity import io.legado.app.ui.widget.recycler.VerticalDivider import io.legado.app.utils.* import io.legado.app.utils.viewbindingdelegate.viewBinding +import kotlinx.coroutines.flow.collect +import kotlinx.coroutines.launch class ChangeSourceDialog : BaseDialogFragment(), @@ -148,13 +150,15 @@ class ChangeSourceDialog : BaseDialogFragment(), viewModel.searchBooksLiveData.observe(viewLifecycleOwner, { adapter.setItems(it) }) - appDb.bookSourceDao.liveGroupEnabled().observe(this, { - groups.clear() - it.map { group -> - groups.addAll(group.splitNotBlank(AppPattern.splitGroupRegex)) + launch { + appDb.bookSourceDao.liveGroupEnabled().collect { + groups.clear() + it.map { group -> + groups.addAll(group.splitNotBlank(AppPattern.splitGroupRegex)) + } + upGroupMenu() } - upGroupMenu() - }) + } } private val stopMenuItem: MenuItem? diff --git a/app/src/main/java/io/legado/app/ui/book/local/ImportBookActivity.kt b/app/src/main/java/io/legado/app/ui/book/local/ImportBookActivity.kt index 5d45d4795..02388239e 100644 --- a/app/src/main/java/io/legado/app/ui/book/local/ImportBookActivity.kt +++ b/app/src/main/java/io/legado/app/ui/book/local/ImportBookActivity.kt @@ -9,7 +9,6 @@ import android.view.MenuItem import androidx.activity.viewModels import androidx.appcompat.widget.PopupMenu import androidx.documentfile.provider.DocumentFile -import androidx.lifecycle.LiveData import androidx.recyclerview.widget.LinearLayoutManager import io.legado.app.R import io.legado.app.base.VMBaseActivity @@ -27,6 +26,7 @@ import io.legado.app.utils.* import io.legado.app.utils.viewbindingdelegate.viewBinding import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.Dispatchers.Main +import kotlinx.coroutines.flow.collect import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import java.io.File @@ -46,7 +46,6 @@ class ImportBookActivity : VMBaseActivity() private lateinit var adapter: ImportBookAdapter - private var localUriLiveData: LiveData>? = null private var sdPath = FileUtils.getSdCardPath() private var path = sdPath private val selectFolder = registerForActivityResult(FilePicker()) { uri -> @@ -125,11 +124,11 @@ class ImportBookActivity : VMBaseActivity>? = null - private var bookData: LiveData>? = null + private var booksFlowJob: Job? = null private var menu: Menu? = null private var precisionSearchMenuItem: MenuItem? = null private var groups = linkedSetOf() @@ -58,7 +60,7 @@ class SearchActivity : VMBaseActivity - groups.addAll(group.splitNotBlank(AppPattern.splitGroupRegex)) + private fun initData() { + launch { + appDb.bookSourceDao.liveGroupEnabled().collect { + groups.clear() + it.map { group -> + groups.addAll(group.splitNotBlank(AppPattern.splitGroupRegex)) + } + upGroupMenu() } - upGroupMenu() - }) + } viewModel.searchBookLiveData.observe(this, { upSearchItems(it) }) @@ -268,23 +272,26 @@ class SearchActivity : VMBaseActivity(), @@ -52,7 +54,7 @@ class BookSourceActivity : VMBaseActivity>? = null + private var sourceFlowJob: Job? = null private val groups = linkedSetOf() private var groupMenu: SubMenu? = null private var sort = Sort.Default @@ -94,7 +96,7 @@ class BookSourceActivity : VMBaseActivity { item.isChecked = true sortCheck(Sort.Default) - initLiveDataBookSource(searchView.query?.toString()) + upBookSource(searchView.query?.toString()) } R.id.menu_sort_auto -> { item.isChecked = true sortCheck(Sort.Weight) - initLiveDataBookSource(searchView.query?.toString()) + upBookSource(searchView.query?.toString()) } R.id.menu_sort_name -> { item.isChecked = true sortCheck(Sort.Name) - initLiveDataBookSource(searchView.query?.toString()) + upBookSource(searchView.query?.toString()) } R.id.menu_sort_url -> { item.isChecked = true sortCheck(Sort.Url) - initLiveDataBookSource(searchView.query?.toString()) + upBookSource(searchView.query?.toString()) } R.id.menu_sort_time -> { item.isChecked = true sortCheck(Sort.Update) - initLiveDataBookSource(searchView.query?.toString()) + upBookSource(searchView.query?.toString()) } R.id.menu_sort_enable -> { item.isChecked = true sortCheck(Sort.Enable) - initLiveDataBookSource(searchView.query?.toString()) + upBookSource(searchView.query?.toString()) } R.id.menu_enabled_group -> { searchView.setQuery(getString(R.string.enabled), true) @@ -199,27 +201,27 @@ class BookSourceActivity : VMBaseActivity { - appDb.bookSourceDao.liveDataAll() - } - searchKey == getString(R.string.enabled) -> { - appDb.bookSourceDao.liveDataEnabled() - } - searchKey == getString(R.string.disabled) -> { - appDb.bookSourceDao.liveDataDisabled() - } - searchKey.startsWith("group:") -> { - val key = searchKey.substringAfter("group:") - appDb.bookSourceDao.liveDataGroupSearch("%$key%") - } - else -> { - appDb.bookSourceDao.liveDataSearch("%$searchKey%") - } - }.apply { - observe(this@BookSourceActivity, { data -> + private fun upBookSource(searchKey: String? = null) { + sourceFlowJob?.cancel() + sourceFlowJob = launch { + when { + searchKey.isNullOrEmpty() -> { + appDb.bookSourceDao.liveDataAll() + } + searchKey == getString(R.string.enabled) -> { + appDb.bookSourceDao.liveDataEnabled() + } + searchKey == getString(R.string.disabled) -> { + appDb.bookSourceDao.liveDataDisabled() + } + searchKey.startsWith("group:") -> { + val key = searchKey.substringAfter("group:") + appDb.bookSourceDao.liveDataGroupSearch("%$key%") + } + else -> { + appDb.bookSourceDao.liveDataSearch("%$searchKey%") + } + }.collect { data -> val sourceList = if (sortAscending) when (sort) { Sort.Weight -> data.sortedBy { it.weight } @@ -254,7 +256,7 @@ class BookSourceActivity : VMBaseActivity data.reversed() } adapter.setItems(sourceList, adapter.diffItemCallback) - }) + } } } @@ -273,13 +275,16 @@ class BookSourceActivity : VMBaseActivity - groups.addAll(group.splitNotBlank(AppPattern.splitGroupRegex)) - } - upGroupMenu() - }) + launch { + appDb.bookSourceDao.liveGroup() + .collect { + groups.clear() + it.forEach { group -> + groups.addAll(group.splitNotBlank(AppPattern.splitGroupRegex)) + } + upGroupMenu() + } + } } override fun selectAll(selectAll: Boolean) { @@ -453,7 +458,7 @@ class BookSourceActivity : VMBaseActivity() - it.map { group -> - groups.addAll(group.splitNotBlank(AppPattern.splitGroupRegex)) + launch { + appDb.bookSourceDao.liveGroup().collect { + val groups = linkedSetOf() + it.map { group -> + groups.addAll(group.splitNotBlank(AppPattern.splitGroupRegex)) + } + adapter.setItems(groups.toList()) } - adapter.setItems(groups.toList()) - }) + } } override fun onMenuItemClick(item: MenuItem?): Boolean { diff --git a/app/src/main/java/io/legado/app/ui/main/bookshelf/style1/books/BooksFragment.kt b/app/src/main/java/io/legado/app/ui/main/bookshelf/style1/books/BooksFragment.kt index ea918d46a..70ae87acc 100644 --- a/app/src/main/java/io/legado/app/ui/main/bookshelf/style1/books/BooksFragment.kt +++ b/app/src/main/java/io/legado/app/ui/main/bookshelf/style1/books/BooksFragment.kt @@ -4,7 +4,6 @@ import android.os.Bundle import android.view.View import androidx.core.view.isGone import androidx.fragment.app.activityViewModels -import androidx.lifecycle.LiveData import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView @@ -29,6 +28,9 @@ import io.legado.app.utils.getPrefInt import io.legado.app.utils.observeEvent import io.legado.app.utils.startActivity import io.legado.app.utils.viewbindingdelegate.viewBinding +import kotlinx.coroutines.Job +import kotlinx.coroutines.flow.collect +import kotlinx.coroutines.launch import kotlin.math.max /** @@ -52,7 +54,7 @@ class BooksFragment : BaseFragment(R.layout.fragment_books), private val activityViewModel: MainViewModel by activityViewModels() private lateinit var booksAdapter: BaseBooksAdapter<*> - private var bookshelfLiveData: LiveData>? = null + private var booksFlowJob: Job? = null private var position = 0 private var groupId = -1L @@ -101,15 +103,15 @@ class BooksFragment : BaseFragment(R.layout.fragment_books), } private fun upRecyclerData() { - bookshelfLiveData?.removeObservers(this) - bookshelfLiveData = when (groupId) { - AppConst.bookGroupAllId -> appDb.bookDao.observeAll() - AppConst.bookGroupLocalId -> appDb.bookDao.observeLocal() - AppConst.bookGroupAudioId -> appDb.bookDao.observeAudio() - AppConst.bookGroupNoneId -> appDb.bookDao.observeNoGroup() - else -> appDb.bookDao.observeByGroup(groupId) - }.apply { - observe(viewLifecycleOwner) { list -> + booksFlowJob?.cancel() + booksFlowJob = launch { + when (groupId) { + AppConst.bookGroupAllId -> appDb.bookDao.observeAll() + AppConst.bookGroupLocalId -> appDb.bookDao.observeLocal() + AppConst.bookGroupAudioId -> appDb.bookDao.observeAudio() + AppConst.bookGroupNoneId -> appDb.bookDao.observeNoGroup() + else -> appDb.bookDao.observeByGroup(groupId) + }.collect { list -> binding.tvEmptyMsg.isGone = list.isNotEmpty() val books = when (getPrefInt(PreferKey.bookshelfSort)) { 1 -> list.sortedByDescending { it.latestChapterTime } diff --git a/app/src/main/java/io/legado/app/ui/main/bookshelf/style2/BookshelfFragment2.kt b/app/src/main/java/io/legado/app/ui/main/bookshelf/style2/BookshelfFragment2.kt index 36bf0a16b..d3627eb23 100644 --- a/app/src/main/java/io/legado/app/ui/main/bookshelf/style2/BookshelfFragment2.kt +++ b/app/src/main/java/io/legado/app/ui/main/bookshelf/style2/BookshelfFragment2.kt @@ -32,6 +32,9 @@ import io.legado.app.utils.getPrefInt import io.legado.app.utils.observeEvent import io.legado.app.utils.startActivity import io.legado.app.utils.viewbindingdelegate.viewBinding +import kotlinx.coroutines.Job +import kotlinx.coroutines.flow.collect +import kotlinx.coroutines.launch import kotlin.math.max /** @@ -46,7 +49,7 @@ class BookshelfFragment2 : BaseBookshelfFragment(R.layout.fragment_bookshelf1), private lateinit var booksAdapter: BaseBooksAdapter<*> override var groupId = AppConst.bookGroupNoneId private var bookGroupLiveData: LiveData>? = null - private var bookshelfLiveData: LiveData>? = null + private var booksFlowJob: Job? = null private var bookGroups: List = emptyList() override var books: List = emptyList() @@ -130,15 +133,15 @@ class BookshelfFragment2 : BaseBookshelfFragment(R.layout.fragment_bookshelf1), } private fun initBooksData() { - bookshelfLiveData?.removeObservers(this) - bookshelfLiveData = when (groupId) { - AppConst.bookGroupAllId -> appDb.bookDao.observeAll() - AppConst.bookGroupLocalId -> appDb.bookDao.observeLocal() - AppConst.bookGroupAudioId -> appDb.bookDao.observeAudio() - AppConst.bookGroupNoneId -> appDb.bookDao.observeNoGroup() - else -> appDb.bookDao.observeByGroup(groupId) - }.apply { - observe(viewLifecycleOwner) { list -> + booksFlowJob?.cancel() + booksFlowJob = launch { + when (groupId) { + AppConst.bookGroupAllId -> appDb.bookDao.observeAll() + AppConst.bookGroupLocalId -> appDb.bookDao.observeLocal() + AppConst.bookGroupAudioId -> appDb.bookDao.observeAudio() + AppConst.bookGroupNoneId -> appDb.bookDao.observeNoGroup() + else -> appDb.bookDao.observeByGroup(groupId) + }.collect { list -> binding.tvEmptyMsg.isGone = list.isNotEmpty() books = when (getPrefInt(PreferKey.bookshelfSort)) { 1 -> list.sortedByDescending { diff --git a/app/src/main/java/io/legado/app/ui/main/explore/ExploreFragment.kt b/app/src/main/java/io/legado/app/ui/main/explore/ExploreFragment.kt index d8988e842..606616dab 100644 --- a/app/src/main/java/io/legado/app/ui/main/explore/ExploreFragment.kt +++ b/app/src/main/java/io/legado/app/ui/main/explore/ExploreFragment.kt @@ -8,7 +8,6 @@ import android.view.View import androidx.appcompat.widget.SearchView import androidx.core.view.isGone import androidx.fragment.app.viewModels -import androidx.lifecycle.LiveData import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView @@ -27,6 +26,9 @@ import io.legado.app.utils.cnCompare import io.legado.app.utils.splitNotBlank import io.legado.app.utils.startActivity import io.legado.app.utils.viewbindingdelegate.viewBinding +import kotlinx.coroutines.Job +import kotlinx.coroutines.flow.collect +import kotlinx.coroutines.launch /** * 发现界面 @@ -39,8 +41,7 @@ class ExploreFragment : VMBaseFragment(R.layout.fragment_explo private lateinit var linearLayoutManager: LinearLayoutManager private lateinit var searchView: SearchView private val groups = linkedSetOf() - private var liveGroup: LiveData>? = null - private var liveExplore: LiveData>? = null + private var exploreFlowJob: Job? = null private var groupsMenu: SubMenu? = null override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) { @@ -49,7 +50,7 @@ class ExploreFragment : VMBaseFragment(R.layout.fragment_explo initSearchView() initRecyclerView() initGroupData() - initExploreData() + upExploreData() } override fun onCompatCreateOptionsMenu(menu: Menu) { @@ -76,7 +77,7 @@ class ExploreFragment : VMBaseFragment(R.layout.fragment_explo } override fun onQueryTextChange(newText: String?): Boolean { - initExploreData(newText) + upExploreData(newText) return false } }) @@ -100,38 +101,41 @@ class ExploreFragment : VMBaseFragment(R.layout.fragment_explo } private fun initGroupData() { - liveGroup?.removeObservers(viewLifecycleOwner) - liveGroup = appDb.bookSourceDao.liveExploreGroup() - liveGroup?.observe(viewLifecycleOwner, { - groups.clear() - it.map { group -> - groups.addAll(group.splitNotBlank(AppPattern.splitGroupRegex)) - } - upGroupsMenu() - }) + launch { + appDb.bookSourceDao.liveExploreGroup() + .collect { + groups.clear() + it.map { group -> + groups.addAll(group.splitNotBlank(AppPattern.splitGroupRegex)) + } + upGroupsMenu() + } + } } - private fun initExploreData(searchKey: String? = null) { - liveExplore?.removeObservers(viewLifecycleOwner) - liveExplore = when { - searchKey.isNullOrBlank() -> { - appDb.bookSourceDao.liveExplore() - } - searchKey.startsWith("group:") -> { - val key = searchKey.substringAfter("group:") - appDb.bookSourceDao.liveGroupExplore("%$key%") + private fun upExploreData(searchKey: String? = null) { + exploreFlowJob?.cancel() + exploreFlowJob = launch { + val exploreFlow = when { + searchKey.isNullOrBlank() -> { + appDb.bookSourceDao.liveExplore() + } + searchKey.startsWith("group:") -> { + val key = searchKey.substringAfter("group:") + appDb.bookSourceDao.liveGroupExplore("%$key%") + } + else -> { + appDb.bookSourceDao.liveExplore("%$searchKey%") + } } - else -> { - appDb.bookSourceDao.liveExplore("%$searchKey%") + exploreFlow.collect { + binding.tvEmptyMsg.isGone = it.isNotEmpty() || searchView.query.isNotEmpty() + val diffResult = DiffUtil + .calculateDiff(ExploreDiffCallBack(ArrayList(adapter.getItems()), it)) + adapter.setItems(it) + diffResult.dispatchUpdatesTo(adapter) } } - liveExplore?.observe(viewLifecycleOwner, { - binding.tvEmptyMsg.isGone = it.isNotEmpty() || searchView.query.isNotEmpty() - val diffResult = DiffUtil - .calculateDiff(ExploreDiffCallBack(ArrayList(adapter.getItems()), it)) - adapter.setItems(it) - diffResult.dispatchUpdatesTo(adapter) - }) } private fun upGroupsMenu() = groupsMenu?.let { subMenu -> @@ -151,7 +155,7 @@ class ExploreFragment : VMBaseFragment(R.layout.fragment_explo } override fun refreshData() { - initExploreData(searchView.query?.toString()) + upExploreData(searchView.query?.toString()) } override fun scrollTo(pos: Int) {