Could a `sealed class` be a good option for an abs...
# android
d
Could a
sealed class
be a good option for an abstract
Fragment
?
Copy code
sealed class BaseFragment: Fragment()

abstract class RootFragment: BaseFragment()
abstract class NestedFragment: BaseFragment()
g
I don't think that it somehow related to sealed classes, not much different from just 2 different abstract classes But I think it's wrong to program fragment nesting information to type, especially using inheritance, because this is completely runtime thing: you cannot prevent adding root fragment to child fragment manager or vice versa. Also it make fragment usage not so flexible
d
Thanks for the answer. Yes you're right, but I'm on a very small app, I'll use those NestedFragment only once and they basically won't have any params, where my old
BaseFragment
has ( had, no
RootFragmant
has ) many, like title, titleColor, etc
That's because I use single activity pattern, so on Fragment changed I'll handle those aspect from the Activity and I just wanted to make stuff clearer than have
BaseFragment
everywhere and 2
Fragment
in my codebase
r
it doesn't need to be sealed.just create a abstract base fragment...
d
Nothing need to be sealed šŸ˜…
g
Yes, but in this case it is not clear how sealed can help, rather it forces you to extend this class without any real reason (so it makes already bad hierarchy of fragments even worse), you can use interface or just runtime check without special subclass for that
d
I donā€™t think an interface is a good idea, because I want to: ā€¢ define some generic behaviours on all my *Fragment*s ā€¢ expose their ā€œparamsā€ externally ( basically I got a Fragment resume callback in my Activity and there Iā€™ll set a toolbar title or an options menu according to the current Fragment param ) ā€¢ Reduce some verbosity, e.g. define a
layoutRes
and inflate the View only in the
BaseFragment
Using an interface would make sense if I want to define a specific behaviour for some Fragments: e.g.
SomeFrag: Fragment(), RotationEnabled
->
if ( fragment is RotationEnabled ) fragment.rotate()
, in that case I wonā€™t care to have a ā€œsolid distinctionā€ between a
RotationEnabled
and a
Fragment
Given a method like this
Copy code
supportFragmentManager.onFragmentResumed { 
        val fragment = it as BaseFragment // I don't really do that in this way, it's just for explanation purpose :D

        fragment.title?.let { title = it }
        toolbar.setTitleTextColor( fragment.titleColor )
        fragment.setHasOptionsMenu( fragment.menuRes != null )
        setBackgroundColor( fragment.backgroundColor ?: getThemeColor( android.R.attr.colorBackground ) )
}
Using an interface Iā€™ll end up in this
Copy code
val fragment = it as BaseFragment
...
toolbar.setTitleTextColor( fragment.titleColor )
fragment.setHasOptionsMenu // Dho! BaseFragment is not a Fragment so it doesn't have this method
( Here Iā€™m referencing to a BaseFragment, cause of my ā€œusualā€ implementation and again for explanation purpose, but Iā€™d have those params only on my RootFragment ofc, Iā€™ll think if I need some on NestedFragment )
g
I think approach in general wrong and sealed class doesnā€™t do it better
fragment.setHasOptionsMenu // Dho! BaseFragment is not a Fragment so it doesnā€™t have this method```
Not sure what you mean, because any fragment has method
setHasOptionsMenu
Of course, I do not suggest you to make interface BaseFragment that doesnā€™t related to Fragment hierachy, I suggest (according to your example) add interface `Rotatable`:
Copy code
interface Rotatable {
   fun rotate()
}
Copy code
if (fragment is Rotatable) {
   fragment.rotate()
}
...
toolbar.setTitleTextColor( fragment.titleColor )
fragment.setHasOptionsMenu(blah) // Yes! This will work anyway!
Reduce some verbosity, e.g. define a
layoutRes
and inflate the View only in the
BaseFragment
But how this related to Nested/Root fragment? Iā€™m not strongly against BaseFragment in general, Iā€™m talking about your case with sealed class
d
( how to quote text? ) you said "if fragment is rotabile... fragment.titleColorRes" but
titleColorRes
is a property of my RootFragmant šŸ˜ All described above is not strictly related to sealed class, sealed class is a side-effect of my current use case. Usually I only use that BaseFragment without nesting Fragment, but now I want a Fragment to have 2 nested Frags and, since nested Frags must NOT have params such title or options menu, I've choose to "transform"
BaseFragment
in
RootFragmant
and use
BaseFragment
as an abstraction layer suitable from boot root Frags and nested Frags and, since I won't other types of Frags, I wanted to make
BaseFragment
"sealed" and I thought to use sealed class instead of an abstract class with a protected constructor. So basically, before: * BaseFragment ( frags behaviors and params such as title color, etc ) after: * BaseFragment ( only common behaviors and params suitable for both types ) * RootFragmant ( params for root Fragments ) * NestedFragment ( actually basically a BaseFragment, maybe will implement behaviors for only nested Fragment,Ike
parentFragment
- i won't do that, just for give an idea )