tweaked NewsAdapter to avoid image blink at first fragment entry
parent
00b2632407
commit
9f36fb865e
|
|
@ -8,7 +8,8 @@ const val tag = "fr.forum_thalie.tsumugi"
|
||||||
const val noConnectionValue = "—"
|
const val noConnectionValue = "—"
|
||||||
const val streamDownValue = "Tsumugi est HS !" // we don't want this value to be displaed in the "last played" screen.
|
const val streamDownValue = "Tsumugi est HS !" // we don't want this value to be displaed in the "last played" screen.
|
||||||
val weekdaysArray : Array<String> = arrayOf( "Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi", "Dimanche")
|
val weekdaysArray : Array<String> = arrayOf( "Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi", "Dimanche")
|
||||||
|
const val newsDateTimePattern = "EEE, d MMM yyyy HH:mm:ss Z"
|
||||||
|
const val newsDisplayDatePattern = "dd MMM yyyy"
|
||||||
// Below this line is only automatically programmed values. Unless your week does not start with Monday, you don't need to change this.
|
// Below this line is only automatically programmed values. Unless your week does not start with Monday, you don't need to change this.
|
||||||
|
|
||||||
val weekdays = ArrayList<String>().apply { weekdaysArray.forEach { add(it) } }
|
val weekdays = ArrayList<String>().apply { weekdaysArray.forEach { add(it) } }
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ import androidx.core.text.HtmlCompat
|
||||||
import androidx.core.widget.TextViewCompat
|
import androidx.core.widget.TextViewCompat
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import fr.forum_thalie.tsumugi.R
|
import fr.forum_thalie.tsumugi.R
|
||||||
|
import fr.forum_thalie.tsumugi.newsDisplayDatePattern
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
import java.net.URL
|
import java.net.URL
|
||||||
|
|
@ -84,7 +85,7 @@ class ImageGetterAsyncTask(
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class NewsAdapter(private val dataSet: ArrayList<News>, private val c: Context
|
class NewsAdapter(private val dataSet: ArrayList<News>, private val c: Context, private val vm: NewsViewModel
|
||||||
/*,
|
/*,
|
||||||
context: Context,
|
context: Context,
|
||||||
resource: Int,
|
resource: Int,
|
||||||
|
|
@ -125,23 +126,34 @@ class NewsAdapter(private val dataSet: ArrayList<News>, private val c: Context
|
||||||
|
|
||||||
header.text = HtmlCompat.fromHtml(dataSet[position].header, HtmlCompat.FROM_HTML_MODE_LEGACY).replace(Regex("\n"), " ")
|
header.text = HtmlCompat.fromHtml(dataSet[position].header, HtmlCompat.FROM_HTML_MODE_LEGACY).replace(Regex("\n"), " ")
|
||||||
author.text = "| ${dataSet[position].author}"
|
author.text = "| ${dataSet[position].author}"
|
||||||
val sdf = SimpleDateFormat("dd MMM yyyy", Locale.getDefault())
|
val sdf = SimpleDateFormat(newsDisplayDatePattern, Locale.getDefault())
|
||||||
date.text = sdf.format(dataSet[position].date)
|
date.text = sdf.format(dataSet[position].date)
|
||||||
TextViewCompat.setAutoSizeTextTypeWithDefaults(author, TextViewCompat.AUTO_SIZE_TEXT_TYPE_UNIFORM)
|
TextViewCompat.setAutoSizeTextTypeWithDefaults(author, TextViewCompat.AUTO_SIZE_TEXT_TYPE_UNIFORM)
|
||||||
|
|
||||||
val spanned = HtmlCompat.fromHtml(
|
val spanned = // the trick is to avoid loading images when the adapter is called with preloading.
|
||||||
|
if (vm.isPreLoadingNews) {
|
||||||
|
HtmlCompat.fromHtml(
|
||||||
|
dataSet[position].text,
|
||||||
|
HtmlCompat.FROM_HTML_MODE_LEGACY)
|
||||||
|
} else {
|
||||||
|
HtmlCompat.fromHtml(
|
||||||
dataSet[position].text,
|
dataSet[position].text,
|
||||||
HtmlCompat.FROM_HTML_MODE_LEGACY,
|
HtmlCompat.FROM_HTML_MODE_LEGACY,
|
||||||
ImageGetter { source ->
|
ImageGetter { source ->
|
||||||
val d = LevelListDrawable()
|
val d = LevelListDrawable()
|
||||||
|
/*
|
||||||
val empty: Drawable? = ContextCompat.getDrawable(c, R.drawable.exo_icon_play)
|
val empty: Drawable? = ContextCompat.getDrawable(c, R.drawable.exo_icon_play)
|
||||||
|
|
||||||
d.addLevel(0, 0, empty!!)
|
d.addLevel(0, 0, empty!!)
|
||||||
d.setBounds(0, 0, empty.intrinsicWidth, empty.intrinsicHeight)
|
d.setBounds(0, 0, empty.intrinsicWidth, empty.intrinsicHeight)
|
||||||
|
*/
|
||||||
ImageGetterAsyncTask(c, source, d).execute(text)
|
ImageGetterAsyncTask(c, source, d).execute(text)
|
||||||
d
|
d
|
||||||
}, null
|
}, null
|
||||||
)
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
text.text = spanned
|
text.text = spanned
|
||||||
text.movementMethod = LinkMovementMethod.getInstance()
|
text.movementMethod = LinkMovementMethod.getInstance()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,7 @@ class NewsFragment : Fragment() {
|
||||||
newsViewModel.root = inflater.inflate(R.layout.fragment_news, container, false) as SwipeRefreshLayout
|
newsViewModel.root = inflater.inflate(R.layout.fragment_news, container, false) as SwipeRefreshLayout
|
||||||
|
|
||||||
viewManager = LinearLayoutManager(context)
|
viewManager = LinearLayoutManager(context)
|
||||||
viewAdapter = NewsAdapter(newsViewModel.newsArray, context!!)
|
viewAdapter = NewsAdapter(newsViewModel.newsArray, context!!, newsViewModel)
|
||||||
recyclerView = newsViewModel.root.findViewById<RecyclerView>(R.id.news_recycler).apply {
|
recyclerView = newsViewModel.root.findViewById<RecyclerView>(R.id.news_recycler).apply {
|
||||||
// use this setting to improve performance if you know that changes
|
// use this setting to improve performance if you know that changes
|
||||||
// in content do not change the layout size of the RecyclerView
|
// in content do not change the layout size of the RecyclerView
|
||||||
|
|
@ -100,7 +100,7 @@ class NewsFragment : Fragment() {
|
||||||
newsViewModel =
|
newsViewModel =
|
||||||
ViewModelProviders.of(this).get(NewsViewModel::class.java)
|
ViewModelProviders.of(this).get(NewsViewModel::class.java)
|
||||||
|
|
||||||
newsViewModel.fetch(c = context!!)
|
newsViewModel.fetch(c = context!!, isPreloading = true)
|
||||||
Log.d(tag, "news fetched onCreate")
|
Log.d(tag, "news fetched onCreate")
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,16 +8,13 @@ import android.webkit.WebView
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.prof.rssparser.Parser
|
import com.prof.rssparser.Parser
|
||||||
import fr.forum_thalie.tsumugi.Async
|
|
||||||
import fr.forum_thalie.tsumugi.R
|
import fr.forum_thalie.tsumugi.R
|
||||||
|
import fr.forum_thalie.tsumugi.newsDateTimePattern
|
||||||
import fr.forum_thalie.tsumugi.tag
|
import fr.forum_thalie.tsumugi.tag
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import org.json.JSONArray
|
|
||||||
import org.json.JSONObject
|
|
||||||
import java.net.URL
|
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import kotlin.collections.ArrayList
|
import kotlin.collections.ArrayList
|
||||||
|
|
@ -30,6 +27,7 @@ class NewsViewModel : ViewModel() {
|
||||||
lateinit var root: View
|
lateinit var root: View
|
||||||
var webView: WebView? = null
|
var webView: WebView? = null
|
||||||
var webViewNews: WebViewNews? = null
|
var webViewNews: WebViewNews? = null
|
||||||
|
var isPreLoadingNews = false
|
||||||
|
|
||||||
val newsArray : ArrayList<News> = ArrayList()
|
val newsArray : ArrayList<News> = ArrayList()
|
||||||
var isWebViewLoaded = false
|
var isWebViewLoaded = false
|
||||||
|
|
@ -37,7 +35,7 @@ class NewsViewModel : ViewModel() {
|
||||||
private val viewModelJob = Job()
|
private val viewModelJob = Job()
|
||||||
private val coroutineScope = CoroutineScope(Dispatchers.Main + viewModelJob)
|
private val coroutineScope = CoroutineScope(Dispatchers.Main + viewModelJob)
|
||||||
|
|
||||||
fun fetch(root: androidx.swiperefreshlayout.widget.SwipeRefreshLayout? = null, viewAdapter: RecyclerView.Adapter<*>? = null, c: Context)
|
fun fetch(root: androidx.swiperefreshlayout.widget.SwipeRefreshLayout? = null, viewAdapter: RecyclerView.Adapter<*>? = null, c: Context, isPreloading: Boolean = false)
|
||||||
{
|
{
|
||||||
val urlToScrape = c.getString(R.string.rss_url)
|
val urlToScrape = c.getString(R.string.rss_url)
|
||||||
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT)
|
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT)
|
||||||
|
|
@ -60,9 +58,9 @@ class NewsViewModel : ViewModel() {
|
||||||
news.text = item.content ?: ""
|
news.text = item.content ?: ""
|
||||||
news.header = item.description ?: ""
|
news.header = item.description ?: ""
|
||||||
|
|
||||||
val formatter6 = SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss Z", Locale.ENGLISH)
|
val formatter6 = SimpleDateFormat(newsDateTimePattern, Locale.ENGLISH)
|
||||||
val dateString = item.pubDate.toString()
|
val dateString = item.pubDate.toString()
|
||||||
Log.d(tag, "$news --- ${dateString}")
|
Log.d(tag, "$news --- $dateString")
|
||||||
|
|
||||||
news.date = formatter6.parse(dateString) ?: Date(0)
|
news.date = formatter6.parse(dateString) ?: Date(0)
|
||||||
|
|
||||||
|
|
@ -70,6 +68,7 @@ class NewsViewModel : ViewModel() {
|
||||||
}
|
}
|
||||||
// The list contains all article's data. For example you can use it for your adapter.
|
// The list contains all article's data. For example you can use it for your adapter.
|
||||||
root?.isRefreshing = false
|
root?.isRefreshing = false
|
||||||
|
isPreLoadingNews = isPreloading
|
||||||
viewAdapter?.notifyDataSetChanged()
|
viewAdapter?.notifyDataSetChanged()
|
||||||
}catch (e: Exception)
|
}catch (e: Exception)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue