RSS快速添加对话框

pull/36/head
mabdc 6 years ago
commit 066460ac15
  1. 4
      app/src/main/java/io/legado/app/ui/book/source/debug/SourceDebugActivity.kt
  2. 146
      app/src/main/java/io/legado/app/ui/book/source/edit/SourceEditActivity.kt
  3. 26
      app/src/main/java/io/legado/app/ui/main/rss/RssFragment.kt
  4. 64
      app/src/main/java/io/legado/app/ui/rss/article/RssArticlesActivity.kt
  5. 4
      app/src/main/java/io/legado/app/ui/rss/read/ReadRssActivity.kt
  6. 14
      app/src/main/java/io/legado/app/ui/rss/source/debug/RssSourceDebugActivity.kt
  7. 62
      app/src/main/java/io/legado/app/ui/rss/source/edit/RssSourceEditActivity.kt
  8. 24
      app/src/main/java/io/legado/app/ui/rss/source/edit/RssSourceEditViewModel.kt
  9. 2
      app/src/main/res/layout/activity_rss_source_edit.xml
  10. 0
      app/src/main/res/layout/activity_source_debug.xml
  11. 10
      app/src/main/res/layout/item_rss.xml

@ -12,13 +12,13 @@ import io.legado.app.lib.theme.ATH
import io.legado.app.lib.theme.accentColor import io.legado.app.lib.theme.accentColor
import io.legado.app.ui.qrcode.QrCodeActivity import io.legado.app.ui.qrcode.QrCodeActivity
import io.legado.app.utils.getViewModel import io.legado.app.utils.getViewModel
import kotlinx.android.synthetic.main.activity_book_source_debug.* import kotlinx.android.synthetic.main.activity_source_debug.*
import kotlinx.android.synthetic.main.view_search.* import kotlinx.android.synthetic.main.view_search.*
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import org.jetbrains.anko.startActivityForResult import org.jetbrains.anko.startActivityForResult
import org.jetbrains.anko.toast import org.jetbrains.anko.toast
class SourceDebugActivity : VMBaseActivity<SourceDebugModel>(R.layout.activity_book_source_debug) { class SourceDebugActivity : VMBaseActivity<SourceDebugModel>(R.layout.activity_source_debug) {
override val viewModel: SourceDebugModel override val viewModel: SourceDebugModel
get() = getViewModel(SourceDebugModel::class.java) get() = getViewModel(SourceDebugModel::class.java)

@ -79,20 +79,14 @@ class SourceEditActivity :
override fun onCompatOptionsItemSelected(item: MenuItem): Boolean { override fun onCompatOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) { when (item.itemId) {
R.id.menu_save -> { R.id.menu_save -> {
val bookSource = getSource() getSource()?.let {
if (bookSource == null) { viewModel.save(it) { setResult(Activity.RESULT_OK); finish() }
toast("书源名称和URL不能为空")
} else {
viewModel.save(bookSource) { setResult(Activity.RESULT_OK); finish() }
} }
} }
R.id.menu_debug_source -> { R.id.menu_debug_source -> {
val bookSource = getSource() getSource()?.let {
if (bookSource == null) { viewModel.save(it) {
toast("书源名称和URL不能为空") startActivity<SourceDebugActivity>(Pair("key", it.bookSourceUrl))
} else {
viewModel.save(bookSource) {
startActivity<SourceDebugActivity>(Pair("key", bookSource.bookSourceUrl))
} }
} }
} }
@ -147,7 +141,7 @@ class SourceEditActivity :
} }
//基本信息 //基本信息
sourceEntities.clear() sourceEntities.clear()
searchEntities.apply { sourceEntities.apply {
add(EditEntity("bookSourceUrl", bookSource?.bookSourceUrl, R.string.book_source_url)) add(EditEntity("bookSourceUrl", bookSource?.bookSourceUrl, R.string.book_source_url))
add(EditEntity("bookSourceName", bookSource?.bookSourceName, R.string.book_source_name)) add(EditEntity("bookSourceName", bookSource?.bookSourceName, R.string.book_source_name))
add( add(
@ -249,84 +243,76 @@ class SourceEditActivity :
val bookInfoRule = BookInfoRule() val bookInfoRule = BookInfoRule()
val tocRule = TocRule() val tocRule = TocRule()
val contentRule = ContentRule() val contentRule = ContentRule()
for (entity in sourceEntities) { sourceEntities.forEach {
with(entity) { when (it.key) {
when (key) { "bookSourceUrl" -> source.bookSourceUrl = it.value ?: ""
"bookSourceUrl" -> value?.let { source.bookSourceUrl = it } ?: return null "bookSourceName" -> source.bookSourceName = it.value ?: ""
"bookSourceName" -> value?.let { source.bookSourceName = it } ?: return null "bookSourceGroup" -> source.bookSourceGroup = it.value
"bookSourceGroup" -> source.bookSourceGroup = value "loginUrl" -> source.loginUrl = it.value
"loginUrl" -> source.loginUrl = value "bookUrlPattern" -> source.bookUrlPattern = it.value
"bookUrlPattern" -> source.bookUrlPattern = value "header" -> source.header = it.value
"header" -> source.header = value
}
} }
} }
for (entity in searchEntities) { if (source.bookSourceUrl.isBlank() || source.bookSourceName.isBlank()) {
with(entity) { toast("书源名称和URL不能为空")
when (key) { return null
"searchUrl" -> source.searchUrl = value }
"bookList" -> searchRule.bookList = value searchEntities.forEach {
"name" -> searchRule.name = value when (it.key) {
"author" -> searchRule.author = value "searchUrl" -> source.searchUrl = it.value
"kind" -> searchRule.kind = value "bookList" -> searchRule.bookList = it.value
"intro" -> searchRule.intro = value "name" -> searchRule.name = it.value
"updateTime" -> searchRule.updateTime = value "author" -> searchRule.author = it.value
"wordCount" -> searchRule.wordCount = value "kind" -> searchRule.kind = it.value
"lastChapter" -> searchRule.lastChapter = value "intro" -> searchRule.intro = it.value
"coverUrl" -> searchRule.coverUrl = value "updateTime" -> searchRule.updateTime = it.value
"bookUrl" -> searchRule.bookUrl = value "wordCount" -> searchRule.wordCount = it.value
} "lastChapter" -> searchRule.lastChapter = it.value
"coverUrl" -> searchRule.coverUrl = it.value
"bookUrl" -> searchRule.bookUrl = it.value
} }
} }
for (entity in findEntities) { findEntities.forEach {
with(entity) { when (it.key) {
when (key) { "exploreUrl" -> source.exploreUrl = it.value
"exploreUrl" -> source.exploreUrl = value "bookList" -> exploreRule.bookList = it.value
"bookList" -> exploreRule.bookList = value "name" -> exploreRule.name = it.value
"name" -> exploreRule.name = value "author" -> exploreRule.author = it.value
"author" -> exploreRule.author = value "kind" -> exploreRule.kind = it.value
"kind" -> exploreRule.kind = value "intro" -> exploreRule.intro = it.value
"intro" -> exploreRule.intro = value "updateTime" -> exploreRule.updateTime = it.value
"updateTime" -> exploreRule.updateTime = value "wordCount" -> exploreRule.wordCount = it.value
"wordCount" -> exploreRule.wordCount = value "lastChapter" -> exploreRule.lastChapter = it.value
"lastChapter" -> exploreRule.lastChapter = value "coverUrl" -> exploreRule.coverUrl = it.value
"coverUrl" -> exploreRule.coverUrl = value "bookUrl" -> exploreRule.bookUrl = it.value
"bookUrl" -> exploreRule.bookUrl = value
}
} }
} }
for (entity in infoEntities) { infoEntities.forEach {
with(entity) { when (it.key) {
when (key) { "init" -> bookInfoRule.init = it.value
"init" -> bookInfoRule.init = value "name" -> bookInfoRule.name = it.value
"name" -> bookInfoRule.name = value "author" -> bookInfoRule.author = it.value
"author" -> bookInfoRule.author = value "kind" -> bookInfoRule.kind = it.value
"kind" -> bookInfoRule.kind = value "intro" -> bookInfoRule.intro = it.value
"intro" -> bookInfoRule.intro = value "updateTime" -> bookInfoRule.updateTime = it.value
"updateTime" -> bookInfoRule.updateTime = value "wordCount" -> bookInfoRule.wordCount = it.value
"wordCount" -> bookInfoRule.wordCount = value "lastChapter" -> bookInfoRule.lastChapter = it.value
"lastChapter" -> bookInfoRule.lastChapter = value "coverUrl" -> bookInfoRule.coverUrl = it.value
"coverUrl" -> bookInfoRule.coverUrl = value "tocUrl" -> bookInfoRule.tocUrl = it.value
"tocUrl" -> bookInfoRule.tocUrl = value
}
} }
} }
for (entity in tocEntities) { tocEntities.forEach {
with(entity) { when (it.key) {
when (key) { "chapterList" -> tocRule.chapterList = it.value
"chapterList" -> tocRule.chapterList = value "chapterName" -> tocRule.chapterName = it.value
"chapterName" -> tocRule.chapterName = value "chapterUrl" -> tocRule.chapterUrl = it.value
"chapterUrl" -> tocRule.chapterUrl = value "nextTocUrl" -> tocRule.nextTocUrl = it.value
"nextTocUrl" -> tocRule.nextTocUrl = value
}
} }
} }
for (entity in contentEntities) { contentEntities.forEach {
with(entity) { when (it.key) {
when (key) { "content" -> contentRule.content = it.value
"content" -> contentRule.content = value "nextContentUrl" -> contentRule.nextContentUrl = it.value
"nextContentUrl" -> contentRule.nextContentUrl = value
}
} }
} }
source.ruleSearch = GSON.toJson(searchRule) source.ruleSearch = GSON.toJson(searchRule)

@ -1,20 +1,28 @@
package io.legado.app.ui.main.rss package io.legado.app.ui.main.rss
import android.os.Bundle import android.os.Bundle
import android.util.Log
import android.view.Gravity
import android.view.Menu import android.view.Menu
import android.view.MenuItem import android.view.MenuItem
import android.view.View import android.view.View
import android.widget.EditText
import android.widget.LinearLayout
import androidx.lifecycle.Observer import androidx.lifecycle.Observer
import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.GridLayoutManager
import io.legado.app.App import io.legado.app.App
import io.legado.app.R import io.legado.app.R
import io.legado.app.base.BaseFragment import io.legado.app.base.BaseFragment
import io.legado.app.lib.dialogs.alert
import io.legado.app.lib.dialogs.cancelButton
import io.legado.app.lib.dialogs.yesButton
import io.legado.app.lib.theme.ATH import io.legado.app.lib.theme.ATH
import io.legado.app.ui.rss.article.RssArticlesActivity import io.legado.app.ui.rss.article.RssArticlesActivity
import io.legado.app.ui.rss.source.manage.RssSourceActivity import io.legado.app.ui.rss.source.manage.RssSourceActivity
import io.legado.app.utils.startActivity import io.legado.app.utils.startActivity
import kotlinx.android.synthetic.main.fragment_rss.* import kotlinx.android.synthetic.main.fragment_rss.*
import kotlinx.android.synthetic.main.view_title_bar.* import kotlinx.android.synthetic.main.view_title_bar.*
import org.jetbrains.anko.padding
class RssFragment : BaseFragment(R.layout.fragment_rss), class RssFragment : BaseFragment(R.layout.fragment_rss),
RssAdapter.CallBack { RssAdapter.CallBack {
@ -36,7 +44,23 @@ class RssFragment : BaseFragment(R.layout.fragment_rss),
when (item.itemId) { when (item.itemId) {
R.id.menu_rss_config -> startActivity<RssSourceActivity>() R.id.menu_rss_config -> startActivity<RssSourceActivity>()
R.id.menu_rss_add -> { R.id.menu_rss_add -> {
startActivity<RssArticlesActivity>() alert {
title = "快速添加并预览"
val layout = LinearLayout(activity)
val urlEdit = EditText(activity)
urlEdit.hint = "输入RSS地址"
urlEdit.width = 800
layout.gravity = Gravity.CENTER
layout.addView(urlEdit)
customView = layout
cancelButton{
Log.i("RSS","Quick Add URL cancel")
}
yesButton{
Log.i("RSS","Quick Add URL: ${urlEdit.text}")
startActivity<RssArticlesActivity>("QuickAddURL" to urlEdit.text.toString().trim())
}
}.show()
} }
} }
} }

@ -1,5 +1,6 @@
package io.legado.app.ui.rss.article package io.legado.app.ui.rss.article
import android.app.ProgressDialog
import android.content.Context import android.content.Context
import android.os.Bundle import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
@ -13,68 +14,47 @@ import io.legado.app.model.rss.RssParser
import io.legado.app.ui.rss.read.ReadRssActivity import io.legado.app.ui.rss.read.ReadRssActivity
import kotlinx.android.synthetic.main.item_rss.view.* import kotlinx.android.synthetic.main.item_rss.view.*
import org.jetbrains.anko.* import org.jetbrains.anko.*
import org.jetbrains.anko.sdk27.listeners.onClick
import org.jetbrains.anko.sdk27.listeners.onItemClick import org.jetbrains.anko.sdk27.listeners.onItemClick
import java.net.URL import java.net.URL
class RssArticlesActivity : AppCompatActivity() { class RssArticlesActivity : AppCompatActivity() {
val zhihu_dayli = "https://rsshub.app/zhihu/daily"
val nytimes = "https://rsshub.app/nytimes/dual"
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
var articles = mutableListOf<RssArticle>() if (intent.hasExtra("QuickAddURL")) {
val adapter = ArticleAdapter(articles, this) // 处理从 快速添加并预览 跳转到这个页面
verticalLayout { val urlString = intent.getStringExtra("QuickAddURL")
val url = editText { val adapter = ArticleAdapter(mutableListOf<RssArticle>(), this)
hint = "请输入RSS地址"
}
fun loadRss(urlString:String){
Thread {
val xml = URL(urlString).readText()
articles = RssParser.parseXML(xml)
runOnUiThread {
adapter.articles = articles
adapter.notifyDataSetChanged()
}
}.start()
}
button("解析") {
onClick {
val urlString = url.text.toString().trim()
if(urlString != ""){
loadRss(urlString)
}
}
}
button("知乎日报") {
onClick {
loadRss(zhihu_dayli)
}
}
button("纽约时报") {
onClick {
loadRss(nytimes)
}
}
listView { listView {
this.adapter = adapter this.adapter = adapter
onItemClick { p0, p1, p2, p3 -> onItemClick { p0, p1, p2, p3 ->
startActivity<ReadRssActivity>("description" to articles[p2].description) startActivity<ReadRssActivity>("description" to adapter.articles[p2].description)
} }
} }
val loading = ProgressDialog(this@RssArticlesActivity)
loading.setMessage("加载中...")
loading.show()
Thread {
val xml = URL(urlString).readText()
val articles = RssParser.parseXML(xml)
runOnUiThread {
adapter.articles = articles
adapter.notifyDataSetChanged()
loading.dismiss()
}
}.start()
} }
} }
} }
class ArticleAdapter(var articles: List<RssArticle>, var context: Context) : BaseAdapter() { class ArticleAdapter(var articles: MutableList<RssArticle>, var context: Context) : BaseAdapter() {
override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View { override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View {
val item_rss= LayoutInflater.from(context).inflate(R.layout.item_rss, null) val item_rss = LayoutInflater.from(context).inflate(R.layout.item_rss, null)
val article = articles[position] val article = articles[position]
item_rss.title.text = article.title item_rss.title.text = article.title
item_rss.pub_date.text = article.pubDate item_rss.pub_date.text = article.pubDate
if(article.author != null && article.author != ""){ if (article.author != null && article.author != "") {
item_rss.author.text = article.author item_rss.author.text = article.author
} else{ } else {
item_rss.author.text = article.link item_rss.author.text = article.link
} }
return item_rss return item_rss

@ -9,7 +9,7 @@ class ReadRssActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
setContentView(R.layout.activity_read_rss) setContentView(R.layout.activity_read_rss)
val s = intent.getStringExtra("description") val description = intent.getStringExtra("description")
webView.loadData("<style>img{max-width:100%}</style>"+s,"text/html","utf-8") webView.loadData("<style>img{max-width:100%}</style>$description","text/html", "utf-8")
} }
} }

@ -1,2 +1,16 @@
package io.legado.app.ui.rss.source.debug package io.legado.app.ui.rss.source.debug
import android.os.Bundle
import io.legado.app.R
import io.legado.app.base.BaseActivity
class RssSourceDebugActivity : BaseActivity(R.layout.activity_source_debug, false) {
override fun onActivityCreated(savedInstanceState: Bundle?) {
}
}

@ -1,9 +1,14 @@
package io.legado.app.ui.rss.source.edit package io.legado.app.ui.rss.source.edit
import android.app.Activity
import android.content.ClipData
import android.content.ClipboardManager
import android.content.Context
import android.graphics.Rect import android.graphics.Rect
import android.os.Bundle import android.os.Bundle
import android.view.Gravity import android.view.Gravity
import android.view.Menu import android.view.Menu
import android.view.MenuItem
import android.view.ViewTreeObserver import android.view.ViewTreeObserver
import android.widget.EditText import android.widget.EditText
import android.widget.PopupWindow import android.widget.PopupWindow
@ -15,10 +20,13 @@ import io.legado.app.constant.AppConst
import io.legado.app.data.entities.EditEntity import io.legado.app.data.entities.EditEntity
import io.legado.app.data.entities.RssSource import io.legado.app.data.entities.RssSource
import io.legado.app.lib.theme.ATH import io.legado.app.lib.theme.ATH
import io.legado.app.ui.rss.source.debug.RssSourceDebugActivity
import io.legado.app.ui.widget.KeyboardToolPop import io.legado.app.ui.widget.KeyboardToolPop
import io.legado.app.utils.GSON
import io.legado.app.utils.getViewModel import io.legado.app.utils.getViewModel
import kotlinx.android.synthetic.main.activity_book_source_edit.* import kotlinx.android.synthetic.main.activity_book_source_edit.*
import org.jetbrains.anko.displayMetrics import org.jetbrains.anko.displayMetrics
import org.jetbrains.anko.startActivity
import kotlin.math.abs import kotlin.math.abs
class RssSourceEditActivity : class RssSourceEditActivity :
@ -28,7 +36,7 @@ class RssSourceEditActivity :
private var mSoftKeyboardTool: PopupWindow? = null private var mSoftKeyboardTool: PopupWindow? = null
private var mIsSoftKeyBoardShowing = false private var mIsSoftKeyBoardShowing = false
private lateinit var adapter: RssSourceEditAdapter private val adapter = RssSourceEditAdapter()
private val sourceEntities: ArrayList<EditEntity> = ArrayList() private val sourceEntities: ArrayList<EditEntity> = ArrayList()
override val viewModel: RssSourceEditViewModel override val viewModel: RssSourceEditViewModel
@ -62,6 +70,34 @@ class RssSourceEditActivity :
return super.onCompatCreateOptionsMenu(menu) return super.onCompatCreateOptionsMenu(menu)
} }
override fun onCompatOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
R.id.menu_save -> {
getRssSource()?.let {
viewModel.save(it) {
setResult(Activity.RESULT_OK)
finish()
}
}
}
R.id.menu_debug_source -> {
getRssSource()?.let {
viewModel.save(it) {
startActivity<RssSourceDebugActivity>(Pair("key", it.sourceUrl))
}
}
}
R.id.menu_copy_source -> {
GSON.toJson(getRssSource())?.let { sourceStr ->
val clipboard = getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager?
clipboard?.primaryClip = ClipData.newPlainText(null, sourceStr)
}
}
R.id.menu_paste_source -> viewModel.pasteSource()
}
return super.onCompatOptionsItemSelected(item)
}
private fun initView() { private fun initView() {
ATH.applyEdgeEffectColor(recycler_view) ATH.applyEdgeEffectColor(recycler_view)
mSoftKeyboardTool = KeyboardToolPop(this, AppConst.keyboardToolChars, this) mSoftKeyboardTool = KeyboardToolPop(this, AppConst.keyboardToolChars, this)
@ -98,7 +134,31 @@ class RssSourceEditActivity :
add(EditEntity("ruleContent", rssSource?.ruleContent, R.string.rss_rule_content)) add(EditEntity("ruleContent", rssSource?.ruleContent, R.string.rss_rule_content))
add(EditEntity("ruleLink", rssSource?.ruleLink, R.string.rss_rule_link)) add(EditEntity("ruleLink", rssSource?.ruleLink, R.string.rss_rule_link))
} }
adapter.editEntities = sourceEntities
}
private fun getRssSource(): RssSource? {
val source = viewModel.sourceLiveData.value ?: RssSource()
sourceEntities.forEach {
when (it.key) {
"sourceName" -> source.sourceName = it.value ?: ""
"sourceUrl" -> source.sourceName = it.value ?: ""
"iconUrl" -> source.sourceName = it.value ?: ""
"ruleTitle" -> source.sourceName = it.value ?: ""
"ruleAuthor" -> source.sourceName = it.value ?: ""
"ruleGuid" -> source.sourceName = it.value ?: ""
"rulePubDate" -> source.sourceName = it.value ?: ""
"ruleCategories" -> source.sourceName = it.value ?: ""
"ruleDescription" -> source.sourceName = it.value ?: ""
"ruleImage" -> source.sourceName = it.value ?: ""
"ruleContent" -> source.sourceName = it.value ?: ""
"ruleLink" -> source.sourceName = it.value ?: ""
}
}
if (source.sourceName.isBlank() || source.sourceName.isBlank()) {
return null
}
return source
} }
override fun sendText(text: String) { override fun sendText(text: String) {

@ -1,10 +1,14 @@
package io.legado.app.ui.rss.source.edit package io.legado.app.ui.rss.source.edit
import android.app.Application import android.app.Application
import android.content.ClipboardManager
import android.content.Context
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import io.legado.app.App import io.legado.app.App
import io.legado.app.base.BaseViewModel import io.legado.app.base.BaseViewModel
import io.legado.app.data.entities.RssSource import io.legado.app.data.entities.RssSource
import io.legado.app.utils.GSON
import io.legado.app.utils.fromJsonObject
class RssSourceEditViewModel(application: Application) : BaseViewModel(application) { class RssSourceEditViewModel(application: Application) : BaseViewModel(application) {
@ -18,5 +22,25 @@ class RssSourceEditViewModel(application: Application) : BaseViewModel(applicati
} }
} }
fun save(rssSource: RssSource, success: (() -> Unit)) {
execute {
App.db.rssSourceDao().insert(rssSource)
}.onSuccess {
success()
}
}
fun pasteSource() {
execute {
val clipboard = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager?
clipboard?.primaryClip?.let {
if (it.itemCount > 0) {
val json = it.getItemAt(0).text.toString()
GSON.fromJsonObject<RssSource>(json)?.let { source ->
sourceLiveData.postValue(source)
} ?: toast("格式不对")
}
}
}
}
} }

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/ll_content"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:orientation="vertical"> android:orientation="vertical">
@ -11,6 +12,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:contentInsetStartWithNavigation="0dp" app:contentInsetStartWithNavigation="0dp"
app:displayHomeAsUp="true" app:displayHomeAsUp="true"
app:fitStatusBar="false"
app:title="@string/rss_source_edit" /> app:title="@string/rss_source_edit" />
<androidx.recyclerview.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView

@ -1,8 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android" <androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
android:padding="12dp" android:padding="16dp"
android:layout_margin="20dp"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:cardCornerRadius="2dp" app:cardCornerRadius="2dp"
@ -17,6 +16,7 @@
android:id="@+id/title" android:id="@+id/title"
android:textSize="18sp" android:textSize="18sp"
android:text="Title" android:text="Title"
android:layout_gravity="center"
android:textStyle="bold" android:textStyle="bold"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"/> android:layout_height="wrap_content"/>
@ -24,7 +24,10 @@
<TextView <TextView
android:id="@+id/pub_date" android:id="@+id/pub_date"
android:textSize="12sp" android:textSize="12sp"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:text="2019-10-01 13:48:00" android:text="2019-10-01 13:48:00"
android:layout_gravity="center"
android:textStyle="italic" android:textStyle="italic"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"/> android:layout_height="wrap_content"/>
@ -32,7 +35,8 @@
<TextView <TextView
android:id="@+id/author" android:id="@+id/author"
android:textSize="16sp" android:textSize="16sp"
android:text="Content" android:text="author"
android:layout_gravity="center"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"/> android:layout_height="wrap_content"/>

Loading…
Cancel
Save