Litho Radio Group 容器
Litho Radio Group container
我遵循了 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)
}
}
但是我认为这是为了获得多个单选框而将其包装在父级中,并且必须从父级管理状态。正如文档中提到的:
Let’s take the example of a list of radio buttons, where you cannot
have multiple items checked at the same time. The state of all the
radio buttons depends on whether other items get clicked and checked.
Instead of making all the radio buttons stateful, you should keep the
state of what item is clicked in the parent and propagate that
information top-down to the children through props.
我进行了大量搜索,但找不到任何相关内容。我还检查了 Spinner 组件的实现,但无法获得良好的实现。如果我能被引导到一个具体的例子,那将是一个很大的帮助?
您必须创建一个 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
)
}
}
参考文献:
- https://jayrambhia.com/blog/android-litho-state
- https://fblitho.com/docs/state
- https://fblitho.com/docs/best-practices
奖励:- 这也是一个很好的示例,说明如何在视图模型中获取用户操作回调,以及服务器驱动 UI on Android 的紧凑示例。
我遵循了 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)
}
}
但是我认为这是为了获得多个单选框而将其包装在父级中,并且必须从父级管理状态。正如文档中提到的:
Let’s take the example of a list of radio buttons, where you cannot have multiple items checked at the same time. The state of all the radio buttons depends on whether other items get clicked and checked. Instead of making all the radio buttons stateful, you should keep the state of what item is clicked in the parent and propagate that information top-down to the children through props.
我进行了大量搜索,但找不到任何相关内容。我还检查了 Spinner 组件的实现,但无法获得良好的实现。如果我能被引导到一个具体的例子,那将是一个很大的帮助?
您必须创建一个 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
)
}
}
参考文献:
- https://jayrambhia.com/blog/android-litho-state
- https://fblitho.com/docs/state
- https://fblitho.com/docs/best-practices
奖励:- 这也是一个很好的示例,说明如何在视图模型中获取用户操作回调,以及服务器驱动 UI on Android 的紧凑示例。