Using MVP - I have a call that returns for instanc...
# announcements
j
Using MVP - I have a call that returns for instance a number between 1-43, then I need to do something like if it's between 1 and 5 show this image, if it's between 6 and 29 another one, so since in Presenter I can't put anything about R and Android context, how do I let the view know which icon has to show? Because as far as I understand view doesn't have to do any logic. Or for instance, I get a Boolean from API and then from VIEW I want to show an image or another one, I thought about create showWhiteBackground() and showBlackBackground() and then call the correct one, this is ok if the value is between 2, but when it's between 1-43 I can not do something like this 😕
s
We do emit
R.id
and
R.string
, etc from our ViewModels (or Presenters in your case)
j
ViewModels is like a Presenter?
s
The
R
constants are just that, constants. As long as you don’t import Views, Bitmaps, Drawables, Activities, etc into your Presenter source files, it should be good. Those
R
constants just resolve to plain Integers… even in your tests.
j
But I need to do something like : if it's between 1 and 5 show this image R.drawable.whatever
s
E.g. in some of our apps, when the MVP wants to show a string in the UI (Activity/Fragment) to which it is attached, we emit an instance of a class of our own called
StringResource
. Its constructor takes a
R.string
value and a vararg of arguments. Then we have a few extension-functions on
StringResource
somewhere else, tied to the UI, that take a
Context
or a
Fragment
or a
View
to extract a String from that
StringResource
. E.g.
fun Context.getString(stringRes: StringResource) : String = ...
. For drawables, colors, etc, we just emit a simple
Int
, the resource-id
Copy code
val drawable = when {
   1 <= level and level <= 5 -> R.drawable.level_low
    6 <= level and level <= 10 -> R.drawable.level_mid
    else -> R.drawable.level_hight
}

view.showLevel(drawable)
j
Yes I know, but it is ok to use R in presenter?
s
Why not, it is just a constant, an Int
Those
R
constants are not dependent on any Android context/framework. They are auto-generated. Consider them part of your UI-model.
j
Thought I couldn't use R there
But let's see if someone can answer tho the question to hear more examples and options
s
You can. You can use the
R
constants in your unit-tests as well. Compiles fine 🙂
j
I know it compiles, but it's Anti-pattern to use R.drawable and R.string, at least that's what I understood
s
To have a translation in your Activity/Fragment from some other set of constants into constants from the
R
is overkill in my opinion and it adds to much code in your Activities and Fragments that cannot be tested by plain unit-tests.
It’s an anti-pattern to use
View
,
Activity
,
Drawable
,
Application
, etc that are only defined within an Android context. The
R
values are generated by the compiler (apt) and are part of your app as plain constants. You could have written those
R
constants yourself, but the compiler does it for you. 🙂
j
So, if it's this import: import com.name.project.R
without Drawable what happens
s
Do you mean
import com.name.project.R.drawable.*
? This would just import a bunch of
Int
constants. The
drawable
here is just a word, has nothing to do with
Drawable
classes.
j
And what about if I create an Enum which contains the Drawable Int inside?
Is that ok?
s
If you mean by ‘Drawable Int’ the integer constant of a drawable resource, yep, that is fine. You can wrap them in other classes (enums, data classes, etc) that are part of your UI-model.
j
Something like this I mean
Copy code
enum class Color(val rgb: Int) {
        RED(R.drawable.red),
        GREEN(R.drawable.green),
        BLUE(R.drawable.blue)
}
s
If that makes your Presenter code more readable, yes, this looks great to me.
I would not call its property
rgb
, though, since it is not a RGB value. It is a resource-id value.
j
nono, I just changed the values from the documentation
s
And the enum name is
Color
, but the values are
<http://R.drawable.xxx|R.drawable.xxx>
not
R.color.xxxx
j
I just modified the things inside of the ENUMS to show the idea
s
Ah… 🙂 I see, just an example. Be careful with naming though 🙂
j
So anton, to say a number is between 2 numbers is the way you put?
I thought I could use something like in 1..3
Something like this :
Copy code
return when(weatherIcon) {
            in 1..3 -> SomeReturn
            else -> SomeReturn
        }
s
Yup, that will work.
j
so, if weatherIcon is 1 or 3 should join on the first right?
Solved, play.kotlinlang.org is a good tool 😄
💯 1
s
Or just put
fun main() { .... }
in any of your source files and hit the ‘play’ icon shown in the gutter in front of that main function.
l
FYI, there's an #android channel.