更新界面
This commit is contained in:
@@ -5,6 +5,7 @@ import android.graphics.Canvas
|
||||
import android.graphics.Color
|
||||
import android.graphics.Paint
|
||||
import android.graphics.Rect
|
||||
import android.graphics.Typeface
|
||||
import android.text.TextPaint
|
||||
import android.view.View
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
@@ -28,10 +29,11 @@ class BookmarkDecoration(
|
||||
}
|
||||
|
||||
private val textPaint = TextPaint().apply {
|
||||
textSize = 16f.spToPx()
|
||||
textSize = 14f.spToPx()
|
||||
color =
|
||||
MaterialColors.getColor(context, androidx.appcompat.R.attr.colorPrimary, Color.BLACK)
|
||||
isAntiAlias = true
|
||||
typeface = Typeface.DEFAULT_BOLD
|
||||
}
|
||||
|
||||
private val textRect = Rect()
|
||||
|
||||
@@ -8,6 +8,7 @@ import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.os.Looper
|
||||
import android.view.Gravity
|
||||
import android.view.HapticFeedbackConstants
|
||||
import android.view.InputDevice
|
||||
import android.view.KeyEvent
|
||||
import android.view.Menu
|
||||
@@ -788,21 +789,25 @@ class ReadBookActivity : BaseReadBookActivity(),
|
||||
/**
|
||||
* 更新文字选择开始位置
|
||||
*/
|
||||
override fun upSelectedStart(x: Float, y: Float, top: Float) = binding.run {
|
||||
override fun upSelectedStart(x: Float, y: Float, top: Float): Unit = binding.run {
|
||||
cursorLeft.x = x - cursorLeft.width
|
||||
cursorLeft.y = y
|
||||
cursorLeft.visible(true)
|
||||
textMenuPosition.x = x
|
||||
textMenuPosition.y = top
|
||||
|
||||
root.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS)
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新文字选择结束位置
|
||||
*/
|
||||
override fun upSelectedEnd(x: Float, y: Float) = binding.run {
|
||||
override fun upSelectedEnd(x: Float, y: Float): Unit = binding.run {
|
||||
cursorRight.x = x
|
||||
cursorRight.y = y
|
||||
cursorRight.visible(true)
|
||||
|
||||
root.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -32,12 +32,12 @@ class BookmarkAdapter(context: Context, val callback: Callback) :
|
||||
override fun registerListener(holder: ItemViewHolder, binding: ItemBookmarkBinding) {
|
||||
binding.root.setOnClickListener {
|
||||
getItem(holder.layoutPosition)?.let { bookmark ->
|
||||
callback.onClick(bookmark)
|
||||
callback.onLongClick(bookmark, holder.layoutPosition)
|
||||
}
|
||||
}
|
||||
binding.root.onLongClick {
|
||||
getItem(holder.layoutPosition)?.let { bookmark ->
|
||||
callback.onLongClick(bookmark, holder.layoutPosition)
|
||||
callback.onClick(bookmark)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ import io.legato.kazusa.ui.widget.recycler.VerticalDivider
|
||||
import io.legato.kazusa.utils.applyNavigationBarPadding
|
||||
import io.legato.kazusa.utils.showDialogFragment
|
||||
import io.legato.kazusa.utils.viewbindingdelegate.viewBinding
|
||||
import io.legato.kazusa.utils.visible
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Dispatchers.IO
|
||||
import kotlinx.coroutines.flow.catch
|
||||
@@ -51,24 +52,27 @@ class BookmarkFragment : VMBaseFragment<TocViewModel>(R.layout.fragment_bookmark
|
||||
binding.recyclerView.addItemDecoration(VerticalDivider(requireContext()))
|
||||
binding.recyclerView.adapter = adapter
|
||||
binding.recyclerView.applyNavigationBarPadding()
|
||||
|
||||
binding.tvEmptyMsg.visible(false)
|
||||
}
|
||||
|
||||
override fun upBookmark(searchKey: String?) {
|
||||
val book = viewModel.bookData.value ?: return
|
||||
lifecycleScope.launch {
|
||||
when {
|
||||
val flow = when {
|
||||
searchKey.isNullOrBlank() -> appDb.bookmarkDao.flowByBook(book.name, book.author)
|
||||
else -> appDb.bookmarkDao.flowSearch(book.name, book.author, searchKey)
|
||||
}.catch {
|
||||
}
|
||||
|
||||
flow.catch {
|
||||
AppLog.put("目录界面获取书签数据失败\n${it.localizedMessage}", it)
|
||||
}.flowOn(IO).collect {
|
||||
adapter.setItems(it)
|
||||
}.flowOn(IO).collect { list ->
|
||||
adapter.setItems(list)
|
||||
binding.tvEmptyMsg.visible(list.isEmpty())
|
||||
var scrollPos = 0
|
||||
withContext(Dispatchers.Default) {
|
||||
adapter.getItems().forEachIndexed { index, bookmark ->
|
||||
if (bookmark.chapterIndex >= durChapterIndex) {
|
||||
return@withContext
|
||||
}
|
||||
if (bookmark.chapterIndex >= durChapterIndex) return@withContext
|
||||
scrollPos = index
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,15 +14,17 @@ import io.legato.kazusa.data.entities.BookChapter
|
||||
import io.legato.kazusa.databinding.ItemChapterListBinding
|
||||
import io.legato.kazusa.help.book.ContentProcessor
|
||||
import io.legato.kazusa.help.config.AppConfig
|
||||
import io.legato.kazusa.help.coroutine.Coroutine
|
||||
import io.legato.kazusa.lib.theme.ThemeUtils
|
||||
import io.legato.kazusa.utils.gone
|
||||
import io.legato.kazusa.utils.longToastOnUi
|
||||
import io.legato.kazusa.utils.themeColor
|
||||
import io.legato.kazusa.utils.visible
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.ensureActive
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
|
||||
class ChapterListAdapter(context: Context, val callback: Callback) :
|
||||
@@ -30,6 +32,7 @@ class ChapterListAdapter(context: Context, val callback: Callback) :
|
||||
|
||||
val cacheFileNames = hashSetOf<String>()
|
||||
private val displayTitleMap = ConcurrentHashMap<String, String>()
|
||||
|
||||
private val handler = Handler(Looper.getMainLooper())
|
||||
|
||||
override val diffItemCallback: DiffUtil.ItemCallback<BookChapter>
|
||||
@@ -58,7 +61,7 @@ class ChapterListAdapter(context: Context, val callback: Callback) :
|
||||
|
||||
}
|
||||
|
||||
private var upDisplayTileJob: Coroutine<*>? = null
|
||||
private var upDisplayTileJob: Job? = null
|
||||
|
||||
override fun onCurrentListChanged() {
|
||||
super.onCurrentListChanged()
|
||||
@@ -72,42 +75,31 @@ class ChapterListAdapter(context: Context, val callback: Callback) :
|
||||
|
||||
fun upDisplayTitles(startIndex: Int) {
|
||||
upDisplayTileJob?.cancel()
|
||||
upDisplayTileJob = Coroutine.async(callback.scope) {
|
||||
val book = callback.book ?: return@async
|
||||
upDisplayTileJob = callback.scope.launch(Dispatchers.Default) {
|
||||
val book = callback.book ?: return@launch
|
||||
val replaceRules = ContentProcessor.get(book.name, book.origin).getTitleReplaceRules()
|
||||
val useReplace = AppConfig.tocUiUseReplace && book.getUseReplaceRule()
|
||||
val items = getItems()
|
||||
launch {
|
||||
for (i in startIndex until items.size) {
|
||||
val item = items[i]
|
||||
if (displayTitleMap[item.title] == null) {
|
||||
ensureActive()
|
||||
val displayTitle = item.getDisplayTitle(replaceRules, useReplace)
|
||||
ensureActive()
|
||||
displayTitleMap[item.title] = displayTitle
|
||||
handler.post {
|
||||
notifyItemChanged(i, true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
launch {
|
||||
for (i in startIndex downTo 0) {
|
||||
val item = items[i]
|
||||
if (displayTitleMap[item.title] == null) {
|
||||
ensureActive()
|
||||
val displayTitle = item.getDisplayTitle(replaceRules, useReplace)
|
||||
ensureActive()
|
||||
displayTitleMap[item.title] = displayTitle
|
||||
handler.post {
|
||||
notifyItemChanged(i, true)
|
||||
}
|
||||
|
||||
val indices = (startIndex until items.size) + (startIndex downTo 0)
|
||||
|
||||
for (i in indices) {
|
||||
val item = items[i]
|
||||
val key = item.url
|
||||
if (displayTitleMap[key] == null) {
|
||||
ensureActive()
|
||||
val displayTitle = item.getDisplayTitle(replaceRules, useReplace)
|
||||
displayTitleMap[key] = displayTitle
|
||||
ensureActive()
|
||||
withContext(Dispatchers.Main) {
|
||||
notifyItemChanged(i, true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private fun getDisplayTitle(chapter: BookChapter): String {
|
||||
return displayTitleMap[chapter.title] ?: chapter.title
|
||||
}
|
||||
@@ -128,17 +120,22 @@ class ChapterListAdapter(context: Context, val callback: Callback) :
|
||||
|| item.isVolume
|
||||
|| cacheFileNames.contains(item.getFileName())
|
||||
if (payloads.isEmpty()) {
|
||||
if (isDur) {
|
||||
tvChapterName.setTextColor(context.themeColor(androidx.appcompat.R.attr.colorPrimary))
|
||||
tvChapterItem.setBackgroundColor(context.themeColor(com.google.android.material.R.attr.colorSurfaceContainer))
|
||||
} else {
|
||||
tvChapterName.setTextColor(context.themeColor(com.google.android.material.R.attr.colorOnSurface))
|
||||
tvChapterItem.setBackgroundColor(context.themeColor(com.google.android.material.R.attr.colorSurface))
|
||||
}
|
||||
tvChapterName.text = getDisplayTitle(item)
|
||||
|
||||
if (item.isVolume) {
|
||||
tvChapterItem.setBackgroundColor(context.themeColor(com.google.android.material.R.attr.colorSecondaryContainer))
|
||||
ivVolume.visible()
|
||||
tvChapterName.text = getDisplayTitle(item)
|
||||
tvChapterName.textSize = 12f
|
||||
tvChapterName.setTextColor(context.themeColor(com.google.android.material.R.attr.colorTertiary))
|
||||
} else {
|
||||
ivVolume.gone()
|
||||
if (isDur) {
|
||||
tvChapterName.setTextColor(context.themeColor(androidx.appcompat.R.attr.colorPrimary))
|
||||
tvChapterItem.setBackgroundColor(context.themeColor(com.google.android.material.R.attr.colorSurfaceContainer))
|
||||
} else {
|
||||
tvChapterName.setTextColor(context.themeColor(com.google.android.material.R.attr.colorOnSurface))
|
||||
tvChapterItem.setBackgroundColor(context.themeColor(com.google.android.material.R.attr.colorSurface))
|
||||
}
|
||||
tvChapterName.text = getDisplayTitle(item)
|
||||
tvChapterItem.foreground =
|
||||
ThemeUtils.resolveDrawable(context, android.R.attr.selectableItemBackground)
|
||||
}
|
||||
@@ -165,10 +162,10 @@ class ChapterListAdapter(context: Context, val callback: Callback) :
|
||||
ivLocked.gone()
|
||||
}
|
||||
|
||||
upHasCache(binding, isDur, cached)
|
||||
upHasCache(binding, cached)
|
||||
} else {
|
||||
tvChapterName.text = getDisplayTitle(item)
|
||||
upHasCache(binding, isDur, cached)
|
||||
upHasCache(binding, cached)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -187,12 +184,11 @@ class ChapterListAdapter(context: Context, val callback: Callback) :
|
||||
}
|
||||
}
|
||||
|
||||
private fun upHasCache(binding: ItemChapterListBinding, isDur: Boolean, cached: Boolean) =
|
||||
private fun upHasCache(binding: ItemChapterListBinding, cached: Boolean) =
|
||||
binding.apply {
|
||||
when {
|
||||
isDur -> ivChecked.gone()
|
||||
cached -> {
|
||||
ivChecked.setImageResource(R.drawable.ic_check)
|
||||
ivChecked.setImageResource(R.drawable.ic_download_done)
|
||||
ivChecked.visible()
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
package io.legato.kazusa.ui.book.toc
|
||||
|
||||
//import io.legado.app.lib.theme.bottomBackground
|
||||
//import io.legado.app.lib.theme.getPrimaryTextColor
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Activity.RESULT_OK
|
||||
import android.content.Intent
|
||||
@@ -36,7 +34,6 @@ import io.legato.kazusa.utils.themeColor
|
||||
import io.legato.kazusa.utils.toastOnUi
|
||||
import io.legato.kazusa.utils.viewbindingdelegate.viewBinding
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers.Default
|
||||
import kotlinx.coroutines.Dispatchers.IO
|
||||
import kotlinx.coroutines.Dispatchers.Main
|
||||
import kotlinx.coroutines.launch
|
||||
@@ -79,7 +76,7 @@ class ChapterListFragment : VMBaseFragment<TocViewModel>(R.layout.fragment_chapt
|
||||
|
||||
toastOnUi("开始下载: ${adapter.getItem(position)?.title}")
|
||||
CacheBook.start(requireContext(), book, chapter.index, chapter.index)
|
||||
VibrationUtils.vibrate(context!!, 100)
|
||||
VibrationUtils.vibratePattern(requireContext(), longArrayOf(0, 50, 30, 50), -1)
|
||||
adapter.notifyItemChanged(position)
|
||||
}
|
||||
|
||||
@@ -191,16 +188,11 @@ class ChapterListFragment : VMBaseFragment<TocViewModel>(R.layout.fragment_chapt
|
||||
override fun observeLiveBus() {
|
||||
observeEvent<Pair<Book, BookChapter>>(EventBus.SAVE_CONTENT) { (book, chapter) ->
|
||||
viewModel.bookData.value?.bookUrl?.let { bookUrl ->
|
||||
if (book.bookUrl == bookUrl) {
|
||||
if (book.bookUrl == viewModel.bookData.value?.bookUrl) {
|
||||
adapter.cacheFileNames.add(chapter.getFileName())
|
||||
if (viewModel.searchKey.isNullOrEmpty()) {
|
||||
adapter.notifyItemChanged(chapter.index, true)
|
||||
} else {
|
||||
adapter.getItems().forEachIndexed { index, bookChapter ->
|
||||
if (bookChapter.index == chapter.index) {
|
||||
adapter.notifyItemChanged(index, true)
|
||||
}
|
||||
}
|
||||
val index = adapter.getItems().indexOfFirst { it.index == chapter.index }
|
||||
if (index >= 0) {
|
||||
adapter.notifyItemChanged(index, true)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -225,15 +217,9 @@ class ChapterListFragment : VMBaseFragment<TocViewModel>(R.layout.fragment_chapt
|
||||
|
||||
override fun onListChanged() {
|
||||
lifecycleScope.launch {
|
||||
var scrollPos = 0
|
||||
withContext(Default) {
|
||||
adapter.getItems().forEachIndexed { index, bookChapter ->
|
||||
if (bookChapter.index >= durChapterIndex) {
|
||||
return@withContext
|
||||
}
|
||||
scrollPos = index
|
||||
}
|
||||
}
|
||||
val scrollPos = adapter.getItems()
|
||||
.indexOfLast { it.index < durChapterIndex }
|
||||
.coerceAtLeast(0)
|
||||
mLayoutManager.scrollToPositionWithOffset(scrollPos, 0)
|
||||
adapter.upDisplayTitles(scrollPos)
|
||||
}
|
||||
|
||||
@@ -60,8 +60,9 @@ class TocActivity : VMBaseActivity<ActivityChapterListBinding, TocViewModel>(),
|
||||
tabLayout = binding.tabLayout
|
||||
binding.viewPager.adapter = TabFragmentPageAdapter()
|
||||
tabLayout.setupWithViewPager(binding.viewPager)
|
||||
viewModel.bookData.observe(this) {
|
||||
menu?.setGroupVisible(R.id.menu_group_text, it.isLocalTxt)
|
||||
viewModel.bookData.observe(this) { book ->
|
||||
menu?.setGroupVisible(R.id.menu_group_text, book.isLocalTxt)
|
||||
supportActionBar?.title = book.name
|
||||
}
|
||||
intent.getStringExtra("bookUrl")?.let {
|
||||
viewModel.initBook(it)
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<size android:height="1px" />
|
||||
<solid android:color="@color/bg_divider_line" />
|
||||
</shape>
|
||||
<?xml version="1.0" encoding="utf-8"?><!-- res/drawable/md3_divider_inset.xml -->
|
||||
<inset xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:insetLeft="16dp"
|
||||
android:insetRight="16dp">
|
||||
<shape android:shape="rectangle">
|
||||
<size android:height="1dp" />
|
||||
<solid android:color="?attr/colorSurfaceContainer" />
|
||||
</shape>
|
||||
</inset>
|
||||
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:tint="?attr/colorControlNormal"
|
||||
android:viewportWidth="960"
|
||||
android:viewportHeight="960">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M382,640L155,413L212,356L382,526L748,160L805,217L382,640ZM200,800L200,720L760,720L760,800L200,800Z" />
|
||||
</vector>
|
||||
@@ -19,7 +19,7 @@
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
app:layout_collapseMode="pin"
|
||||
app:navigationIcon="@drawable/ic_arrow_back"
|
||||
app:title="@string/chapter_list" />
|
||||
app:title="" />
|
||||
|
||||
<com.google.android.material.tabs.TabLayout
|
||||
android:id="@+id/tab_layout"
|
||||
|
||||
@@ -78,7 +78,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Σ(#`O′)"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="24sp" />
|
||||
android:textSize="32sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_msg"
|
||||
@@ -90,7 +90,7 @@
|
||||
android:id="@+id/tv_retry"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/Widget.Material3Expressive.Button.IconButton.Tonal"
|
||||
style="@style/Widget.Material3Expressive.Button.TonalButton"
|
||||
app:icon="@drawable/ic_refresh"
|
||||
android:layout_margin="16dp"
|
||||
app:iconPadding="4dp"
|
||||
|
||||
@@ -9,18 +9,34 @@
|
||||
android:orientation="vertical"
|
||||
tools:ignore="UselessParent">
|
||||
|
||||
<androidx.appcompat.widget.Toolbar
|
||||
android:id="@+id/tool_bar"
|
||||
android:layout_width="match_parent"
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical"
|
||||
android:paddingHorizontal="16dp"
|
||||
android:paddingBottom="8dp">
|
||||
|
||||
<com.google.android.material.bottomsheet.BottomSheetDragHandleView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:theme="?attr/actionBarStyle"
|
||||
app:title="@string/bookmark" />
|
||||
android:layout_gravity="center_horizontal" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/bottom_sheet_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:text="@string/bookmark"
|
||||
android:textSize="18sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_chapter_name"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="16dp" />
|
||||
android:paddingHorizontal="16dp" />
|
||||
|
||||
<androidx.core.widget.NestedScrollView
|
||||
android:layout_width="match_parent"
|
||||
@@ -36,8 +52,7 @@
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="3dp">
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:id="@+id/edit_book_text"
|
||||
@@ -74,11 +89,10 @@
|
||||
<!-- 删除按钮靠左 -->
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/btn_delete"
|
||||
style="@style/Widget.Material3Expressive.Button.TonalButton"
|
||||
style="@style/Widget.Material3Expressive.Button.IconButton.Outlined"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="12dp"
|
||||
android:text="@string/delete"
|
||||
app:icon="@drawable/ic_clear_all"
|
||||
android:visibility="invisible"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
@@ -90,7 +104,7 @@
|
||||
style="@style/Widget.Material3Expressive.Button.TonalButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="12dp"
|
||||
android:minWidth="0dp"
|
||||
android:text="@string/cancel"
|
||||
app:layout_constraintEnd_toStartOf="@id/btn_ok"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
@@ -100,10 +114,10 @@
|
||||
<!-- 确认按钮靠右 -->
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/btn_ok"
|
||||
style="@style/Widget.Material3Expressive.Button.TonalButton"
|
||||
style="@style/Widget.Material3Expressive.Button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="12dp"
|
||||
android:minWidth="0dp"
|
||||
android:text="@string/ok"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
|
||||
@@ -7,22 +7,20 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:paddingHorizontal="16dp"
|
||||
android:paddingVertical="8dp">
|
||||
android:paddingBottom="8dp">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:gravity="center"
|
||||
android:paddingVertical="8dp"
|
||||
android:paddingBottom="8dp"
|
||||
android:paddingHorizontal="16dp">
|
||||
|
||||
<View
|
||||
android:layout_width="36dp"
|
||||
android:layout_height="4dp"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:background="@drawable/bg_bottom_sheet_handle"
|
||||
android:layout_marginBottom="16dp" />
|
||||
<com.google.android.material.bottomsheet.BottomSheetDragHandleView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/bottom_sheet_title"
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:descendantFocusability="blocksDescendants">
|
||||
|
||||
<io.legato.kazusa.ui.widget.recycler.scroller.FastScrollRecyclerView
|
||||
@@ -11,4 +12,31 @@
|
||||
android:clipToPadding="false"
|
||||
android:overScrollMode="never" />
|
||||
|
||||
<LinearLayout
|
||||
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:orientation="vertical"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="(๑`^´๑)"
|
||||
android:textSize="32sp" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="8dp"
|
||||
android:text="还没有添加书签哦!" />
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -30,7 +30,7 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="(๑`^´๑)"
|
||||
android:textSize="30sp"/>
|
||||
android:textSize="32sp" />
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
|
||||
@@ -10,54 +10,80 @@
|
||||
android:paddingHorizontal="16dp"
|
||||
android:paddingVertical="12dp">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_locked"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:paddingEnd="8dp"
|
||||
android:src="@drawable/ic_lock_outline"
|
||||
android:visibility="gone"
|
||||
<LinearLayout
|
||||
android:id="@+id/ll_info"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_locked"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:padding="4dp"
|
||||
android:src="@drawable/ic_lock_outline"
|
||||
android:visibility="visible" />
|
||||
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
android:id="@+id/iv_volume"
|
||||
android:layout_width="4dp"
|
||||
android:layout_height="16dp"
|
||||
android:layout_marginEnd="4dp"
|
||||
android:visibility="visible"
|
||||
app:cardBackgroundColor="?attr/colorTertiary"
|
||||
app:strokeWidth="0dp" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="4dp"
|
||||
android:orientation="vertical"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@id/iv_checked"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:ignore="RtlSymmetry" />
|
||||
app:layout_constraintStart_toEndOf="@id/ll_info">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_chapter_name"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="14sp"
|
||||
android:textStyle="bold"
|
||||
android:maxLines="2"
|
||||
app:layout_constraintEnd_toStartOf="@+id/iv_checked"
|
||||
app:layout_constraintStart_toEndOf="@+id/iv_locked"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
<TextView
|
||||
android:id="@+id/tv_chapter_name"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:maxLines="2"
|
||||
android:textSize="14sp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintEnd_toStartOf="@+id/iv_checked"
|
||||
app:layout_constraintStart_toEndOf="@+id/iv_locked"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_word_count"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="4dp"
|
||||
android:paddingEnd="18dp"
|
||||
android:singleLine="true"
|
||||
android:textSize="12sp"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintEnd_toStartOf="@+id/iv_checked"
|
||||
app:layout_constraintStart_toEndOf="@+id/iv_locked"
|
||||
app:layout_constraintTop_toBottomOf="@id/tv_chapter_name"
|
||||
tools:ignore="RtlSymmetry" />
|
||||
<TextView
|
||||
android:id="@+id/tv_word_count"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="4dp"
|
||||
android:paddingEnd="18dp"
|
||||
android:singleLine="true"
|
||||
android:textSize="12sp"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintEnd_toStartOf="@+id/iv_checked"
|
||||
app:layout_constraintStart_toEndOf="@+id/iv_locked"
|
||||
app:layout_constraintTop_toBottomOf="@id/tv_chapter_name"
|
||||
tools:ignore="RtlSymmetry" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_tag"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="4dp"
|
||||
android:singleLine="true"
|
||||
android:textSize="12sp"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintEnd_toStartOf="@+id/iv_checked"
|
||||
app:layout_constraintStart_toEndOf="@+id/iv_locked"
|
||||
app:layout_constraintTop_toBottomOf="@id/tv_word_count" />
|
||||
<TextView
|
||||
android:id="@+id/tv_tag"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="4dp"
|
||||
android:singleLine="true"
|
||||
android:textSize="12sp"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintEnd_toStartOf="@+id/iv_checked"
|
||||
app:layout_constraintStart_toEndOf="@+id/iv_locked"
|
||||
app:layout_constraintTop_toBottomOf="@id/tv_word_count" />
|
||||
</LinearLayout>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_checked"
|
||||
|
||||
@@ -88,6 +88,7 @@
|
||||
android:id="@+id/cd_count"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="gone"
|
||||
android:layout_marginVertical="4dp"
|
||||
app:cardBackgroundColor="?attr/colorSurfaceContainer"
|
||||
app:cardCornerRadius="4dp"
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<com.google.android.material.progressindicator.CircularProgressIndicator
|
||||
<com.google.android.material.loadingindicator.LoadingIndicator
|
||||
android:id="@+id/rotate_loading"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
|
||||
Reference in New Issue
Block a user