feat: 优化代码

pull/182/head
kunfei 5 years ago
parent 06fcfc94b6
commit 1cd3bc1f69
  1. 2
      app/src/main/AndroidManifest.xml
  2. 2
      app/src/main/java/io/legado/app/data/AppDatabase.kt
  3. 2
      app/src/main/java/io/legado/app/data/entities/RssArticle.kt
  4. 2
      app/src/main/java/io/legado/app/data/entities/RssSource.kt
  5. 2
      app/src/main/java/io/legado/app/data/entities/RssStar.kt
  6. 6
      app/src/main/java/io/legado/app/model/Rss.kt
  7. 3
      app/src/main/java/io/legado/app/model/rss/RssParser.kt
  8. 7
      app/src/main/java/io/legado/app/model/rss/RssParserByRule.kt
  9. 4
      app/src/main/java/io/legado/app/ui/main/rss/RssFragment.kt
  10. 104
      app/src/main/java/io/legado/app/ui/rss/article/RssArticlesFragment.kt
  11. 123
      app/src/main/java/io/legado/app/ui/rss/article/RssArticlesViewModel.kt
  12. 102
      app/src/main/java/io/legado/app/ui/rss/article/RssSortActivity.kt
  13. 52
      app/src/main/java/io/legado/app/ui/rss/article/RssSortViewModel.kt
  14. 26
      app/src/main/res/layout/activity_rss_artivles.xml
  15. 15
      app/src/main/res/layout/fragment_rss_articles.xml

@ -257,7 +257,7 @@
android:launchMode="singleTop" /> android:launchMode="singleTop" />
<!--订阅条目--> <!--订阅条目-->
<activity <activity
android:name=".ui.rss.article.RssArticlesActivity" android:name=".ui.rss.article.RssSortActivity"
android:launchMode="singleTop" /> android:launchMode="singleTop" />
<!--Rss收藏--> <!--Rss收藏-->
<activity <activity

@ -18,7 +18,7 @@ import kotlinx.coroutines.launch
ReplaceRule::class, SearchBook::class, SearchKeyword::class, Cookie::class, ReplaceRule::class, SearchBook::class, SearchKeyword::class, Cookie::class,
RssSource::class, Bookmark::class, RssArticle::class, RssReadRecord::class, RssSource::class, Bookmark::class, RssArticle::class, RssReadRecord::class,
RssStar::class, TxtTocRule::class], RssStar::class, TxtTocRule::class],
version = 9, version = 10,
exportSchema = true exportSchema = true
) )
abstract class AppDatabase : RoomDatabase() { abstract class AppDatabase : RoomDatabase() {

@ -9,6 +9,7 @@ import androidx.room.Entity
) )
data class RssArticle( data class RssArticle(
var origin: String = "", var origin: String = "",
var sort: String = "",
var title: String = "", var title: String = "",
var order: Long = 0, var order: Long = 0,
var link: String = "", var link: String = "",
@ -36,6 +37,7 @@ data class RssArticle(
fun toStar(): RssStar { fun toStar(): RssStar {
return RssStar( return RssStar(
origin = origin, origin = origin,
sort = sort,
title = title, title = title,
starTime = System.currentTimeMillis(), starTime = System.currentTimeMillis(),
link = link, link = link,

@ -104,7 +104,7 @@ data class RssSource(
val sortMap = linkedMapOf<String, String>() val sortMap = linkedMapOf<String, String>()
val sortUrl = sortUrl val sortUrl = sortUrl
if (sortUrl.isNullOrEmpty()) { if (sortUrl.isNullOrEmpty()) {
sortMap["default"] = sourceUrl sortMap[""] = sourceUrl
} else { } else {
sortUrl.split("(&&|\n)+".toRegex()).forEach { c -> sortUrl.split("(&&|\n)+".toRegex()).forEach { c ->
val d = c.split("::") val d = c.split("::")

@ -9,6 +9,7 @@ import androidx.room.Entity
) )
data class RssStar( data class RssStar(
var origin: String = "", var origin: String = "",
var sort: String = "",
var title: String = "", var title: String = "",
var starTime: Long = 0, var starTime: Long = 0,
var link: String = "", var link: String = "",
@ -20,6 +21,7 @@ data class RssStar(
fun toRssArticle(): RssArticle { fun toRssArticle(): RssArticle {
return RssArticle( return RssArticle(
origin = origin, origin = origin,
sort = sort,
title = title, title = title,
link = link, link = link,
pubDate = pubDate, pubDate = pubDate,

@ -15,6 +15,8 @@ import kotlin.coroutines.CoroutineContext
object Rss { object Rss {
fun getArticles( fun getArticles(
sortName: String,
sortUrl: String,
rssSource: RssSource, rssSource: RssSource,
pageUrl: String? = null, pageUrl: String? = null,
scope: CoroutineScope = Coroutine.DEFAULT, scope: CoroutineScope = Coroutine.DEFAULT,
@ -22,11 +24,11 @@ object Rss {
): Coroutine<Result> { ): Coroutine<Result> {
return Coroutine.async(scope, context) { return Coroutine.async(scope, context) {
val analyzeUrl = AnalyzeUrl( val analyzeUrl = AnalyzeUrl(
pageUrl ?: rssSource.sourceUrl, pageUrl ?: sortUrl,
headerMapF = rssSource.getHeaderMap() headerMapF = rssSource.getHeaderMap()
) )
val body = analyzeUrl.getResponseAwait(rssSource.sourceUrl).body val body = analyzeUrl.getResponseAwait(rssSource.sourceUrl).body
RssParserByRule.parseXML(body, rssSource) RssParserByRule.parseXML(sortName, sortUrl, body, rssSource)
} }
} }

@ -11,7 +11,7 @@ import java.io.StringReader
object RssParser { object RssParser {
@Throws(XmlPullParserException::class, IOException::class) @Throws(XmlPullParserException::class, IOException::class)
fun parseXML(xml: String, sourceUrl: String): Result { fun parseXML(sortName: String, xml: String, sourceUrl: String): Result {
val articleList = mutableListOf<RssArticle>() val articleList = mutableListOf<RssArticle>()
var currentArticle = RssArticle() var currentArticle = RssArticle()
@ -87,6 +87,7 @@ object RssParser {
// The item is correctly parsed // The item is correctly parsed
insideItem = false insideItem = false
currentArticle.origin = sourceUrl currentArticle.origin = sourceUrl
currentArticle.sort = sortName
articleList.add(currentArticle) articleList.add(currentArticle)
currentArticle = RssArticle() currentArticle = RssArticle()
} }

@ -13,7 +13,7 @@ import io.legado.app.utils.NetworkUtils
object RssParserByRule { object RssParserByRule {
@Throws(Exception::class) @Throws(Exception::class)
fun parseXML(body: String?, rssSource: RssSource): Result { fun parseXML(sortName: String, sortUrl: String, body: String?, rssSource: RssSource): Result {
val sourceUrl = rssSource.sourceUrl val sourceUrl = rssSource.sourceUrl
var nextUrl: String? = null var nextUrl: String? = null
if (body.isNullOrBlank()) { if (body.isNullOrBlank()) {
@ -28,11 +28,11 @@ object RssParserByRule {
var ruleArticles = rssSource.ruleArticles var ruleArticles = rssSource.ruleArticles
if (ruleArticles.isNullOrBlank()) { if (ruleArticles.isNullOrBlank()) {
Debug.log(sourceUrl, "⇒列表规则为空, 使用默认规则解析") Debug.log(sourceUrl, "⇒列表规则为空, 使用默认规则解析")
return RssParser.parseXML(body, sourceUrl) return RssParser.parseXML(sortName, body, sourceUrl)
} else { } else {
val articleList = mutableListOf<RssArticle>() val articleList = mutableListOf<RssArticle>()
val analyzeRule = AnalyzeRule() val analyzeRule = AnalyzeRule()
analyzeRule.setContent(body, rssSource.sourceUrl) analyzeRule.setContent(body, sortUrl)
var reverse = false var reverse = false
if (ruleArticles.startsWith("-")) { if (ruleArticles.startsWith("-")) {
reverse = true reverse = true
@ -59,6 +59,7 @@ object RssParserByRule {
sourceUrl, item, analyzeRule, index == 0, sourceUrl, item, analyzeRule, index == 0,
ruleTitle, rulePubDate, ruleDescription, ruleImage, ruleLink ruleTitle, rulePubDate, ruleDescription, ruleImage, ruleLink
)?.let { )?.let {
it.sort = sortName
it.origin = rssSource.sourceUrl it.origin = rssSource.sourceUrl
articleList.add(it) articleList.add(it)
} }

@ -12,7 +12,7 @@ import io.legado.app.base.BaseFragment
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.main.MainViewModel import io.legado.app.ui.main.MainViewModel
import io.legado.app.ui.rss.article.RssArticlesActivity import io.legado.app.ui.rss.article.RssSortActivity
import io.legado.app.ui.rss.favorites.RssFavoritesActivity import io.legado.app.ui.rss.favorites.RssFavoritesActivity
import io.legado.app.ui.rss.source.manage.RssSourceActivity import io.legado.app.ui.rss.source.manage.RssSourceActivity
import io.legado.app.utils.getViewModelOfActivity import io.legado.app.utils.getViewModelOfActivity
@ -60,6 +60,6 @@ class RssFragment : BaseFragment(R.layout.fragment_rss),
} }
override fun openRss(rssSource: RssSource) { override fun openRss(rssSource: RssSource) {
startActivity<RssArticlesActivity>(Pair("url", rssSource.sourceUrl)) startActivity<RssSortActivity>(Pair("url", rssSource.sourceUrl))
} }
} }

@ -1,83 +1,67 @@
package io.legado.app.ui.rss.article package io.legado.app.ui.rss.article
import android.os.Bundle import android.os.Bundle
import android.view.Menu import android.view.View
import android.view.MenuItem
import androidx.lifecycle.LiveData import androidx.lifecycle.LiveData
import androidx.lifecycle.Observer import androidx.lifecycle.Observer
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
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.VMBaseActivity import io.legado.app.base.VMBaseFragment
import io.legado.app.data.entities.RssArticle import io.legado.app.data.entities.RssArticle
import io.legado.app.lib.theme.ATH import io.legado.app.lib.theme.ATH
import io.legado.app.ui.rss.read.ReadRssActivity import io.legado.app.ui.rss.read.ReadRssActivity
import io.legado.app.ui.rss.source.edit.RssSourceEditActivity
import io.legado.app.ui.widget.recycler.LoadMoreView import io.legado.app.ui.widget.recycler.LoadMoreView
import io.legado.app.ui.widget.recycler.VerticalDivider import io.legado.app.ui.widget.recycler.VerticalDivider
import io.legado.app.utils.getViewModel import io.legado.app.utils.getViewModel
import kotlinx.android.synthetic.main.activity_rss_artivles.* import io.legado.app.utils.getViewModelOfActivity
import io.legado.app.utils.startActivity
import kotlinx.android.synthetic.main.fragment_rss_articles.*
import kotlinx.android.synthetic.main.view_load_more.view.* import kotlinx.android.synthetic.main.view_load_more.view.*
import kotlinx.android.synthetic.main.view_refresh_recycler.* import kotlinx.android.synthetic.main.view_refresh_recycler.*
import org.jetbrains.anko.startActivity
import org.jetbrains.anko.startActivityForResult
class RssArticlesActivity : VMBaseActivity<RssArticlesViewModel>(R.layout.activity_rss_artivles), class RssArticlesFragment : VMBaseFragment<RssArticlesViewModel>(R.layout.fragment_rss_articles),
RssArticlesViewModel.CallBack,
RssArticlesAdapter.CallBack { RssArticlesAdapter.CallBack {
companion object {
fun create(sortName: String, sortUrl: String): RssArticlesFragment {
return RssArticlesFragment().apply {
val bundle = Bundle()
bundle.putString("sortName", sortName)
bundle.putString("sortUrl", sortUrl)
arguments = bundle
}
}
}
private val activityViewModel: RssSortViewModel
get() = getViewModelOfActivity(RssSortViewModel::class.java)
override val viewModel: RssArticlesViewModel override val viewModel: RssArticlesViewModel
get() = getViewModel(RssArticlesViewModel::class.java) get() = getViewModel(RssArticlesViewModel::class.java)
lateinit var adapter: RssArticlesAdapter
override lateinit var adapter: RssArticlesAdapter
private val editSource = 12319
private lateinit var loadMoreView: LoadMoreView private lateinit var loadMoreView: LoadMoreView
private var rssArticlesData: LiveData<List<RssArticle>>? = null private var rssArticlesData: LiveData<List<RssArticle>>? = null
override fun onActivityCreated(savedInstanceState: Bundle?) { override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) {
viewModel.callBack = this viewModel.init(arguments)
viewModel.titleLiveData.observe(this, Observer {
title_bar.title = it
})
initView() initView()
viewModel.initData(intent) { refresh_recycler_view.startLoading()
initData() initView()
refresh_recycler_view.startLoading() initData()
}
}
override fun onCompatCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.rss_articles, menu)
return super.onCompatCreateOptionsMenu(menu)
}
override fun onCompatOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
R.id.menu_edit_source -> viewModel.rssSource?.sourceUrl?.let {
startActivityForResult<RssSourceEditActivity>(editSource, Pair("data", it))
}
R.id.menu_clear -> {
viewModel.url?.let {
refresh_progress_bar.isAutoLoading = true
viewModel.clearArticles()
}
}
}
return super.onCompatOptionsItemSelected(item)
} }
private fun initView() { private fun initView() {
ATH.applyEdgeEffectColor(recycler_view) ATH.applyEdgeEffectColor(recycler_view)
recycler_view.layoutManager = LinearLayoutManager(this) recycler_view.layoutManager = LinearLayoutManager(requireContext())
recycler_view.addItemDecoration(VerticalDivider(this)) recycler_view.addItemDecoration(VerticalDivider(requireContext()))
adapter = RssArticlesAdapter(this, this) adapter = RssArticlesAdapter(requireContext(), this)
recycler_view.adapter = adapter recycler_view.adapter = adapter
loadMoreView = LoadMoreView(this) loadMoreView = LoadMoreView(requireContext())
adapter.addFooterView(loadMoreView) adapter.addFooterView(loadMoreView)
refresh_recycler_view.onRefreshStart = { refresh_recycler_view.onRefreshStart = {
viewModel.url?.let { activityViewModel.rssSource?.let {
viewModel.loadContent() viewModel.loadContent(it)
} }
} }
recycler_view.addOnScrollListener(object : RecyclerView.OnScrollListener() { recycler_view.addOnScrollListener(object : RecyclerView.OnScrollListener() {
@ -91,10 +75,10 @@ class RssArticlesActivity : VMBaseActivity<RssArticlesViewModel>(R.layout.activi
} }
private fun initData() { private fun initData() {
viewModel.url?.let { activityViewModel.url?.let {
rssArticlesData?.removeObservers(this) rssArticlesData?.removeObservers(this)
rssArticlesData = App.db.rssArticleDao().liveByOrigin(it) rssArticlesData = App.db.rssArticleDao().liveByOrigin(it)
rssArticlesData?.observe(this, Observer { list -> rssArticlesData?.observe(viewLifecycleOwner, Observer { list ->
adapter.setItems(list) adapter.setItems(list)
}) })
} }
@ -104,21 +88,25 @@ class RssArticlesActivity : VMBaseActivity<RssArticlesViewModel>(R.layout.activi
if (viewModel.isLoading) return if (viewModel.isLoading) return
if (loadMoreView.hasMore && adapter.getActualItemCount() > 0) { if (loadMoreView.hasMore && adapter.getActualItemCount() > 0) {
loadMoreView.rotate_loading.show() loadMoreView.rotate_loading.show()
viewModel.loadMore() activityViewModel.rssSource?.let {
viewModel.loadMore(it)
}
} }
} }
override fun loadFinally(hasMore: Boolean) { override fun observeLiveBus() {
refresh_recycler_view.stopLoading() viewModel.loadFinally.observe(viewLifecycleOwner, Observer {
if (hasMore) { refresh_recycler_view.stopLoading()
loadMoreView.startLoad() if (it) {
} else { loadMoreView.startLoad()
loadMoreView.noMore() } else {
} loadMoreView.noMore()
}
})
} }
override fun readRss(rssArticle: RssArticle) { override fun readRss(rssArticle: RssArticle) {
viewModel.read(rssArticle) activityViewModel.read(rssArticle)
startActivity<ReadRssActivity>( startActivity<ReadRssActivity>(
Pair("title", rssArticle.title), Pair("title", rssArticle.title),
Pair("origin", rssArticle.origin), Pair("origin", rssArticle.origin),

@ -1,124 +1,85 @@
package io.legado.app.ui.rss.article package io.legado.app.ui.rss.article
import android.app.Application import android.app.Application
import android.content.Intent import android.os.Bundle
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.RssArticle import io.legado.app.data.entities.RssArticle
import io.legado.app.data.entities.RssReadRecord
import io.legado.app.data.entities.RssSource import io.legado.app.data.entities.RssSource
import io.legado.app.model.Rss import io.legado.app.model.Rss
import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Dispatchers.Main
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
class RssArticlesViewModel(application: Application) : BaseViewModel(application) { class RssArticlesViewModel(application: Application) : BaseViewModel(application) {
var callBack: CallBack? = null val loadFinally = MutableLiveData<Boolean>()
var url: String? = null
var rssSource: RssSource? = null
val titleLiveData = MutableLiveData<String>()
var isLoading = true var isLoading = true
var order = System.currentTimeMillis() var order = System.currentTimeMillis()
private var nextPageUrl: String? = null private var nextPageUrl: String? = null
private val articles = arrayListOf<RssArticle>()
var sortName: String = ""
var sortUrl: String = ""
fun initData(intent: Intent, finally: () -> Unit) { fun init(bundle: Bundle?) {
execute { bundle?.let {
url = intent.getStringExtra("url") sortName = it.getString("sortName") ?: ""
url?.let { url -> sortUrl = it.getString("sortUrl") ?: ""
rssSource = App.db.rssSourceDao().getByKey(url)
rssSource?.let {
titleLiveData.postValue(it.sourceName)
} ?: let {
rssSource = RssSource(sourceUrl = url)
}
}
}.onFinally {
finally()
} }
} }
fun loadContent() {
fun loadContent(rssSource: RssSource) {
isLoading = true isLoading = true
rssSource?.let { rssSource -> Rss.getArticles(sortName, sortUrl, rssSource, null)
Rss.getArticles(rssSource, null) .onSuccess(Dispatchers.IO) {
.onSuccess(IO) { nextPageUrl = it.nextPageUrl
nextPageUrl = it.nextPageUrl it.articles.let { list ->
it.articles.let { list -> list.forEach { rssArticle ->
list.forEach { rssArticle -> rssArticle.order = order--
rssArticle.order = order-- }
} App.db.rssArticleDao().insert(*list.toTypedArray())
App.db.rssArticleDao().insert(*list.toTypedArray()) if (!rssSource.ruleNextPage.isNullOrEmpty()) {
if (!rssSource.ruleNextPage.isNullOrEmpty()) { App.db.rssArticleDao().clearOld(rssSource.sourceUrl, order)
App.db.rssArticleDao().clearOld(url!!, order) loadFinally.postValue(true)
withContext(Main) { } else {
callBack?.loadFinally(true) withContext(Dispatchers.Main) {
} loadFinally.postValue(false)
} else {
withContext(Main) {
callBack?.loadFinally(false)
}
} }
isLoading = false
} }
}.onError { isLoading = false
toast(it.localizedMessage)
} }
} }.onError {
toast(it.localizedMessage)
}
} }
fun loadMore() { fun loadMore(rssSource: RssSource) {
isLoading = true isLoading = true
val source = rssSource
val pageUrl = nextPageUrl val pageUrl = nextPageUrl
if (source != null && !pageUrl.isNullOrEmpty()) { if (!pageUrl.isNullOrEmpty()) {
Rss.getArticles(source, pageUrl) Rss.getArticles(sortName, sortUrl, rssSource, pageUrl)
.onSuccess(IO) { .onSuccess(Dispatchers.IO) {
nextPageUrl = it.nextPageUrl nextPageUrl = it.nextPageUrl
it.articles.let { list -> it.articles.let { list ->
if (list.isEmpty()) { if (list.isEmpty()) {
callBack?.loadFinally(false) loadFinally.postValue(true)
return@let return@let
} }
callBack?.adapter?.getItems()?.let { adapterItems -> if (articles.contains(list.first())) {
if (adapterItems.contains(list.first())) { loadFinally.postValue(false)
callBack?.loadFinally(false) } else {
} else { list.forEach { rssArticle ->
list.forEach { rssArticle -> rssArticle.order = order--
rssArticle.order = order--
}
App.db.rssArticleDao().insert(*list.toTypedArray())
} }
App.db.rssArticleDao().insert(*list.toTypedArray())
} }
} }
isLoading = false isLoading = false
} }
} else { } else {
callBack?.loadFinally(false) loadFinally.postValue(false)
} }
} }
fun read(rssArticle: RssArticle) {
execute {
App.db.rssArticleDao().insertRecord(RssReadRecord(rssArticle.link))
}
}
fun clearArticles() {
execute {
url?.let {
App.db.rssArticleDao().delete(it)
}
order = System.currentTimeMillis()
}.onSuccess {
loadContent()
}
}
interface CallBack {
var adapter: RssArticlesAdapter
fun loadFinally(hasMore: Boolean)
}
} }

@ -0,0 +1,102 @@
package io.legado.app.ui.rss.article
import android.app.Activity
import android.content.Intent
import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.FragmentStatePagerAdapter
import androidx.lifecycle.Observer
import io.legado.app.R
import io.legado.app.base.VMBaseActivity
import io.legado.app.ui.rss.source.edit.RssSourceEditActivity
import io.legado.app.utils.getViewModel
import io.legado.app.utils.gone
import io.legado.app.utils.visible
import kotlinx.android.synthetic.main.activity_rss_artivles.*
import kotlinx.android.synthetic.main.view_refresh_recycler.*
import org.jetbrains.anko.startActivityForResult
class RssSortActivity : VMBaseActivity<RssSortViewModel>(R.layout.activity_rss_artivles) {
override val viewModel: RssSortViewModel
get() = getViewModel(RssSortViewModel::class.java)
private val editSource = 12319
private val fragments = linkedMapOf<String, RssArticlesFragment>()
private lateinit var adapter: TabFragmentPageAdapter
override fun onActivityCreated(savedInstanceState: Bundle?) {
adapter = TabFragmentPageAdapter(supportFragmentManager)
tab_layout.setupWithViewPager(view_pager)
view_pager.adapter = adapter
viewModel.titleLiveData.observe(this, Observer {
title_bar.title = it
})
viewModel.initData(intent) {
upFragments()
}
}
override fun onCompatCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.rss_articles, menu)
return super.onCompatCreateOptionsMenu(menu)
}
override fun onCompatOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
R.id.menu_edit_source -> viewModel.rssSource?.sourceUrl?.let {
startActivityForResult<RssSourceEditActivity>(editSource, Pair("data", it))
}
R.id.menu_clear -> {
viewModel.url?.let {
refresh_progress_bar.isAutoLoading = true
viewModel.clearArticles()
}
}
}
return super.onCompatOptionsItemSelected(item)
}
private fun upFragments() {
fragments.clear()
viewModel.rssSource?.sortUrls()?.forEach {
fragments[it.key] = RssArticlesFragment.create(it.key, it.value)
}
if (fragments.size == 1) {
tab_layout.gone()
} else {
tab_layout.visible()
}
adapter.notifyDataSetChanged()
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
when (requestCode) {
editSource -> if (resultCode == Activity.RESULT_OK) {
viewModel.initData(intent) {
upFragments()
}
}
}
}
private inner class TabFragmentPageAdapter internal constructor(fm: FragmentManager) :
FragmentStatePagerAdapter(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {
override fun getPageTitle(position: Int): CharSequence? {
return fragments.keys.elementAt(position)
}
override fun getItem(position: Int): Fragment {
return fragments.values.elementAt(position)
}
override fun getCount(): Int {
return fragments.size
}
}
}

@ -0,0 +1,52 @@
package io.legado.app.ui.rss.article
import android.app.Application
import android.content.Intent
import androidx.lifecycle.MutableLiveData
import io.legado.app.App
import io.legado.app.base.BaseViewModel
import io.legado.app.data.entities.RssArticle
import io.legado.app.data.entities.RssReadRecord
import io.legado.app.data.entities.RssSource
class RssSortViewModel(application: Application) : BaseViewModel(application) {
var url: String? = null
var rssSource: RssSource? = null
val titleLiveData = MutableLiveData<String>()
var order = System.currentTimeMillis()
fun initData(intent: Intent, finally: () -> Unit) {
execute {
url = intent.getStringExtra("url")
url?.let { url ->
rssSource = App.db.rssSourceDao().getByKey(url)
rssSource?.let {
titleLiveData.postValue(it.sourceName)
} ?: let {
rssSource = RssSource(sourceUrl = url)
}
}
}.onFinally {
finally()
}
}
fun read(rssArticle: RssArticle) {
execute {
App.db.rssArticleDao().insertRecord(RssReadRecord(rssArticle.link))
}
}
fun clearArticles() {
execute {
url?.let {
App.db.rssArticleDao().delete(it)
}
order = System.currentTimeMillis()
}.onSuccess {
}
}
}

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
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">
@ -8,21 +7,16 @@
<io.legado.app.ui.widget.TitleBar <io.legado.app.ui.widget.TitleBar
android:id="@+id/title_bar" android:id="@+id/title_bar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content" />
app:layout_constraintTop_toTopOf="parent" />
<io.legado.app.ui.widget.dynamiclayout.DynamicFrameLayout <com.google.android.material.tabs.TabLayout
android:id="@+id/content_view" android:id="@+id/tab_layout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="0dp" android:layout_height="wrap_content" />
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@id/title_bar">
<io.legado.app.ui.widget.recycler.RefreshRecyclerView <androidx.viewpager.widget.ViewPager
android:id="@+id/refresh_recycler_view" android:id="@+id/view_pager"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" /> android:layout_height="wrap_content" />
</io.legado.app.ui.widget.dynamiclayout.DynamicFrameLayout>
</androidx.constraintlayout.widget.ConstraintLayout> </LinearLayout>

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<io.legado.app.ui.widget.dynamiclayout.DynamicFrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/content_view"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@id/title_bar">
<io.legado.app.ui.widget.recycler.RefreshRecyclerView
android:id="@+id/refresh_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</io.legado.app.ui.widget.dynamiclayout.DynamicFrameLayout>
Loading…
Cancel
Save