首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >AirBnb Epoxy视图被复制,而不是替换

AirBnb Epoxy视图被复制,而不是替换
EN

Stack Overflow用户
提问于 2020-12-10 08:29:43
回答 1查看 1.3K关注 0票数 1

我正在根据从服务器获取的JSON响应来呈现一个表单。

我的用例包括从单选按钮中听到一次单击,根据radioButton选择切换特定文本字段的可见性,并使用可视textView刷新布局。

预期的输出应该是用现在可见的textView更新相同的视图,但是我现在看到相同的表单两次,第一次是默认状态,第二次是更新状态。

我是否以某种方式创建了一个全新的model_类并将其传递给控制器?我只想更改现有模型的布尔字段并更新视图。

我的模型课

代码语言:javascript
复制
@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
  }

我的控制器班

代码语言:javascript
复制
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)
    }
}

我的片段实现了on单选按钮选中的侦听器,修改了formInput.isVisible = true并调用了formInputController.setData(componentList)

请帮帮我,谢谢!

EN

回答 1

Stack Overflow用户

发布于 2021-02-11 16:34:47

我不认为你使用Epoxy是正确的,这不是应该的。

  1. 首先,让我们从Holder开始:您不应该在bind/unbind中膨胀视图,只需在那里设置视图即可。而且,视图是从您在R.layout.layout_panel_input指定的布局文件中膨胀的,因此根本不需要膨胀.

您应该将其复制到您的项目中:https://github.com/airbnb/epoxy/blob/master/kotlinsample/src/main/java/com/airbnb/epoxy/kotlinsample/helpers/KotlinEpoxyHolder.kt

然后用这样的方式创建你的持有者:

代码语言:javascript
复制
class PanelInputHolder : KotlinHolder() {

    val textView by bind<TextView>(R.id.your_text_view_id)
    val button by bind<Button>(R.id.your_button_id)
}

  1. 让我们转到您的模型类:您应该从构造函数中删除这些变量,因为它们将是注释处理器创建实际类的引用。另外,不要从注释中设置布局区域,因为这在将来是不允许的。

就像这样:

代码语言:javascript
复制
@EpoxyModelClass
class PanelInputModel : EpoxyModelWithHolder<PanelInputHolder>() {

    @EpoxyAttribute
    lateinit var text: String
    @EpoxyAttribute(DoNotHash)
    lateinit var listener: View.OnClickListener

    override fun getDefaultLayout(): Int {
        return R.layout.layout_panel_input
    }

    override fun bind(holder: PanelInputHolder) {

        // here set your views
        holder.textView.text = text
        holder.textView.setOnClickListener(listener)
    }

    override fun unbind(holder: PanelInputHolder) {

        // here unset your views
        holder.textView.text = null
        holder.textView.setOnClickListener(null)
    }
}

  1. 在控制器内循环数据,而不是在模型内:

代码语言:javascript
复制
class FormInputController : TypedEpoxyController<FormInput>() {
    
    
    override fun buildModels(data: FormInput?) {
    
        data?.let {

            // do your layout as you want, with the models you specify
            // for example a header
        
            PanelInputModel_()
                .id(it.id)
                .text("Hello WOrld!")
                .listener { // do something here }
                .addTo(this)
        
            // generate a model per item
            it.images.forEach {
            
                ImageModel_()
                    .id(it.imageId)
                    .image(it)
                    .addTo(this)
            }
        }
    }
}

在选择您的id时,请记住Epoxy将跟踪这些信息,并在有吸引力的情况下进行更新,因此不要使用位置,而是使用不会被复制的唯一id。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65230968

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档