I am rendering a form based on JSON response that I fetch from the server.
My use case involves listening to a click from a radio button, toggling the visibility of certain text fields based on the radioButton selection, and refreshing the layout with the visible textView.
The expected output should be to update the same view with the textView now visible, but I'm now seeing the same form twice, first with default state, and second with updated state.
Have I somehow created an entirely new model_
class and passing it to the controller? I just want to change the boolean field of the existing model and update the view.
My Model Class
@EpoxyModelClass(layout = R.layout.layout_panel_input)
abstract class PanelInputModel(
@EpoxyAttribute var panelInput: PanelInput,
@EpoxyAttribute var isVisible: Boolean,
@EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) var context: Context,
@EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) var textChangedListener: InputTextChangedListener,
@EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) var radioButtonSelectedListener: RadioButtonSelectedListener,
@EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) var validationChangedListener: ValidationChangedListener
) : EpoxyModelWithHolder<PanelInputModel.PanelInputHolder>() {
@EpoxyAttribute var imageList = mutableListOf<ImageInput>()
override fun bind(holder: PanelInputHolder) {
val inflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
generateViews(holder, inflater, panelInput.elements) // Generates textViews, radioButtons, etc, based on ElementType enum inside Panel input
}
fun generateRadioButtonView(element: Element) {
// Created a custom listener and calling its function
radioButtonSelectedListener.radioButtonSelected(chip.id, chip.text.toString())
}
fun generateTextView() {
// Show/hide textView based on isVisible value
}
My Controller Class
class FormInputController(
var context: Context,
var position: Int, // Fragment Position in PagerAdapter
var textChangedListener: InputTextChangedListener,
var radioButtonSelectedListener: RadioButtonSelectedListener,
var validationChangedListener: ValidationChangedListener
) : TypedEpoxyController<FormInput>() {
override fun buildModels(data: FormInput?) {
val panelInputModel = PanelInputModel_(
data as PanelInput,
data.isVisible,
context,
textChangedListener,
radioButtonSelectedListener,
validationChangedListener
)
panelInputModel.id(position)
panelInputModel.addTo(this)
}
}
My fragment implements the on radio button checked listener, modifies the formInput.isVisible = true
and calls formInputController.setData(componentList)
Please help me out on this, thanks!
I don't think you are using Epoxy correctly, that's not how it's supposed to be.
R.layout.layout_panel_input
, so there is no need to inflate at all.You should copy this into your project: https://github.com/airbnb/epoxy/blob/master/kotlinsample/src/main/java/com/airbnb/epoxy/kotlinsample/helpers/KotlinEpoxyHolder.kt
And create your holder in this way:
Like so:
When choosing your id, keep in mind that Epoxy will keep track of those and update if the attrs change, so don't use a position, but a unique id that will not get duplicated.