0

我遵循了 Litho 指南上的复选框示例,并为单选按钮构建了一个类似的实现:

@LayoutSpec
object CRadioSpec {

    @OnCreateLayout
    fun onCreateLayout(
        c: ComponentContext,
        @Prop value: String,
        @State isChecked: Boolean
    ): Component? {
        return Column.create(c)
            .alignContent(YogaAlign.CENTER)
            .widthDip(20F)
            .child(
                Image.create(c)
                    .drawableRes(
                        if (isChecked) R.drawable.ic_checkbox_on
                        else R.drawable.ic_checkbox_off)
                    .clickHandler(CRadio.onCheckboxClicked(c))
            )
            .child(
                Text.create(c)
                    .alignment(TextAlignment.CENTER)
                    .alignSelf(YogaAlign.CENTER)
                    .widthDip(20F)
                    .text(value)
                    .build()
            )
            .build()
    }

    @OnCreateInitialState
    fun onCreateInitialState(
        c: ComponentContext?,
        isChecked: StateValue<Boolean?>,
        @Prop initChecked: Boolean
    ) {
        isChecked.set(initChecked)
    }

    @OnUpdateState
    fun updateCheckboxState(isChecked: StateValue<Boolean?>) {
         isChecked.get()?.let {
             isChecked.set(it.not())
         }
    }

    @OnUpdateState
    fun updateCheckbox(isChecked: StateValue<Boolean?>) {
        isChecked.get()?.let {
            isChecked.set(it.not())
        }

    }

    @OnEvent(ClickEvent::class)
    fun onCheckboxClicked(c: ComponentContext?) {
        CRadio.updateCheckbox(c)
    }
}

但是我相信这将被包裹在一个父级中,以便获得多个单选框,并且必须从父级管理状态。正如文档中提到的:

让我们以单选按钮列表为例,您不能同时检查多个项目。所有单选按钮的状态取决于是否单击和检查了其他项目。与其让所有单选按钮成为有状态的,不如保持在父项中单击的项目的状态,并通过道具自上而下将该信息传播给子项。

关联

我做了很多搜索,但我找不到任何相关的东西。我还检查了 Spinner 组件的实现,但无法得到一个好的实现。如果我可以指导一个具体的例子,那将是一个很大的帮助?

4

1 回答 1

1

您必须创建一个 Radio 组并从那里管理状态,即父组:

这是一种方法:

@LayoutSpec
object CrgSpec {
    @OnCreateLayout
    fun onCreateLayout(
        c: ComponentContext,
        @Prop viewModel: ViewModel,
        @State fields: ArrayList<RadioItem>,
        @Prop parentId: String
    ): Component? {
        val row =
            Row.create(c)
                .alignItems(YogaAlign.CENTER)
                .alignContent(YogaAlign.SPACE_AROUND)
                .flexGrow(1F)
                .wrap(YogaWrap.WRAP)
        fields.forEach { item ->
            row.child(
                CRadio.create(c)
                    .value(item.text)
                    .clickHandler(Crg.onClicked(c, item.id, item.text))
                    .isChecked(item.isChecked)
                    .id(item.id)
                    .build()
            )
        }
        val column = Column.create(c)
            .paddingDip(YogaEdge.TOP, 20F)
            .child(row.build())
        return column.child(
            TextInput.create(c)
                //.visibleHandler()
                .backgroundRes(R.drawable.edit_text_bg)
                .build()
        ).build()
    }

    @OnCreateInitialState
    fun onCreateInitialState(
        c: ComponentContext?,
        fields: StateValue<ArrayList<RadioItem>>,
        @Prop initChecked: ArrayList<RadioItem>
    ) {
        fields.set(initChecked)
    }

    @OnUpdateState
    fun updateCheckboxState(
        fields: StateValue<ArrayList<RadioItem>>,
        @Param id: String
    ) {
        fields.get()?.let { radioItem ->
            radioItem.forEach {
                it.isChecked = it.id == id
            }
            fields.set(radioItem)
        }
    }


    @OnUpdateState
    fun updateCheckbox(
        fields: StateValue<ArrayList<RadioItem>>,
        @Param id: String
    ) {
        fields.get()?.let { radioItem ->
            radioItem.forEach {
                it.isChecked = it.id == id
            }
            fields.set(radioItem)
        }
    }

    @OnEvent(ClickEvent::class)
    fun onClicked(
        c: ComponentContext?,
        @Prop viewModel: ViewModel,
        @Param id: String,
        @Prop parentId: String,
        @Param itemValue: String
    ) {
        Timber.d("id is: $id")
        CirclesRadioGroup.updateCheckbox(c, id)
        viewModel.onRadioUpdate(
            id,
            parentId,
            itemValue
        )
    }
}

参考文献:

奖励:- 这也是一个很好的例子,说明如何在视图模型中获取用户操作回调,以及 Android 上服务器驱动 UI 的紧凑示例。

于 2020-04-25T12:01:38.730 回答