From 9f36fb865e7722d161f213b59101a8e365ce408f Mon Sep 17 00:00:00 2001 From: yattoz <12408848+yattoz@users.noreply.github.com> Date: Mon, 30 Dec 2019 20:22:58 +0100 Subject: [PATCH] tweaked NewsAdapter to avoid image blink at first fragment entry --- .../java/fr/forum_thalie/tsumugi/Values.kt | 3 +- .../tsumugi/ui/news/NewsAdapter.kt | 40 ++++++++++++------- .../tsumugi/ui/news/NewsFragment.kt | 4 +- .../tsumugi/ui/news/NewsViewModel.kt | 13 +++--- 4 files changed, 36 insertions(+), 24 deletions(-) diff --git a/app/src/main/java/fr/forum_thalie/tsumugi/Values.kt b/app/src/main/java/fr/forum_thalie/tsumugi/Values.kt index 4a77e03..95b51b9 100644 --- a/app/src/main/java/fr/forum_thalie/tsumugi/Values.kt +++ b/app/src/main/java/fr/forum_thalie/tsumugi/Values.kt @@ -8,7 +8,8 @@ const val tag = "fr.forum_thalie.tsumugi" const val noConnectionValue = "—" const val streamDownValue = "Tsumugi est HS !" // we don't want this value to be displaed in the "last played" screen. val weekdaysArray : Array = 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. val weekdays = ArrayList().apply { weekdaysArray.forEach { add(it) } } diff --git a/app/src/main/java/fr/forum_thalie/tsumugi/ui/news/NewsAdapter.kt b/app/src/main/java/fr/forum_thalie/tsumugi/ui/news/NewsAdapter.kt index 2378de6..f058fd8 100644 --- a/app/src/main/java/fr/forum_thalie/tsumugi/ui/news/NewsAdapter.kt +++ b/app/src/main/java/fr/forum_thalie/tsumugi/ui/news/NewsAdapter.kt @@ -21,6 +21,7 @@ import androidx.core.text.HtmlCompat import androidx.core.widget.TextViewCompat import androidx.recyclerview.widget.RecyclerView import fr.forum_thalie.tsumugi.R +import fr.forum_thalie.tsumugi.newsDisplayDatePattern import java.io.IOException import java.io.InputStream import java.net.URL @@ -84,7 +85,7 @@ class ImageGetterAsyncTask( } -class NewsAdapter(private val dataSet: ArrayList, private val c: Context +class NewsAdapter(private val dataSet: ArrayList, private val c: Context, private val vm: NewsViewModel /*, context: Context, resource: Int, @@ -125,23 +126,34 @@ class NewsAdapter(private val dataSet: ArrayList, private val c: Context header.text = HtmlCompat.fromHtml(dataSet[position].header, HtmlCompat.FROM_HTML_MODE_LEGACY).replace(Regex("\n"), " ") 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) TextViewCompat.setAutoSizeTextTypeWithDefaults(author, TextViewCompat.AUTO_SIZE_TEXT_TYPE_UNIFORM) - val spanned = HtmlCompat.fromHtml( - dataSet[position].text, - HtmlCompat.FROM_HTML_MODE_LEGACY, - ImageGetter { source -> - val d = LevelListDrawable() - val empty: Drawable? = ContextCompat.getDrawable(c, R.drawable.exo_icon_play) + 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, + HtmlCompat.FROM_HTML_MODE_LEGACY, + ImageGetter { source -> + val d = LevelListDrawable() + /* + val empty: Drawable? = ContextCompat.getDrawable(c, R.drawable.exo_icon_play) + d.addLevel(0, 0, empty!!) + d.setBounds(0, 0, empty.intrinsicWidth, empty.intrinsicHeight) + */ + ImageGetterAsyncTask(c, source, d).execute(text) + d + }, null + ) + } + + - d.addLevel(0, 0, empty!!) - d.setBounds(0, 0, empty.intrinsicWidth, empty.intrinsicHeight) - ImageGetterAsyncTask(c, source, d).execute(text) - d - }, null - ) text.text = spanned text.movementMethod = LinkMovementMethod.getInstance() } diff --git a/app/src/main/java/fr/forum_thalie/tsumugi/ui/news/NewsFragment.kt b/app/src/main/java/fr/forum_thalie/tsumugi/ui/news/NewsFragment.kt index d914649..aa86d71 100644 --- a/app/src/main/java/fr/forum_thalie/tsumugi/ui/news/NewsFragment.kt +++ b/app/src/main/java/fr/forum_thalie/tsumugi/ui/news/NewsFragment.kt @@ -58,7 +58,7 @@ class NewsFragment : Fragment() { newsViewModel.root = inflater.inflate(R.layout.fragment_news, container, false) as SwipeRefreshLayout viewManager = LinearLayoutManager(context) - viewAdapter = NewsAdapter(newsViewModel.newsArray, context!!) + viewAdapter = NewsAdapter(newsViewModel.newsArray, context!!, newsViewModel) recyclerView = newsViewModel.root.findViewById(R.id.news_recycler).apply { // use this setting to improve performance if you know that changes // in content do not change the layout size of the RecyclerView @@ -100,7 +100,7 @@ class NewsFragment : Fragment() { newsViewModel = ViewModelProviders.of(this).get(NewsViewModel::class.java) - newsViewModel.fetch(c = context!!) + newsViewModel.fetch(c = context!!, isPreloading = true) Log.d(tag, "news fetched onCreate") super.onCreate(savedInstanceState) } diff --git a/app/src/main/java/fr/forum_thalie/tsumugi/ui/news/NewsViewModel.kt b/app/src/main/java/fr/forum_thalie/tsumugi/ui/news/NewsViewModel.kt index 8df7267..ab2ea0d 100644 --- a/app/src/main/java/fr/forum_thalie/tsumugi/ui/news/NewsViewModel.kt +++ b/app/src/main/java/fr/forum_thalie/tsumugi/ui/news/NewsViewModel.kt @@ -8,16 +8,13 @@ import android.webkit.WebView import androidx.lifecycle.ViewModel import androidx.recyclerview.widget.RecyclerView import com.prof.rssparser.Parser -import fr.forum_thalie.tsumugi.Async import fr.forum_thalie.tsumugi.R +import fr.forum_thalie.tsumugi.newsDateTimePattern import fr.forum_thalie.tsumugi.tag import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job import kotlinx.coroutines.launch -import org.json.JSONArray -import org.json.JSONObject -import java.net.URL import java.text.SimpleDateFormat import java.util.* import kotlin.collections.ArrayList @@ -30,6 +27,7 @@ class NewsViewModel : ViewModel() { lateinit var root: View var webView: WebView? = null var webViewNews: WebViewNews? = null + var isPreLoadingNews = false val newsArray : ArrayList = ArrayList() var isWebViewLoaded = false @@ -37,7 +35,7 @@ class NewsViewModel : ViewModel() { private val viewModelJob = Job() 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) if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) @@ -60,9 +58,9 @@ class NewsViewModel : ViewModel() { news.text = item.content ?: "" 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() - Log.d(tag, "$news --- ${dateString}") + Log.d(tag, "$news --- $dateString") 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. root?.isRefreshing = false + isPreLoadingNews = isPreloading viewAdapter?.notifyDataSetChanged() }catch (e: Exception) {