In Workflow, I'd like my ViewFactory to inject som...
# squarelibraries
d
In Workflow, I'd like my ViewFactory to inject some dependencies (not included in the Rendering) into the View it creates. And so I need to be able to pass arbitrary parameters into the ViewFactory. What's the best way to achieve this?
Extending LayoutRunner with a constructor that accepts more parameters seems to not work.
r
We have dagger create the view factory, and inject it into the activity that sets up workflow layout
d
That sounds good, but I'm stumbling a bit on the "create the view factory" part. If I define a ViewFactory like so:
Copy code
@OptIn(WorkflowUiExperimentalApi::class)
class DiscoverViewFactory(val imageLoader:IImageLoader):ViewFactory<DiscoverRendering> {

	override val type = DiscoverRendering::class

	override fun buildView(
		initialRendering:DiscoverRendering,
		initialViewEnvironment:ViewEnvironment,
		contextForNewView:Context,
		container:ViewGroup?
	):View {
		return DiscoverView(
			imageLoader = imageLoader,
			context = contextForNewView
		)
	}
}
and put an instance of that in the viewRegistry, I'm getting an error saying that
bindShowRendering
was not called
what is
bindShowRendering
exactly?
r
It's an extension function that puts your show rendering function where we can find it for updates. You need to call that it on the view before you return it. Looking for an example...
Just add this:
Copy code
import com.squareup.workflow1.ui.bindShowRendering

		return DiscoverView(
			imageLoader = imageLoader,
			context = contextForNewView
		).apply {
                  bindShowRendering(initialRendering, initialEnv, ::update)
                }
Where
update
is whatever function your view defines to receive fresh instances of the rendering.
grrr, thanks Slack, one sec...
d
ok, so the view (or something) needs to define a function with the signature:
Copy code
(RenderingT, ViewEnvironment) -> Unit
and have the factory do something like
Copy code
@OptIn(WorkflowUiExperimentalApi::class)
class DiscoverViewFactory(val imageLoader:IImageLoader):ViewFactory<DiscoverRendering> {

	override val type = DiscoverRendering::class

	override fun buildView(
		initialRendering:DiscoverRendering,
		initialViewEnvironment:ViewEnvironment,
		contextForNewView:Context,
		container:ViewGroup?
	):View {
		return DiscoverView(
			imageLoader = imageLoader,
			context = contextForNewView
		).apply {
			bindShowRendering(initialRendering, initialViewEnvironment){ ren:DiscoverRendering, env:ViewEnvironment ->
				showRendering(ren, env)
			}
		}
	}
}
?
r
Exactly.
d
I see, thanks!
r
You also might need to add this to that apply block:
Copy code
layoutParams = LayoutParams(MATCH_PARENT, MATCH_PARENT)
d
cool, thanks for the tip
r
Sure thing, thanks for trying it out
d
The idea of a UDF framework that lets me not use Fragments is pretty exciting!
🙂 1