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