Repository navigation
Why isn't Balloon open?
#849
Replies: 3 comments
|
Because modern and clean code should always favor composition over inheritance. I would suggest looking into different creation patterns. |
|
As the previous commenter noted, // A factory that auto-generates a preference name from the call-site class
fun balloonFor(owner: Any, context: Context, block: Balloon.Builder.() -> Unit): Balloon {
return Balloon.Builder(context)
.setPreferenceName(owner::class.java.canonicalName)
.apply(block)
.build()
}Usage — as clean as subclassing: object FooBalloon {
fun build(context: Context) = balloonFor(this, context) {
setText("Hello from Foo")
setTextSize(14f)
setWidthRatio(0.6f)
}
}
object BarBalloon {
fun build(context: Context) = balloonFor(this, context) {
setText("Hello from Bar")
setBackgroundColorResource(R.color.bar_color)
}
}Each In Compose, the same pattern works with @Composable
fun rememberFooBalloon(): BalloonWindow {
return rememberBalloonBuilder {
setPreferenceName("my.app.FooBalloon") // or a const
setText("Hello from Foo")
}
}The |
|
A factory can give you the same per-tooltip defaults, but I would make the persistence identity explicit rather than derive it from For the 1.x View API, for example: enum class AppTip(val preferenceKey: String) {
EDIT_PROFILE("tip.edit_profile.v1"),
EXPORT("tip.export.v1"),
}
fun createAppTip(
context: Context,
tip: AppTip,
configure: Balloon.Builder.() -> Unit,
): Balloon = Balloon.Builder(context)
.setPreferenceName(tip.preferenceKey)
.setShowCounts(1)
.apply(configure)
.build()You manage the IDs centrally, and callers only choose a tip and customize its content. Bumping the explicit version is also a deliberate way to show a substantially revised tip again. Create the actual balloon in the UI owner's lifecycle; the singleton can describe the tip, without holding a window or Activity context. There is also a version caveat in the earlier Compose example: |
Uh oh!
There was an error while loading. Please reload this page.
Why isn't
Balloonan open class?This question is prompted by an experiment I'm doing. I anticipate having many balloons in the app, and using the "Persistence" feature to only show each one once.
For that to work I need to give each balloon its own preference name.
Having to create and manage each preference name feels like very tedious work, so I thought I should be able to:
Balloonsubclass for my app that sets various defaults, and overridespreferenceNameto returnthis::class.java.canonicalname. This ensures that each subclass of that gets a sensible preference name.Something like this:
This fails at the first hurdle, because
Balloonis final, and can't be subclassed from. It also doesn't implement an interface, so I can't implement that interface in myAppBalloon, and delegate to an underlying implementation either.All reactions