commit
672ac5fe1b
Binary file not shown.
Binary file not shown.
@ -1 +1 @@ |
|||||||
{"x86":"ff4b324fca11309c5e93a45f65970540","armeabi-v7a":"65e8bb0095d5be314ada2f523718f477","x86_64":"3dac75809f86b8edd1399a642bd26f59","arm64-v8a":"ac515c2995b4fb831419313056b1d3f0","version":"100.0.4896.58"} |
{"x86_64":"d08640c5057600d40e6582f292d858e2","arm64-v8a":"f99bb5a1e465754635e19b57204af9f5","armeabi-v7a":"f195422fc23bf985b120c9918091e9b8","x86":"ca9a32dc413021834c2b6a658656c5aa","version":"100.0.4896.79"} |
File diff suppressed because one or more lines are too long
@ -1,3 +1,3 @@ |
|||||||
<!DOCTYPE html><html lang="en" style="padding: 0;height:100%"><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=0"><link rel="icon" href="../favicon.ico" type="image/x-icon"><link rel="shortcut icon" href="../favicon.ico" type="image/x-icon"><title>Legado Bookshelf</title><link href="css/about.54684f5f.css" rel="prefetch"><link href="css/detail.c24d2b34.css" rel="prefetch"><link href="js/about.56b5bbf2.js" rel="prefetch"><link href="js/detail.b1145ea3.js" rel="prefetch"><link href="css/app.e4c919b7.css" rel="preload" as="style"><link href="css/chunk-vendors.5f0f4fba.css" rel="preload" as="style"><link href="js/app.f9143363.js" rel="preload" as="script"><link href="js/chunk-vendors.be6090cd.js" rel="preload" as="script"><link href="css/chunk-vendors.5f0f4fba.css" rel="stylesheet"><link href="css/app.e4c919b7.css" rel="stylesheet"></head><style>body::-webkit-scrollbar { |
<!DOCTYPE html><html lang="en" style="padding: 0;height:100%"><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=0"><link rel="icon" href="../favicon.ico" type="image/x-icon"><link rel="shortcut icon" href="../favicon.ico" type="image/x-icon"><title>Legado Bookshelf</title><link href="css/about.54684f5f.css" rel="prefetch"><link href="css/detail.01ad55b1.css" rel="prefetch"><link href="js/about.a288ed22.js" rel="prefetch"><link href="js/detail.562e75a6.js" rel="prefetch"><link href="css/app.e4c919b7.css" rel="preload" as="style"><link href="css/chunk-vendors.5f0f4fba.css" rel="preload" as="style"><link href="js/app.cfea0936.js" rel="preload" as="script"><link href="js/chunk-vendors.be6090cd.js" rel="preload" as="script"><link href="css/chunk-vendors.5f0f4fba.css" rel="stylesheet"><link href="css/app.e4c919b7.css" rel="stylesheet"></head><style>body::-webkit-scrollbar { |
||||||
display: none; |
display: none; |
||||||
}</style><body style="margin: 0;height:100%"><noscript><strong>We're sorry but yd-web-tool doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div><script src="js/chunk-vendors.be6090cd.js"></script><script src="js/app.f9143363.js"></script></body></html> |
}</style><body style="margin: 0;height:100%"><noscript><strong>We're sorry but yd-web-tool doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div><script src="js/chunk-vendors.be6090cd.js"></script><script src="js/app.cfea0936.js"></script></body></html> |
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -0,0 +1,45 @@ |
|||||||
|
package io.legado.app.ui.book.arrange |
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.Column |
||||||
|
import androidx.compose.material.AlertDialog |
||||||
|
import androidx.compose.material.LinearProgressIndicator |
||||||
|
import androidx.compose.material.Text |
||||||
|
import androidx.compose.material.TextButton |
||||||
|
import androidx.compose.runtime.Composable |
||||||
|
import androidx.compose.runtime.MutableState |
||||||
|
import androidx.compose.ui.Alignment |
||||||
|
import io.legado.app.R |
||||||
|
import splitties.init.appCtx |
||||||
|
|
||||||
|
@Composable |
||||||
|
fun BatchChangeSourceDialog( |
||||||
|
state: MutableState<Boolean>, |
||||||
|
size: MutableState<Int>, |
||||||
|
position: MutableState<Int>, |
||||||
|
cancel: () -> Unit |
||||||
|
) { |
||||||
|
if (state.value) { |
||||||
|
AlertDialog( |
||||||
|
onDismissRequest = { }, |
||||||
|
confirmButton = { |
||||||
|
TextButton(onClick = { |
||||||
|
cancel.invoke() |
||||||
|
state.value = false |
||||||
|
}, content = { |
||||||
|
Text(text = "取消") |
||||||
|
}) |
||||||
|
}, |
||||||
|
title = { |
||||||
|
Text(text = appCtx.getString(R.string.change_source_batch)) |
||||||
|
}, |
||||||
|
text = { |
||||||
|
Column(horizontalAlignment = Alignment.CenterHorizontally) { |
||||||
|
Text(text = "${position.value}/${size.value}") |
||||||
|
LinearProgressIndicator( |
||||||
|
progress = position.value / size.value.toFloat() |
||||||
|
) |
||||||
|
} |
||||||
|
} |
||||||
|
) |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,121 @@ |
|||||||
|
package io.legado.app.ui.book.arrange |
||||||
|
|
||||||
|
import android.content.Context |
||||||
|
import android.os.Bundle |
||||||
|
import android.view.View |
||||||
|
import android.view.ViewGroup |
||||||
|
import androidx.appcompat.widget.SearchView |
||||||
|
import androidx.core.view.setPadding |
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager |
||||||
|
import io.legado.app.R |
||||||
|
import io.legado.app.base.BaseDialogFragment |
||||||
|
import io.legado.app.base.adapter.ItemViewHolder |
||||||
|
import io.legado.app.base.adapter.RecyclerAdapter |
||||||
|
import io.legado.app.data.appDb |
||||||
|
import io.legado.app.data.entities.BookSource |
||||||
|
import io.legado.app.databinding.DialogSourcePickerBinding |
||||||
|
import io.legado.app.databinding.Item1lineTextBinding |
||||||
|
import io.legado.app.lib.theme.primaryColor |
||||||
|
import io.legado.app.lib.theme.primaryTextColor |
||||||
|
import io.legado.app.utils.applyTint |
||||||
|
import io.legado.app.utils.dpToPx |
||||||
|
import io.legado.app.utils.setLayout |
||||||
|
import io.legado.app.utils.viewbindingdelegate.viewBinding |
||||||
|
import kotlinx.coroutines.Job |
||||||
|
import kotlinx.coroutines.launch |
||||||
|
import splitties.views.onClick |
||||||
|
|
||||||
|
class SourcePickerDialog : BaseDialogFragment(R.layout.dialog_source_picker) { |
||||||
|
|
||||||
|
private val binding by viewBinding(DialogSourcePickerBinding::bind) |
||||||
|
private val searchView: SearchView by lazy { |
||||||
|
binding.toolBar.findViewById(R.id.search_view) |
||||||
|
} |
||||||
|
private val adapter by lazy { |
||||||
|
SourceAdapter(requireContext()) |
||||||
|
} |
||||||
|
private var sourceFlowJob: Job? = null |
||||||
|
|
||||||
|
override fun onStart() { |
||||||
|
super.onStart() |
||||||
|
setLayout(1f, ViewGroup.LayoutParams.MATCH_PARENT) |
||||||
|
} |
||||||
|
|
||||||
|
override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) { |
||||||
|
initView() |
||||||
|
initData() |
||||||
|
} |
||||||
|
|
||||||
|
private fun initView() { |
||||||
|
binding.toolBar.setBackgroundColor(primaryColor) |
||||||
|
binding.toolBar.title = "选择书源" |
||||||
|
binding.recyclerView.layoutManager = LinearLayoutManager(requireContext()) |
||||||
|
binding.recyclerView.adapter = adapter |
||||||
|
searchView.applyTint(primaryTextColor) |
||||||
|
searchView.onActionViewExpanded() |
||||||
|
searchView.isSubmitButtonEnabled = true |
||||||
|
searchView.queryHint = getString(R.string.search_book_source) |
||||||
|
searchView.clearFocus() |
||||||
|
searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener { |
||||||
|
override fun onQueryTextSubmit(query: String?): Boolean { |
||||||
|
return false |
||||||
|
} |
||||||
|
|
||||||
|
override fun onQueryTextChange(newText: String?): Boolean { |
||||||
|
initData(newText) |
||||||
|
return false |
||||||
|
} |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
private fun initData(searchKey: String? = null) { |
||||||
|
sourceFlowJob?.cancel() |
||||||
|
sourceFlowJob = launch { |
||||||
|
when { |
||||||
|
searchKey.isNullOrEmpty() -> appDb.bookSourceDao.flowEnabled() |
||||||
|
else -> appDb.bookSourceDao.flowSearchEnabled(searchKey) |
||||||
|
}.collect { |
||||||
|
adapter.setItems(it) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
inner class SourceAdapter(context: Context) : |
||||||
|
RecyclerAdapter<BookSource, Item1lineTextBinding>(context) { |
||||||
|
|
||||||
|
override fun getViewBinding(parent: ViewGroup): Item1lineTextBinding { |
||||||
|
return Item1lineTextBinding.inflate(inflater, parent, false).apply { |
||||||
|
root.setPadding(16.dpToPx()) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
override fun convert( |
||||||
|
holder: ItemViewHolder, |
||||||
|
binding: Item1lineTextBinding, |
||||||
|
item: BookSource, |
||||||
|
payloads: MutableList<Any> |
||||||
|
) { |
||||||
|
binding.textView.text = item.getDisPlayNameGroup() |
||||||
|
} |
||||||
|
|
||||||
|
override fun registerListener(holder: ItemViewHolder, binding: Item1lineTextBinding) { |
||||||
|
binding.root.onClick { |
||||||
|
getItemByLayoutPosition(holder.layoutPosition)?.let { |
||||||
|
callback?.sourceOnClick(it) |
||||||
|
dismissAllowingStateLoss() |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
private val callback: Callback? |
||||||
|
get() { |
||||||
|
return (parentFragment as? Callback) ?: activity as? Callback |
||||||
|
} |
||||||
|
|
||||||
|
interface Callback { |
||||||
|
fun sourceOnClick(source: BookSource) |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,47 @@ |
|||||||
|
package io.legado.app.ui.book.bookmark |
||||||
|
|
||||||
|
import android.os.Bundle |
||||||
|
import androidx.activity.viewModels |
||||||
|
import io.legado.app.base.VMBaseActivity |
||||||
|
import io.legado.app.data.entities.Bookmark |
||||||
|
import io.legado.app.databinding.ActivityAllBookmarkBinding |
||||||
|
import io.legado.app.utils.showDialogFragment |
||||||
|
import io.legado.app.utils.viewbindingdelegate.viewBinding |
||||||
|
|
||||||
|
class AllBookmarkActivity : VMBaseActivity<ActivityAllBookmarkBinding, AllBookmarkViewModel>(), |
||||||
|
BookmarkAdapter.Callback, |
||||||
|
BookmarkDialog.Callback { |
||||||
|
|
||||||
|
override val viewModel by viewModels<AllBookmarkViewModel>() |
||||||
|
override val binding by viewBinding(ActivityAllBookmarkBinding::inflate) |
||||||
|
private val adapter by lazy { |
||||||
|
BookmarkAdapter(this, this) |
||||||
|
} |
||||||
|
|
||||||
|
override fun onActivityCreated(savedInstanceState: Bundle?) { |
||||||
|
initView() |
||||||
|
viewModel.initData { |
||||||
|
adapter.setItems(it) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private fun initView() { |
||||||
|
binding.recyclerView.addItemDecoration(BookmarkDecoration(adapter)) |
||||||
|
binding.recyclerView.adapter = adapter |
||||||
|
} |
||||||
|
|
||||||
|
override fun onItemClick(bookmark: Bookmark, position: Int) { |
||||||
|
showDialogFragment(BookmarkDialog(bookmark, position)) |
||||||
|
} |
||||||
|
|
||||||
|
override fun upBookmark(pos: Int, bookmark: Bookmark) { |
||||||
|
adapter.setItem(pos, bookmark) |
||||||
|
} |
||||||
|
|
||||||
|
override fun deleteBookmark(pos: Int) { |
||||||
|
adapter.getItem(pos)?.let { |
||||||
|
viewModel.deleteBookmark(it) |
||||||
|
} |
||||||
|
adapter.removeItem(pos) |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,25 @@ |
|||||||
|
package io.legado.app.ui.book.bookmark |
||||||
|
|
||||||
|
import android.app.Application |
||||||
|
import io.legado.app.base.BaseViewModel |
||||||
|
import io.legado.app.data.appDb |
||||||
|
import io.legado.app.data.entities.Bookmark |
||||||
|
|
||||||
|
class AllBookmarkViewModel(application: Application) : BaseViewModel(application) { |
||||||
|
|
||||||
|
|
||||||
|
fun initData(onSuccess: (bookmarks: List<Bookmark>) -> Unit) { |
||||||
|
execute { |
||||||
|
appDb.bookmarkDao.all |
||||||
|
}.onSuccess { |
||||||
|
onSuccess.invoke(it) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
fun deleteBookmark(bookmark: Bookmark) { |
||||||
|
execute { |
||||||
|
appDb.bookmarkDao.delete(bookmark) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,60 @@ |
|||||||
|
package io.legado.app.ui.book.bookmark |
||||||
|
|
||||||
|
import android.content.Context |
||||||
|
import android.view.ViewGroup |
||||||
|
import io.legado.app.base.adapter.ItemViewHolder |
||||||
|
import io.legado.app.base.adapter.RecyclerAdapter |
||||||
|
import io.legado.app.data.entities.Bookmark |
||||||
|
import io.legado.app.databinding.ItemBookmarkBinding |
||||||
|
import io.legado.app.utils.gone |
||||||
|
import splitties.views.onClick |
||||||
|
|
||||||
|
class BookmarkAdapter(context: Context, val callback: Callback) : |
||||||
|
RecyclerAdapter<Bookmark, ItemBookmarkBinding>(context) { |
||||||
|
|
||||||
|
override fun getViewBinding(parent: ViewGroup): ItemBookmarkBinding { |
||||||
|
return ItemBookmarkBinding.inflate(inflater, parent, false) |
||||||
|
} |
||||||
|
|
||||||
|
override fun convert( |
||||||
|
holder: ItemViewHolder, |
||||||
|
binding: ItemBookmarkBinding, |
||||||
|
item: Bookmark, |
||||||
|
payloads: MutableList<Any> |
||||||
|
) { |
||||||
|
binding.tvChapterName.text = item.chapterName |
||||||
|
binding.tvBookText.gone(item.bookText.isEmpty()) |
||||||
|
binding.tvBookText.text = item.bookText |
||||||
|
binding.tvContent.gone(item.content.isEmpty()) |
||||||
|
binding.tvContent.text = item.content |
||||||
|
} |
||||||
|
|
||||||
|
override fun registerListener(holder: ItemViewHolder, binding: ItemBookmarkBinding) { |
||||||
|
binding.root.onClick { |
||||||
|
getItemByLayoutPosition(holder.layoutPosition)?.let { |
||||||
|
callback.onItemClick(it, holder.layoutPosition) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
fun getHeaderText(position: Int): String { |
||||||
|
return with(getItem(position)) { |
||||||
|
"${this?.bookName ?: ""}(${this?.bookAuthor ?: ""})" |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
fun isItemHeader(position: Int): Boolean { |
||||||
|
if (position == 0) return true |
||||||
|
val lastItem = getItem(position - 1) |
||||||
|
val curItem = getItem(position) |
||||||
|
return !(lastItem?.bookName == curItem?.bookName |
||||||
|
&& lastItem?.bookAuthor == curItem?.bookAuthor) |
||||||
|
} |
||||||
|
|
||||||
|
interface Callback { |
||||||
|
|
||||||
|
fun onItemClick(bookmark: Bookmark, position: Int) |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,110 @@ |
|||||||
|
package io.legado.app.ui.book.bookmark |
||||||
|
|
||||||
|
import android.graphics.Canvas |
||||||
|
import android.graphics.Paint |
||||||
|
import android.graphics.Rect |
||||||
|
import android.text.TextPaint |
||||||
|
import android.view.View |
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager |
||||||
|
import androidx.recyclerview.widget.RecyclerView |
||||||
|
import io.legado.app.lib.theme.accentColor |
||||||
|
import io.legado.app.lib.theme.backgroundColor |
||||||
|
import io.legado.app.utils.dpToPx |
||||||
|
import io.legado.app.utils.spToPx |
||||||
|
import splitties.init.appCtx |
||||||
|
import kotlin.math.min |
||||||
|
|
||||||
|
class BookmarkDecoration(val adapter: BookmarkAdapter) : RecyclerView.ItemDecoration() { |
||||||
|
|
||||||
|
private val headerLeft = 16f.dpToPx() |
||||||
|
private val headerHeight = 32f.dpToPx() |
||||||
|
|
||||||
|
private val headerPaint = Paint().apply { |
||||||
|
color = appCtx.backgroundColor |
||||||
|
} |
||||||
|
private val textPaint = TextPaint().apply { |
||||||
|
textSize = 16f.spToPx() |
||||||
|
color = appCtx.accentColor |
||||||
|
} |
||||||
|
private val textRect = Rect() |
||||||
|
|
||||||
|
override fun onDraw(c: Canvas, parent: RecyclerView, state: RecyclerView.State) { |
||||||
|
val count = parent.childCount |
||||||
|
for (i in 0 until count) { |
||||||
|
val view = parent.getChildAt(i) |
||||||
|
val position = parent.getChildLayoutPosition(view) |
||||||
|
val isHeader = adapter.isItemHeader(position) |
||||||
|
if (isHeader) { |
||||||
|
c.drawRect( |
||||||
|
0f, |
||||||
|
view.top - headerHeight, |
||||||
|
parent.width.toFloat(), |
||||||
|
view.top.toFloat(), |
||||||
|
headerPaint |
||||||
|
) |
||||||
|
val headerText = adapter.getHeaderText(position) |
||||||
|
textPaint.getTextBounds(headerText, 0, headerText.length, textRect) |
||||||
|
c.drawText( |
||||||
|
headerText, |
||||||
|
headerLeft, |
||||||
|
(view.top - headerHeight) + headerHeight / 2 + textRect.height() / 2, |
||||||
|
textPaint |
||||||
|
) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
override fun onDrawOver(c: Canvas, parent: RecyclerView, state: RecyclerView.State) { |
||||||
|
val position = (parent.layoutManager as LinearLayoutManager).findFirstVisibleItemPosition() |
||||||
|
val view = parent.findViewHolderForAdapterPosition(position)?.itemView ?: return |
||||||
|
val isHeader = adapter.isItemHeader(position + 1) |
||||||
|
val headerText = adapter.getHeaderText(position) |
||||||
|
if (isHeader) { |
||||||
|
val bottom = min(headerHeight.toInt(), view.bottom) |
||||||
|
c.drawRect( |
||||||
|
0f, |
||||||
|
view.top - headerHeight, |
||||||
|
parent.width.toFloat(), |
||||||
|
bottom.toFloat(), |
||||||
|
headerPaint |
||||||
|
) |
||||||
|
textPaint.getTextBounds(headerText, 0, headerText.length, textRect) |
||||||
|
c.drawText( |
||||||
|
headerText, |
||||||
|
headerLeft, |
||||||
|
headerHeight / 2 + textRect.height() / 2 - (headerHeight - bottom), |
||||||
|
textPaint |
||||||
|
) |
||||||
|
} else { |
||||||
|
c.drawRect( |
||||||
|
0f, |
||||||
|
0f, |
||||||
|
parent.width.toFloat(), |
||||||
|
headerHeight, |
||||||
|
headerPaint |
||||||
|
) |
||||||
|
textPaint.getTextBounds(headerText, 0, headerText.length, textRect) |
||||||
|
c.drawText( |
||||||
|
headerText, |
||||||
|
headerLeft, |
||||||
|
headerHeight / 2 + textRect.height() / 2, |
||||||
|
textPaint |
||||||
|
) |
||||||
|
} |
||||||
|
c.save() |
||||||
|
} |
||||||
|
|
||||||
|
override fun getItemOffsets( |
||||||
|
outRect: Rect, |
||||||
|
view: View, |
||||||
|
parent: RecyclerView, |
||||||
|
state: RecyclerView.State |
||||||
|
) { |
||||||
|
val position = parent.getChildLayoutPosition(view) |
||||||
|
val isHeader = adapter.isItemHeader(position) |
||||||
|
if (isHeader) { |
||||||
|
outRect.top = headerHeight.toInt() |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,22 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||||
|
<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"> |
||||||
|
|
||||||
|
<io.legado.app.ui.widget.TitleBar |
||||||
|
android:id="@+id/title_bar" |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
app:title="@string/all_bookmark" |
||||||
|
app:layout_constraintTop_toTopOf="parent" /> |
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView |
||||||
|
android:id="@+id/recycler_view" |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="0dp" |
||||||
|
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" |
||||||
|
app:layout_constraintTop_toBottomOf="@+id/title_bar" |
||||||
|
app:layout_constraintBottom_toBottomOf="parent" /> |
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout> |
@ -0,0 +1,100 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" |
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto" |
||||||
|
xmlns:tools="http://schemas.android.com/tools" |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="match_parent" |
||||||
|
android:orientation="vertical"> |
||||||
|
|
||||||
|
<io.legado.app.ui.widget.TitleBar |
||||||
|
android:id="@+id/tool_bar" |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:theme="?attr/actionBarStyle" |
||||||
|
android:paddingRight="16dp" |
||||||
|
app:attachToActivity="false" |
||||||
|
app:contentLayout="@layout/view_search" |
||||||
|
app:fitStatusBar="false" |
||||||
|
app:popupTheme="@style/AppTheme.PopupOverlay" |
||||||
|
app:titleTextAppearance="@style/ToolbarTitle" |
||||||
|
tools:ignore="RtlHardcoded,RtlSymmetry" /> |
||||||
|
|
||||||
|
<FrameLayout |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="0dp" |
||||||
|
android:layout_weight="1"> |
||||||
|
|
||||||
|
<io.legado.app.ui.widget.recycler.scroller.FastScrollRecyclerView |
||||||
|
android:id="@+id/recycler_view" |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="match_parent" |
||||||
|
android:scrollbars="none" |
||||||
|
tools:ignore="SpeakableTextPresentCheck" /> |
||||||
|
|
||||||
|
<io.legado.app.ui.widget.anima.RotateLoading |
||||||
|
android:id="@+id/rotate_loading" |
||||||
|
android:layout_width="36dp" |
||||||
|
android:layout_height="36dp" |
||||||
|
android:layout_gravity="center" |
||||||
|
android:layout_margin="6dp" |
||||||
|
android:visibility="gone" |
||||||
|
app:loading_width="2dp" /> |
||||||
|
|
||||||
|
<TextView |
||||||
|
android:id="@+id/tv_msg" |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:layout_gravity="center" |
||||||
|
android:padding="16dp" |
||||||
|
android:textColor="@color/secondaryText" |
||||||
|
android:visibility="gone" /> |
||||||
|
|
||||||
|
</FrameLayout> |
||||||
|
|
||||||
|
<com.google.android.flexbox.FlexboxLayout |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:paddingLeft="12dp" |
||||||
|
android:paddingRight="12dp" |
||||||
|
app:flexWrap="wrap" |
||||||
|
app:justifyContent="space_between"> |
||||||
|
|
||||||
|
<io.legado.app.ui.widget.text.AccentTextView |
||||||
|
android:id="@+id/tv_footer_left" |
||||||
|
android:layout_width="wrap_content" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:padding="12dp" |
||||||
|
android:visibility="gone" |
||||||
|
tools:ignore="RtlHardcoded" /> |
||||||
|
|
||||||
|
<Space |
||||||
|
android:layout_width="0dp" |
||||||
|
android:layout_height="0dp" /> |
||||||
|
|
||||||
|
<LinearLayout |
||||||
|
android:layout_width="wrap_content" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:orientation="horizontal"> |
||||||
|
|
||||||
|
<io.legado.app.ui.widget.text.AccentTextView |
||||||
|
android:id="@+id/tv_cancel" |
||||||
|
android:layout_width="wrap_content" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:padding="12dp" |
||||||
|
android:text="@string/cancel" |
||||||
|
android:visibility="gone" |
||||||
|
tools:ignore="RtlHardcoded" /> |
||||||
|
|
||||||
|
<io.legado.app.ui.widget.text.AccentTextView |
||||||
|
android:id="@+id/tv_ok" |
||||||
|
android:layout_width="wrap_content" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:padding="12dp" |
||||||
|
android:text="@string/ok" |
||||||
|
android:visibility="gone" |
||||||
|
tools:ignore="RtlHardcoded" /> |
||||||
|
|
||||||
|
</LinearLayout> |
||||||
|
|
||||||
|
</com.google.android.flexbox.FlexboxLayout> |
||||||
|
</LinearLayout> |
@ -0,0 +1,20 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" |
||||||
|
xmlns:tools="http://schemas.android.com/tools" |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:gravity="center_vertical" |
||||||
|
android:orientation="horizontal" |
||||||
|
android:padding="6dp" |
||||||
|
android:background="?attr/selectableItemBackground" |
||||||
|
tools:ignore="UseCompoundDrawables"> |
||||||
|
|
||||||
|
<TextView |
||||||
|
android:id="@+id/text_view" |
||||||
|
android:layout_width="0dp" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:layout_weight="1" |
||||||
|
android:singleLine="true" |
||||||
|
android:textColor="@color/primaryText" /> |
||||||
|
|
||||||
|
</LinearLayout> |
Loading…
Reference in new issue