https://kotlinlang.org logo
#android
Title
# android
a

Alin B.

07/11/2018, 1:30 PM
I have a class like class
someClass(val id : String, val imageResourceId: Int)
. Basically I want to set the drawable id as the source of the image resource to show in the app. However, resIds may change upon adding new resources so I end up with a database which hosts wrong ids. One way I can think of is adding the icons in the
assets
folder and user Glide to load from there. Any other thoughts?
g

gildor

07/11/2018, 1:35 PM
But why do you worry about Id changes, Android automatically generate all of them in R.class, so you can use this fields directly and do not worry that I'd will be changed
c

Can Orhan

07/11/2018, 1:36 PM
@gildor From what I understood, the generated ID is being stored. When the build changes the id, the ones in the DB become stale
a

Alin B.

07/11/2018, 1:37 PM
Indeed, I may store the resource name, but then each time I need it, I need to search it.
c

Can Orhan

07/11/2018, 1:37 PM
@Alin B. Sorry - Not sure I understand the concern.
a

Alin B.

07/11/2018, 1:38 PM
I mean each time I want to display it I need to do
resources.getIdentifier(name, "drawable", "your.package.name")
g

gildor

07/11/2018, 1:38 PM
Just cache it, if you need this many times, I still not completely understand your case
1
Do you serialize this value as Can supposed?
a

Alin B.

07/11/2018, 1:40 PM
I am at the point of deciding how to store the value. To better put let me add another example table categories with id, name and icon. The icon is included in the app and I need to decide what to store in the icon field.
I can store "ic_category_one" and then use
getIdentifier
with that name and load it with
Glide
g

gildor

07/11/2018, 1:43 PM
To store value in database?
a

Alin B.

07/11/2018, 1:43 PM
other way is to put it in
assets
and load it with glide `"file:///android_asset/ic_category_one.jpg"
yes, what to store in the db as icon value in order to be easy to retrieve it when I want to show it
g

gildor

07/11/2018, 1:44 PM
I would rather use some custom id for icon and map it to actual reaource on runtime
For example you have 2 types of icon: home and work
c

Can Orhan

07/11/2018, 1:45 PM
^I was thinking the same thing but it can be annoying to maintain something like that.
g

gildor

07/11/2018, 1:46 PM
I would just save this id in database and map this id to actual resource like: when(iconId) { "home" -> R.drawable.ic_home_red_24dp }
a

Alin B.

07/11/2018, 1:47 PM
but in this case I could use
when (category.name)
, no?
g

gildor

07/11/2018, 1:47 PM
Otherwise you can one day decide to change icon (like on ic_dead_star_black_36dp, and of course you want to have proper name for icon not some hardcoded one
Also it's much more flexible, one day you want to have dynamic icona and so on
Yes,. you can use when or even just Map<String, Int>
a

Alin B.

07/11/2018, 1:49 PM
so maybe have a get() for imageResId which has a when based on the
name
g

gildor

07/11/2018, 1:49 PM
To be honest I don't think it's too much tedious, depends on amount of icons of course
But why do you need imageResId than?
a

Alin B.

07/11/2018, 1:50 PM
I don't anymore if I go with your approach, just a getter to return the drawable id I want based on the name
g

gildor

07/11/2018, 1:52 PM
Again, depends on case, for example we have emoju drawables and of course we do not map them all, but we use unicode id of emoji to generate resource I'd and llokup by name
But if you have limited set of icons I would rather use manual mapping
Also you probably have some list of available options in UI, so would be good to convert this list to map of type -> drawable
We actually also use this in case of emoji
a

Alin B.

07/11/2018, 1:55 PM
I am talking about a few icons, 5 maybe. To be sure understand you right, have something like
Copy code
class Category(val id:Int, val name, val imageResId:Int){
    val imageResId:Int
	get()=when(...)
}
pseudo-code I still don't know Kotlin too well 🙂
g

gildor

07/11/2018, 1:59 PM
If categories are not dynamic, just use enum for category and serialize it as enum name, will be type safe, declarative and flexible Also no need to serialize all unnecessary data to database if you already declare it
a

Alin B.

07/11/2018, 2:05 PM
ok, digging enum in kotlin... everything is new to me. This:
Copy code
enum class Category(val name:String){
    HOME("home"),
    WORK("work")
}
g

gildor

07/11/2018, 2:06 PM
Yes, and also property for icon
And store in db just enum name
a

Alin B.

07/11/2018, 2:06 PM
This is a really great answer. Thank you very much!
g

gildor

07/11/2018, 2:06 PM
Kotlin enums implementation almost identical to java, so no real difference
a

Alin B.

07/11/2018, 2:08 PM
How about for a scenario where I have products and the user can pick a generic icon from a set of icons to a new added product. In this case I need to store something in the database as I insert the product
kind of the same really, as icons are in a enum and store the enum name
g

gildor

07/11/2018, 2:08 PM
Also one more good thing about enums is that you can get a full list of possible options and for example iterate them
Yes, the same, just represent each category as item of enum, can be useful not only for icons, but for some other cases (like category config), when user choose category for product use this enum and store to database
Thumb of rule: use enum for any ENUMerable static data. If you have something dynamic than you need something else, can use db to store settings, but for thing like static set of icons I would still use enums
👍 1
a

Alin B.

07/11/2018, 2:21 PM
I did a little coding to get a hold of the idea, here is how I think it could be
Copy code
enum class CategoryType(val id: String, val imageResId: Int) {
    HOME("home", R.id.ic_home),
    WORK("work", R.id.ic_work)
}
then when I use it
Copy code
val categoryType = CategoryType.valueOf(item.dbCategoryValue)

val imageResIdToLoad = categoryType.imageResId
however, I am not sure that I need the
val id
since I can store HOME or WORK in db
c

Can Orhan

07/11/2018, 2:28 PM
Could you get away with not using the id param instead?
Copy code
enum class CategoryType(val id: Int) {
        HOME(R.id.ic_home),
        WORK(R.id.ic_work)
    }
CategoryType.valueOf("HOME").id
a

Alin B.

07/11/2018, 2:30 PM
That what I said above, the id seemed not needed
c

Can Orhan

07/11/2018, 2:30 PM
Ah sorry!
a

Alin B.

07/11/2018, 2:31 PM
No need to, thanks for the code sample.
@gildor, @Can Orhan thank you very much for your time and info. It sure came out a solution which I did not have in mind when asked.
👍 1
😁 1
c

Can Orhan

07/11/2018, 2:33 PM
Happy to help
g

gildor

07/11/2018, 4:19 PM
Also if you use some mapper of db to objects, you can just use enums, probably your mapper can do that automatically. You mentioned Room in one of other threads, you can use enums with room without manual unwrapping them from string
a

Alin B.

07/11/2018, 4:24 PM
Yeah I am using Room
not sure what you mean by without unwrapping
you mean, use in @Query CategoryType as a field?
g

gildor

07/11/2018, 4:29 PM
Sure
If you want to use it as field in some other data, like in your "product", example
a

Alin B.

07/11/2018, 4:34 PM
Awesome, thank you very much for you help.
2 Views