xebia-functional / macroid

A modular functional UI language for Android
527 stars 37 forks source link

Adding bricks in subclasses/subtraits #81

Closed tymm closed 8 years ago

tymm commented 8 years ago

I have a base trait for my views in which I call setContentView to set a layout. Then I have several subtraits that extend from the base trait in order to add certain layout elements.

Base trait

trait View[V <: IView, M <: AbstractViewModel[V]]
        extends ViewModelBaseActivity[V, M]
        with Contexts[Activity] { self: V ⇒
    def layout: Ui[android.view.ViewGroup]

    def onCreateView( state: Bundle ): Unit

    override def onCreate( state: Bundle ) = {
        super.onCreate( state )

        onCreateView( state )

        setContentView {
            getUi{
                layout
            }
        }

        setModelView( self )
    }
}

Subtrait:

trait Coordinator[V <: IView, M <: AbstractViewModel[V]]
        extends View[V, M]
        with Contexts[Activity] { self: V ⇒
    val coordinator = l[CoordinatorLayout]()

    override def onCreateView( state: Bundle ) = {
        coordinator <~ addViews(
            Seq(
                w[TextView] <~ text( "test" )
            )
        )
    }

    override val layout = coordinator
}

However when I create a new view which extends the Coordinator subtrait, there is no TextView displaying "test". It works when I do the layout manipulation directly in the base trait.

stanch commented 8 years ago

Hey,

You need to wrap coordinator <~ addViews(...) into getUi :)

tymm commented 8 years ago

Ah, I need to wrap it into getUi so the tweak happens right away, right?

Unfortunately it doesn't help.

javipacheco commented 8 years ago

Maybe you should wrap it into runUi

runUi(coordinator <~ addViews(Seq(w[TextView] <~ text( "test" ))))

If you are using the github version, you should call to run

(coordinator <~ addViews(Seq(w[TextView] <~ text( "test" )))).run

I hope that this helps you

tymm commented 8 years ago

Thank you for the hint. Unfortunately this also doesn't help.

tymm commented 8 years ago

I just did some more testing and it turns out I can't even do the following (which makes me think that it maybe has to do something with the ViewModel framework I use).

trait View[V <: IView, M <: AbstractViewModel[V]]
        extends ViewModelBaseActivity[V, M]
        with Contexts[Activity] { self: V ⇒
    val layout = l[CoordinatorLayout]()

    def onCreateView( state: Bundle ): Unit

    override def onCreate( state: Bundle ) = {
        super.onCreate( state )

        onCreateView( state )

        runUi {
            layout <~ addViews(
                Seq(
                    w[TextView] <~ text( "test" )
                )
            )
        }

        setContentView {
            getUi{
                layout
            }
        }

        setModelView( self )
    }
}

It only works if I manipulate the ViewGroup right away like val layout = l[CoordinatorLayout]() <~ addViews(...)

pfn commented 8 years ago

You're misusing layout, it is not mutable. It is a Ui[CoordinatorLayout], not a widget you can mutate. It is effectively like a reader or IO monad

On Sun, Mar 27, 2016, 8:23 PM Timm Schäuble notifications@github.com wrote:

I just did some more testing and it turns out I can't even do the following (which makes me think that it maybe has to do something with the ViewModel framework I use).

trait View[V <: IView, M <: AbstractViewModel[V]] extends ViewModelBaseActivity[V, M] with Contexts[Activity] { self: V ⇒ val layout = l[CoordinatorLayout]()

def onCreateView( state: Bundle ): Unit

override def onCreate( state: Bundle ) = {
    super.onCreate( state )

    onCreateView( state )

    runUi {
        layout <~ addViews(
            Seq(
                w[TextView] <~ text( "test" )
            )
        )
    }

    setContentView {
        getUi{
            layout
        }
    }

    setModelView( self )
}

}

It only works if I manipulate the ViewGroup right away like val layout = l[CoordinatorLayout]() <~ addViews(...)

— You are receiving this because you are subscribed to this thread. Reply to this email directly or view it on GitHub https://github.com/47deg/macroid/issues/81#issuecomment-202217228

tymm commented 8 years ago

@pfn but it says the following in the Bricks section of the Macroid guide?

You can add children to an empty layout later by doing layout <~ addViews(button, textView, ...)

pfn commented 8 years ago

Any <~ returns a new Ui, you must use the new value going forward. When all is said and done after composing all <~ you must getUi on the final value

On Sun, Mar 27, 2016, 8:44 PM Timm Schäuble notifications@github.com wrote:

@pfn https://github.com/pfn but it says the following in the Bricks section of the Macroid guide?

You can add children to an empty layout later by doing layout <~ addViews(button, textView, ...)

— You are receiving this because you were mentioned.

Reply to this email directly or view it on GitHub https://github.com/47deg/macroid/issues/81#issuecomment-202220146

tymm commented 8 years ago

Thanks @pfn. That did the trick. However using Macroid's slots was what solved my issue in the end.