NewsAdapter.kt 7.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. package fr.riff_app.riff.ui.news
  2. import android.annotation.SuppressLint
  3. import android.app.Activity
  4. import android.content.Context
  5. import android.graphics.Bitmap
  6. import android.graphics.BitmapFactory
  7. import android.graphics.Point
  8. import android.graphics.drawable.BitmapDrawable
  9. import android.graphics.drawable.Drawable
  10. import android.graphics.drawable.LevelListDrawable
  11. import android.os.AsyncTask
  12. import android.text.Html.ImageGetter
  13. import android.text.method.LinkMovementMethod
  14. import android.view.LayoutInflater
  15. import android.view.ViewGroup
  16. import android.widget.TextView
  17. import androidx.constraintlayout.widget.ConstraintLayout
  18. import androidx.core.content.ContextCompat
  19. import androidx.core.text.HtmlCompat
  20. import androidx.core.widget.TextViewCompat
  21. import androidx.recyclerview.widget.RecyclerView
  22. import fr.riff_app.riff.R
  23. import fr.riff_app.riff.newsDisplayDatePattern
  24. import java.io.IOException
  25. import java.io.InputStream
  26. import java.net.URL
  27. import java.text.SimpleDateFormat
  28. import java.util.*
  29. // Using solution found here: https://stackoverflow.com/questions/3758535/display-images-on-android-using-textview-and-html-imagegetter-asynchronously
  30. // but without Picasso (just fetching image by myself.)
  31. class ImageGetterAsyncTask(
  32. private val context: Context,
  33. private val source: String?,
  34. private val levelListDrawable: LevelListDrawable
  35. ) :
  36. AsyncTask<TextView?, Void?, Bitmap?>() {
  37. private var t: TextView? = null
  38. override fun doInBackground(vararg params: TextView?): Bitmap? {
  39. t = params[0]
  40. return try {
  41. ////[REMOVE LOG CALLS]//[REMOVE LOG CALLS]Log.d(LOG_CAT, "Downloading the image from: $source")
  42. var k: InputStream? = null
  43. var pic: Bitmap? = null
  44. try {
  45. k = URL(source).content as InputStream
  46. val options = BitmapFactory.Options()
  47. options.inSampleSize = 1
  48. // Putting 2 makes 1/2 of origin image size from width and height.
  49. // it alleviates the memory and CPU too for weak devices.
  50. pic = BitmapFactory.decodeStream(k, null, options)
  51. k.close()
  52. } catch (e: IOException) {
  53. e.printStackTrace()
  54. } finally {
  55. k?.close()
  56. }
  57. pic
  58. } catch (e: Exception) {
  59. null
  60. }
  61. }
  62. override fun onPostExecute(bitmap: Bitmap?) {
  63. try {
  64. val d: Drawable = BitmapDrawable(context.resources, bitmap)
  65. val size = Point()
  66. (context as Activity).windowManager.defaultDisplay.getSize(size)
  67. // Lets calculate the ratio according to the screen width in px
  68. val multiplier: Double = (size.x).toDouble() / (bitmap!!.width.toDouble())
  69. levelListDrawable.addLevel(1, 1, d)
  70. // Set bounds width and height according to the bitmap resized size
  71. levelListDrawable.setBounds(
  72. 0,
  73. 0,
  74. (bitmap.width.toDouble() * multiplier).toInt(),
  75. (bitmap.height.toDouble() * multiplier).toInt()
  76. )
  77. levelListDrawable.level = 1
  78. t!!.text = t!!.text // invalidate() doesn't work correctly...
  79. } catch (e: Exception) { /* Like a null bitmap, etc. */
  80. }
  81. }
  82. }
  83. class NewsAdapter(private val dataSet: ArrayList<News>, private val c: Context, private val vm: NewsViewModel
  84. /*,
  85. context: Context,
  86. resource: Int,
  87. objects: Array<out Song>*/
  88. ) : RecyclerView.Adapter<NewsAdapter.MyViewHolder>() /*ArrayAdapter<Song>(context, resource, objects)*/ {
  89. // Provide a reference to the views for each data item
  90. // Complex data items may need more than one view per item, and
  91. // you provide access to all the views for a data item in a view holder.
  92. // Each data item is just a string in this case that is shown in a TextView.
  93. class MyViewHolder(view: ConstraintLayout) : RecyclerView.ViewHolder(view)
  94. // Create new views (invoked by the layout manager)
  95. override fun onCreateViewHolder(parent: ViewGroup,
  96. viewType: Int): MyViewHolder {
  97. // create a new view
  98. val view = LayoutInflater.from(parent.context)
  99. .inflate(R.layout.news_view, parent, false) as ConstraintLayout
  100. // set the view's size, margins, paddings and layout parameters
  101. //...
  102. return MyViewHolder(view)
  103. }
  104. // Replace the contents of a view (invoked by the layout manager)
  105. @SuppressLint("SetTextI18n")
  106. override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
  107. val title = holder.itemView.findViewById<TextView>(R.id.news_title)
  108. val text = holder.itemView.findViewById<TextView>(R.id.news_text)
  109. val author = holder.itemView.findViewById<TextView>(R.id.news_author)
  110. val header = holder.itemView.findViewById<TextView>(R.id.news_header)
  111. val date = holder.itemView.findViewById<TextView>(R.id.news_date)
  112. val titleLink = "<a href=\"${dataSet[position].link}\">${dataSet[position].title}</>"
  113. title.text = HtmlCompat.fromHtml(titleLink, HtmlCompat.FROM_HTML_MODE_LEGACY)
  114. title.movementMethod = LinkMovementMethod.getInstance()
  115. header.text = HtmlCompat.fromHtml(dataSet[position].header, HtmlCompat.FROM_HTML_MODE_LEGACY).replace(Regex("\n"), " ")
  116. author.text = "| ${dataSet[position].author}"
  117. val sdf = SimpleDateFormat(newsDisplayDatePattern, Locale.getDefault())
  118. date.text = sdf.format(dataSet[position].date)
  119. TextViewCompat.setAutoSizeTextTypeWithDefaults(author, TextViewCompat.AUTO_SIZE_TEXT_TYPE_UNIFORM)
  120. val spanned = // the trick is to avoid loading images when the adapter is called with preloading.
  121. if (vm.isPreLoadingNews) {
  122. HtmlCompat.fromHtml(
  123. dataSet[position].text,
  124. HtmlCompat.FROM_HTML_MODE_LEGACY)
  125. } else {
  126. HtmlCompat.fromHtml(
  127. dataSet[position].text,
  128. HtmlCompat.FROM_HTML_MODE_LEGACY,
  129. ImageGetter { source ->
  130. val d = LevelListDrawable()
  131. /*
  132. val empty: Drawable? = ContextCompat.getDrawable(c, R.drawable.exo_icon_play)
  133. d.addLevel(0, 0, empty!!)
  134. d.setBounds(0, 0, empty.intrinsicWidth, empty.intrinsicHeight)
  135. */
  136. ImageGetterAsyncTask(c, source, d).execute(text)
  137. d
  138. }, null
  139. )
  140. }
  141. text.text = spanned
  142. text.movementMethod = LinkMovementMethod.getInstance()
  143. }
  144. // Return the size of your dataset (invoked by the layout manager)
  145. override fun getItemCount() = dataSet.size
  146. /*
  147. override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
  148. // create a new view
  149. val view = LayoutInflater.from(parent.context)
  150. .inflate(R.layout.song_view, parent, false) as ConstraintLayout
  151. }
  152. */
  153. }