Как добавить поддержку клавиатуры на Facebook LITHO

Я пытаюсь использовать Facebook Litho для создания Android-приложения для телевидения.

Нам нужно поддерживать события клавиатуры (вверх / вниз / влево / вправо) для управления навигацией.

Я могу перехватывать события клавиатуры по onKeyDown в действии, но я не знаю, как обновить статус компонента из действия.

1 ответ

обзор

Я решил похожую проблему, которая заключается в повторной визуализации компонента Litho верхнего уровня, когда происходит внешнее действие, выполнив следующие действия:

  1. хранение ссылки на LithoView создано в моей деятельности onCreate метод
  2. Определите какой-либо объект для отслеживания состояния при визуализации, он должен содержать любое состояние, необходимое для визуализации дерева компонентов. это будет @Prop на вашем компоненте верхнего уровня
  3. создать начальное состояние в onCreate и вывести мой начальный компонент из этого
  4. когда я получаю обратный вызов, вычисляем новый объект состояния и создаем новый Component экземпляр из этого
  5. вызов 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();
    }
}
Другие вопросы по тегам