Как добавить поддержку клавиатуры на Facebook LITHO
Я пытаюсь использовать Facebook Litho для создания Android-приложения для телевидения.
Нам нужно поддерживать события клавиатуры (вверх / вниз / влево / вправо) для управления навигацией.
Я могу перехватывать события клавиатуры по onKeyDown в действии, но я не знаю, как обновить статус компонента из действия.
1 ответ
обзор
Я решил похожую проблему, которая заключается в повторной визуализации компонента Litho верхнего уровня, когда происходит внешнее действие, выполнив следующие действия:
- хранение ссылки на
LithoView
создано в моей деятельностиonCreate
метод - Определите какой-либо объект для отслеживания состояния при визуализации, он должен содержать любое состояние, необходимое для визуализации дерева компонентов. это будет
@Prop
на вашем компоненте верхнего уровня - создать начальное состояние в
onCreate
и вывести мой начальный компонент из этого - когда я получаю обратный вызов, вычисляем новый объект состояния и создаем новый
Component
экземпляр из этого - вызов
LithoView#setComponent(Component)
с этим экземпляром
По сути, это реализация подхода MVI, как описано здесь для Android с Mosby, хотя показанный пример сильно упрощен.
Пример:
Деятельность:
public class CounterActivity extends Activity {
private LithoView lithoView; // 1: keeps the same LithoView instance for the entirety of the Activity
private ComponentContext c;
private State currentState; // 2: remembers the current State
static class State {
private int counter;
State(int count) {
this.counter = count;
}
public int getCounter() {
return counter;
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
c = new ComponentContext(this);
// 3: create the initial UI state (note: you probably need to use savedInstanceState or some other external state here)
setState(getInitialApplicationState());
}
// 4: A silly example of an Activity-level callback to drive state updates
@Override
public void onBackPressed() {
setState(new State(currentState.getCounter() + 1));
}
// This will store the new state in the Activity and update the component accordingly
private void setState(State newState) {
currentState = newState;
updateView(newState);
}
// There is a 1:1 mapping between State and UI
private Component componentForState(State state) {
return CounterComponent.create(c).state(state).build();
}
// 5: set the Component on the LithoView for the current state
private void updateView(State currentState) {
Component contentComponent = componentForState(currentState);
if (lithoView == null) {
lithoView = LithoView.create(this, contentComponent);
setContentView(lithoView);
} else {
lithoView.setComponent(contentComponent);
}
}
private State getInitialApplicationState() {
return new State(0);
}
}
Spec:
@LayoutSpec
public class CounterComponentSpec {
@OnCreateLayout
static ComponentLayout onCreateLayout(
ComponentContext c,
@Prop CounterActivity.State state) {
return Text.create(c)
.text("Count: " + state.getCounter())
.textSizeSp(44f)
.buildWithLayout();
}
}