mirror of
https://github.com/gedoor/legado.git
synced 2025-08-10 00:52:30 +00:00
rss收藏增加分组管理 (#4236)
* rss收藏增加分组和标题编辑选项 * 优化变量命名 * 订阅收藏按分组展示 * 优化:订阅收藏分组展示 * 优化 * 优化rss收藏分组管理 * 优化数据库版本控制
This commit is contained in:
1912
app/schemas/io.legado.app.data.AppDatabase/72.json
Normal file
1912
app/schemas/io.legado.app.data.AppDatabase/72.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -63,7 +63,7 @@ val appDb by lazy {
|
||||
}
|
||||
|
||||
@Database(
|
||||
version = 71,
|
||||
version = 72,
|
||||
exportSchema = true,
|
||||
entities = [Book::class, BookGroup::class, BookSource::class, BookChapter::class,
|
||||
ReplaceRule::class, SearchBook::class, SearchKeyword::class, Cookie::class,
|
||||
@@ -99,6 +99,7 @@ val appDb by lazy {
|
||||
AutoMigration(from = 68, to = 69),
|
||||
AutoMigration(from = 69, to = 70),
|
||||
AutoMigration(from = 70, to = 71),
|
||||
AutoMigration(from = 71, to = 72),
|
||||
]
|
||||
)
|
||||
abstract class AppDatabase : RoomDatabase() {
|
||||
|
||||
@@ -13,7 +13,7 @@ interface RssArticleDao {
|
||||
|
||||
@Query(
|
||||
"""select t1.link, t1.sort, t1.origin, t1.`order`, t1.title, t1.content,
|
||||
t1.description, t1.image, t1.pubDate, t1.variable, ifNull(t2.read, 0) as read
|
||||
t1.description, t1.image, t1.`group`, t1.pubDate, t1.variable, ifNull(t2.read, 0) as read
|
||||
from rssArticles as t1 left join rssReadRecords as t2
|
||||
on t1.link = t2.record where origin = :origin and sort = :sort
|
||||
order by `order` desc"""
|
||||
|
||||
@@ -10,6 +10,12 @@ interface RssStarDao {
|
||||
@get:Query("select * from rssStars order by starTime desc")
|
||||
val all: List<RssStar>
|
||||
|
||||
@Query("select `group` from rssStars group by `group` order by `group`")
|
||||
fun groupList(): Flow<List<String>>
|
||||
|
||||
@Query("select * from rssStars where `group` = :group order by starTime desc")
|
||||
fun getByGroup(group: String): Flow<List<RssStar>>
|
||||
|
||||
@Query("select * from rssStars where origin = :origin and link = :link")
|
||||
fun get(origin: String, link: String): RssStar?
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package io.legado.app.data.entities
|
||||
|
||||
import androidx.room.ColumnInfo
|
||||
import androidx.room.Entity
|
||||
import androidx.room.Ignore
|
||||
import io.legado.app.utils.GSON
|
||||
import io.legado.app.utils.fromJsonObject
|
||||
import kotlinx.parcelize.IgnoredOnParcel
|
||||
|
||||
|
||||
@Entity(
|
||||
tableName = "rssArticles",
|
||||
primaryKeys = ["origin", "link"]
|
||||
@@ -21,6 +21,8 @@ data class RssArticle(
|
||||
var description: String? = null,
|
||||
var content: String? = null,
|
||||
var image: String? = null,
|
||||
@ColumnInfo(defaultValue = "默认分组")
|
||||
var group: String = "默认分组",
|
||||
var read: Boolean = false,
|
||||
override var variable: String? = null
|
||||
) : BaseRssArticle {
|
||||
@@ -49,6 +51,7 @@ data class RssArticle(
|
||||
description = description,
|
||||
content = content,
|
||||
image = image,
|
||||
group = group,
|
||||
variable = variable
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package io.legado.app.data.entities
|
||||
|
||||
import androidx.room.ColumnInfo
|
||||
import androidx.room.Entity
|
||||
import androidx.room.Ignore
|
||||
import io.legado.app.utils.GSON
|
||||
@@ -21,6 +22,8 @@ data class RssStar(
|
||||
var description: String? = null,
|
||||
var content: String? = null,
|
||||
var image: String? = null,
|
||||
@ColumnInfo(defaultValue = "默认分组")
|
||||
var group: String = "默认分组",
|
||||
override var variable: String? = null
|
||||
) : BaseRssArticle {
|
||||
|
||||
@@ -40,6 +43,7 @@ data class RssStar(
|
||||
description = description,
|
||||
content = content,
|
||||
image = image,
|
||||
group = group,
|
||||
variable = variable
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,62 +1,84 @@
|
||||
@file:Suppress("DEPRECATION")
|
||||
|
||||
package io.legado.app.ui.rss.favorites
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.FragmentStatePagerAdapter
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import io.legado.app.base.BaseActivity
|
||||
import io.legado.app.constant.AppLog
|
||||
import io.legado.app.data.appDb
|
||||
import io.legado.app.data.entities.RssStar
|
||||
import io.legado.app.databinding.ActivityRssFavoritesBinding
|
||||
import io.legado.app.lib.theme.accentColor
|
||||
import io.legado.app.ui.rss.read.ReadRssActivity
|
||||
import io.legado.app.ui.widget.recycler.VerticalDivider
|
||||
import io.legado.app.utils.startActivity
|
||||
import io.legado.app.utils.gone
|
||||
import io.legado.app.utils.viewbindingdelegate.viewBinding
|
||||
import io.legado.app.utils.visible
|
||||
import kotlinx.coroutines.Dispatchers.IO
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.flow.catch
|
||||
import kotlinx.coroutines.flow.conflate
|
||||
import kotlinx.coroutines.flow.flowOn
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
/**
|
||||
* 收藏夹
|
||||
*/
|
||||
class RssFavoritesActivity : BaseActivity<ActivityRssFavoritesBinding>(),
|
||||
RssFavoritesAdapter.CallBack {
|
||||
class RssFavoritesActivity : BaseActivity<ActivityRssFavoritesBinding>(){
|
||||
|
||||
override val binding by viewBinding(ActivityRssFavoritesBinding::inflate)
|
||||
private val adapter by lazy { RssFavoritesAdapter(this, this) }
|
||||
private val adapter by lazy { TabFragmentPageAdapter() }
|
||||
private var groupList = mutableListOf<String>()
|
||||
private var rssStarFlowJob: Job? = null
|
||||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
initView()
|
||||
initData()
|
||||
binding.viewPager.adapter = adapter
|
||||
binding.tabLayout.setupWithViewPager(binding.viewPager)
|
||||
binding.tabLayout.setSelectedTabIndicatorColor(accentColor)
|
||||
upFragments()
|
||||
}
|
||||
|
||||
private fun initView() {
|
||||
binding.refreshLayout.setColorSchemeColors(accentColor)
|
||||
binding.recyclerView.let {
|
||||
it.layoutManager = LinearLayoutManager(this)
|
||||
it.addItemDecoration(VerticalDivider(this))
|
||||
it.adapter = adapter
|
||||
}
|
||||
}
|
||||
|
||||
private fun initData() {
|
||||
lifecycleScope.launch {
|
||||
appDb.rssStarDao.liveAll().catch {
|
||||
AppLog.put("订阅收藏夹界面获取数据失败\n${it.localizedMessage}", it)
|
||||
}.flowOn(IO).conflate().collect {
|
||||
adapter.setItems(it)
|
||||
private fun upFragments() {
|
||||
rssStarFlowJob?.cancel()
|
||||
rssStarFlowJob = lifecycleScope.launch {
|
||||
appDb.rssStarDao.groupList().catch {
|
||||
AppLog.put("订阅分组数据获取失败\n${it.localizedMessage}", it)
|
||||
}.flowOn(IO).collect {
|
||||
groupList.clear()
|
||||
groupList.addAll(it)
|
||||
if (groupList.size == 1) {
|
||||
binding.tabLayout.gone()
|
||||
} else {
|
||||
binding.tabLayout.visible()
|
||||
}
|
||||
adapter.notifyDataSetChanged()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun readRss(rssStar: RssStar) {
|
||||
startActivity<ReadRssActivity> {
|
||||
putExtra("title", rssStar.title)
|
||||
putExtra("origin", rssStar.origin)
|
||||
putExtra("link", rssStar.link)
|
||||
private inner class TabFragmentPageAdapter :
|
||||
FragmentStatePagerAdapter(supportFragmentManager, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {
|
||||
|
||||
override fun getItemPosition(`object`: Any): Int {
|
||||
return POSITION_NONE
|
||||
}
|
||||
|
||||
override fun getPageTitle(position: Int): CharSequence {
|
||||
return groupList[position]
|
||||
}
|
||||
|
||||
override fun getItem(position: Int): Fragment {
|
||||
val group = groupList[position]
|
||||
return RssFavoritesFragment(group)
|
||||
}
|
||||
|
||||
override fun getCount(): Int {
|
||||
return groupList.size
|
||||
}
|
||||
|
||||
override fun instantiateItem(container: ViewGroup, position: Int): Any {
|
||||
val fragment = super.instantiateItem(container, position) as Fragment
|
||||
return fragment
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
package io.legado.app.ui.rss.favorites
|
||||
|
||||
import android.os.Bundle
|
||||
import android.text.TextUtils
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import io.legado.app.R
|
||||
import io.legado.app.base.BaseDialogFragment
|
||||
import io.legado.app.data.entities.RssArticle
|
||||
import io.legado.app.databinding.DialogRssfavoritesBinding
|
||||
import io.legado.app.lib.theme.primaryColor
|
||||
import io.legado.app.utils.setLayout
|
||||
import io.legado.app.utils.viewbindingdelegate.viewBinding
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
class RssFavoritesDialog() : BaseDialogFragment(R.layout.dialog_rssfavorites, true) {
|
||||
|
||||
constructor(rssArticle: RssArticle) : this() {
|
||||
arguments = Bundle().apply {
|
||||
putString("title", rssArticle.title)
|
||||
putString("group", rssArticle.group)
|
||||
}
|
||||
}
|
||||
|
||||
private val binding by viewBinding(DialogRssfavoritesBinding::bind)
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)
|
||||
}
|
||||
|
||||
override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) {
|
||||
binding.toolBar.setBackgroundColor(primaryColor)
|
||||
val arguments = arguments ?: let {
|
||||
dismiss()
|
||||
return
|
||||
}
|
||||
|
||||
var title = arguments.getString("title") ?: "默认名称"
|
||||
var group = arguments.getString("group") ?: "默认分组"
|
||||
binding.run {
|
||||
editTitle.setText(title)
|
||||
editGroup.setText(group)
|
||||
tvCancel.setOnClickListener {
|
||||
dismiss()
|
||||
}
|
||||
tvOk.setOnClickListener {
|
||||
val editTitle = editTitle.text.toString()
|
||||
if(!TextUtils.isEmpty(editTitle)){
|
||||
title = editTitle
|
||||
}
|
||||
val editGroup = editGroup.text.toString()
|
||||
if(!TextUtils.isEmpty(editGroup)){
|
||||
group = editGroup
|
||||
}
|
||||
lifecycleScope.launch {
|
||||
callback?.updateFavorite(title, group)
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
tvFooterLeft.setOnClickListener {
|
||||
lifecycleScope.launch {
|
||||
callback?.deleteFavorite()
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val callback get() = (parentFragment as? Callback) ?: (activity as? Callback)
|
||||
|
||||
interface Callback {
|
||||
|
||||
fun updateFavorite(title: String, group: String)
|
||||
|
||||
fun deleteFavorite()
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
package io.legado.app.ui.rss.favorites
|
||||
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import androidx.fragment.app.viewModels
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import io.legado.app.R
|
||||
import io.legado.app.base.VMBaseFragment
|
||||
import io.legado.app.constant.AppLog
|
||||
import io.legado.app.data.appDb
|
||||
import io.legado.app.data.entities.RssStar
|
||||
import io.legado.app.databinding.FragmentRssArticlesBinding
|
||||
import io.legado.app.lib.theme.primaryColor
|
||||
import io.legado.app.ui.rss.read.ReadRssActivity
|
||||
import io.legado.app.ui.widget.recycler.VerticalDivider
|
||||
import io.legado.app.utils.setEdgeEffectColor
|
||||
import io.legado.app.utils.startActivity
|
||||
import io.legado.app.utils.viewbindingdelegate.viewBinding
|
||||
import kotlinx.coroutines.Dispatchers.IO
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.flow.catch
|
||||
import kotlinx.coroutines.flow.flowOn
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
class RssFavoritesFragment() : VMBaseFragment<RssFavoritesViewModel>(R.layout.fragment_rss_articles),
|
||||
RssFavoritesAdapter.CallBack {
|
||||
|
||||
constructor(group: String) : this() {
|
||||
arguments = Bundle().apply {
|
||||
putString("group", group)
|
||||
}
|
||||
}
|
||||
|
||||
private val binding by viewBinding(FragmentRssArticlesBinding::bind)
|
||||
override val viewModel by viewModels<RssFavoritesViewModel>()
|
||||
private val adapter: RssFavoritesAdapter by lazy {
|
||||
RssFavoritesAdapter(requireContext(), this@RssFavoritesFragment)
|
||||
}
|
||||
private var articlesFlowJob: Job? = null
|
||||
|
||||
override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) {
|
||||
initView()
|
||||
}
|
||||
|
||||
private fun initView() = binding.run {
|
||||
refreshLayout.setEnabled(false)
|
||||
recyclerView.setEdgeEffectColor(primaryColor)
|
||||
recyclerView.layoutManager = run {
|
||||
recyclerView.addItemDecoration(VerticalDivider(requireContext()))
|
||||
LinearLayoutManager(requireContext())
|
||||
}
|
||||
recyclerView.adapter = adapter
|
||||
loadArticles()
|
||||
}
|
||||
|
||||
private fun loadArticles() {
|
||||
articlesFlowJob?.cancel()
|
||||
articlesFlowJob = lifecycleScope.launch {
|
||||
val group = arguments?.getString("group") ?: "默认分组"
|
||||
appDb.rssStarDao.getByGroup(group).catch {
|
||||
AppLog.put("订阅文章界面获取数据失败\n${it.localizedMessage}", it)
|
||||
}.flowOn(IO).collect {
|
||||
adapter.setItems(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun readRss(rssStar: RssStar) {
|
||||
startActivity<ReadRssActivity> {
|
||||
putExtra("title", rssStar.title)
|
||||
putExtra("origin", rssStar.origin)
|
||||
putExtra("link", rssStar.link)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package io.legado.app.ui.rss.favorites
|
||||
|
||||
import android.app.Application
|
||||
import io.legado.app.base.BaseViewModel
|
||||
|
||||
|
||||
class RssFavoritesViewModel(application: Application) : BaseViewModel(application) {
|
||||
|
||||
}
|
||||
@@ -42,6 +42,7 @@ import io.legado.app.model.Download
|
||||
import io.legado.app.ui.association.OnLineImportActivity
|
||||
import io.legado.app.ui.file.HandleFileContract
|
||||
import io.legado.app.ui.login.SourceLoginActivity
|
||||
import io.legado.app.ui.rss.favorites.RssFavoritesDialog
|
||||
import io.legado.app.utils.ACache
|
||||
import io.legado.app.utils.NetworkUtils
|
||||
import io.legado.app.utils.get
|
||||
@@ -53,6 +54,7 @@ import io.legado.app.utils.openUrl
|
||||
import io.legado.app.utils.setDarkeningAllowed
|
||||
import io.legado.app.utils.setTintMutate
|
||||
import io.legado.app.utils.share
|
||||
import io.legado.app.utils.showDialogFragment
|
||||
import io.legado.app.utils.splitNotBlank
|
||||
import io.legado.app.utils.startActivity
|
||||
import io.legado.app.utils.textArray
|
||||
@@ -70,7 +72,7 @@ import java.util.regex.PatternSyntaxException
|
||||
/**
|
||||
* rss阅读界面
|
||||
*/
|
||||
class ReadRssActivity : VMBaseActivity<ActivityRssReadBinding, ReadRssViewModel>() {
|
||||
class ReadRssActivity : VMBaseActivity<ActivityRssReadBinding, ReadRssViewModel>(), RssFavoritesDialog.Callback {
|
||||
|
||||
override val binding by viewBinding(ActivityRssReadBinding::inflate)
|
||||
override val viewModel by viewModels<ReadRssViewModel>()
|
||||
@@ -151,8 +153,12 @@ class ReadRssActivity : VMBaseActivity<ActivityRssReadBinding, ReadRssViewModel>
|
||||
R.id.menu_rss_refresh -> viewModel.refresh {
|
||||
binding.webView.reload()
|
||||
}
|
||||
|
||||
R.id.menu_rss_star -> viewModel.favorite()
|
||||
R.id.menu_rss_star -> {
|
||||
viewModel.addFavorite()
|
||||
viewModel.rssArticle?.let {
|
||||
showDialogFragment(RssFavoritesDialog(it))
|
||||
}
|
||||
}
|
||||
R.id.menu_share_it -> {
|
||||
binding.webView.url?.let {
|
||||
share(it)
|
||||
@@ -174,6 +180,16 @@ class ReadRssActivity : VMBaseActivity<ActivityRssReadBinding, ReadRssViewModel>
|
||||
return super.onCompatOptionsItemSelected(item)
|
||||
}
|
||||
|
||||
override fun updateFavorite(title: String, group: String) {
|
||||
viewModel.rssArticle?.title = title
|
||||
viewModel.rssArticle?.group = group
|
||||
viewModel.updateFavorite()
|
||||
}
|
||||
|
||||
override fun deleteFavorite() {
|
||||
viewModel.delFavorite()
|
||||
}
|
||||
|
||||
@JavascriptInterface
|
||||
fun isNightTheme(): Boolean {
|
||||
return AppConfig.isNightTheme
|
||||
@@ -188,7 +204,7 @@ class ReadRssActivity : VMBaseActivity<ActivityRssReadBinding, ReadRssViewModel>
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("SetJavaScriptEnabled")
|
||||
@SuppressLint("SetJavaScriptEnabled", "JavascriptInterface")
|
||||
private fun initWebView() {
|
||||
binding.progressBar.fontColor = accentColor
|
||||
binding.webView.webChromeClient = CustomWebChromeClient()
|
||||
|
||||
@@ -135,6 +135,39 @@ class ReadRssViewModel(application: Application) : BaseViewModel(application), J
|
||||
}
|
||||
}
|
||||
|
||||
fun addFavorite() {
|
||||
execute {
|
||||
rssStar ?: rssArticle?.toStar()?.let {
|
||||
appDb.rssStarDao.insert(it)
|
||||
rssStar = it
|
||||
}
|
||||
}.onSuccess {
|
||||
upStarMenuData.postValue(true)
|
||||
}
|
||||
}
|
||||
|
||||
fun updateFavorite() {
|
||||
execute {
|
||||
rssArticle?.toStar()?.let {
|
||||
appDb.rssStarDao.update(it)
|
||||
rssStar = it
|
||||
}
|
||||
}.onSuccess {
|
||||
upStarMenuData.postValue(true)
|
||||
}
|
||||
}
|
||||
|
||||
fun delFavorite() {
|
||||
execute {
|
||||
rssStar?.let {
|
||||
appDb.rssStarDao.delete(it.origin, it.link)
|
||||
rssStar = null
|
||||
}
|
||||
}.onSuccess {
|
||||
upStarMenuData.postValue(true)
|
||||
}
|
||||
}
|
||||
|
||||
fun saveImage(webPic: String?, uri: Uri) {
|
||||
webPic ?: return
|
||||
execute {
|
||||
|
||||
@@ -1,30 +1,27 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
<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="match_parent"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:orientation="vertical">
|
||||
|
||||
<io.legado.app.ui.widget.TitleBar
|
||||
android:id="@+id/title_bar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:title="@string/favorites"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
app:title="@string/favorites" />
|
||||
|
||||
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||
android:id="@+id/refresh_layout"
|
||||
<com.google.android.material.tabs.TabLayout
|
||||
android:id="@+id/tab_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/title_bar"
|
||||
app:layout_constraintVertical_bias="0.0">
|
||||
android:layout_height="wrap_content"
|
||||
app:tabMode="scrollable" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/recycler_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
<androidx.viewpager.widget.ViewPager
|
||||
android:id="@+id/view_pager"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
tools:ignore="SpeakableTextPresentCheck" />
|
||||
|
||||
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</LinearLayout>
|
||||
112
app/src/main/res/layout/dialog_rssfavorites.xml
Normal file
112
app/src/main/res/layout/dialog_rssfavorites.xml
Normal file
@@ -0,0 +1,112 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout 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:padding="16dp">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/vw_bg"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:background="@drawable/shape_card_view"
|
||||
android:orientation="vertical"
|
||||
tools:ignore="UselessParent">
|
||||
|
||||
<androidx.appcompat.widget.Toolbar
|
||||
android:id="@+id/tool_bar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:theme="?attr/actionBarStyle"
|
||||
app:popupTheme="@style/AppTheme.PopupOverlay"
|
||||
app:title="@string/favorite"
|
||||
app:titleTextAppearance="@style/ToolbarTitle" />
|
||||
|
||||
<androidx.core.widget.NestedScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1"
|
||||
android:overScrollMode="ifContentScrolls">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:padding="16dp">
|
||||
|
||||
<io.legado.app.ui.widget.text.TextInputLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="3dp">
|
||||
|
||||
<io.legado.app.lib.theme.view.ThemeEditText
|
||||
android:id="@+id/edit_title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="@string/title"
|
||||
tools:ignore="SpeakableTextPresentCheck,TouchTargetSizeCheck" />
|
||||
|
||||
</io.legado.app.ui.widget.text.TextInputLayout>
|
||||
|
||||
<io.legado.app.ui.widget.text.TextInputLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="3dp">
|
||||
|
||||
<io.legado.app.lib.theme.view.ThemeEditText
|
||||
android:id="@+id/edit_group"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="@string/group_name"
|
||||
tools:ignore="SpeakableTextPresentCheck,TouchTargetSizeCheck" />
|
||||
|
||||
</io.legado.app.ui.widget.text.TextInputLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
|
||||
<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:text="@string/delete"
|
||||
tools:ignore="RtlHardcoded" />
|
||||
|
||||
<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"
|
||||
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"
|
||||
tools:ignore="RtlHardcoded" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</com.google.android.flexbox.FlexboxLayout>
|
||||
</LinearLayout>
|
||||
</FrameLayout>
|
||||
Reference in New Issue
Block a user