我正在尝试使用 facebook litho 构建用于电视的 android 应用程序。
我们需要支持键盘事件(上/下/左/右)来控制导航。
我可以在activity中通过onKeyDown拦截键盘事件,但是我不知道如何从activity中更新组件的状态。
我已经解决了一个类似的问题,即通过执行以下操作在发生外部操作时重新渲染顶级 Litho 组件:
LithoView
在我的活动onCreate
方法中创建的引用@Prop
您的顶级组件onCreate
并从中派生我的初始组件Component
从中创建一个新实例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();
}
}