Skip to content

Instantly share code, notes, and snippets.

@jayrambhia
Last active April 26, 2017 13:24
Show Gist options
  • Save jayrambhia/cecafd7daf1bf6fc0a528c16ae2dddc6 to your computer and use it in GitHub Desktop.
Save jayrambhia/cecafd7daf1bf6fc0a528c16ae2dddc6 to your computer and use it in GitHub Desktop.
Component Navigation with Litho
@LayoutSpec
public class FullScreenComponentSpec {
@OnCreateInitialState
static void createInitialState(ComponentContext c, StateValue<Boolean> isLiked, @Prop boolean initLiked) {
isLiked.set(initLiked);
}
@OnCreateLayout
static ComponentLayout onCreateLayout(ComponentContext context, @Prop RequestManager glide, @Prop GifItem gif, @State boolean isLiked) {
return Column.create(context)
.justifyContent(YogaJustify.SPACE_AROUND)
.heightPercent(100)
.child(GifImageView.create(context)
.gif(gif)
.isFullScreen(true)
.glide(glide)
.withLayout()
.alignSelf(YogaAlign.CENTER)
.build())
.child(Image.create(context)
.drawableRes(isLiked ? R.drawable.ic_favorite_accent_48dp : R.drawable.ic_favorite_border_accent_48dp)
.withLayout()
.clickHandler(FullScreenComponent.onLikeButtonClicked(context))
.widthDip(64)
.heightDip(64)
.alignSelf(YogaAlign.CENTER)
.paddingDip(YogaEdge.ALL, 8)
.build())
.build();
}
@OnUpdateState
static void updateLikeButton(StateValue<Boolean> isLiked) {
isLiked.set(!isLiked.get());
}
@OnEvent(ClickEvent.class)
static void onLikeButtonClicked(ComponentContext c, @State boolean isLiked, @Prop GifItem gif, @Prop (optional = true) Callback callback) {
if (callback != null) {
callback.onGifLiked(gif.getId(), !isLiked);
}
}
public interface Callback {
void onGifLiked(String id, boolean liked);
}
}
@MountSpec
public class GifImageViewSpec {
@OnPrepare
static void onPrepare(ComponentContext context, @Prop GifItem gif, Output<Float> ratio) {
ratio.set((float) gif.getWidth() / gif.getHeight());
}
@OnMeasure
static void onMeasure(ComponentContext c, ComponentLayout layout, int widthSpec, int heightSpec, Size size,
@Prop (optional = true) boolean isFullScreen, @FromPrepare float ratio) {
MeasureUtils.measureWithAspectRatio(widthSpec, heightSpec, isFullScreen ? ratio : 1, size);
}
@OnCreateMountContent
static ImageView onCreateMountContent(ComponentContext c) {
ImageView view = new ImageView(c.getApplicationContext());
view.setAdjustViewBounds(true);
view.setBackgroundColor(Color.WHITE);
view.setScaleType(ImageView.ScaleType.CENTER_CROP);
return view;
}
@OnMount
static void onMount(ComponentContext c, ImageView view, @Prop RequestManager glide, @Prop GifItem gif,
@Prop (optional = true) boolean isFullScreen) {
glide.load(isFullScreen ? gif.getImage() : gif.getSmall()).asGif().into(view);
}
@OnUnmount
static void onUnMount(ComponentContext c, ImageView view) {
Glide.clear(view);
}
}
public class GifItem {
private final String id;
private final String image;
private final String small;
private final int width;
private final int height;
private final boolean isLiked;
public GifItem(JsonObject json, boolean isLiked) {
this.id = json.get("id").getAsString();
this.small = json.get("images").getAsJsonObject().get("fixed_height_downsampled").getAsJsonObject().get("url").getAsString();
JsonObject image = json.get("images").getAsJsonObject().get("original").getAsJsonObject();
this.image = image.get("url").getAsString();
this.width = image.get("width").getAsInt();
this.height = image.get("height").getAsInt();
this.isLiked = isLiked;
}
public String getId() {
return id;
}
public String getImage() {
return image;
}
public String getSmall() {
return small;
}
public int getWidth() {
return width;
}
public int getHeight() {
return height;
}
public boolean isLiked() {
return isLiked;
}
}
@LayoutSpec
public class GifItemViewSpec {
@OnCreateInitialState
static void createInitialState(ComponentContext c, StateValue<Boolean> isLiked, @Prop boolean initLiked) {
isLiked.set(initLiked);
}
@OnCreateLayout
static ComponentLayout onCreateLayout(ComponentContext context, @Prop GifItem gif,
@Prop RequestManager glide, @State boolean isLiked) {
return Column.create(context)
.child(GifImageView.create(context)
.gif(gif)
.glide(glide)
.withLayout()
.alignSelf(YogaAlign.CENTER)
.build())
.child(Image.create(context)
.drawableRes(isLiked ? R.drawable.ic_favorite_accent_24dp :R.drawable.ic_favorite_border_accent_24dp)
.withLayout()
.clickHandler(GifItemView.onLikeButtonClicked(context))
.positionType(YogaPositionType.ABSOLUTE)
.widthDip(40)
.heightDip(40)
.paddingDip(YogaEdge.ALL, 8)
.alignSelf(YogaAlign.FLEX_END)
.build())
.clickHandler(GifItemView.onViewClicked(context))
.build();
}
@OnUpdateState
static void updateLikeButton(StateValue<Boolean> isLiked, @Param boolean updatedValue) {
isLiked.set(updatedValue);
}
@OnEvent(ClickEvent.class)
static void onLikeButtonClicked(ComponentContext c, @State boolean isLiked, @Prop GifItem gif, @Prop (optional = true) GifCallback callback) {
if (callback != null) {
callback.onGifLiked(gif.getId(), !isLiked);
}
GifItemView.updateLikeButtonAsync(c, !isLiked);
}
@OnEvent(ClickEvent.class)
static void onViewClicked(ComponentContext c, @Prop GifItem gif, @Prop (optional = true) GifCallback callback) {
if (callback != null) {
callback.onGifSelected(gif);
}
}
public interface GifCallback {
void onGifLiked(String id, boolean liked);
void onGifSelected(GifItem gif);
}
}
public class MainActivity extends AppCompatActivity {
private Component homeComponent;
private LithoView root;
private boolean isFullScreen;
private static final String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
... initialize ComponentContext, LikeStore, etc
final GifItemViewSpec.GifCallback callback = new GifItemViewSpec.GifCallback() {
@Override
public void onGifLiked(String id, boolean liked) {
likeStore.setLiked(id, liked);
}
@Override
public void onGifSelected(GifItem gif, Component gifComponent) {
showFullScreen(c, glide, gif, likeStore);
}
};
... GifProvider code here
homeComponent = HomeComponent.create(c)
.hint("Search Gif")
.binder(binder)
.listener(queryListener)
.build();
root = LithoView.create(this, homeComponent);
setContentView(root);
}
private void showFullScreen(ComponentContext context, RequestManager glide, GifItem gif, final LikeStore likeStore) {
Component fullScreenComponent = FullScreenComponent.create(context)
.initLiked(likeStore.isLiked(gif.getId()))
.gif(gif)
.key(gif.getId())
.glide(glide)
.callback(new FullScreenComponentSpec.Callback() {
@Override
public void onGifLiked(String id, boolean liked) {
likeStore.setLiked(id, liked);
}
})
.build();
root.setComponentAsync(fullScreenComponent);
isFullScreen = true;
}
@Override
public void onBackPressed() {
if (isFullScreen) {
isFullScreen = false;
root.setComponentAsync(homeComponent);
return;
}
super.onBackPressed();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment