Closed nschwermann closed 7 years ago
You can get a content View
in Android.
http://stackoverflow.com/questions/5273436/how-to-get-activitys-content-view
These solutions all require a known id to be set and have the function call overhead of finding the view by that id. Also, without testing it looks like most of these solutions would return the parent of my layout rather than the root of my layout.
Knowing the id wouldn't be horrible if we had some good syntax for generating a known id. ie @+id/
The only reason I should ever need an id is when using something like RelativeLayout that requires it. In that case generating an id from kotlin is fine and easy because we can just say id = genId() and never need to know or care about what that id was.
On Jun 21, 2015 5:50 AM, "Yan Zhulanow" notifications@github.com wrote:
You can get a content View in Android.
http://stackoverflow.com/questions/5273436/how-to-get-activitys-content-view
— Reply to this email directly or view it on GitHub https://github.com/JetBrains/anko/issues/66#issuecomment-113884677.
That gives me an idea. Perhaps a global id generator class could be useful in this library. You could create ids with an overloaded operator like this.
id = Id + "textview"
The + operator should check an inner map for an id that already matches "textview" to reuse or create a new one store it in the map and return the id.
Then in kotlin would it be possible to expose ids by keys like this?
//shows up automatically now that we have called Id + "textview"
Id.textview : Int
Ok well this isn't exactly as handy as I originally thought. I didn't realize you could just do this.
var layout : FrameLayout by Delagates.notNull()
var toolbar : Toolbar by Delagates.notNull()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
layout = frameLayout {
toolbar = toolBar{}
}
}
I have been thinking about implementing a "id generator" some time, but now it is unclear where should generator cache live.
The most appropriate candidate is UiHelper
, though there are many questions to find answers for.
I think the id generator would need to be some kind of statically generated class, unless there is a way to expose mutable map keys as properties in kotlin.
On Tue, Jun 23, 2015 at 2:00 PM, Yan Zhulanow notifications@github.com wrote:
I have been thinking about implementing a "id generator" some time, but now it is unclear where should generator cache live.
The most appropriate candidate is UiHelper, though there are many questions to find answers for.
— Reply to this email directly or view it on GitHub https://github.com/JetBrains/anko/issues/66#issuecomment-114608911.
Nathan Schwermann 785-312-0080
@yanex I did this in an application I was working on, but being paranoid about id collisions I ended up sticking to defining IDs in an XML resource instead. I was hoping Kotlin had some sort of sugar for this akin to Ruby Symbols.
@EddieRingle you are guaranteed not to collide with this. Found on gist https://gist.github.com/schwiz/0152caee426e247f90ce
private object ViewCounter {
private val viewCounter = AtomicInteger(1)
public fun generateViewId(): Int {
while (true) {
val result = viewCounter.get()
// aapt-generated IDs have the high byte nonzero; clamp to the range under that.
var newValue = result + 1
if (newValue > 16777215) newValue = 1 // Roll over to 1, not 0.
if (viewCounter.compareAndSet(result, newValue)) {
return result
}
}
}
}
fun View.generateViewIdCompat(): Int {
if (android.os.Build.VERSION.SDK_INT >= 19)
return View.generateViewId()
else
return ViewCounter.generateViewId()
}
@schwiz That's very similar to the generator I wrote.
I'm not worried about colliding with IDs from the same generator, but more paranoid about colliding with IDs generated from XML resources. Of course, I use the term "paranoid" because the integers generated in the R class begin at 0x7f000000 and my worrying about colliding with those IDs is crazy. :)
Still, it'd be nice if this was baked into the language runtime (again, like Ruby symbols).
@EddieRingle Yes that is what I'm trying to say, this function clamps the generated ids to be lower than what aapt generates. Its backported from kitkat.
@schwiz I know. I'm more or less just complaining that Kotlin doesn't have sugar for this, that's all. :)
I see. Can you give an example? I'm not familiar with ruby. On Jun 26, 2015 4:53 PM, "Eddie Ringle" notifications@github.com wrote:
@schwiz https://github.com/schwiz I know. I'm more or less just complaining that Kotlin doesn't have sugar for this, that's all. :)
— Reply to this email directly or view it on GitHub https://github.com/JetBrains/anko/issues/66#issuecomment-115900838.
The problem with referencing Views from inside the DSL can be solved by using lateinit var
properties.
Some View id generator would be very handy, though it's not clear how it could be done without writing the Kotlin compiler plugin.
I mark the issue as "closed". Please create the new issue if you still have any troubles.
The problem: To me there was no apparent way to get references to the root view of DSL scripts. So I thought of this way to sort of mimic the framework setContent api and get us a reference to our DSL root. I'm new to kotlin and anko so feedback is much appreciated.
The solution:
usage