package com.airbnb.epoxy;
import android.os.Looper;
import android.view.ViewGroup;
import com.facebook.litho.Component;
import com.facebook.litho.ComponentContext;
import com.facebook.litho.ComponentLifecycle;
import com.facebook.litho.ComponentTree;
import com.facebook.litho.LithoView;
import java.util.List;
/**
* Experiment support for Facebook's Litho library. Any litho component specs will automatically
* have a model generated for them that extends this class.
*/
public abstract class EpoxyLithoModel<T extends ComponentLifecycle>
extends EpoxyModelWithView<LithoView> {
private Component<T> component;
protected abstract Component<T> buildComponent(ComponentContext context);
public Component<T> getComponent(ComponentContext context) {
// TODO: (eli_hart 4/23/17) verify added to controller first?
if (component == null) {
// TODO: (eli_hart 4/23/17) reuse component context?
component = buildComponent(context);
}
return component;
}
public void clearComponent() {
// TODO: (eli_hart 4/23/17) Do this at some point to avoid leaking the context?
component = null;
}
@Override
public void bind(LithoView view) {
Component<T> component = getComponent(view.getComponentContext());
if (view.getComponentTree() == null) {
view.setComponentTree(ComponentTree.create(view.getComponentContext(), component)
.asyncStateUpdates(false) // does this need to be off?
.layoutThreadLooper(Looper.getMainLooper())
.incrementalMount(
false) // this needs to be off for recyclerview to work. Should we manually
// incrementally mount views in a scroll listener?
.layoutDiffing(false) // should we use this?
.build());
}
view.setComponent(component);
}
@Override
public void bind(LithoView view, List<Object> payloads) {
if (payloads.isEmpty()) {
bind(view);
} else {
view.getComponentTree().setRoot(getComponent(view.getComponentContext()), true);
}
}
@Override
public void bind(LithoView view, EpoxyModel<?> previouslyBoundModel) {
view.getComponentTree().setRoot(getComponent(view.getComponentContext()), true);
}
@Override
public void onViewAttachedToWindow(LithoView view) {
// view.rebind(); ?????
}
@Override
public void onViewDetachedFromWindow(LithoView view) {
// view.unbind(); ???
}
@Override
public void unbind(LithoView view) {
// The litho view is already unbound when it is detached from the window
}
@Override
protected LithoView buildView(ViewGroup parent) {
return new LithoView(parent.getContext());
}
}