Is there any alternative to Anko? I can’t justify ...
# anko
r
Is there any alternative to Anko? I can’t justify starting a new app without androidx...
p
r
I’m using that, I was talking more about the view DSL part of Anko
p
l
@ribesg Look for the Views DSL module in Splitties. Also, if you encounter any issue, you have English and French support here on Slack 😉
r
Oh, I saw that but forgot about it, thanks for linking it again, I’ll take a look
@louiscad do I need to do something for it to work with AndroidX ?
l
@ribesg You need to use the 3.0.0+ version that I currently marked as alpha because some modules could change a bit
r
Oh, ok. Thanks
@louiscad do you know if the Views DSL IDE Preview is supposed to work in IDEA?
l
I remember about a reported bug in AS preview that has been fixed since then, but it probably made it to IntelliJ and the fix may be later down the road in an upcoming release. But before drawing conclusions, make sure you executed compileDebugKotlin for the module and attempted to refresh the preview.
@ribesg Also, on my side, it works in AS 3.5 Canary
r
Yep, I did execute the
compileDebugKotlin
task multiple times and tried to close and reopen the file / the project / IDEA, but it doesn’t seem to work
Note that it’s not super important for me as I never got it to work with Anko either, so I’m used to not having it. I’m also working on mpp libs and iOS apps so I already use IDEA, AppCode and XCode, it’s already too much so I’m not going to add Android Studio to the mix 😛
l
@ribesg You can click on the exclamation mark, the last icon in the preview toolbar, to see the root cause of the error, it may be caused by your code, a bad reference or even a typo in the xml
r
@louiscad It says there’s no issues
l
@ribesg Which IDEA version are you on?
r
The latest non-EAP one, but wait I re-run
compileDebugKotlin
and forced refreshed and there’s an error now: https://gist.github.com/Ribesg/f5d502d35110c4dbefc9e10f976a8f77
@louiscad I invalidated cache, restarted, and can no longer reproduce the issue, the preview works!
l
Good news!
b
@ribesg The safest solution I’ve found so far is to build your own DSL by extending ViewGroup. It is not something big nor complicated to build, it is also easy to maintain. Also I’ve seen many view DSL and they all have their downsides, making your own would allow you to have one that fits your needs
l
@Benoît Did you try Splitties Views DSL? I'm curious what downsides you found that you could avoid by making your own DSL.
b
Hey Louis ! Yes I did after our conversation last time, I don’t remember much but I think that my issue with it was that you have to call addView all the time, it’s not automatically added to the ViewGroup you’re on. Not sure though, it’s been a while and as I said I just found it easier to come up with my own, as it’s really easy to make one.
r
That’s an issue I agree with, I prefer the way Anko did it. This
Copy code
add(
            textView {
                text = "Test"
            },
            lParams {
                ...
            }
        )
is less readable than this
Copy code
textView {
            text = "Test"
        }.lparams {
            ...
        }
but I think I also understand why @louiscad made that choice. I think the idea is to separate the view itself, which you define somewhere else (a local property, a local function, whatever) and the layout params of that view in it’s container.
b
@ribesg here’s an example of a ViewDsl I’ve built, do not use it, it’s not maintained or anything but it can give you an idea on how to make your own. https://github.com/benoitthore/Enamel/tree/master/EnamelAndroid/src/main/java/com/thorebenoit/enamel/android/dsl Also I understand why Splitties does it that way but my solution to this problem was to have the ViewGroup classes being “buildable” from Context. Here is how I’ve done it: https://github.com/benoitthore/Enamel/blob/master/EnamelAndroid/src/main/java/com/thorebenoit/enamel/android/dsl/views/layoutCreation.kt
r
Unfortunately I don’t have time to maintain such thing, and my other alternative is to create the view with basic code, so I’m just going to use Splitties anyway. It’s a little different than Anko but it’s very well made and very well documented!
l
@ribesg The way anko did it had a major drawback: it needed a subclass for every combination of
View
and
ViewGroup.LayoutParams
, which made the library more heavyweight and didn't scale well with custom Views (including from third parties or Material Components). Also, it would implictly add the view to the current
ViewGroup
, which was often an error if you did not specify the layout params. In your "more readable" example, the fact that the
textView
is added is implicit, so of course, missing explictedness is quicker to read, but it can also be slower to understand at scale because you have to guess or remember.
r
What if
.lparams
adds the view to the parent? It’s an obscure behavior, but not really more obscure than what Anko does
b
@ribesg That could be a solution, as I said, there’s many ways of implementing it and they all have they up/downsides One thing we can all agree on though, is that extending the
viewgroups
is a terrible idea
@louiscad Adding the view to the current ViewGroup is what XML does which is why I didn’t feel like it was an issue. But once again, there’s many ways of doing it, it’s a matter of personal preferences
l
@ribesg Then it can be perceived as less implicit, but you still need to write code for every combination for every
View
and
ViewGroup.LayoutParams
. This is a mutliplication, and multipying the amount of code one needs to write doesn't scale well, and it bloats the final app. In other words, that would still have the major drawback of Anko's approach.
👍 1
@Benoît But xml mixes layout params with view attributes, which is not possible in typesafe Kotlin. My preference leans towards efficiency of resulting code, and efficiency of the developer (writing and reading the code). If a solution can introduce more efficiency in one of these areas without a major drawback, I'm all in.
b
My solution was to let the developer add the wrong layout parameters if not paying attention, just like it is possible if you’d build the view without a DSL, by doing this:
Copy code
inline fun <T : View> T.frameLayoutLP(
    width: Int = matchParent,
    height: Int = matchParent,
    init: FrameLayout.LayoutParams.() -> Unit = {}
): T {
    layoutParams = FrameLayout.LayoutParams(width, height).apply(init)
    return this
}
r
Right now I’m used to the Anko way so I have my
override val root = constraintLayout {
and then a lot of
add
blocks under it, which is kinda hard to read, I just need to get used to the correct way of writing `Ui`s... but what is the correct way? @louiscad is there no problem having local properties keeping references to subviews in my
Ui
?
l
BTW, Splitties Views DSL (for Android) is just the start. My ultimate goal is to move away from Android's View framework as much as possible, dealing mostly with interfaces and functions (implemented in Android's View or other platform native way of displaying UI controls) for my day to day UIs. This is hardly possible with xml, but with code, and coroutines, there's definitely possibilities.
@ribesg There's no problem in keeping additional references to some views in your
Ui
implementation, there's already a strong reference to it (
root
). I also have a lot of
add
calls referencing properties (of type
View
) with
lParams { ... }
in it.
s
r
@louiscad
dealing mostly with interfaces and functions (implemented in Android's View or other platform native way of displaying UI controls)
How do you envision this? I was thinking of having class hierarchy replicating Android View classes and also implementing needed interfaces, but you explicitly mention above that you don't consider this solution acceptable. As a side note, if you see at least some people using your library, it may be logical to create #splitties for it :)
l
@r4zzz4k View hierarchies APIs have different structures across platforms. On Android, you need a contextual
Context
to create any
View
or access resources. On iOS, you don't, and any
View
may have subViews, while on Android, it's only possible for
ViewGroup
subclasses. So the solution is to move away from the widgets when defining the user interfaces, and using
interface
for that. I already do this even though I'm not really multiplatform yet. Splitties in its current form helps me to implement those `interface`s I create for the Android platform. At some point, I'd like to define platform agnostic types for two values controls (implemented by Switches, CheckBoxes, toggles, etc), values selection with limited count controls (implemented by lists, dropdowns, etc), and other kinds of scenarios, where you'd care about input values, ouput values, and what implementation you pick, that'd be a one line change to swap it for another implementation.
@r4zzz4k Great suggestion for the channel, I just created it: #splitties
r
Cool, moving there.
146 Views