From 10861ffe9f5baac4e1b3fa5969ee76c11a58ce10 Mon Sep 17 00:00:00 2001 From: gedoor Date: Mon, 31 May 2021 17:11:17 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/io/legado/app/help/MediaHelp.kt | 6 +- .../app/service/BaseReadAloudService.kt | 7 +- .../ui/book/arrange/ArrangeBookActivity.kt | 10 +- .../legado/app/ui/book/cache/CacheActivity.kt | 7 +- .../ui/main/bookshelf/BookshelfFragment.kt | 2 - .../ui/main/bookshelf1/BaseBooksAdapter.kt | 83 +++++ .../ui/main/bookshelf1/BooksAdapterGrid.kt | 104 ++++++ .../ui/main/bookshelf1/BooksAdapterList.kt | 119 +++++++ .../ui/main/bookshelf1/BookshelfFragment.kt | 329 ++++++++++++++++++ .../widget/recycler/RecyclerViewAtPager2.kt | 6 +- .../main/res/layout/fragment_bookshelf1.xml | 48 +++ 11 files changed, 712 insertions(+), 9 deletions(-) create mode 100644 app/src/main/java/io/legado/app/ui/main/bookshelf1/BaseBooksAdapter.kt create mode 100644 app/src/main/java/io/legado/app/ui/main/bookshelf1/BooksAdapterGrid.kt create mode 100644 app/src/main/java/io/legado/app/ui/main/bookshelf1/BooksAdapterList.kt create mode 100644 app/src/main/java/io/legado/app/ui/main/bookshelf1/BookshelfFragment.kt create mode 100644 app/src/main/res/layout/fragment_bookshelf1.xml diff --git a/app/src/main/java/io/legado/app/help/MediaHelp.kt b/app/src/main/java/io/legado/app/help/MediaHelp.kt index 31272d1d6..9153b9fd2 100644 --- a/app/src/main/java/io/legado/app/help/MediaHelp.kt +++ b/app/src/main/java/io/legado/app/help/MediaHelp.kt @@ -51,9 +51,9 @@ object MediaHelp { audioManager: AudioManager, focusRequest: AudioFocusRequestCompat? ): Boolean { - val request: Int = - focusRequest?.let { AudioManagerCompat.requestAudioFocus(audioManager, focusRequest) } - ?: AudioManager.AUDIOFOCUS_REQUEST_GRANTED + val request = focusRequest?.let { + AudioManagerCompat.requestAudioFocus(audioManager, focusRequest) + } ?: AudioManager.AUDIOFOCUS_REQUEST_GRANTED return request == AudioManager.AUDIOFOCUS_REQUEST_GRANTED } diff --git a/app/src/main/java/io/legado/app/service/BaseReadAloudService.kt b/app/src/main/java/io/legado/app/service/BaseReadAloudService.kt index c62bca0b6..a6c35c7ae 100644 --- a/app/src/main/java/io/legado/app/service/BaseReadAloudService.kt +++ b/app/src/main/java/io/legado/app/service/BaseReadAloudService.kt @@ -26,6 +26,7 @@ import io.legado.app.ui.book.read.ReadBookActivity import io.legado.app.ui.book.read.page.entities.TextChapter import io.legado.app.utils.getPrefBoolean import io.legado.app.utils.postEvent +import io.legado.app.utils.toastOnUi import splitties.init.appCtx abstract class BaseReadAloudService : BaseService(), @@ -202,7 +203,11 @@ abstract class BaseReadAloudService : BaseService(), * @return 音频焦点 */ fun requestFocus(): Boolean { - return MediaHelp.requestFocus(audioManager, mFocusRequest) + val requestFocus = MediaHelp.requestFocus(audioManager, mFocusRequest) + if (!requestFocus) { + toastOnUi("未获取到音频焦点") + } + return requestFocus } /** 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 d75e13828..0f995ea8d 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 @@ -26,6 +26,9 @@ import io.legado.app.ui.widget.recycler.ItemTouchCallback import io.legado.app.ui.widget.recycler.VerticalDivider import io.legado.app.utils.cnCompare import io.legado.app.utils.getPrefInt +import kotlinx.coroutines.Dispatchers.IO +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext class ArrangeBookActivity : VMBaseActivity(), @@ -50,7 +53,12 @@ class ArrangeBookActivity : VMBaseActivity() override fun onActivityCreated(savedInstanceState: Bundle?) { groupId = intent.getLongExtra("groupId", -1) - binding.titleBar.subtitle = intent.getStringExtra("groupName") ?: getString(R.string.all) + launch { + binding.titleBar.subtitle = withContext(IO) { + appDb.bookGroupDao.getByID(groupId)?.groupName + ?: getString(R.string.no_group) + } + } initRecyclerView() initGroupData() initBookData() diff --git a/app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfFragment.kt b/app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfFragment.kt index 4a3eab128..c291a4f99 100644 --- a/app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfFragment.kt +++ b/app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfFragment.kt @@ -87,11 +87,9 @@ class BookshelfFragment : VMBaseFragment(R.layout.fragment_b R.id.menu_add_url -> addBookByUrl() R.id.menu_arrange_bookshelf -> startActivity { putExtra("groupId", selectedGroup.groupId) - putExtra("groupName", selectedGroup.groupName) } R.id.menu_download -> startActivity { putExtra("groupId", selectedGroup.groupId) - putExtra("groupName", selectedGroup.groupName) } R.id.menu_export_bookshelf -> { val fragment = fragmentMap[selectedGroup.groupId] diff --git a/app/src/main/java/io/legado/app/ui/main/bookshelf1/BaseBooksAdapter.kt b/app/src/main/java/io/legado/app/ui/main/bookshelf1/BaseBooksAdapter.kt new file mode 100644 index 000000000..e33243e83 --- /dev/null +++ b/app/src/main/java/io/legado/app/ui/main/bookshelf1/BaseBooksAdapter.kt @@ -0,0 +1,83 @@ +package io.legado.app.ui.main.bookshelf1 + +import android.content.Context +import androidx.core.os.bundleOf +import androidx.recyclerview.widget.DiffUtil +import androidx.recyclerview.widget.RecyclerView +import io.legado.app.data.entities.Book + +abstract class BaseBooksAdapter(val context: Context) : + RecyclerView.Adapter() { + + val diffItemCallback: DiffUtil.ItemCallback + get() = object : DiffUtil.ItemCallback() { + + override fun areItemsTheSame(oldItem: Book, newItem: Book): Boolean { + return oldItem.name == newItem.name + && oldItem.author == newItem.author + } + + override fun areContentsTheSame(oldItem: Book, newItem: Book): Boolean { + return when { + oldItem.durChapterTime != newItem.durChapterTime -> false + oldItem.name != newItem.name -> false + oldItem.author != newItem.author -> false + oldItem.durChapterTitle != newItem.durChapterTitle -> false + oldItem.latestChapterTitle != newItem.latestChapterTitle -> false + oldItem.lastCheckCount != newItem.lastCheckCount -> false + oldItem.getDisplayCover() != newItem.getDisplayCover() -> false + oldItem.getUnreadChapterNum() != newItem.getUnreadChapterNum() -> false + else -> true + } + } + + override fun getChangePayload(oldItem: Book, newItem: Book): Any? { + val bundle = bundleOf() + if (oldItem.name != newItem.name) { + bundle.putString("name", newItem.name) + } + if (oldItem.author != newItem.author) { + bundle.putString("author", newItem.author) + } + if (oldItem.durChapterTitle != newItem.durChapterTitle) { + bundle.putString("dur", newItem.durChapterTitle) + } + if (oldItem.latestChapterTitle != newItem.latestChapterTitle) { + bundle.putString("last", newItem.latestChapterTitle) + } + if (oldItem.getDisplayCover() != newItem.getDisplayCover()) { + bundle.putString("cover", newItem.getDisplayCover()) + } + if (oldItem.lastCheckCount != newItem.lastCheckCount + || oldItem.durChapterTime != newItem.durChapterTime + || oldItem.getUnreadChapterNum() != newItem.getUnreadChapterNum() + || oldItem.lastCheckCount != newItem.lastCheckCount + ) { + bundle.putBoolean("refresh", true) + } + if (bundle.isEmpty) return null + return bundle + } + + } + + fun notification(bookUrl: String) { +// for (i in 0 until itemCount) { +// getItem(i)?.let { +// if (it.bookUrl == bookUrl) { +// notifyItemChanged(i, bundleOf(Pair("refresh", null))) +// return +// } +// } +// } + } + + + interface CallBack { + fun onItemClick(position: Int) + fun onItemLongClick(position: Int) + fun isUpdate(bookUrl: String): Boolean + fun getItemCount(): Int + fun getItem(position: Int): Any + } +} \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/ui/main/bookshelf1/BooksAdapterGrid.kt b/app/src/main/java/io/legado/app/ui/main/bookshelf1/BooksAdapterGrid.kt new file mode 100644 index 000000000..0bdb7ca5b --- /dev/null +++ b/app/src/main/java/io/legado/app/ui/main/bookshelf1/BooksAdapterGrid.kt @@ -0,0 +1,104 @@ +package io.legado.app.ui.main.bookshelf1 + +import android.content.Context +import android.os.Bundle +import android.view.LayoutInflater +import android.view.ViewGroup +import androidx.recyclerview.widget.RecyclerView +import io.legado.app.constant.BookType +import io.legado.app.data.entities.Book +import io.legado.app.data.entities.BookGroup +import io.legado.app.databinding.ItemBookshelfGridBinding +import io.legado.app.help.AppConfig +import io.legado.app.utils.invisible +import splitties.views.onLongClick + +class BooksAdapterGrid(context: Context, private val callBack: CallBack) : + BaseBooksAdapter(context) { + + override fun getItemCount(): Int { + return callBack.getItemCount() + } + + override fun onCreateViewHolder( + parent: ViewGroup, + viewType: Int + ): ItemViewHolder { + return ItemViewHolder( + ItemBookshelfGridBinding.inflate(LayoutInflater.from(context), parent, false) + ) + } + + override fun onBindViewHolder( + holder: ItemViewHolder, + position: Int, + payloads: MutableList + ) { + holder.binding.run { + val bundle = payloads.getOrNull(0) as? Bundle + if (bundle == null) { + super.onBindViewHolder(holder, position, payloads) + } else { + when (val item = callBack.getItem(position)) { + is Book -> { + bundle.keySet().forEach { + when (it) { + "name" -> tvName.text = item.name + "cover" -> ivCover.load( + item.getDisplayCover(), + item.name, + item.author + ) + "refresh" -> upRefresh(this, item) + } + } + } + is BookGroup -> { + tvName.text = item.groupName + } + } + + } + } + } + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + holder.binding.run { + when (val item = callBack.getItem(position)) { + is Book -> { + tvName.text = item.name + ivCover.load(item.getDisplayCover(), item.name, item.author) + upRefresh(this, item) + } + is BookGroup -> { + tvName.text = item.groupName + } + } + root.setOnClickListener { + callBack.onItemClick(position) + } + root.onLongClick { + callBack.onItemLongClick(position) + } + } + } + + private fun upRefresh(binding: ItemBookshelfGridBinding, item: Book) { + if (item.origin != BookType.local && callBack.isUpdate(item.bookUrl)) { + binding.bvUnread.invisible() + binding.rlLoading.show() + } else { + binding.rlLoading.hide() + if (AppConfig.showUnread) { + binding.bvUnread.setBadgeCount(item.getUnreadChapterNum()) + binding.bvUnread.setHighlight(item.lastCheckCount > 0) + } else { + binding.bvUnread.invisible() + } + } + } + + class ItemViewHolder(val binding: ItemBookshelfGridBinding) : + RecyclerView.ViewHolder(binding.root) + +} \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/ui/main/bookshelf1/BooksAdapterList.kt b/app/src/main/java/io/legado/app/ui/main/bookshelf1/BooksAdapterList.kt new file mode 100644 index 000000000..0748db7f3 --- /dev/null +++ b/app/src/main/java/io/legado/app/ui/main/bookshelf1/BooksAdapterList.kt @@ -0,0 +1,119 @@ +package io.legado.app.ui.main.bookshelf1 + +import android.content.Context +import android.os.Bundle +import android.view.LayoutInflater +import android.view.ViewGroup +import androidx.recyclerview.widget.RecyclerView +import io.legado.app.constant.BookType +import io.legado.app.data.entities.Book +import io.legado.app.data.entities.BookGroup +import io.legado.app.databinding.ItemBookshelfListBinding +import io.legado.app.help.AppConfig +import io.legado.app.utils.gone +import io.legado.app.utils.invisible +import io.legado.app.utils.visible +import splitties.views.onLongClick + +class BooksAdapterList(context: Context, private val callBack: CallBack) : + BaseBooksAdapter(context) { + + override fun getItemCount(): Int { + return callBack.getItemCount() + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder { + return ItemViewHolder( + ItemBookshelfListBinding.inflate(LayoutInflater.from(context), parent, false) + ) + } + + override fun onBindViewHolder( + holder: ItemViewHolder, + position: Int, + payloads: MutableList + ) { + val bundle = payloads.getOrNull(0) as? Bundle + if (bundle == null) { + super.onBindViewHolder(holder, position, payloads) + } else { + holder.binding.run { + when (val item = callBack.getItem(position)) { + is Book -> { + tvRead.text = item.durChapterTitle + tvLast.text = item.latestChapterTitle + bundle.keySet().forEach { + when (it) { + "name" -> tvName.text = item.name + "author" -> tvAuthor.text = item.author + "cover" -> ivCover.load( + item.getDisplayCover(), + item.name, + item.author + ) + "refresh" -> upRefresh(this, item) + } + } + } + is BookGroup -> { + tvName.text = item.groupName + } + } + } + } + } + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + holder.binding.run { + when (val item = callBack.getItem(position)) { + is Book -> { + tvName.text = item.name + tvAuthor.text = item.author + tvRead.text = item.durChapterTitle + tvLast.text = item.latestChapterTitle + ivCover.load(item.getDisplayCover(), item.name, item.author) + flHasNew.visible() + ivAuthor.visible() + ivLast.visible() + ivRead.visible() + upRefresh(this, item) + } + is BookGroup -> { + tvName.text = item.groupName + flHasNew.gone() + ivAuthor.gone() + ivLast.gone() + ivRead.gone() + tvAuthor.gone() + tvLast.gone() + tvRead.gone() + } + } + root.setOnClickListener { + callBack.onItemClick(position) + } + root.onLongClick { + callBack.onItemLongClick(position) + } + } + } + + private fun upRefresh(binding: ItemBookshelfListBinding, item: Book) { + if (item.origin != BookType.local && callBack.isUpdate(item.bookUrl)) { + binding.bvUnread.invisible() + binding.rlLoading.show() + } else { + binding.rlLoading.hide() + if (AppConfig.showUnread) { + binding.bvUnread.setHighlight(item.lastCheckCount > 0) + binding.bvUnread.setBadgeCount(item.getUnreadChapterNum()) + } else { + binding.bvUnread.invisible() + } + } + } + + class ItemViewHolder(val binding: ItemBookshelfListBinding) : + RecyclerView.ViewHolder(binding.root) + +} \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/ui/main/bookshelf1/BookshelfFragment.kt b/app/src/main/java/io/legado/app/ui/main/bookshelf1/BookshelfFragment.kt new file mode 100644 index 000000000..ede5e76d4 --- /dev/null +++ b/app/src/main/java/io/legado/app/ui/main/bookshelf1/BookshelfFragment.kt @@ -0,0 +1,329 @@ +package io.legado.app.ui.main.bookshelf1 + +import android.annotation.SuppressLint +import android.os.Bundle +import android.view.Menu +import android.view.MenuItem +import android.view.View +import androidx.appcompat.widget.SearchView +import androidx.core.view.isGone +import androidx.fragment.app.activityViewModels +import androidx.fragment.app.viewModels +import androidx.lifecycle.LiveData +import androidx.recyclerview.widget.GridLayoutManager +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView +import io.legado.app.R +import io.legado.app.base.VMBaseFragment +import io.legado.app.constant.AppConst +import io.legado.app.constant.BookType +import io.legado.app.constant.EventBus +import io.legado.app.constant.PreferKey +import io.legado.app.data.appDb +import io.legado.app.data.entities.Book +import io.legado.app.data.entities.BookGroup +import io.legado.app.databinding.DialogBookshelfConfigBinding +import io.legado.app.databinding.DialogEditTextBinding +import io.legado.app.databinding.FragmentBookshelf1Binding +import io.legado.app.help.AppConfig +import io.legado.app.lib.dialogs.alert +import io.legado.app.lib.theme.ATH +import io.legado.app.lib.theme.accentColor +import io.legado.app.ui.audio.AudioPlayActivity +import io.legado.app.ui.book.arrange.ArrangeBookActivity +import io.legado.app.ui.book.cache.CacheActivity +import io.legado.app.ui.book.group.GroupManageDialog +import io.legado.app.ui.book.info.BookInfoActivity +import io.legado.app.ui.book.local.ImportBookActivity +import io.legado.app.ui.book.read.ReadBookActivity +import io.legado.app.ui.book.search.SearchActivity +import io.legado.app.ui.document.FilePicker +import io.legado.app.ui.document.FilePickerParam +import io.legado.app.ui.main.MainViewModel +import io.legado.app.ui.main.bookshelf.BookshelfViewModel +import io.legado.app.utils.* +import io.legado.app.utils.viewbindingdelegate.viewBinding +import kotlin.math.max + +/** + * 书架界面 + */ +class BookshelfFragment : VMBaseFragment(R.layout.fragment_bookshelf1), + SearchView.OnQueryTextListener, + BaseBooksAdapter.CallBack { + + private val binding by viewBinding(FragmentBookshelf1Binding::bind) + override val viewModel: BookshelfViewModel by viewModels() + private val activityViewModel: MainViewModel by activityViewModels() + private lateinit var booksAdapter: BaseBooksAdapter<*> + private var groupId = AppConst.bookGroupNoneId + private var bookGroupLiveData: LiveData>? = null + private var bookshelfLiveData: LiveData>? = null + private var bookGroups: List = emptyList() + private var books: List = emptyList() + + private val importBookshelf = registerForActivityResult(FilePicker()) { + it?.readText(requireContext())?.let { text -> + viewModel.importBookshelf(text, groupId) + } + } + + override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) { + setSupportToolbar(binding.titleBar.toolbar) + initView() + initGroupData() + initBooksData() + } + + override fun onCompatCreateOptionsMenu(menu: Menu) { + menuInflater.inflate(R.menu.main_bookshelf, menu) + } + + override fun onCompatOptionsItemSelected(item: MenuItem) { + super.onCompatOptionsItemSelected(item) + when (item.itemId) { + R.id.menu_search -> startActivity() + R.id.menu_update_toc -> activityViewModel.upToc(books) + R.id.menu_bookshelf_layout -> configBookshelf() + R.id.menu_group_manage -> GroupManageDialog() + .show(childFragmentManager, "groupManageDialog") + R.id.menu_add_local -> startActivity() + R.id.menu_add_url -> addBookByUrl() + R.id.menu_arrange_bookshelf -> startActivity { + putExtra("groupId", groupId) + } + R.id.menu_download -> startActivity { + putExtra("groupId", groupId) + } + R.id.menu_export_bookshelf -> viewModel.exportBookshelf(books) { + activity?.share(it) + } + R.id.menu_import_bookshelf -> importBookshelfAlert() + } + } + + private fun initView() { + ATH.applyEdgeEffectColor(binding.rvBookshelf) + binding.refreshLayout.setColorSchemeColors(accentColor) + binding.refreshLayout.setOnRefreshListener { + binding.refreshLayout.isRefreshing = false + activityViewModel.upToc(books) + } + val bookshelfLayout = getPrefInt(PreferKey.bookshelfLayout) + if (bookshelfLayout == 0) { + binding.rvBookshelf.layoutManager = LinearLayoutManager(context) + booksAdapter = BooksAdapterList(requireContext(), this) + } else { + binding.rvBookshelf.layoutManager = GridLayoutManager(context, bookshelfLayout + 2) + booksAdapter = BooksAdapterGrid(requireContext(), this) + } + binding.rvBookshelf.adapter = booksAdapter + booksAdapter.registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() { + override fun onItemRangeInserted(positionStart: Int, itemCount: Int) { + val layoutManager = binding.rvBookshelf.layoutManager + if (positionStart == 0 && layoutManager is LinearLayoutManager) { + val scrollTo = layoutManager.findFirstVisibleItemPosition() - itemCount + binding.rvBookshelf.scrollToPosition(max(0, scrollTo)) + } + } + + override fun onItemRangeMoved(fromPosition: Int, toPosition: Int, itemCount: Int) { + val layoutManager = binding.rvBookshelf.layoutManager + if (toPosition == 0 && layoutManager is LinearLayoutManager) { + val scrollTo = layoutManager.findFirstVisibleItemPosition() - itemCount + binding.rvBookshelf.scrollToPosition(max(0, scrollTo)) + } + } + }) + } + + private fun initGroupData() { + bookGroupLiveData?.removeObservers(this) + bookGroupLiveData = appDb.bookGroupDao.liveDataShow().apply { + observe(viewLifecycleOwner) { + if (it.size != bookGroups.size) { + bookGroups = it + booksAdapter.notifyDataSetChanged() + } else { + + } + } + } + } + + 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 -> + binding.tvEmptyMsg.isGone = list.isNotEmpty() + 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 + } + } + booksAdapter.notifyDataSetChanged() + } + } + } + + override fun onQueryTextSubmit(query: String?): Boolean { + startActivity { + putExtra("key", query) + } + return false + } + + override fun onQueryTextChange(newText: String?): Boolean { + return false + } + + @SuppressLint("InflateParams") + private fun configBookshelf() { + alert(titleResource = R.string.bookshelf_layout) { + val bookshelfLayout = getPrefInt(PreferKey.bookshelfLayout) + val bookshelfSort = getPrefInt(PreferKey.bookshelfSort) + val alertBinding = + DialogBookshelfConfigBinding.inflate(layoutInflater) + .apply { + rgLayout.checkByIndex(bookshelfLayout) + rgSort.checkByIndex(bookshelfSort) + swShowUnread.isChecked = AppConfig.showUnread + } + customView { alertBinding.root } + okButton { + alertBinding.apply { + var changed = false + if (bookshelfLayout != rgLayout.getCheckedIndex()) { + putPrefInt(PreferKey.bookshelfLayout, rgLayout.getCheckedIndex()) + changed = true + } + if (bookshelfSort != rgSort.getCheckedIndex()) { + putPrefInt(PreferKey.bookshelfSort, rgSort.getCheckedIndex()) + changed = true + } + if (AppConfig.showUnread != swShowUnread.isChecked) { + AppConfig.showUnread = swShowUnread.isChecked + changed = true + } + if (changed) { + activity?.recreate() + } + } + } + noButton() + }.show() + } + + @SuppressLint("InflateParams") + private fun addBookByUrl() { + alert(titleResource = R.string.add_book_url) { + val alertBinding = DialogEditTextBinding.inflate(layoutInflater) + customView { alertBinding.root } + okButton { + alertBinding.editView.text?.toString()?.let { + viewModel.addBookByUrl(it) + } + } + noButton() + }.show() + } + + fun gotoTop() { + if (AppConfig.isEInkMode) { + binding.rvBookshelf.scrollToPosition(0) + } else { + binding.rvBookshelf.smoothScrollToPosition(0) + } + } + + private fun importBookshelfAlert() { + alert(titleResource = R.string.import_bookshelf) { + val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply { + editView.hint = "url/json" + } + customView { alertBinding.root } + okButton { + alertBinding.editView.text?.toString()?.let { + viewModel.importBookshelf(it, groupId) + } + } + noButton() + neutralButton(R.string.select_file) { + importBookshelf.launch( + FilePickerParam( + mode = FilePicker.FILE, + allowExtensions = arrayOf("txt", "json") + ) + ) + } + }.show() + } + + override fun onItemClick(position: Int) { + if (position < bookGroups.size) { + val bookGroup = bookGroups[position] + + } else { + val book = books[position - bookGroups.size] + when (book.type) { + BookType.audio -> + startActivity { + putExtra("bookUrl", book.bookUrl) + } + else -> startActivity { + putExtra("bookUrl", book.bookUrl) + } + } + } + } + + override fun onItemLongClick(position: Int) { + if (position < bookGroups.size) { + + } else { + val book = books[position - bookGroups.size] + startActivity { + putExtra("name", book.name) + putExtra("author", book.author) + } + } + } + + override fun isUpdate(bookUrl: String): Boolean { + return bookUrl in activityViewModel.updateList + } + + override fun getItemCount(): Int { + return bookGroups.size + books.size + } + + override fun getItem(position: Int): Any { + return if (position < bookGroups.size) { + bookGroups[position] + } else { + books[position - bookGroups.size] + } + } + + override fun observeLiveBus() { + super.observeLiveBus() + observeEvent(EventBus.UP_BOOK) { + booksAdapter.notification(it) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/ui/widget/recycler/RecyclerViewAtPager2.kt b/app/src/main/java/io/legado/app/ui/widget/recycler/RecyclerViewAtPager2.kt index 7ab5ed8e9..1dc4d7b5f 100644 --- a/app/src/main/java/io/legado/app/ui/widget/recycler/RecyclerViewAtPager2.kt +++ b/app/src/main/java/io/legado/app/ui/widget/recycler/RecyclerViewAtPager2.kt @@ -7,6 +7,7 @@ import androidx.recyclerview.widget.RecyclerView import kotlin.math.abs class RecyclerViewAtPager2 : RecyclerView { + constructor(context: Context) : super(context) constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super( @@ -17,6 +18,7 @@ class RecyclerViewAtPager2 : RecyclerView { private var startX = 0 private var startY = 0 + override fun dispatchTouchEvent(ev: MotionEvent): Boolean { when (ev.action) { MotionEvent.ACTION_DOWN -> { @@ -37,8 +39,10 @@ class RecyclerViewAtPager2 : RecyclerView { parent.requestDisallowInterceptTouchEvent(true) } } - MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> parent.requestDisallowInterceptTouchEvent(false) + MotionEvent.ACTION_UP, + MotionEvent.ACTION_CANCEL -> parent.requestDisallowInterceptTouchEvent(false) } return super.dispatchTouchEvent(ev) } + } \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_bookshelf1.xml b/app/src/main/res/layout/fragment_bookshelf1.xml new file mode 100644 index 000000000..f889fca92 --- /dev/null +++ b/app/src/main/res/layout/fragment_bookshelf1.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + \ No newline at end of file