pull/1023/head
gedoor 4 years ago
parent c06da6ac9b
commit 10861ffe9f
  1. 6
      app/src/main/java/io/legado/app/help/MediaHelp.kt
  2. 7
      app/src/main/java/io/legado/app/service/BaseReadAloudService.kt
  3. 10
      app/src/main/java/io/legado/app/ui/book/arrange/ArrangeBookActivity.kt
  4. 7
      app/src/main/java/io/legado/app/ui/book/cache/CacheActivity.kt
  5. 2
      app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfFragment.kt
  6. 83
      app/src/main/java/io/legado/app/ui/main/bookshelf1/BaseBooksAdapter.kt
  7. 104
      app/src/main/java/io/legado/app/ui/main/bookshelf1/BooksAdapterGrid.kt
  8. 119
      app/src/main/java/io/legado/app/ui/main/bookshelf1/BooksAdapterList.kt
  9. 329
      app/src/main/java/io/legado/app/ui/main/bookshelf1/BookshelfFragment.kt
  10. 6
      app/src/main/java/io/legado/app/ui/widget/recycler/RecyclerViewAtPager2.kt
  11. 48
      app/src/main/res/layout/fragment_bookshelf1.xml

@ -51,9 +51,9 @@ object MediaHelp {
audioManager: AudioManager, audioManager: AudioManager,
focusRequest: AudioFocusRequestCompat? focusRequest: AudioFocusRequestCompat?
): Boolean { ): Boolean {
val request: Int = val request = focusRequest?.let {
focusRequest?.let { AudioManagerCompat.requestAudioFocus(audioManager, focusRequest) } AudioManagerCompat.requestAudioFocus(audioManager, focusRequest)
?: AudioManager.AUDIOFOCUS_REQUEST_GRANTED } ?: AudioManager.AUDIOFOCUS_REQUEST_GRANTED
return request == AudioManager.AUDIOFOCUS_REQUEST_GRANTED return request == AudioManager.AUDIOFOCUS_REQUEST_GRANTED
} }

@ -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.ui.book.read.page.entities.TextChapter
import io.legado.app.utils.getPrefBoolean import io.legado.app.utils.getPrefBoolean
import io.legado.app.utils.postEvent import io.legado.app.utils.postEvent
import io.legado.app.utils.toastOnUi
import splitties.init.appCtx import splitties.init.appCtx
abstract class BaseReadAloudService : BaseService(), abstract class BaseReadAloudService : BaseService(),
@ -202,7 +203,11 @@ abstract class BaseReadAloudService : BaseService(),
* @return 音频焦点 * @return 音频焦点
*/ */
fun requestFocus(): Boolean { fun requestFocus(): Boolean {
return MediaHelp.requestFocus(audioManager, mFocusRequest) val requestFocus = MediaHelp.requestFocus(audioManager, mFocusRequest)
if (!requestFocus) {
toastOnUi("未获取到音频焦点")
}
return requestFocus
} }
/** /**

@ -26,6 +26,9 @@ import io.legado.app.ui.widget.recycler.ItemTouchCallback
import io.legado.app.ui.widget.recycler.VerticalDivider import io.legado.app.ui.widget.recycler.VerticalDivider
import io.legado.app.utils.cnCompare import io.legado.app.utils.cnCompare
import io.legado.app.utils.getPrefInt import io.legado.app.utils.getPrefInt
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
class ArrangeBookActivity : VMBaseActivity<ActivityArrangeBookBinding, ArrangeBookViewModel>(), class ArrangeBookActivity : VMBaseActivity<ActivityArrangeBookBinding, ArrangeBookViewModel>(),
@ -50,7 +53,12 @@ class ArrangeBookActivity : VMBaseActivity<ActivityArrangeBookBinding, ArrangeBo
override fun onActivityCreated(savedInstanceState: Bundle?) { override fun onActivityCreated(savedInstanceState: Bundle?) {
groupId = intent.getLongExtra("groupId", -1) 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)
}
}
initView() initView()
initGroupData() initGroupData()
initBookData() initBookData()

@ -67,7 +67,12 @@ class CacheActivity : VMBaseActivity<ActivityCacheBookBinding, CacheViewModel>()
override fun onActivityCreated(savedInstanceState: Bundle?) { override fun onActivityCreated(savedInstanceState: Bundle?) {
groupId = intent.getLongExtra("groupId", -1) 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() initRecyclerView()
initGroupData() initGroupData()
initBookData() initBookData()

@ -87,11 +87,9 @@ class BookshelfFragment : VMBaseFragment<BookshelfViewModel>(R.layout.fragment_b
R.id.menu_add_url -> addBookByUrl() R.id.menu_add_url -> addBookByUrl()
R.id.menu_arrange_bookshelf -> startActivity<ArrangeBookActivity> { R.id.menu_arrange_bookshelf -> startActivity<ArrangeBookActivity> {
putExtra("groupId", selectedGroup.groupId) putExtra("groupId", selectedGroup.groupId)
putExtra("groupName", selectedGroup.groupName)
} }
R.id.menu_download -> startActivity<CacheActivity> { R.id.menu_download -> startActivity<CacheActivity> {
putExtra("groupId", selectedGroup.groupId) putExtra("groupId", selectedGroup.groupId)
putExtra("groupName", selectedGroup.groupName)
} }
R.id.menu_export_bookshelf -> { R.id.menu_export_bookshelf -> {
val fragment = fragmentMap[selectedGroup.groupId] val fragment = fragmentMap[selectedGroup.groupId]

@ -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<VH : RecyclerView.ViewHolder>(val context: Context) :
RecyclerView.Adapter<VH>() {
val diffItemCallback: DiffUtil.ItemCallback<Book>
get() = object : DiffUtil.ItemCallback<Book>() {
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
}
}

@ -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<BooksAdapterGrid.ItemViewHolder>(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<Any>
) {
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)
}

@ -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<BooksAdapterList.ItemViewHolder>(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<Any>
) {
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)
}

@ -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<BookshelfViewModel>(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<List<BookGroup>>? = null
private var bookshelfLiveData: LiveData<List<Book>>? = null
private var bookGroups: List<BookGroup> = emptyList()
private var books: List<Book> = 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<SearchActivity>()
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<ImportBookActivity>()
R.id.menu_add_url -> addBookByUrl()
R.id.menu_arrange_bookshelf -> startActivity<ArrangeBookActivity> {
putExtra("groupId", groupId)
}
R.id.menu_download -> startActivity<CacheActivity> {
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<SearchActivity> {
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<AudioPlayActivity> {
putExtra("bookUrl", book.bookUrl)
}
else -> startActivity<ReadBookActivity> {
putExtra("bookUrl", book.bookUrl)
}
}
}
}
override fun onItemLongClick(position: Int) {
if (position < bookGroups.size) {
} else {
val book = books[position - bookGroups.size]
startActivity<BookInfoActivity> {
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<String>(EventBus.UP_BOOK) {
booksAdapter.notification(it)
}
}
}

@ -7,6 +7,7 @@ import androidx.recyclerview.widget.RecyclerView
import kotlin.math.abs import kotlin.math.abs
class RecyclerViewAtPager2 : RecyclerView { class RecyclerViewAtPager2 : RecyclerView {
constructor(context: Context) : super(context) constructor(context: Context) : super(context)
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super( constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(
@ -17,6 +18,7 @@ class RecyclerViewAtPager2 : RecyclerView {
private var startX = 0 private var startX = 0
private var startY = 0 private var startY = 0
override fun dispatchTouchEvent(ev: MotionEvent): Boolean { override fun dispatchTouchEvent(ev: MotionEvent): Boolean {
when (ev.action) { when (ev.action) {
MotionEvent.ACTION_DOWN -> { MotionEvent.ACTION_DOWN -> {
@ -37,8 +39,10 @@ class RecyclerViewAtPager2 : RecyclerView {
parent.requestDisallowInterceptTouchEvent(true) 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) return super.dispatchTouchEvent(ev)
} }
} }

@ -0,0 +1,48 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<io.legado.app.ui.widget.TitleBar
android:id="@+id/title_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:attachToActivity="false"
app:contentLayout="@layout/view_search"
app:layout_constraintTop_toTopOf="parent"
app:title="@string/bookshelf" />
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/refresh_layout"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintTop_toBottomOf="@+id/title_bar"
app:layout_constraintBottom_toBottomOf="parent">
<io.legado.app.ui.widget.recycler.RecyclerViewAtPager2
android:id="@+id/rv_bookshelf"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:listitem="@layout/item_bookshelf_list" />
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
<TextView
android:id="@+id/tv_empty_msg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_margin="16dp"
android:gravity="center"
android:text="@string/bookshelf_empty"
android:visibility="gone"
app:layout_constraintTop_toBottomOf="@+id/title_bar"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
tools:text="TextView" />
</androidx.constraintlayout.widget.ConstraintLayout>
Loading…
Cancel
Save