pull/35/head
kunfei 5 years ago
parent 866289bae2
commit 33bcc77103
  1. 1
      app/src/main/AndroidManifest.xml
  2. 76
      app/src/main/java/io/legado/app/ui/bookshelf/BookshelfActivity.kt
  3. 11
      app/src/main/java/io/legado/app/ui/bookshelf/BookshelfViewModel.kt
  4. 40
      app/src/main/java/io/legado/app/ui/main/MainViewModel.kt
  5. 57
      app/src/main/java/io/legado/app/ui/main/bookshelf/BooksAdapter.kt
  6. 102
      app/src/main/java/io/legado/app/ui/main/bookshelf/BooksFragment.kt
  7. 9
      app/src/main/java/io/legado/app/ui/main/bookshelf/BooksViewModel.kt
  8. 98
      app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfAdapter.kt
  9. 53
      app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfFragment.kt
  10. 41
      app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfViewModel.kt
  11. 11
      app/src/main/res/layout/fragment_books.xml
  12. 15
      app/src/main/res/layout/fragment_bookshelf.xml

@ -59,7 +59,6 @@
<activity android:name=".ui.replacerule.ReplaceRuleActivity" />
<activity android:name="io.legado.app.ui.book.search.SearchActivity" />
<activity android:name=".ui.about.AboutActivity" />
<activity android:name=".ui.bookshelf.BookshelfActivity" />
<activity android:name=".ui.qrcode.QrCodeActivity" />
<activity android:name=".ui.about.DonateActivity" />
<activity android:name=".ui.book.info.BookInfoActivity" />

@ -1,76 +0,0 @@
package io.legado.app.ui.bookshelf
import android.os.Bundle
import android.widget.LinearLayout
import androidx.lifecycle.LiveData
import androidx.lifecycle.Observer
import androidx.paging.LivePagedListBuilder
import androidx.paging.PagedList
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.LinearLayoutManager
import io.legado.app.App
import io.legado.app.R
import io.legado.app.base.VMBaseActivity
import io.legado.app.data.entities.Book
import io.legado.app.lib.theme.ATH
import io.legado.app.utils.getViewModel
import kotlinx.android.synthetic.main.activity_bookshelf.*
class BookshelfActivity : VMBaseActivity<BookshelfViewModel>(R.layout.activity_bookshelf) {
override val viewModel: BookshelfViewModel
get() = getViewModel(BookshelfViewModel::class.java)
private lateinit var bookshelfAdapter: BookshelfAdapter
private var bookshelfLiveData: LiveData<PagedList<Book>>? = null
override fun onActivityCreated(savedInstanceState: Bundle?) {
if (viewModel.bookGroup == null) {
viewModel.bookGroup = intent.getParcelableExtra("data")
}
viewModel.bookGroup?.let {
title_bar.title = it.groupName
}
initRecyclerView()
upRecyclerData()
}
private fun initRecyclerView() {
ATH.applyEdgeEffectColor(rv_bookshelf)
rv_bookshelf.layoutManager = LinearLayoutManager(this)
rv_bookshelf.addItemDecoration(DividerItemDecoration(this, LinearLayout.VERTICAL))
bookshelfAdapter = BookshelfAdapter()
rv_bookshelf.adapter = bookshelfAdapter
}
private fun upRecyclerData() {
viewModel.bookGroup?.let {
bookshelfLiveData?.removeObservers(this)
when (it.groupId) {
-1 -> {
bookshelfLiveData =
LivePagedListBuilder(App.db.bookDao().observeAll(), 10).build()
}
-2 -> {
bookshelfLiveData =
LivePagedListBuilder(App.db.bookDao().observeLocal(), 10).build()
}
-3 -> {
bookshelfLiveData =
LivePagedListBuilder(App.db.bookDao().observeAudio(), 10).build()
}
else -> {
bookshelfLiveData =
LivePagedListBuilder(
App.db.bookDao().observeByGroup(it.groupId),
10
).build()
}
}
bookshelfLiveData?.observe(
this,
Observer { pageList -> bookshelfAdapter.submitList(pageList) })
}
}
}

@ -1,11 +0,0 @@
package io.legado.app.ui.bookshelf
import android.app.Application
import io.legado.app.base.BaseViewModel
import io.legado.app.data.entities.BookGroup
class BookshelfViewModel(application: Application) : BaseViewModel(application) {
var bookGroup: BookGroup? = null
}

@ -1,16 +1,56 @@
package io.legado.app.ui.main
import android.app.Application
import io.legado.app.App
import io.legado.app.base.BaseViewModel
import io.legado.app.constant.BookType
import io.legado.app.constant.Bus
import io.legado.app.help.storage.Restore
import io.legado.app.model.WebBook
import io.legado.app.utils.postEvent
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
class MainViewModel(application: Application) : BaseViewModel(application) {
val updateList = arrayListOf<String>()
fun restore() {
launch(IO) {
Restore.importYueDuData(getApplication())
}
}
fun upChapterList() {
execute {
App.db.bookDao().getRecentRead().forEach { book ->
if (book.origin != BookType.local) {
App.db.bookSourceDao().getBookSource(book.origin)?.let { bookSource ->
synchronized(this) {
updateList.add(book.bookUrl)
postEvent(Bus.UP_BOOK, book.bookUrl)
}
WebBook(bookSource).getChapterList(book)
.onSuccess(IO) {
it?.let {
App.db.bookDao().update(book)
App.db.bookChapterDao().delByBook(book.bookUrl)
App.db.bookChapterDao().insert(*it.toTypedArray())
}
}
.onError {
it.printStackTrace()
}
.onFinally {
synchronized(this) {
updateList.remove(book.bookUrl)
postEvent(Bus.UP_BOOK, book.bookUrl)
}
}
}
}
delay(50)
}
}
}
}

@ -1,4 +1,4 @@
package io.legado.app.ui.bookshelf
package io.legado.app.ui.main.bookshelf
import android.view.LayoutInflater
import android.view.View
@ -7,12 +7,18 @@ import androidx.paging.PagedListAdapter
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView
import io.legado.app.R
import io.legado.app.constant.BookType
import io.legado.app.data.entities.Book
import io.legado.app.help.ImageLoader
import io.legado.app.lib.theme.ATH
import io.legado.app.lib.theme.ThemeStore
import io.legado.app.utils.getCompatColor
import io.legado.app.utils.invisible
import kotlinx.android.synthetic.main.item_bookshelf_list.view.*
import org.jetbrains.anko.sdk27.listeners.onClick
import org.jetbrains.anko.sdk27.listeners.onLongClick
class BookshelfAdapter : PagedListAdapter<Book, BookshelfAdapter.MyViewHolder>(DIFF_CALLBACK) {
class BooksAdapter(private val callBack: CallBack) :
PagedListAdapter<Book, BooksAdapter.MyViewHolder>(DIFF_CALLBACK) {
companion object {
@JvmField
@ -21,23 +27,28 @@ class BookshelfAdapter : PagedListAdapter<Book, BookshelfAdapter.MyViewHolder>(D
oldItem.bookUrl == newItem.bookUrl
override fun areContentsTheSame(oldItem: Book, newItem: Book): Boolean =
oldItem.bookUrl == newItem.bookUrl
&& oldItem.durChapterTitle == newItem.durChapterTitle
oldItem.durChapterTitle == newItem.durChapterTitle
&& oldItem.latestChapterTitle == newItem.latestChapterTitle
&& oldItem.durChapterTime == newItem.durChapterTime
&& oldItem.lastCheckTime == newItem.lastCheckTime
}
}
var callBack: CallBack? = null
fun notification(bookUrl: String) {
for (i in 0..itemCount) {
getItem(i)?.let {
if (it.bookUrl == bookUrl) {
notifyItemChanged(i)
return
}
}
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
return MyViewHolder(
LayoutInflater.from(parent.context).inflate(
R.layout.item_bookshelf_list,
parent,
false
)
LayoutInflater.from(parent.context)
.inflate(R.layout.item_bookshelf_list, parent, false)
)
}
@ -50,27 +61,41 @@ class BookshelfAdapter : PagedListAdapter<Book, BookshelfAdapter.MyViewHolder>(D
class MyViewHolder(view: View) : RecyclerView.ViewHolder(view) {
init {
ATH.applyBackgroundTint(itemView)
itemView.setBackgroundColor(ThemeStore.backgroundColor(itemView.context))
}
fun bind(book: Book, callBack: CallBack?) = with(itemView) {
fun bind(book: Book, callBack: CallBack) = with(itemView) {
this.setBackgroundColor(context.getCompatColor(R.color.background))
tv_name.text = book.name
tv_author.text = book.author
tv_read.text = book.durChapterTitle
tv_last.text = book.latestChapterTitle
book.getDisplayCover()?.let {
ImageLoader.load(context, it)//Glide自动识别http://和file:///
ImageLoader.load(context, it)//Glide自动识别http://和file://
.placeholder(R.drawable.img_cover_default)
.error(R.drawable.img_cover_default)
.centerCrop()
.setAsDrawable(iv_cover)
}
itemView.setOnClickListener { callBack?.open(book) }
itemView.onClick { callBack.open(book) }
itemView.onLongClick {
callBack.openBookInfo(book)
true
}
if (book.origin != BookType.local && callBack.isUpdate(book.bookUrl)) {
bv_unread.invisible()
rl_loading.show()
} else {
rl_loading.hide()
bv_unread.setBadgeCount(book.getUnreadChapterNum())
bv_unread.setHighlight(book.lastCheckCount > 0)
}
}
}
interface CallBack {
fun open(book: Book)
fun search()
fun openBookInfo(book: Book)
fun isUpdate(bookUrl: String): Boolean
}
}

@ -0,0 +1,102 @@
package io.legado.app.ui.main.bookshelf
import android.os.Bundle
import android.view.View
import androidx.lifecycle.LiveData
import androidx.lifecycle.Observer
import androidx.paging.LivePagedListBuilder
import androidx.paging.PagedList
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.LinearLayoutManager
import io.legado.app.App
import io.legado.app.R
import io.legado.app.base.VMBaseFragment
import io.legado.app.data.entities.Book
import io.legado.app.lib.theme.ATH
import io.legado.app.lib.theme.accentColor
import io.legado.app.ui.book.info.BookInfoActivity
import io.legado.app.ui.book.read.ReadBookActivity
import io.legado.app.ui.main.MainViewModel
import io.legado.app.utils.getViewModel
import io.legado.app.utils.getViewModelOfActivity
import kotlinx.android.synthetic.main.fragment_books.*
import org.jetbrains.anko.startActivity
class BooksFragment : VMBaseFragment<BooksViewModel>(R.layout.fragment_books),
BooksAdapter.CallBack {
override val viewModel: BooksViewModel
get() = getViewModel(BooksViewModel::class.java)
private lateinit var activityViewModel: MainViewModel
private lateinit var booksAdapter: BooksAdapter
private var bookshelfLiveData: LiveData<PagedList<Book>>? = null
private val groupId = -1
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
activityViewModel = getViewModelOfActivity(MainViewModel::class.java)
initRecyclerView()
upRecyclerData()
}
private fun initRecyclerView() {
ATH.applyEdgeEffectColor(rv_bookshelf)
refresh_layout.setColorSchemeColors(accentColor)
refresh_layout.setOnRefreshListener {
refresh_layout.isRefreshing = false
activityViewModel.upChapterList()
}
rv_bookshelf.layoutManager = LinearLayoutManager(context)
rv_bookshelf.addItemDecoration(
DividerItemDecoration(
rv_bookshelf.context,
LinearLayoutManager.VERTICAL
)
)
booksAdapter = BooksAdapter(this)
rv_bookshelf.adapter = booksAdapter
}
private fun upRecyclerData() {
bookshelfLiveData?.removeObservers(this)
when (groupId) {
-1 -> {
bookshelfLiveData =
LivePagedListBuilder(App.db.bookDao().observeAll(), 10).build()
}
-2 -> {
bookshelfLiveData =
LivePagedListBuilder(App.db.bookDao().observeLocal(), 10).build()
}
-3 -> {
bookshelfLiveData =
LivePagedListBuilder(App.db.bookDao().observeAudio(), 10).build()
}
else -> {
bookshelfLiveData =
LivePagedListBuilder(
App.db.bookDao().observeByGroup(groupId),
10
).build()
}
}
bookshelfLiveData?.observe(
this,
Observer { pageList -> booksAdapter.submitList(pageList) })
}
override fun open(book: Book) {
context?.startActivity<ReadBookActivity>(Pair("bookUrl", book.bookUrl))
}
override fun openBookInfo(book: Book) {
context?.startActivity<BookInfoActivity>(Pair("bookUrl", book.bookUrl))
}
override fun isUpdate(bookUrl: String): Boolean {
return bookUrl in activityViewModel.updateList
}
}

@ -0,0 +1,9 @@
package io.legado.app.ui.main.bookshelf
import android.app.Application
import io.legado.app.base.BaseViewModel
class BooksViewModel(application: Application) : BaseViewModel(application) {
}

@ -1,101 +1,17 @@
package io.legado.app.ui.main.bookshelf
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.paging.PagedListAdapter
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView
import io.legado.app.R
import io.legado.app.constant.BookType
import io.legado.app.data.entities.Book
import io.legado.app.help.ImageLoader
import io.legado.app.lib.theme.ThemeStore
import io.legado.app.utils.getCompatColor
import io.legado.app.utils.invisible
import kotlinx.android.synthetic.main.item_bookshelf_list.view.*
import org.jetbrains.anko.sdk27.listeners.onClick
import org.jetbrains.anko.sdk27.listeners.onLongClick
import androidx.fragment.app.Fragment
import androidx.viewpager2.adapter.FragmentStateAdapter
class BookshelfAdapter(private val callBack: CallBack) :
PagedListAdapter<Book, BookshelfAdapter.MyViewHolder>(DIFF_CALLBACK) {
companion object {
@JvmField
val DIFF_CALLBACK = object : DiffUtil.ItemCallback<Book>() {
override fun areItemsTheSame(oldItem: Book, newItem: Book): Boolean =
oldItem.bookUrl == newItem.bookUrl
class BookshelfAdapter(fragment: Fragment) : FragmentStateAdapter(fragment) {
override fun areContentsTheSame(oldItem: Book, newItem: Book): Boolean =
oldItem.durChapterTitle == newItem.durChapterTitle
&& oldItem.latestChapterTitle == newItem.latestChapterTitle
&& oldItem.durChapterTime == newItem.durChapterTime
&& oldItem.lastCheckTime == newItem.lastCheckTime
}
override fun getItemCount(): Int {
return 3
}
fun notification(bookUrl: String) {
for (i in 0..itemCount) {
getItem(i)?.let {
if (it.bookUrl == bookUrl) {
notifyItemChanged(i)
return
}
}
}
override fun createFragment(position: Int): Fragment {
return BooksFragment()
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
return MyViewHolder(
LayoutInflater.from(parent.context)
.inflate(R.layout.item_bookshelf_list, parent, false)
)
}
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
currentList?.get(position)?.let {
holder.bind(it, callBack)
}
}
class MyViewHolder(view: View) : RecyclerView.ViewHolder(view) {
init {
itemView.setBackgroundColor(ThemeStore.backgroundColor(itemView.context))
}
fun bind(book: Book, callBack: CallBack) = with(itemView) {
this.setBackgroundColor(context.getCompatColor(R.color.background))
tv_name.text = book.name
tv_author.text = book.author
tv_read.text = book.durChapterTitle
tv_last.text = book.latestChapterTitle
book.getDisplayCover()?.let {
ImageLoader.load(context, it)//Glide自动识别http://和file://
.placeholder(R.drawable.img_cover_default)
.error(R.drawable.img_cover_default)
.centerCrop()
.setAsDrawable(iv_cover)
}
itemView.onClick { callBack.open(book) }
itemView.onLongClick {
callBack.openBookInfo(book)
true
}
if (book.origin != BookType.local && callBack.isUpdate(book.bookUrl)) {
bv_unread.invisible()
rl_loading.show()
} else {
rl_loading.hide()
bv_unread.setBadgeCount(book.getUnreadChapterNum())
bv_unread.setHighlight(book.lastCheckCount > 0)
}
}
}
interface CallBack {
fun open(book: Book)
fun openBookInfo(book: Book)
fun isUpdate(bookUrl: String): Boolean
}
}

@ -11,46 +11,36 @@ import androidx.lifecycle.LiveData
import androidx.lifecycle.Observer
import androidx.paging.LivePagedListBuilder
import androidx.paging.PagedList
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.LinearLayoutManager
import io.legado.app.App
import io.legado.app.R
import io.legado.app.base.VMBaseFragment
import io.legado.app.constant.Bus
import io.legado.app.data.entities.Book
import io.legado.app.data.entities.BookGroup
import io.legado.app.lib.dialogs.*
import io.legado.app.lib.theme.ATH
import io.legado.app.lib.theme.accentColor
import io.legado.app.ui.book.info.BookInfoActivity
import io.legado.app.ui.book.read.ReadBookActivity
import io.legado.app.ui.book.search.SearchActivity
import io.legado.app.ui.bookshelf.BookshelfActivity
import io.legado.app.utils.*
import kotlinx.android.synthetic.main.dialog_edit_text.view.*
import kotlinx.android.synthetic.main.fragment_bookshelf.*
import kotlinx.android.synthetic.main.view_title_bar.*
import org.jetbrains.anko.startActivity
import org.jetbrains.anko.textColor
class BookshelfFragment : VMBaseFragment<BookshelfViewModel>(R.layout.fragment_bookshelf),
SearchView.OnQueryTextListener,
BookGroupAdapter.CallBack,
BookshelfAdapter.CallBack {
BookGroupAdapter.CallBack {
override val viewModel: BookshelfViewModel
get() = getViewModel(BookshelfViewModel::class.java)
private lateinit var bookshelfAdapter: BookshelfAdapter
private lateinit var booksAdapter: BooksAdapter
private lateinit var bookGroupAdapter: BookGroupAdapter
private var bookGroupLiveData: LiveData<PagedList<BookGroup>>? = null
private var bookshelfLiveData: LiveData<PagedList<Book>>? = null
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
setSupportToolbar(toolbar)
initRecyclerView()
initBookGroupData()
initBookshelfData()
}
override fun onCompatCreateOptionsMenu(menu: Menu) {
@ -66,27 +56,14 @@ class BookshelfFragment : VMBaseFragment<BookshelfViewModel>(R.layout.fragment_b
}
private fun initRecyclerView() {
ATH.applyEdgeEffectColor(rv_bookshelf)
refresh_layout.setColorSchemeColors(accentColor)
refresh_layout.setOnRefreshListener {
refresh_layout.isRefreshing = false
viewModel.upChapterList()
}
ATH.applyEdgeEffectColor(view_pager_bookshelf)
rv_book_group.layoutManager =
LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false)
bookGroupAdapter = BookGroupAdapter()
rv_book_group.adapter = bookGroupAdapter
bookGroupAdapter.callBack = this
rv_bookshelf.layoutManager = LinearLayoutManager(context)
rv_bookshelf.addItemDecoration(
DividerItemDecoration(
rv_bookshelf.context,
LinearLayoutManager.VERTICAL
)
)
bookshelfAdapter = BookshelfAdapter(this)
rv_bookshelf.adapter = bookshelfAdapter
observeEvent<String>(Bus.UP_BOOK) { bookshelfAdapter.notification(it) }
view_pager_bookshelf.adapter = BookshelfAdapter(this)
observeEvent<String>(Bus.UP_BOOK) { booksAdapter.notification(it) }
}
private fun initBookGroupData() {
@ -95,31 +72,13 @@ class BookshelfFragment : VMBaseFragment<BookshelfViewModel>(R.layout.fragment_b
bookGroupLiveData?.observe(viewLifecycleOwner, Observer { bookGroupAdapter.submitList(it) })
}
private fun initBookshelfData() {
bookshelfLiveData?.removeObservers(viewLifecycleOwner)
bookshelfLiveData = LivePagedListBuilder(App.db.bookDao().recentRead(), 20).build()
bookshelfLiveData?.observe(viewLifecycleOwner, Observer { bookshelfAdapter.submitList(it) })
}
override fun open(bookGroup: BookGroup) {
when (bookGroup.groupId) {
-10 -> showGroupInputDialog()
else -> context?.startActivity<BookshelfActivity>(Pair("data", bookGroup))
else -> context
}
}
override fun open(book: Book) {
context?.startActivity<ReadBookActivity>(Pair("bookUrl", book.bookUrl))
}
override fun openBookInfo(book: Book) {
context?.startActivity<BookInfoActivity>(Pair("bookUrl", book.bookUrl))
}
override fun isUpdate(bookUrl: String): Boolean {
return bookUrl in viewModel.updateList
}
override fun onQueryTextSubmit(query: String?): Boolean {
context?.startActivity<SearchActivity>(Pair("key", query))
return false

@ -3,18 +3,10 @@ package io.legado.app.ui.main.bookshelf
import android.app.Application
import io.legado.app.App
import io.legado.app.base.BaseViewModel
import io.legado.app.constant.BookType
import io.legado.app.constant.Bus
import io.legado.app.data.entities.BookGroup
import io.legado.app.model.WebBook
import io.legado.app.utils.postEvent
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.delay
class BookshelfViewModel(application: Application) : BaseViewModel(application) {
val updateList = arrayListOf<String>()
fun saveBookGroup(group: String?) {
if (!group.isNullOrBlank()) {
execute {
@ -28,37 +20,4 @@ class BookshelfViewModel(application: Application) : BaseViewModel(application)
}
}
fun upChapterList() {
execute {
App.db.bookDao().getRecentRead().forEach { book ->
if (book.origin != BookType.local) {
App.db.bookSourceDao().getBookSource(book.origin)?.let { bookSource ->
synchronized(this) {
updateList.add(book.bookUrl)
postEvent(Bus.UP_BOOK, book.bookUrl)
}
WebBook(bookSource).getChapterList(book)
.onSuccess(IO) {
it?.let {
App.db.bookDao().update(book)
App.db.bookChapterDao().delByBook(book.bookUrl)
App.db.bookChapterDao().insert(*it.toTypedArray())
}
}
.onError {
it.printStackTrace()
}
.onFinally {
synchronized(this) {
updateList.remove(book.bookUrl)
postEvent(Bus.UP_BOOK, book.bookUrl)
}
}
}
}
delay(50)
}
}
}
}

@ -1,17 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/refresh_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<io.legado.app.ui.widget.TitleBar
android:id="@+id/title_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_bookshelf"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>

@ -18,16 +18,9 @@
android:layout_height="wrap_content"
android:overScrollMode="never"/>
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/refresh_layout"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_bookshelf"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/view_pager_bookshelf"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
</LinearLayout>
Loading…
Cancel
Save