一个新的书架样式 #285
This commit is contained in:
7 files changed
+220
-5
No files matched your search
@@ -50,6 +50,7 @@ import io.legado.app.ui.main.bookshelf.BaseBookshelfFragment
|
|||||||
import io.legado.app.ui.main.bookshelf.books.BookshelfFragment1
|
import io.legado.app.ui.main.bookshelf.books.BookshelfFragment1
|
||||||
import io.legado.app.ui.main.bookshelf.books.BookshelfFragment2
|
import io.legado.app.ui.main.bookshelf.books.BookshelfFragment2
|
||||||
import io.legado.app.ui.main.bookshelf.books.BookshelfFragment3
|
import io.legado.app.ui.main.bookshelf.books.BookshelfFragment3
|
||||||
|
import io.legado.app.ui.main.bookshelf.books.BookshelfFragment4
|
||||||
import io.legado.app.ui.main.explore.ExploreFragment
|
import io.legado.app.ui.main.explore.ExploreFragment
|
||||||
import io.legado.app.ui.main.my.MyFragment
|
import io.legado.app.ui.main.my.MyFragment
|
||||||
import io.legado.app.ui.main.rss.RssFragment
|
import io.legado.app.ui.main.rss.RssFragment
|
||||||
@@ -86,6 +87,7 @@ open class MainActivity : VMBaseActivity<ActivityMainBinding, MainViewModel>(),
|
|||||||
private val idBookshelf1 = 11
|
private val idBookshelf1 = 11
|
||||||
private val idBookshelf2 = 12
|
private val idBookshelf2 = 12
|
||||||
private val idBookshelf3 = 13
|
private val idBookshelf3 = 13
|
||||||
|
private val idBookshelf4 = 14
|
||||||
private val idExplore = 1
|
private val idExplore = 1
|
||||||
private val idRss = 2
|
private val idRss = 2
|
||||||
private val idMy = 3
|
private val idMy = 3
|
||||||
@@ -508,6 +510,7 @@ open class MainActivity : VMBaseActivity<ActivityMainBinding, MainViewModel>(),
|
|||||||
0 -> idBookshelf1
|
0 -> idBookshelf1
|
||||||
1 -> idBookshelf2
|
1 -> idBookshelf2
|
||||||
2 -> idBookshelf3
|
2 -> idBookshelf3
|
||||||
|
3 -> idBookshelf4
|
||||||
else -> idBookshelf1
|
else -> idBookshelf1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -543,6 +546,7 @@ open class MainActivity : VMBaseActivity<ActivityMainBinding, MainViewModel>(),
|
|||||||
idBookshelf1 -> BookshelfFragment1(position)
|
idBookshelf1 -> BookshelfFragment1(position)
|
||||||
idBookshelf2 -> BookshelfFragment2(position)
|
idBookshelf2 -> BookshelfFragment2(position)
|
||||||
idBookshelf3 -> BookshelfFragment3(position)
|
idBookshelf3 -> BookshelfFragment3(position)
|
||||||
|
idBookshelf4 -> BookshelfFragment4(position)
|
||||||
idExplore -> ExploreFragment(position)
|
idExplore -> ExploreFragment(position)
|
||||||
idRss -> RssFragment(position)
|
idRss -> RssFragment(position)
|
||||||
else -> MyFragment(position)
|
else -> MyFragment(position)
|
||||||
|
|||||||
@@ -0,0 +1,164 @@
|
|||||||
|
@file:Suppress("DEPRECATION")
|
||||||
|
|
||||||
|
package io.legado.app.ui.main.bookshelf.books
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
|
import android.os.Build
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.View
|
||||||
|
import androidx.appcompat.widget.SearchView
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
import androidx.viewpager2.adapter.FragmentStateAdapter
|
||||||
|
import com.google.android.material.tabs.TabLayout
|
||||||
|
import com.google.android.material.tabs.TabLayoutMediator
|
||||||
|
import io.legado.app.R
|
||||||
|
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.FragmentBookshelf1Binding
|
||||||
|
import io.legado.app.databinding.FragmentBookshelf4Binding
|
||||||
|
import io.legado.app.help.config.AppConfig
|
||||||
|
import io.legado.app.ui.book.group.GroupEditDialog
|
||||||
|
import io.legado.app.ui.book.search.SearchActivity
|
||||||
|
import io.legado.app.ui.main.bookshelf.BaseBookshelfFragment
|
||||||
|
import io.legado.app.utils.showDialogFragment
|
||||||
|
import io.legado.app.utils.toastOnUi
|
||||||
|
import io.legado.app.utils.viewbindingdelegate.viewBinding
|
||||||
|
import kotlin.collections.set
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 书架界面
|
||||||
|
*/
|
||||||
|
class BookshelfFragment4() : BaseBookshelfFragment(R.layout.fragment_bookshelf4),
|
||||||
|
TabLayout.OnTabSelectedListener,
|
||||||
|
SearchView.OnQueryTextListener {
|
||||||
|
|
||||||
|
constructor(position: Int) : this() {
|
||||||
|
val bundle = Bundle()
|
||||||
|
bundle.putInt("position", position)
|
||||||
|
arguments = bundle
|
||||||
|
}
|
||||||
|
|
||||||
|
private val binding by viewBinding(FragmentBookshelf4Binding::bind)
|
||||||
|
|
||||||
|
private val bookGroups = mutableListOf<BookGroup>()
|
||||||
|
private val fragmentMap = hashMapOf<Long, BooksFragment>()
|
||||||
|
override val groupId: Long get() = selectedGroup?.groupId ?: 0
|
||||||
|
|
||||||
|
private lateinit var adapter: TabFragmentPageAdapter
|
||||||
|
|
||||||
|
override val books: List<Book>
|
||||||
|
get() {
|
||||||
|
val fragment = fragmentMap[groupId]
|
||||||
|
return fragment?.getBooks() ?: emptyList()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
setSupportToolbar(binding.topBar)
|
||||||
|
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.S)
|
||||||
|
binding.titleBar.fitsSystemWindows = true
|
||||||
|
initView()
|
||||||
|
initBookGroupData()
|
||||||
|
}
|
||||||
|
|
||||||
|
private val selectedGroup: BookGroup?
|
||||||
|
get() = bookGroups.getOrNull(binding.viewPagerBookshelf.currentItem)
|
||||||
|
|
||||||
|
private fun initView() {
|
||||||
|
adapter = TabFragmentPageAdapter(this)
|
||||||
|
binding.viewPagerBookshelf.adapter = adapter
|
||||||
|
binding.viewPagerBookshelf.offscreenPageLimit = 1
|
||||||
|
|
||||||
|
TabLayoutMediator(binding.tabLayout, binding.viewPagerBookshelf) { tab, position ->
|
||||||
|
tab.text = bookGroups[position].groupName
|
||||||
|
}.attach()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onQueryTextSubmit(query: String?): Boolean {
|
||||||
|
SearchActivity.start(requireContext(), query)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onQueryTextChange(newText: String?): Boolean {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressLint("NotifyDataSetChanged")
|
||||||
|
@Synchronized
|
||||||
|
override fun upGroup(data: List<BookGroup>) {
|
||||||
|
if (data.isEmpty()) {
|
||||||
|
appDb.bookGroupDao.enableGroup(BookGroup.IdAll)
|
||||||
|
} else {
|
||||||
|
if (data != bookGroups) {
|
||||||
|
bookGroups.clear()
|
||||||
|
bookGroups.addAll(data)
|
||||||
|
adapter.notifyDataSetChanged()
|
||||||
|
adapter = TabFragmentPageAdapter(this)
|
||||||
|
binding.viewPagerBookshelf.adapter = adapter
|
||||||
|
|
||||||
|
TabLayoutMediator(binding.tabLayout, binding.viewPagerBookshelf) { tab, position ->
|
||||||
|
tab.text = bookGroups[position].groupName
|
||||||
|
}.attach()
|
||||||
|
|
||||||
|
selectLastTab()
|
||||||
|
|
||||||
|
binding.tabLayout.post {
|
||||||
|
for (i in 0 until bookGroups.size) {
|
||||||
|
binding.tabLayout.getTabAt(i)?.view?.setOnLongClickListener {
|
||||||
|
showDialogFragment(GroupEditDialog(bookGroups[i]))
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun upSort() {
|
||||||
|
childFragmentManager.fragments.forEach {
|
||||||
|
if (it is BooksFragment) {
|
||||||
|
val position = it.position
|
||||||
|
val group = bookGroups.getOrNull(position) ?: return@forEach
|
||||||
|
it.setEnableRefresh(group.enableRefresh)
|
||||||
|
it.upBookSort(group.getRealBookSort())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun selectLastTab() {
|
||||||
|
binding.tabLayout.post {
|
||||||
|
binding.tabLayout.removeOnTabSelectedListener(this)
|
||||||
|
binding.tabLayout.getTabAt(AppConfig.saveTabPosition)?.select()
|
||||||
|
binding.tabLayout.addOnTabSelectedListener(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onTabReselected(tab: TabLayout.Tab) {
|
||||||
|
selectedGroup?.let { group ->
|
||||||
|
fragmentMap[group.groupId]?.let {
|
||||||
|
toastOnUi("${group.groupName}(${it.getBooksCount()})")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onTabUnselected(tab: TabLayout.Tab) = Unit
|
||||||
|
|
||||||
|
override fun onTabSelected(tab: TabLayout.Tab) {
|
||||||
|
AppConfig.saveTabPosition = tab.position
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun gotoTop() {
|
||||||
|
fragmentMap[groupId]?.gotoTop()
|
||||||
|
}
|
||||||
|
|
||||||
|
private inner class TabFragmentPageAdapter(fragment: Fragment) : FragmentStateAdapter(fragment) {
|
||||||
|
override fun getItemCount(): Int = bookGroups.size
|
||||||
|
|
||||||
|
override fun createFragment(position: Int): Fragment {
|
||||||
|
val group = bookGroups[position]
|
||||||
|
val fragment = BooksFragment(position, group)
|
||||||
|
fragmentMap[group.groupId] = fragment
|
||||||
|
return fragment
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -93,7 +93,7 @@
|
|||||||
<TextView
|
<TextView
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:paddingTop="8dp"
|
android:paddingVertical="8dp"
|
||||||
android:text="@string/group_style"
|
android:text="@string/group_style"
|
||||||
android:textSize="14sp"
|
android:textSize="14sp"
|
||||||
android:textStyle="bold" />
|
android:textStyle="bold" />
|
||||||
@@ -103,7 +103,6 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:checkableBehavior="single"
|
android:checkableBehavior="single"
|
||||||
android:paddingBottom="8dp"
|
|
||||||
app:selectionRequired="true"
|
app:selectionRequired="true"
|
||||||
app:singleSelection="true" />
|
app:singleSelection="true" />
|
||||||
|
|
||||||
@@ -111,6 +110,7 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="center_vertical"
|
android:layout_gravity="center_vertical"
|
||||||
|
android:paddingVertical="8dp"
|
||||||
android:text="@string/sortview"
|
android:text="@string/sortview"
|
||||||
android:textSize="14sp"
|
android:textSize="14sp"
|
||||||
android:textStyle="bold" />
|
android:textStyle="bold" />
|
||||||
@@ -119,7 +119,6 @@
|
|||||||
android:id="@+id/chip_group_layout"
|
android:id="@+id/chip_group_layout"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
app:chipSpacingVertical="0dp"
|
|
||||||
android:checkableBehavior="single"
|
android:checkableBehavior="single"
|
||||||
app:selectionRequired="true"
|
app:selectionRequired="true"
|
||||||
app:singleSelection="true">
|
app:singleSelection="true">
|
||||||
@@ -191,6 +190,7 @@
|
|||||||
android:id="@+id/chipGroupOrder"
|
android:id="@+id/chipGroupOrder"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginVertical="8dp"
|
||||||
app:selectionRequired="true"
|
app:selectionRequired="true"
|
||||||
app:singleSelection="true">
|
app:singleSelection="true">
|
||||||
|
|
||||||
@@ -218,7 +218,6 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
app:chipSpacingVertical="0dp"
|
|
||||||
app:selectionRequired="true"
|
app:selectionRequired="true"
|
||||||
app:singleSelection="true" />
|
app:singleSelection="true" />
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,45 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<com.google.android.material.appbar.AppBarLayout
|
||||||
|
android:id="@+id/title_bar"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="@android:color/transparent"
|
||||||
|
android:fitsSystemWindows="true"
|
||||||
|
app:liftOnScroll="false"
|
||||||
|
android:stateListAnimator="@null">
|
||||||
|
|
||||||
|
<com.google.android.material.appbar.MaterialToolbar
|
||||||
|
android:id="@+id/top_bar"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="?attr/actionBarSize"
|
||||||
|
app:title="@string/bookshelf"
|
||||||
|
app:layout_collapseMode="pin" />
|
||||||
|
|
||||||
|
<com.google.android.material.tabs.TabLayout
|
||||||
|
android:id="@+id/tab_layout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:tabMode="fixed"
|
||||||
|
android:background="@android:color/transparent"
|
||||||
|
style="@style/Widget.Material3.TabLayout" />
|
||||||
|
|
||||||
|
</com.google.android.material.appbar.AppBarLayout>
|
||||||
|
|
||||||
|
<io.legado.app.ui.widget.NestedScrollableHost
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
app:layout_behavior="@string/appbar_scrolling_view_behavior">
|
||||||
|
<androidx.viewpager2.widget.ViewPager2
|
||||||
|
android:id="@+id/view_pager_bookshelf"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:paddingHorizontal="8dp" />
|
||||||
|
</io.legado.app.ui.widget.NestedScrollableHost>
|
||||||
|
|
||||||
|
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||||
@@ -11,6 +11,7 @@
|
|||||||
<item>标签</item>
|
<item>标签</item>
|
||||||
<item>文件夹</item>
|
<item>文件夹</item>
|
||||||
<item>隐藏标签</item>
|
<item>隐藏标签</item>
|
||||||
|
<item>材料标签</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
|
|
||||||
<string-array name="text_suffix">
|
<string-array name="text_suffix">
|
||||||
@@ -183,7 +184,7 @@
|
|||||||
|
|
||||||
<string-array name="title_chapter_mode">
|
<string-array name="title_chapter_mode">
|
||||||
<item>不显示标题</item>
|
<item>不显示标题</item>
|
||||||
<item>不显示</item>
|
<item>不显示章节</item>
|
||||||
<item>Disable title and chapter display</item>
|
<item>Disable title and chapter display</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
<item>Tab</item>
|
<item>Tab</item>
|
||||||
<item>Folder</item>
|
<item>Folder</item>
|
||||||
<item>Hide Tab</item>
|
<item>Hide Tab</item>
|
||||||
|
<item>Material Tab</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
|
|
||||||
<string-array name="book_sort">
|
<string-array name="book_sort">
|
||||||
|
|||||||
@@ -35,6 +35,7 @@
|
|||||||
<style name="Widget.MyApp.Chip.Assist" parent="Widget.Material3.Chip.Assist">
|
<style name="Widget.MyApp.Chip.Assist" parent="Widget.Material3.Chip.Assist">
|
||||||
<item name="chipBackgroundColor">@color/chip_background_selector</item>
|
<item name="chipBackgroundColor">@color/chip_background_selector</item>
|
||||||
<item name="chipStrokeColor">@color/chip_stroke_selector</item>
|
<item name="chipStrokeColor">@color/chip_stroke_selector</item>
|
||||||
|
<item name="chipMinTouchTargetSize">0dp</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style name="NoBackgroundNavi" parent="ThemeOverlay.Material3.Toolbar.CircleNavigationButton">
|
<style name="NoBackgroundNavi" parent="ThemeOverlay.Material3.Toolbar.CircleNavigationButton">
|
||||||
|
|||||||
Reference in new issue
Block a user