添加文件夹分组样式

pull/1023/head
gedoor 4 years ago
parent 13b77657c3
commit 95ecbebac2
  1. 1
      app/src/main/java/io/legado/app/constant/PreferKey.kt
  2. 6
      app/src/main/java/io/legado/app/help/AppConfig.kt
  3. 19
      app/src/main/java/io/legado/app/ui/main/MainActivity.kt
  4. 139
      app/src/main/java/io/legado/app/ui/main/bookshelf/BaseBookshelfFragment.kt
  5. 269
      app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfFragment.kt
  6. 166
      app/src/main/java/io/legado/app/ui/main/bookshelf/style1/BookshelfFragment1.kt
  7. 2
      app/src/main/java/io/legado/app/ui/main/bookshelf/style1/books/BaseBooksAdapter.kt
  8. 2
      app/src/main/java/io/legado/app/ui/main/bookshelf/style1/books/BooksAdapterGrid.kt
  9. 2
      app/src/main/java/io/legado/app/ui/main/bookshelf/style1/books/BooksAdapterList.kt
  10. 2
      app/src/main/java/io/legado/app/ui/main/bookshelf/style1/books/BooksFragment.kt
  11. 2
      app/src/main/java/io/legado/app/ui/main/bookshelf/style2/BaseBooksAdapter.kt
  12. 2
      app/src/main/java/io/legado/app/ui/main/bookshelf/style2/BooksAdapterGrid.kt
  13. 2
      app/src/main/java/io/legado/app/ui/main/bookshelf/style2/BooksAdapterList.kt
  14. 160
      app/src/main/java/io/legado/app/ui/main/bookshelf/style2/BookshelfFragment2.kt
  15. 21
      app/src/main/res/layout/dialog_bookshelf_config.xml
  16. 2
      app/src/main/res/values-ja-rJP/strings.xml
  17. 2
      app/src/main/res/values-pt-rBR/strings.xml
  18. 5
      app/src/main/res/values-zh-rHK/arrays.xml
  19. 2
      app/src/main/res/values-zh-rHK/strings.xml
  20. 5
      app/src/main/res/values-zh-rTW/arrays.xml
  21. 2
      app/src/main/res/values-zh-rTW/strings.xml
  22. 5
      app/src/main/res/values-zh/arrays.xml
  23. 2
      app/src/main/res/values-zh/strings.xml
  24. 5
      app/src/main/res/values/arrays.xml
  25. 3
      app/src/main/res/values/strings.xml

@ -5,6 +5,7 @@ object PreferKey {
const val themeMode = "themeMode"
const val userAgent = "userAgent"
const val showUnread = "showUnread"
const val bookGroupStyle = "bookGroupStyle"
const val useDefaultCover = "useDefaultCover"
const val hideStatusBar = "hideStatusBar"
const val clickActionTL = "clickActionTopLeft"

@ -90,6 +90,12 @@ object AppConfig : SharedPreferences.OnSharedPreferenceChangeListener {
val screenOrientation: String?
get() = appCtx.getPrefString(PreferKey.screenOrientation)
var bookGroupStyle: Int
get() = appCtx.getPrefInt(PreferKey.bookGroupStyle, 0)
set(value) {
appCtx.putPrefInt(PreferKey.bookGroupStyle, value)
}
var backupPath: String?
get() = appCtx.getPrefString(PreferKey.backupPath)
set(value) {

@ -27,7 +27,9 @@ import io.legado.app.help.storage.Backup
import io.legado.app.lib.theme.ATH
import io.legado.app.lib.theme.elevation
import io.legado.app.service.BaseReadAloudService
import io.legado.app.ui.main.bookshelf.BookshelfFragment
import io.legado.app.ui.main.bookshelf.BaseBookshelfFragment
import io.legado.app.ui.main.bookshelf.style1.BookshelfFragment1
import io.legado.app.ui.main.bookshelf.style2.BookshelfFragment2
import io.legado.app.ui.main.explore.ExploreFragment
import io.legado.app.ui.main.my.MyFragment
import io.legado.app.ui.main.rss.RssFragment
@ -101,7 +103,7 @@ class MainActivity : VMBaseActivity<ActivityMainBinding, MainViewModel>(),
if (System.currentTimeMillis() - bookshelfReselected > 300) {
bookshelfReselected = System.currentTimeMillis()
} else {
(fragmentMap[0] as? BookshelfFragment)?.gotoTop()
(fragmentMap[getFragmentId(0)] as? BaseBookshelfFragment)?.gotoTop()
}
}
R.id.menu_discovery -> {
@ -210,6 +212,14 @@ class MainActivity : VMBaseActivity<ActivityMainBinding, MainViewModel>(),
}
}
private fun getFragmentId(position: Int): Int {
val p = realPositions[position]
if (p == 0) {
return if (AppConfig.bookGroupStyle == 1) 11 else 0
}
return p
}
private inner class PageChangeCallback : ViewPager.SimpleOnPageChangeListener() {
override fun onPageSelected(position: Int) {
@ -225,7 +235,7 @@ class MainActivity : VMBaseActivity<ActivityMainBinding, MainViewModel>(),
FragmentStatePagerAdapter(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {
private fun getId(position: Int): Int {
return realPositions[position]
return getFragmentId(position)
}
override fun getItemPosition(`object`: Any): Int {
@ -234,7 +244,8 @@ class MainActivity : VMBaseActivity<ActivityMainBinding, MainViewModel>(),
override fun getItem(position: Int): Fragment {
return when (getId(position)) {
0 -> BookshelfFragment()
0 -> BookshelfFragment1()
11 -> BookshelfFragment2()
1 -> ExploreFragment()
2 -> RssFragment()
else -> MyFragment()

@ -0,0 +1,139 @@
package io.legado.app.ui.main.bookshelf
import android.annotation.SuppressLint
import android.view.MenuItem
import androidx.fragment.app.activityViewModels
import androidx.fragment.app.viewModels
import io.legado.app.R
import io.legado.app.base.VMBaseFragment
import io.legado.app.constant.PreferKey
import io.legado.app.data.entities.Book
import io.legado.app.databinding.DialogBookshelfConfigBinding
import io.legado.app.databinding.DialogEditTextBinding
import io.legado.app.help.AppConfig
import io.legado.app.lib.dialogs.alert
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.local.ImportBookActivity
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.utils.*
abstract class BaseBookshelfFragment(layoutId: Int) : VMBaseFragment<BookshelfViewModel>(layoutId) {
val activityViewModel: MainViewModel by activityViewModels()
override val viewModel: BookshelfViewModel by viewModels()
private val importBookshelf = registerForActivityResult(FilePicker()) {
it?.readText(requireContext())?.let { text ->
viewModel.importBookshelf(text, groupId)
}
}
abstract val groupId: Long
abstract val books: List<Book>
abstract fun gotoTop()
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(groupId)
}
}
@SuppressLint("InflateParams")
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()
}
@SuppressLint("InflateParams")
fun configBookshelf() {
alert(titleResource = R.string.bookshelf_layout) {
val bookshelfLayout = getPrefInt(PreferKey.bookshelfLayout)
val bookshelfSort = getPrefInt(PreferKey.bookshelfSort)
val alertBinding =
DialogBookshelfConfigBinding.inflate(layoutInflater)
.apply {
spGroupStyle.setSelection(AppConfig.bookGroupStyle)
rgLayout.checkByIndex(bookshelfLayout)
rgSort.checkByIndex(bookshelfSort)
}
customView { alertBinding.root }
okButton {
alertBinding.apply {
var changed = false
if (AppConfig.bookGroupStyle != spGroupStyle.selectedItemPosition) {
AppConfig.bookGroupStyle = spGroupStyle.selectedItemPosition
changed = true
}
if (bookshelfLayout != rgLayout.getCheckedIndex()) {
putPrefInt(PreferKey.bookshelfLayout, rgLayout.getCheckedIndex())
changed = true
}
if (bookshelfSort != rgSort.getCheckedIndex()) {
putPrefInt(PreferKey.bookshelfSort, rgSort.getCheckedIndex())
changed = true
}
if (changed) {
activity?.recreate()
}
}
}
noButton()
}.show()
}
private fun importBookshelfAlert(groupId: Long) {
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()
}
}

@ -1,269 +0,0 @@
package io.legado.app.ui.main.bookshelf
import android.annotation.SuppressLint
import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.widget.SearchView
import androidx.fragment.app.*
import androidx.lifecycle.LiveData
import com.google.android.material.tabs.TabLayout
import io.legado.app.R
import io.legado.app.base.VMBaseFragment
import io.legado.app.constant.AppConst
import io.legado.app.constant.PreferKey
import io.legado.app.data.appDb
import io.legado.app.data.entities.BookGroup
import io.legado.app.databinding.DialogBookshelfConfigBinding
import io.legado.app.databinding.DialogEditTextBinding
import io.legado.app.databinding.FragmentBookshelfBinding
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.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.local.ImportBookActivity
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.books.BooksFragment
import io.legado.app.utils.*
import io.legado.app.utils.viewbindingdelegate.viewBinding
/**
* 书架界面
*/
class BookshelfFragment : VMBaseFragment<BookshelfViewModel>(R.layout.fragment_bookshelf),
TabLayout.OnTabSelectedListener,
SearchView.OnQueryTextListener {
private val binding by viewBinding(FragmentBookshelfBinding::bind)
override val viewModel: BookshelfViewModel by viewModels()
private val activityViewModel: MainViewModel by activityViewModels()
private lateinit var adapter: FragmentStatePagerAdapter
private lateinit var tabLayout: TabLayout
private var bookGroupLiveData: LiveData<List<BookGroup>>? = null
private val bookGroups = mutableListOf<BookGroup>()
private val fragmentMap = hashMapOf<Long, BooksFragment>()
private val importBookshelf = registerForActivityResult(FilePicker()) {
it?.readText(requireContext())?.let { text ->
viewModel.importBookshelf(text, selectedGroup.groupId)
}
}
override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) {
tabLayout = binding.titleBar.findViewById(R.id.tab_layout)
setSupportToolbar(binding.titleBar.toolbar)
initView()
initBookGroupData()
}
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 -> {
val fragment = fragmentMap[selectedGroup.groupId]
fragment?.getBooks()?.let {
activityViewModel.upToc(it)
}
}
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", selectedGroup.groupId)
}
R.id.menu_download -> startActivity<CacheActivity> {
putExtra("groupId", selectedGroup.groupId)
}
R.id.menu_export_bookshelf -> {
val fragment = fragmentMap[selectedGroup.groupId]
viewModel.exportBookshelf(fragment?.getBooks()) {
activity?.share(it)
}
}
R.id.menu_import_bookshelf -> importBookshelfAlert()
}
}
private val selectedGroup: BookGroup
get() = bookGroups[tabLayout.selectedTabPosition]
private fun initView() {
ATH.applyEdgeEffectColor(binding.viewPagerBookshelf)
tabLayout.isTabIndicatorFullWidth = false
tabLayout.tabMode = TabLayout.MODE_SCROLLABLE
tabLayout.setSelectedTabIndicatorColor(requireContext().accentColor)
tabLayout.setupWithViewPager(binding.viewPagerBookshelf)
binding.viewPagerBookshelf.offscreenPageLimit = 1
adapter = TabFragmentPageAdapter(childFragmentManager)
binding.viewPagerBookshelf.adapter = adapter
}
private fun initBookGroupData() {
bookGroupLiveData?.removeObservers(viewLifecycleOwner)
bookGroupLiveData = appDb.bookGroupDao.liveDataShow().apply {
observe(viewLifecycleOwner) {
viewModel.checkGroup(it)
upGroup(it)
}
}
}
override fun onQueryTextSubmit(query: String?): Boolean {
startActivity<SearchActivity> {
putExtra("key", query)
}
return false
}
override fun onQueryTextChange(newText: String?): Boolean {
return false
}
@Synchronized
private fun upGroup(data: List<BookGroup>) {
if (data.isEmpty()) {
appDb.bookGroupDao.enableGroup(AppConst.bookGroupAllId)
} else {
if (data != bookGroups) {
bookGroups.clear()
bookGroups.addAll(data)
adapter.notifyDataSetChanged()
selectLastTab()
}
}
}
@Synchronized
private fun selectLastTab() {
tabLayout.removeOnTabSelectedListener(this)
tabLayout.getTabAt(getPrefInt(PreferKey.saveTabPosition, 0))?.select()
tabLayout.addOnTabSelectedListener(this)
}
@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)
}
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 (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()
}
override fun onTabReselected(tab: TabLayout.Tab) {
fragmentMap[selectedGroup.groupId]?.let {
toastOnUi("${selectedGroup.groupName}(${it.getBooksCount()})")
}
}
override fun onTabUnselected(tab: TabLayout.Tab) = Unit
override fun onTabSelected(tab: TabLayout.Tab) {
putPrefInt(PreferKey.saveTabPosition, tab.position)
}
fun gotoTop() {
fragmentMap[selectedGroup.groupId]?.gotoTop()
}
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, selectedGroup.groupId)
}
}
noButton()
neutralButton(R.string.select_file) {
importBookshelf.launch(
FilePickerParam(
mode = FilePicker.FILE,
allowExtensions = arrayOf("txt", "json")
)
)
}
}.show()
}
private inner class TabFragmentPageAdapter(fm: FragmentManager) :
FragmentStatePagerAdapter(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {
override fun getPageTitle(position: Int): CharSequence {
return bookGroups[position].groupName
}
override fun getItemPosition(`object`: Any): Int {
return POSITION_NONE
}
override fun getItem(position: Int): Fragment {
val group = bookGroups[position]
return BooksFragment.newInstance(position, group.groupId)
}
override fun getCount(): Int {
return bookGroups.size
}
override fun instantiateItem(container: ViewGroup, position: Int): Any {
val fragment = super.instantiateItem(container, position) as BooksFragment
val group = bookGroups[position]
fragmentMap[group.groupId] = fragment
return fragment
}
}
}

@ -0,0 +1,166 @@
@file:Suppress("DEPRECATION")
package io.legado.app.ui.main.bookshelf.style1
import android.os.Bundle
import android.view.Menu
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.widget.SearchView
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.FragmentStatePagerAdapter
import androidx.lifecycle.LiveData
import com.google.android.material.tabs.TabLayout
import io.legado.app.R
import io.legado.app.constant.AppConst
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.FragmentBookshelfBinding
import io.legado.app.lib.theme.ATH
import io.legado.app.lib.theme.accentColor
import io.legado.app.ui.book.search.SearchActivity
import io.legado.app.ui.main.bookshelf.BaseBookshelfFragment
import io.legado.app.ui.main.bookshelf.style1.books.BooksFragment
import io.legado.app.utils.getPrefInt
import io.legado.app.utils.putPrefInt
import io.legado.app.utils.startActivity
import io.legado.app.utils.toastOnUi
import io.legado.app.utils.viewbindingdelegate.viewBinding
/**
* 书架界面
*/
class BookshelfFragment1 : BaseBookshelfFragment(R.layout.fragment_bookshelf),
TabLayout.OnTabSelectedListener,
SearchView.OnQueryTextListener {
private val binding by viewBinding(FragmentBookshelfBinding::bind)
private lateinit var adapter: FragmentStatePagerAdapter
private lateinit var tabLayout: TabLayout
private var bookGroupLiveData: LiveData<List<BookGroup>>? = null
private val bookGroups = mutableListOf<BookGroup>()
private val fragmentMap = hashMapOf<Long, BooksFragment>()
override val groupId: Long get() = selectedGroup.groupId
override val books: List<Book>
get() {
val fragment = fragmentMap[selectedGroup.groupId]
return fragment?.getBooks() ?: emptyList()
}
override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) {
tabLayout = binding.titleBar.findViewById(R.id.tab_layout)
setSupportToolbar(binding.titleBar.toolbar)
initView()
initBookGroupData()
}
override fun onCompatCreateOptionsMenu(menu: Menu) {
menuInflater.inflate(R.menu.main_bookshelf, menu)
}
private val selectedGroup: BookGroup
get() = bookGroups[tabLayout.selectedTabPosition]
private fun initView() {
ATH.applyEdgeEffectColor(binding.viewPagerBookshelf)
tabLayout.isTabIndicatorFullWidth = false
tabLayout.tabMode = TabLayout.MODE_SCROLLABLE
tabLayout.setSelectedTabIndicatorColor(requireContext().accentColor)
tabLayout.setupWithViewPager(binding.viewPagerBookshelf)
binding.viewPagerBookshelf.offscreenPageLimit = 1
adapter = TabFragmentPageAdapter(childFragmentManager)
binding.viewPagerBookshelf.adapter = adapter
}
private fun initBookGroupData() {
bookGroupLiveData?.removeObservers(viewLifecycleOwner)
bookGroupLiveData = appDb.bookGroupDao.liveDataShow().apply {
observe(viewLifecycleOwner) {
viewModel.checkGroup(it)
upGroup(it)
}
}
}
override fun onQueryTextSubmit(query: String?): Boolean {
startActivity<SearchActivity> {
putExtra("key", query)
}
return false
}
override fun onQueryTextChange(newText: String?): Boolean {
return false
}
@Synchronized
private fun upGroup(data: List<BookGroup>) {
if (data.isEmpty()) {
appDb.bookGroupDao.enableGroup(AppConst.bookGroupAllId)
} else {
if (data != bookGroups) {
bookGroups.clear()
bookGroups.addAll(data)
adapter.notifyDataSetChanged()
selectLastTab()
}
}
}
@Synchronized
private fun selectLastTab() {
tabLayout.removeOnTabSelectedListener(this)
tabLayout.getTabAt(getPrefInt(PreferKey.saveTabPosition, 0))?.select()
tabLayout.addOnTabSelectedListener(this)
}
override fun onTabReselected(tab: TabLayout.Tab) {
fragmentMap[selectedGroup.groupId]?.let {
toastOnUi("${selectedGroup.groupName}(${it.getBooksCount()})")
}
}
override fun onTabUnselected(tab: TabLayout.Tab) = Unit
override fun onTabSelected(tab: TabLayout.Tab) {
putPrefInt(PreferKey.saveTabPosition, tab.position)
}
override fun gotoTop() {
fragmentMap[selectedGroup.groupId]?.gotoTop()
}
private inner class TabFragmentPageAdapter(fm: FragmentManager) :
FragmentStatePagerAdapter(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {
override fun getPageTitle(position: Int): CharSequence {
return bookGroups[position].groupName
}
override fun getItemPosition(`object`: Any): Int {
return POSITION_NONE
}
override fun getItem(position: Int): Fragment {
val group = bookGroups[position]
return BooksFragment.newInstance(position, group.groupId)
}
override fun getCount(): Int {
return bookGroups.size
}
override fun instantiateItem(container: ViewGroup, position: Int): Any {
val fragment = super.instantiateItem(container, position) as BooksFragment
val group = bookGroups[position]
fragmentMap[group.groupId] = fragment
return fragment
}
}
}

@ -1,4 +1,4 @@
package io.legado.app.ui.main.bookshelf.books
package io.legado.app.ui.main.bookshelf.style1.books
import android.content.Context
import androidx.core.os.bundleOf

@ -1,4 +1,4 @@
package io.legado.app.ui.main.bookshelf.books
package io.legado.app.ui.main.bookshelf.style1.books
import android.content.Context
import android.os.Bundle

@ -1,4 +1,4 @@
package io.legado.app.ui.main.bookshelf.books
package io.legado.app.ui.main.bookshelf.style1.books
import android.content.Context
import android.os.Bundle

@ -1,4 +1,4 @@
package io.legado.app.ui.main.bookshelf.books
package io.legado.app.ui.main.bookshelf.style1.books
import android.os.Bundle
import android.view.View

@ -1,4 +1,4 @@
package io.legado.app.ui.main.bookshelf1
package io.legado.app.ui.main.bookshelf.style2
import android.content.Context
import androidx.core.os.bundleOf

@ -1,4 +1,4 @@
package io.legado.app.ui.main.bookshelf1
package io.legado.app.ui.main.bookshelf.style2
import android.content.Context
import android.os.Bundle

@ -1,4 +1,4 @@
package io.legado.app.ui.main.bookshelf1
package io.legado.app.ui.main.bookshelf.style2
import android.content.Context
import android.os.Bundle

@ -1,20 +1,15 @@
package io.legado.app.ui.main.bookshelf1
package io.legado.app.ui.main.bookshelf.style2
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
@ -22,87 +17,72 @@ 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.lib.theme.primaryTextColor
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.ui.main.bookshelf.BaseBookshelfFragment
import io.legado.app.utils.cnCompare
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 kotlin.math.max
/**
* 书架界面
*/
class BookshelfFragment1 : VMBaseFragment<BookshelfViewModel>(R.layout.fragment_bookshelf1),
class BookshelfFragment2 : BaseBookshelfFragment(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 searchView: SearchView
private lateinit var booksAdapter: BaseBooksAdapter<*>
private var groupId = AppConst.bookGroupNoneId
override 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 var books: List<Book> = emptyList()
override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) {
searchView = binding.titleBar.findViewById(R.id.search_view)
setSupportToolbar(binding.titleBar.toolbar)
initView()
initSearchView()
initRecyclerView()
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)
menu.findItem(R.id.menu_search).isVisible = false
}
private fun initSearchView() {
ATH.setTint(searchView, primaryTextColor)
searchView.onActionViewExpanded()
searchView.isSubmitButtonEnabled = true
searchView.queryHint = getString(R.string.screen_find)
searchView.clearFocus()
searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
override fun onQueryTextSubmit(query: String?): Boolean {
return false
}
R.id.menu_export_bookshelf -> viewModel.exportBookshelf(books) {
activity?.share(it)
override fun onQueryTextChange(newText: String?): Boolean {
return false
}
R.id.menu_import_bookshelf -> importBookshelfAlert()
}
})
}
private fun initView() {
private fun initRecyclerView() {
ATH.applyEdgeEffectColor(binding.rvBookshelf)
binding.refreshLayout.setColorSchemeColors(accentColor)
binding.refreshLayout.setOnRefreshListener {
@ -192,58 +172,7 @@ class BookshelfFragment1 : VMBaseFragment<BookshelfViewModel>(R.layout.fragment_
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() {
override fun gotoTop() {
if (AppConfig.isEInkMode) {
binding.rvBookshelf.scrollToPosition(0)
} else {
@ -251,29 +180,6 @@ class BookshelfFragment1 : VMBaseFragment<BookshelfViewModel>(R.layout.fragment_
}
}
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]

@ -14,6 +14,27 @@
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<io.legado.app.ui.widget.text.AccentTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="6dp"
android:text="@string/group_style"
android:textSize="16sp" />
<androidx.appcompat.widget.AppCompatSpinner
android:id="@+id/sp_group_style"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:entries="@array/group_style"
app:theme="@style/Spinner" />
</LinearLayout>
<io.legado.app.ui.widget.text.AccentTextView
android:layout_width="match_parent"
android:layout_height="match_parent"

@ -840,4 +840,6 @@
<string name="hide_when_status_bar_show">Hide when status bar show</string>
<string name="reverse_toc">Reverse toc</string>
<string name="show_discovery">显示发现</string>
<string name="style">样式</string>
<string name="group_style">分组样式</string>
</resources>

@ -840,4 +840,6 @@
<string name="hide_when_status_bar_show">Ocultar quando a barra de status é mostrada</string>
<string name="reverse_toc">TOC reverso</string>
<string name="show_discovery">Mostrar</string>
<string name="style">样式</string>
<string name="group_style">分组样式</string>
</resources>

@ -6,6 +6,11 @@
<item>音頻</item>
</string-array>
<string-array name="group_style">
<item>标签</item>
<item>文件夹</item>
</string-array>
<string-array name="theme_mode">
<item>跟隨系統</item>
<item>亮色主題</item>

@ -838,5 +838,7 @@
<string name="diy_edit_source_group_title">【%s】</string>
<string name="reverse_toc">反转目录</string>
<string name="show_discovery">显示发现</string>
<string name="style">样式</string>
<string name="group_style">分组样式</string>
</resources>

@ -5,6 +5,11 @@
<item>音訊</item>
</string-array>
<string-array name="group_style">
<item>标签</item>
<item>文件夹</item>
</string-array>
<string-array name="text_suffix">
<item>.txt</item>
<item>.json</item>

@ -839,5 +839,7 @@
<string name="hide_when_status_bar_show">状态栏显示时隐藏</string>
<string name="reverse_toc">反转目录</string>
<string name="show_discovery">显示发现</string>
<string name="style">样式</string>
<string name="group_style">分组样式</string>
</resources>

@ -5,6 +5,11 @@
<item>音频</item>
</string-array>
<string-array name="group_style">
<item>标签</item>
<item>文件夹</item>
</string-array>
<string-array name="text_suffix">
<item>.txt</item>
<item>.json</item>

@ -839,5 +839,7 @@
<string name="hide_when_status_bar_show">状态栏显示时隐藏</string>
<string name="reverse_toc">反转目录</string>
<string name="show_discovery">显示发现</string>
<string name="style">样式</string>
<string name="group_style">分组样式</string>
</resources>

@ -5,6 +5,11 @@
<item>Audio</item>
</string-array>
<string-array name="group_style">
<item>Tab</item>
<item>Folder</item>
</string-array>
<string-array name="indent">
<item>@string/indent_0</item>
<item>@string/indent_1</item>

@ -840,4 +840,7 @@
<string name="hide_when_status_bar_show">Hide when status bar show</string>
<string name="reverse_toc">Reverse toc</string>
<string name="show_discovery">Show</string>
<string name="style">Style</string>
<string name="group_style">Group style</string>
</resources>

Loading…
Cancel
Save