https://kotlinlang.org logo
Title
d

Davide Giuseppe Farella

02/09/2019, 4:39 AM
Could a
sealed class
be a good option for an abstract
Fragment
?
sealed class BaseFragment: Fragment()

abstract class RootFragment: BaseFragment()
abstract class NestedFragment: BaseFragment()
g

gildor

02/09/2019, 6:44 AM
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

Davide Giuseppe Farella

02/09/2019, 11:39 AM
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

rkeazor

02/09/2019, 1:30 PM
it doesn't need to be sealed.just create a abstract base fragment...
d

Davide Giuseppe Farella

02/09/2019, 1:33 PM
Nothing need to be sealed 😅
g

gildor

02/10/2019, 9:10 AM
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

Davide Giuseppe Farella

02/10/2019, 9:51 AM
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
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
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

gildor

02/10/2019, 12:17 PM
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`:
interface Rotatable {
   fun rotate()
}
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

Davide Giuseppe Farella

02/10/2019, 1:13 PM
( 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 )