Spec воссоздается при смене видимости софт-клавиатуры
Я использую Litho (0,8).
У меня есть Spec, который создает Recycler, который может содержать несколько компонентов разных типов (текст, флажки, переключатели и т. Д.).
Вот основная спецификация:
@LayoutSpec
public class LithoActivitySpec {
@OnCreateLayout
static ComponentLayout onCreateLayout(final ComponentContext c, @Prop FormDescription formDescription,
@Prop FormFieldSpec.FormFieldListener listener,
@Prop ButtonSpec.ButtonClickListener buttonListener) {
final RecyclerBinder recyclerBinder = new RecyclerBinder.Builder()
.layoutInfo(new LinearLayoutInfo(c, OrientationHelper.VERTICAL, false))
.build(c);
final Component recycler = Recycler.create(c)
.binder(recyclerBinder)
.build();
bindDescriptionToRecycler(c, recyclerBinder, formDescription, listener);
return Column.create(c)
.child(Button.create(c)
.text("validate")
.listener(buttonListener))
.child(recycler)
.build();
}
private static void bindDescriptionToRecycler(ComponentContext c, RecyclerBinder recyclerBinder,
FormDescription formDescription,
FormFieldSpec.FormFieldListener listener) {
List<RenderInfo> renderInfos = new ArrayList<>();
for (ElementValue elementValue : formDescription.elementValues) {
ElementValueType elementValueType = elementValue.getElementValueType();
renderInfos.add(ComponentRenderInfo.create().component(
FormField.create(c)
.text(elementValueType.getName())
.dataType(elementValueType.getElementValueDataType())
.elementValueTypeId(elementValueType.getId())
.listener(listener)
.build())
.build()
);
}
recyclerBinder.insertRangeAt(0, renderInfos);
}
...
}
И вот спецификация, которая будет строить правильный компонент в зависимости от типа данных:
@LayoutSpec
public class FormFieldSpec {
public static final int TEXT_SIZE = 16;
@OnCreateLayout
static ComponentLayout onCreateLayout(ComponentContext c,
@Prop String text,
@Prop ElementValueDataType dataType,
@Prop String elementValueTypeId,
@Prop FormFieldListener listener) {
return Row.create(c)
.paddingDip(YogaEdge.ALL, 16)
.child(Text.create(c)
.text(text)
.verticalGravity(VerticalGravity.CENTER)
.textColor(ContextCompat.getColor(c, android.R.color.tab_indicator_text))
.textStyle(Typeface.BOLD)
.textSizeSp(TEXT_SIZE)
.isSingleLine(false)
.widthPercent(33.0f))
.child(getValueComponentLayout(c, dataType, elementValueTypeId, listener))
.build();
}
private static ComponentLayout getValueComponentLayout(ComponentContext c,
ElementValueDataType dataType,
String elementValueTypeId,
FormFieldListener listener) {
Component.Builder builder;
switch (dataType.getType()) {
case DATE: builder = FormFieldDate.create(c)
.elementValueTypeId(elementValueTypeId)
.allowFuture(((DateDataType) dataType).isFuturePossible())
.withTime(((DateDataType) dataType).isWithTime())
.listener(listener);
break;
case RADIO_BOOLEAN: builder = FormFieldRadioBoolean.create(c)
.elementValueTypeId(elementValueTypeId)
.listener(listener)
.valueTrue(((RadioBooleanDataType) dataType).getValueTrue())
.valueFalse(((RadioBooleanDataType) dataType).getValueFalse());
break;
case CHECK_BOOLEAN: builder = FormFieldCheckBoolean.create(c)
.elementValueTypeId(elementValueTypeId)
.listener(listener)
.valueTrue(((CheckBooleanDataType) dataType).getValueTrue())
.valueFalse(((CheckBooleanDataType) dataType).getValueFalse());
break;
case STRING_LIST: builder = FormFieldVdoList.create(c)
.elementValueTypeId(elementValueTypeId)
.listener(listener)
.allowCustomValues(((StringListDataType) dataType).allowCustomValues())
.rootOption(((StringListDataType) dataType).getRootOption());
break;
default: builder = FormFieldString.create(c)
.elementValueTypeId(elementValueTypeId)
.listener(listener);
}
return builder.buildWithLayout();
}
...
}
Так что, если у меня есть Recycler, который выглядит примерно так:
- Дата
- Радио
- строка
- Проверьте
- строка
Каждый раз, когда я открываю или скрываю клавиатуру, все мои поля становились пустыми. Я установил точку останова на LithoActivitySpec#onCreateLayout()
и я видел, что каждый раз, когда клавиатура меняет свою видимость, вызывается этот метод.
Это ошибка или что-то я не так делаю на моей стороне? Это их onSaveInstanceState
или что-то похожее на это?
Спасибо.