NewsAdapter.kt 6.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. package fr.forum_thalie.tsumugi.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.forum_thalie.tsumugi.R
  23. import java.io.IOException
  24. import java.io.InputStream
  25. import java.net.URL
  26. import java.text.SimpleDateFormat
  27. import java.util.*
  28. // Using solution found here: https://stackoverflow.com/questions/3758535/display-images-on-android-using-textview-and-html-imagegetter-asynchronously
  29. // but without Picasso (just fetching image by myself.)
  30. class ImageGetterAsyncTask(
  31. private val context: Context,
  32. private val source: String,
  33. private val levelListDrawable: LevelListDrawable
  34. ) :
  35. AsyncTask<TextView?, Void?, Bitmap?>() {
  36. private var t: TextView? = null
  37. override fun doInBackground(vararg params: TextView?): Bitmap? {
  38. t = params[0]
  39. return try {
  40. //Log.d(LOG_CAT, "Downloading the image from: $source")
  41. var k: InputStream? = null
  42. var pic: Bitmap? = null
  43. try {
  44. k = URL(source).content as InputStream
  45. val options = BitmapFactory.Options()
  46. options.inSampleSize = 1/4
  47. // this makes 1/2 of origin image size from width and height.
  48. // it alleviates the memory for API16-API19 especially
  49. pic = BitmapFactory.decodeStream(k, null, options)
  50. k.close()
  51. } catch (e: IOException) {
  52. e.printStackTrace()
  53. } finally {
  54. k?.close()
  55. }
  56. pic
  57. } catch (e: Exception) {
  58. null
  59. }
  60. }
  61. override fun onPostExecute(bitmap: Bitmap?) {
  62. try {
  63. val d: Drawable = BitmapDrawable(context.resources, bitmap)
  64. val size = Point()
  65. (context as Activity).windowManager.defaultDisplay.getSize(size)
  66. // Lets calculate the ratio according to the screen width in px
  67. val multiplier: Int = size.x / bitmap!!.width
  68. //Log.d(LOG_CAT, "multiplier: $multiplier")
  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 * multiplier,
  75. bitmap.height * multiplier
  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
  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("dd MMM yyyy", Locale.getDefault())
  118. date.text = sdf.format(dataSet[position].date)
  119. TextViewCompat.setAutoSizeTextTypeWithDefaults(author, TextViewCompat.AUTO_SIZE_TEXT_TYPE_UNIFORM)
  120. val spanned = HtmlCompat.fromHtml(
  121. dataSet[position].text,
  122. HtmlCompat.FROM_HTML_MODE_LEGACY,
  123. ImageGetter { source ->
  124. val d = LevelListDrawable()
  125. val empty: Drawable? = ContextCompat.getDrawable(c, R.drawable.exo_icon_circular_play)
  126. d.addLevel(0, 0, empty!!)
  127. d.setBounds(0, 0, empty.intrinsicWidth, empty.intrinsicHeight)
  128. ImageGetterAsyncTask(c, source, d).execute(text)
  129. d
  130. }, null
  131. )
  132. text.text = spanned
  133. text.movementMethod = LinkMovementMethod.getInstance()
  134. }
  135. // Return the size of your dataset (invoked by the layout manager)
  136. override fun getItemCount() = dataSet.size
  137. /*
  138. override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
  139. // create a new view
  140. val view = LayoutInflater.from(parent.context)
  141. .inflate(R.layout.song_view, parent, false) as ConstraintLayout
  142. }
  143. */
  144. }