Android 石质无线电组容器

Android 石质无线电组容器,android,litho,Android,Litho,我遵循了Litho guide上的复选框示例,并为单选按钮构建了类似的实现: @LayoutSpec object CRadioSpec { @OnCreateLayout fun onCreateLayout( c: ComponentContext, @Prop value: String, @State isChecked: Boolean ): Component? { return Column.

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

@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)
    }
}
@LayoutSpec
物体透视图{
@OnCreateLayout
创建布局的乐趣(
c:组件上下文,
@属性值:字符串,
@已检查状态:布尔值
):组件{
返回列。创建(c)
.alignContent(YogaAlign.CENTER)
.宽倾角(20F)
.孩子(
图像创建(c)
1.提款权(
如果(已选中)R.drawable.ic\u复选框\u打开
else R.drawable.ic_复选框_关闭)
.clickHandler(CRadio.onCheckboxClicked(c))
)
.孩子(
文本。创建(c)
.alignment(TextAlignment.CENTER)
.alignSelf(YogaAlign.CENTER)
.宽倾角(20F)
.文本(值)
.build()
)
.build()
}
@OnCreateInitialState
创建初始状态的乐趣(
c:组件上下文?,
已检查:StateValue,
@属性:布尔值
) {
isChecked.set(initChecked)
}
@无更新状态
趣味updateCheckboxState(已选中:StateValue){
isChecked.get()?.let{
isChecked.set(it.not())
}
}
@无更新状态
趣味updateCheckbox(已选中:StateValue){
isChecked.get()?.let{
isChecked.set(it.not())
}
}
@OneEvent(ClickEvent::class)
点击一次checkboxClicked(c:组件上下文?){
CRadio.updateCheckbox(c)
}
}
然而,我相信这是包装在一个家长,以获得多个电台盒和状态必须从家长管理。正如文件中提到的:

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


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

您必须创建一个无线组并从中管理状态,即父组:

以下是一种方法:

@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
        )
    }
}
@LayoutSpec
对象CrgSpec{
@OnCreateLayout
创建布局的乐趣(
c:组件上下文,
@Prop viewModel:viewModel,
@状态字段:ArrayList,
@Prop parentId:String
):组件{
瓦尔街=
行。创建(c)
.对齐项目(YogaAlign.CENTER)
.alignContent(YogaAlign.SPACE_周围)
.flexGrow(1F)
.wrap(YogaWrap.wrap)
fields.forEach{item->
小朋友(
克雷迪奥创造(c)
.value(item.text)
.clickHandler(Crg.onClicked(c,item.id,item.text))
.isChecked(项目.isChecked)
.id(项目.id)
.build()
)
}
val column=column.create(c)
.paddingDip(YogaEdge.TOP,20F)
.child(行.build())
返回列.child(
TextInput.create(c)
//.visibleHandler()
.背景(R.可绘制.编辑\u文本\u背景)
.build()
).build()
}
@OnCreateInitialState
创建初始状态的乐趣(
c:组件上下文?,
字段:StateValue
  • 奖励:-这也是一个非常好的示例,说明了如何在视图模型中获得用户操作回调,以及Android上服务器驱动UI的一个紧凑示例