0

我正在尝试使用 facebook litho 构建用于电视的 android 应用程序。

我们需要支持键盘事件(上/下/左/右)来控制导航。

我可以在activity中通过onKeyDown拦截键盘事件,但是我不知道如何从activity中更新组件的状态。

4

1 回答 1

0

概述

我已经解决了一个类似的问题,即通过执行以下操作在发生外部操作时重新渲染顶级 Litho 组件:

  1. 存储对LithoView在我的活动onCreate方法中创建的引用
  2. 定义某种对象来跟踪渲染中的状态,这必须包含渲染组件树所需的任何状态。这将是@Prop您的顶级组件
  3. 在其中创建一个初始状态onCreate并从中派生我的初始组件
  4. 当我收到回调时,计算新的状态对象并Component从中创建一个新实例
  5. LithoView#setComponent(Component)用那个实例调用

这本质上是 MVI 方法的实现,正如此处为带有 Mosby 的 Android所解释的那样,尽管显示的示例被高度简化。

例子:

活动:

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);
    }
}

规格:

@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();
    }
}
于 2017-11-27T23:39:48.840 回答