Просмотр исходного кода

added RSS parser and simple news reader. Clicking on title opens website

yattoz 4 лет назад
Родитель
Сommit
99961e8a4e

+ 4 - 1
app/build.gradle Просмотреть файл

@@ -69,12 +69,15 @@ dependencies {
69 69
     implementation 'androidx.lifecycle:lifecycle-extensions:2.1.0'
70 70
     implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.1.0'
71 71
 
72
-    implementation 'androidx.recyclerview:recyclerview:1.0.0'
72
+    implementation 'androidx.recyclerview:recyclerview:1.1.0'
73 73
     implementation 'androidx.preference:preference:1.1.0'
74 74
 
75 75
     // jsoup HTML parser library @ https://jsoup.org/
76 76
     // implementation 'org.jsoup:jsoup:1.12.1'
77 77
 
78
+    // RSS parser library @ https://github.com/prof18/RSS-Parser
79
+    implementation 'com.prof.rssparser:rssparser:2.0.4'
80
+
78 81
     def work_version = "2.2.0"
79 82
     implementation "androidx.work:work-runtime-ktx:$work_version"
80 83
 

+ 1 - 0
app/src/main/java/fr/forum_thalie/tsumugi/ui/news/News.kt Просмотреть файл

@@ -7,6 +7,7 @@ class News {
7 7
     var text: String = ""
8 8
     var header: String = ""
9 9
     var author: String = ""
10
+    var link: String = ""
10 11
     var date: Date = Date()
11 12
 
12 13
     override fun toString() : String

+ 10 - 1
app/src/main/java/fr/forum_thalie/tsumugi/ui/news/NewsAdapter.kt Просмотреть файл

@@ -1,17 +1,21 @@
1 1
 package fr.forum_thalie.tsumugi.ui.news
2 2
 
3 3
 import android.annotation.SuppressLint
4
+import android.content.Context
5
+import android.content.Intent
6
+import android.net.Uri
4 7
 import android.widget.TextView
5 8
 import android.view.LayoutInflater
6 9
 import android.view.ViewGroup
7 10
 import androidx.constraintlayout.widget.ConstraintLayout
11
+import androidx.core.content.ContextCompat.startActivity
8 12
 import androidx.core.text.HtmlCompat
9 13
 import androidx.core.widget.TextViewCompat
10 14
 import androidx.recyclerview.widget.RecyclerView
11 15
 import fr.forum_thalie.tsumugi.R
12 16
 import kotlin.collections.ArrayList
13 17
 
14
-class NewsAdapter(private val dataSet: ArrayList<News>
18
+class NewsAdapter(private val dataSet: ArrayList<News>, private val c: Context
15 19
     /*,
16 20
     context: Context,
17 21
     resource: Int,
@@ -45,6 +49,11 @@ class NewsAdapter(private val dataSet: ArrayList<News>
45 49
         val author = holder.itemView.findViewById<TextView>(R.id.news_author)
46 50
         val header = holder.itemView.findViewById<TextView>(R.id.news_header)
47 51
         title.text = dataSet[position].title
52
+        title.setOnClickListener {
53
+            val i = Intent(Intent.ACTION_VIEW)
54
+            i.data = Uri.parse(dataSet[position].link)
55
+            c.startActivity(i)
56
+        }
48 57
         text.text = HtmlCompat.fromHtml(dataSet[position].text, HtmlCompat.FROM_HTML_MODE_LEGACY)
49 58
         header.text = HtmlCompat.fromHtml(dataSet[position].header, HtmlCompat.FROM_HTML_MODE_LEGACY).replace(Regex("\n"), " ")
50 59
         author.text = "| ${dataSet[position].author}"

+ 1 - 1
app/src/main/java/fr/forum_thalie/tsumugi/ui/news/NewsFragment.kt Просмотреть файл

@@ -29,7 +29,7 @@ class NewsFragment : Fragment() {
29 29
         val root = inflater.inflate(R.layout.fragment_news, container, false) as androidx.swiperefreshlayout.widget.SwipeRefreshLayout
30 30
 
31 31
         viewManager = LinearLayoutManager(context)
32
-        viewAdapter = NewsAdapter(newsViewModel.newsArray)
32
+        viewAdapter = NewsAdapter(newsViewModel.newsArray, context!!)
33 33
         recyclerView = root.findViewById<RecyclerView>(R.id.news_recycler).apply {
34 34
             // use this setting to improve performance if you know that changes
35 35
             // in content do not change the layout size of the RecyclerView

+ 42 - 5
app/src/main/java/fr/forum_thalie/tsumugi/ui/news/NewsViewModel.kt Просмотреть файл

@@ -3,21 +3,28 @@ package fr.forum_thalie.tsumugi.ui.news
3 3
 import android.util.Log
4 4
 import androidx.lifecycle.ViewModel
5 5
 import androidx.recyclerview.widget.RecyclerView
6
+import com.prof.rssparser.Parser
6 7
 import fr.forum_thalie.tsumugi.Async
7 8
 import fr.forum_thalie.tsumugi.tag
9
+import kotlinx.coroutines.CoroutineScope
10
+import kotlinx.coroutines.Dispatchers
11
+import kotlinx.coroutines.Job
12
+import kotlinx.coroutines.launch
8 13
 import org.json.JSONArray
9 14
 import org.json.JSONObject
10 15
 import java.net.URL
11 16
 import java.text.SimpleDateFormat
12 17
 import java.util.*
13 18
 import kotlin.collections.ArrayList
19
+import kotlin.math.max
20
+import kotlin.math.min
14 21
 
15 22
 
16 23
 class NewsViewModel : ViewModel() {
17 24
 
18 25
     val newsArray : ArrayList<News> = ArrayList()
19 26
 
20
-    private val urlToScrape = "https://r-a-d.io/api/news"
27
+    private val urlToScrape = "https://tsumugi.forum-thalie.fr/?feed=rss2"
21 28
 
22 29
     private val scrape : (Any?) -> Unit =
23 30
     {
@@ -41,12 +48,42 @@ class NewsViewModel : ViewModel() {
41 48
         }
42 49
     }
43 50
 
51
+    private val viewModelJob = Job()
52
+    private val coroutineScope = CoroutineScope(Dispatchers.Main + viewModelJob)
53
+
44 54
     fun fetch(root: androidx.swiperefreshlayout.widget.SwipeRefreshLayout? = null, viewAdapter: RecyclerView.Adapter<*>? = null)
45 55
     {
46
-        val post : (parameter: Any?) -> Unit = {
47
-            root?.isRefreshing = false
48
-            viewAdapter?.notifyDataSetChanged()
56
+        val maxNumberOfArticles = 5
57
+        coroutineScope.launch(Dispatchers.Main) {
58
+            Log.d(tag, "launching coroutine")
59
+            try {
60
+                val parser = Parser()
61
+                val articleList = parser.getArticles(urlToScrape)
62
+                newsArray.clear()
63
+                for (i in 0 until min(articleList.size, maxNumberOfArticles))
64
+                {
65
+                    val item = articleList[i]
66
+                    Log.d(tag, "i = $i / ${articleList.size}")
67
+                    val news = News()
68
+                    news.title = item.title ?: ""
69
+                    news.link = item.link ?: urlToScrape
70
+                    news.author = item.author ?: ""
71
+                    news.text = item.content ?: ""
72
+                    news.header = item.description ?: ""
73
+
74
+                    //val formatter6 = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault())
75
+
76
+                    //news.date = formatter6.parse(item.pubDate ?: Date().toString()) ?: Date()
77
+
78
+                    Log.d(tag, "$news - ${item.pubDate}")
79
+                    newsArray.add(news)
80
+                }
81
+                // The list contains all article's data. For example you can use it for your adapter.
82
+                root?.isRefreshing = false
83
+                viewAdapter?.notifyDataSetChanged()
84
+            } catch (e: Exception) {
85
+                // Handle the exception
86
+            }
49 87
         }
50
-        Async(scrape, post)
51 88
     }
52 89
 }