From 8d7d3174aa064132faca8f6b9c99b42b5933a82d Mon Sep 17 00:00:00 2001 From: davidoskky Date: Sun, 26 Mar 2023 11:12:01 +0000 Subject: [PATCH] chore: replace textDrawable library (#136) ## Types of changes - [x] I have read the **CONTRIBUTING** document. - [x] My code follows the code style of this project. - [ ] I have updated the documentation accordingly. - [ ] I have added tests to cover my changes. - [x] All new and existing tests passed. - [x] This is **NOT** translation related. This closes issue #120 Removed the dependency `com.amulyakhare.textdrawable` and slightly simplified the logic required to set circular images. Co-authored-by: davidoskky Reviewed-on: https://gitea.amine-louveau.fr/Louvorg/ReaderForSelfoss-multiplatform/pulls/136 Co-authored-by: davidoskky Co-committed-by: davidoskky --- androidApp/build.gradle.kts | 1 - .../android/adapters/ItemCardAdapter.kt | 17 +---- .../android/adapters/ItemListAdapter.kt | 21 ++----- .../android/adapters/SourcesListAdapter.kt | 19 ++---- .../android/utils/CircleImageView.kt | 62 +++++++++++++++++++ .../android/utils/glide/GlideUtils.kt | 21 ++----- androidApp/src/main/res/layout/card_item.xml | 2 +- .../src/main/res/layout/circle_image_view.xml | 26 ++++++++ androidApp/src/main/res/layout/list_item.xml | 2 +- .../src/main/res/layout/source_list_item.xml | 2 +- androidApp/src/main/res/values/styles.xml | 6 ++ 11 files changed, 114 insertions(+), 65 deletions(-) create mode 100644 androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/utils/CircleImageView.kt create mode 100644 androidApp/src/main/res/layout/circle_image_view.xml diff --git a/androidApp/build.gradle.kts b/androidApp/build.gradle.kts index 40983fb..2435ea6 100644 --- a/androidApp/build.gradle.kts +++ b/androidApp/build.gradle.kts @@ -142,7 +142,6 @@ dependencies { // Material-ish things implementation("com.ashokvarma.android:bottom-navigation-bar:2.2.0") - implementation("com.amulyakhare:com.amulyakhare.textdrawable:1.0.1") // glide kapt("com.github.bumptech.glide:compiler:4.15.0") diff --git a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/adapters/ItemCardAdapter.kt b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/adapters/ItemCardAdapter.kt index f21bd77..11f6f62 100644 --- a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/adapters/ItemCardAdapter.kt +++ b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/adapters/ItemCardAdapter.kt @@ -9,10 +9,9 @@ import android.widget.ImageView.ScaleType import androidx.recyclerview.widget.RecyclerView import bou.amine.apps.readerforselfossv2.android.R import bou.amine.apps.readerforselfossv2.android.databinding.CardItemBinding -import bou.amine.apps.readerforselfossv2.android.model.toTextDrawableString import bou.amine.apps.readerforselfossv2.android.utils.LinkOnTouchListener import bou.amine.apps.readerforselfossv2.android.utils.glide.bitmapCenterCrop -import bou.amine.apps.readerforselfossv2.android.utils.glide.circularBitmapDrawable +import bou.amine.apps.readerforselfossv2.android.utils.glide.circularDrawable import bou.amine.apps.readerforselfossv2.android.utils.openInBrowserAsNewTask import bou.amine.apps.readerforselfossv2.android.utils.openItemUrl import bou.amine.apps.readerforselfossv2.android.utils.shareLink @@ -22,8 +21,6 @@ import bou.amine.apps.readerforselfossv2.service.AppSettingsService import bou.amine.apps.readerforselfossv2.utils.getHtmlDecoded import bou.amine.apps.readerforselfossv2.utils.getIcon import bou.amine.apps.readerforselfossv2.utils.getThumbnail -import com.amulyakhare.textdrawable.TextDrawable -import com.amulyakhare.textdrawable.util.ColorGenerator import com.bumptech.glide.Glide import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers @@ -38,7 +35,6 @@ class ItemCardAdapter( override val updateItems: (ArrayList) -> Unit ) : ItemsAdapter() { private val c: Context = app.baseContext - private val generator: ColorGenerator = ColorGenerator.MATERIAL private val imageMaxHeight: Int = c.resources.getDimension(R.dimen.card_image_max_height).toInt() @@ -83,16 +79,9 @@ class ItemCardAdapter( } if (itm.getIcon(repository.baseUrl).isEmpty()) { - val color = generator.getColor(itm.title.getHtmlDecoded()) - - val drawable = - TextDrawable - .builder() - .round() - .build(itm.title.getHtmlDecoded().toTextDrawableString(), color) - binding.sourceImage.setImageDrawable(drawable) + binding.sourceImage.setBackgroundAndText(itm.sourcetitle.getHtmlDecoded()) } else { - c.circularBitmapDrawable(itm.getIcon(repository.baseUrl), binding.sourceImage) + c.circularDrawable(itm.getIcon(repository.baseUrl), binding.sourceImage) } } } diff --git a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/adapters/ItemListAdapter.kt b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/adapters/ItemListAdapter.kt index bbd53c2..c557b10 100644 --- a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/adapters/ItemListAdapter.kt +++ b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/adapters/ItemListAdapter.kt @@ -7,10 +7,8 @@ import android.view.ViewGroup import androidx.recyclerview.widget.RecyclerView import bou.amine.apps.readerforselfossv2.android.R import bou.amine.apps.readerforselfossv2.android.databinding.ListItemBinding -import bou.amine.apps.readerforselfossv2.android.model.toTextDrawableString import bou.amine.apps.readerforselfossv2.android.utils.LinkOnTouchListener -import bou.amine.apps.readerforselfossv2.android.utils.glide.bitmapCenterCrop -import bou.amine.apps.readerforselfossv2.android.utils.glide.circularBitmapDrawable +import bou.amine.apps.readerforselfossv2.android.utils.glide.circularDrawable import bou.amine.apps.readerforselfossv2.android.utils.openItemUrl import bou.amine.apps.readerforselfossv2.model.SelfossModel import bou.amine.apps.readerforselfossv2.repository.Repository @@ -18,8 +16,6 @@ import bou.amine.apps.readerforselfossv2.service.AppSettingsService import bou.amine.apps.readerforselfossv2.utils.getHtmlDecoded import bou.amine.apps.readerforselfossv2.utils.getIcon import bou.amine.apps.readerforselfossv2.utils.getThumbnail -import com.amulyakhare.textdrawable.TextDrawable -import com.amulyakhare.textdrawable.util.ColorGenerator import org.kodein.di.DI import org.kodein.di.android.closestDI import org.kodein.di.instance @@ -29,7 +25,6 @@ class ItemListAdapter( override var items: ArrayList, override val updateItems: (ArrayList) -> Unit ) : ItemsAdapter() { - private val generator: ColorGenerator = ColorGenerator.MATERIAL private val c: Context = app.baseContext override val di: DI by closestDI(app) @@ -56,20 +51,12 @@ class ItemListAdapter( if (itm.getThumbnail(repository.baseUrl).isEmpty()) { if (itm.getIcon(repository.baseUrl).isEmpty()) { - val color = generator.getColor(itm.title.getHtmlDecoded()) - - val drawable = - TextDrawable - .builder() - .round() - .build(itm.title.getHtmlDecoded().toTextDrawableString(), color) - - binding.itemImage.setImageDrawable(drawable) + binding.itemImage.setBackgroundAndText(itm.sourcetitle.getHtmlDecoded()) } else { - c.circularBitmapDrawable(itm.getIcon(repository.baseUrl), binding.itemImage) + c.circularDrawable(itm.getIcon(repository.baseUrl), binding.itemImage) } } else { - c.bitmapCenterCrop(itm.getThumbnail(repository.baseUrl), binding.itemImage) + c.circularDrawable(itm.getThumbnail(repository.baseUrl), binding.itemImage) } } } diff --git a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/adapters/SourcesListAdapter.kt b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/adapters/SourcesListAdapter.kt index 2eba4c1..731ec51 100644 --- a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/adapters/SourcesListAdapter.kt +++ b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/adapters/SourcesListAdapter.kt @@ -10,17 +10,14 @@ import android.widget.Button import android.widget.Toast import androidx.constraintlayout.widget.ConstraintLayout import androidx.recyclerview.widget.RecyclerView -import bou.amine.apps.readerforselfossv2.android.UpsertSourceActivity import bou.amine.apps.readerforselfossv2.android.R +import bou.amine.apps.readerforselfossv2.android.UpsertSourceActivity import bou.amine.apps.readerforselfossv2.android.databinding.SourceListItemBinding -import bou.amine.apps.readerforselfossv2.android.model.toTextDrawableString -import bou.amine.apps.readerforselfossv2.android.utils.glide.circularBitmapDrawable +import bou.amine.apps.readerforselfossv2.android.utils.glide.circularDrawable import bou.amine.apps.readerforselfossv2.model.SelfossModel import bou.amine.apps.readerforselfossv2.repository.Repository import bou.amine.apps.readerforselfossv2.utils.getHtmlDecoded import bou.amine.apps.readerforselfossv2.utils.getIcon -import com.amulyakhare.textdrawable.TextDrawable -import com.amulyakhare.textdrawable.util.ColorGenerator import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch @@ -34,7 +31,6 @@ class SourcesListAdapter( private val items: ArrayList ) : RecyclerView.Adapter(), DIAware { private val c: Context = app.baseContext - private val generator: ColorGenerator = ColorGenerator.MATERIAL private lateinit var binding: SourceListItemBinding override val di: DI by closestDI(app) @@ -49,16 +45,9 @@ class SourcesListAdapter( val itm = items[position] if (itm.getIcon(repository.baseUrl).isEmpty()) { - val color = generator.getColor(itm.title.getHtmlDecoded()) - - val drawable = - TextDrawable - .builder() - .round() - .build(itm.title.getHtmlDecoded().toTextDrawableString(), color) - binding.itemImage.setImageDrawable(drawable) + binding.itemImage.setBackgroundAndText(itm.title.getHtmlDecoded()) } else { - c.circularBitmapDrawable(itm.getIcon(repository.baseUrl), binding.itemImage) + c.circularDrawable(itm.getIcon(repository.baseUrl), binding.itemImage) } if (!itm.error.isNullOrBlank()) { diff --git a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/utils/CircleImageView.kt b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/utils/CircleImageView.kt new file mode 100644 index 0000000..afe81ce --- /dev/null +++ b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/utils/CircleImageView.kt @@ -0,0 +1,62 @@ +package bou.amine.apps.readerforselfossv2.android.utils + +import android.content.Context +import android.graphics.drawable.GradientDrawable +import android.util.AttributeSet +import android.view.LayoutInflater +import android.view.View +import android.widget.RelativeLayout +import android.widget.TextView +import bou.amine.apps.readerforselfossv2.android.R +import bou.amine.apps.readerforselfossv2.android.model.toTextDrawableString +import com.google.android.material.imageview.ShapeableImageView +import kotlin.math.abs + +class CircleImageView @JvmOverloads constructor( + context: Context, + attrs: AttributeSet? = null, + defStyleAttr: Int = 0 +) : RelativeLayout(context, attrs, defStyleAttr) { + val view: View + val imageView: ShapeableImageView + val textView: TextView + + private val colorScheme = listOf( + -0x1a8c8d, + -0xf9d6e, + -0x459738, + -0x6a8a33, + -0x867935, + -0x9b4a0a, + -0xb03c09, + -0xb22f1f, + -0xb24954, + -0x7e387c, + -0x512a7f, + -0x759b, + -0x2b1ea9, + -0x2ab1, + -0x48b3, + -0x5e7781, + -0x6f5b52 + ) + + init { + view = LayoutInflater.from(context).inflate(R.layout.circle_image_view, this, true) + imageView = view.findViewById(R.id.circleImage) + textView = view.findViewById(R.id.circleText) + } + + fun setBackgroundAndText(text: String) { + val circleDrawable = GradientDrawable() + val color = colorFromIdentifier(text) + circleDrawable.setColor(color) + imageView.setImageDrawable(circleDrawable) + + textView.text = text.toTextDrawableString() + } + + private fun colorFromIdentifier(key: String): Int { + return colorScheme[abs(key.hashCode()) % colorScheme.size] + } +} \ No newline at end of file diff --git a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/utils/glide/GlideUtils.kt b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/utils/glide/GlideUtils.kt index 5d91e62..ead2bec 100644 --- a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/utils/glide/GlideUtils.kt +++ b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/utils/glide/GlideUtils.kt @@ -3,10 +3,9 @@ package bou.amine.apps.readerforselfossv2.android.utils.glide import android.content.Context import android.graphics.Bitmap import android.widget.ImageView -import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory +import bou.amine.apps.readerforselfossv2.android.utils.CircleImageView import com.bumptech.glide.Glide import com.bumptech.glide.request.RequestOptions -import com.bumptech.glide.request.target.BitmapImageViewTarget import java.io.ByteArrayInputStream import java.io.ByteArrayOutputStream import java.io.InputStream @@ -18,21 +17,13 @@ fun Context.bitmapCenterCrop(url: String, iv: ImageView) = .apply(RequestOptions.centerCropTransform()) .into(iv) -fun Context.circularBitmapDrawable(url: String, iv: ImageView) = +fun Context.circularDrawable(url: String, view: CircleImageView) { + view.textView.text ="" + Glide.with(this) - .asBitmap() .load(url) - .apply(RequestOptions.centerCropTransform()) - .into(object : BitmapImageViewTarget(iv) { - override fun setResource(resource: Bitmap?) { - val circularBitmapDrawable = RoundedBitmapDrawableFactory.create( - resources, - resource - ) - circularBitmapDrawable.isCircular = true - iv.setImageDrawable(circularBitmapDrawable) - } - }) + .into(view.imageView) +} fun getBitmapInputStream(bitmap:Bitmap,compressFormat: Bitmap.CompressFormat): InputStream { val byteArrayOutputStream = ByteArrayOutputStream() diff --git a/androidApp/src/main/res/layout/card_item.xml b/androidApp/src/main/res/layout/card_item.xml index 329b68e..b153220 100644 --- a/androidApp/src/main/res/layout/card_item.xml +++ b/androidApp/src/main/res/layout/card_item.xml @@ -39,7 +39,7 @@ app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/itemImage"> - + + + + + + diff --git a/androidApp/src/main/res/layout/list_item.xml b/androidApp/src/main/res/layout/list_item.xml index 8e36b3b..9b66604 100644 --- a/androidApp/src/main/res/layout/list_item.xml +++ b/androidApp/src/main/res/layout/list_item.xml @@ -5,7 +5,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content"> - - @null true + + +