react-native-navigation的迁移库

ImageLoader.kt 4.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. package com.reactnativenavigation.utils
  2. import android.app.Activity
  3. import android.content.Context
  4. import android.graphics.BitmapFactory
  5. import android.graphics.drawable.BitmapDrawable
  6. import android.graphics.drawable.Drawable
  7. import android.net.Uri
  8. import android.os.StrictMode
  9. import android.view.View
  10. import androidx.core.content.ContextCompat
  11. import com.facebook.react.views.imagehelper.ResourceDrawableIdHelper
  12. import com.reactnativenavigation.R
  13. import java.io.FileNotFoundException
  14. import java.io.IOException
  15. import java.io.InputStream
  16. import java.net.URL
  17. import java.util.*
  18. open class ImageLoader {
  19. interface ImagesLoadingListener {
  20. fun onComplete(drawable: List<Drawable>)
  21. fun onComplete(drawable: Drawable)
  22. fun onError(error: Throwable?)
  23. }
  24. open fun getBackButtonIcon(context: Activity): Drawable? {
  25. val isRTL = context.window.decorView.layoutDirection == View.LAYOUT_DIRECTION_RTL
  26. return ContextCompat.getDrawable(context, if (isRTL) R.drawable.ic_arrow_back_black_rtl_24dp else R.drawable.ic_arrow_back_black_24dp)
  27. }
  28. open fun loadIcon(context: Context, uri: String?): Drawable? {
  29. if (uri == null) return null
  30. try {
  31. return getDrawable(context, uri)
  32. } catch (e: IOException) {
  33. e.printStackTrace()
  34. }
  35. return null
  36. }
  37. open fun loadIcon(context: Context, uri: String, listener: ImagesLoadingListener) {
  38. try {
  39. listener.onComplete(getDrawable(context, uri))
  40. } catch (e: IOException) {
  41. listener.onError(e)
  42. }
  43. }
  44. open fun loadIcons(context: Context, uris: List<String>, listener: ImagesLoadingListener) {
  45. try {
  46. val drawables: MutableList<Drawable> = ArrayList()
  47. for (uri in uris) {
  48. val drawable = getDrawable(context, uri)
  49. drawables.add(drawable)
  50. }
  51. listener.onComplete(drawables)
  52. } catch (e: IOException) {
  53. listener.onError(e)
  54. }
  55. }
  56. @Throws(IOException::class)
  57. private fun getDrawable(context: Context, source: String): Drawable {
  58. var drawable: Drawable?
  59. if (isLocalFile(Uri.parse(source))) {
  60. drawable = loadFile(context, source)
  61. } else {
  62. drawable = loadResource(context, source)
  63. if (drawable == null && context.isDebug()) {
  64. drawable = readJsDevImage(context, source)
  65. }
  66. }
  67. if (drawable == null) throw RuntimeException("Could not load image $source")
  68. return drawable
  69. }
  70. @Throws(IOException::class)
  71. private fun readJsDevImage(context: Context, source: String): Drawable {
  72. val threadPolicy = adjustThreadPolicyDebug(context)
  73. val `is` = openStream(context, source)
  74. val bitmap = BitmapFactory.decodeStream(`is`)
  75. restoreThreadPolicyDebug(context, threadPolicy)
  76. return BitmapDrawable(context.resources, bitmap)
  77. }
  78. private fun isLocalFile(uri: Uri): Boolean {
  79. return FILE_SCHEME == uri.scheme
  80. }
  81. private fun loadFile(context: Context, uri: String): Drawable {
  82. val bitmap = BitmapFactory.decodeFile(Uri.parse(uri).path)
  83. return BitmapDrawable(context.resources, bitmap)
  84. }
  85. private fun adjustThreadPolicyDebug(context: Context): StrictMode.ThreadPolicy? {
  86. var threadPolicy: StrictMode.ThreadPolicy? = null
  87. if (context.isDebug()) {
  88. threadPolicy = StrictMode.getThreadPolicy()
  89. StrictMode.setThreadPolicy(StrictMode.ThreadPolicy.Builder().permitNetwork().build())
  90. }
  91. return threadPolicy
  92. }
  93. private fun restoreThreadPolicyDebug(context: Context, threadPolicy: StrictMode.ThreadPolicy?) {
  94. if (context.isDebug() && threadPolicy != null) {
  95. StrictMode.setThreadPolicy(threadPolicy)
  96. }
  97. }
  98. companion object {
  99. private const val FILE_SCHEME = "file"
  100. private fun loadResource(context: Context, iconSource: String): Drawable? {
  101. return ResourceDrawableIdHelper.getInstance().getResourceDrawable(context, iconSource)
  102. }
  103. @Throws(IOException::class)
  104. private fun openStream(context: Context, uri: String): InputStream? {
  105. return if (uri.contains("http")) remoteUrl(uri) else localFile(context, uri)
  106. }
  107. @Throws(IOException::class)
  108. private fun remoteUrl(uri: String): InputStream {
  109. return URL(uri).openStream()
  110. }
  111. @Throws(FileNotFoundException::class)
  112. private fun localFile(context: Context, uri: String): InputStream? {
  113. return context.contentResolver.openInputStream(Uri.parse(uri))
  114. }
  115. }
  116. }