airbnb / epoxy

Epoxy is an Android library for building complex screens in a RecyclerView
https://goo.gl/eIK82p
Apache License 2.0
8.5k stars 733 forks source link

Carousel - Detecting current item #833

Closed denison-chua closed 4 years ago

denison-chua commented 4 years ago

Hi, how would you go about detecting the current position that the carousel has snapped to, given that setNumViewsToShowOnScreen is set to 1?

`void buildModels() {

List photoModels = new ArrayList(); for (photo in photos) { photoModels.add(new PhotoViewModel_() .id(photo.id()) .url(photo.url)) }

new CarouselModel_() .id("carousel") .models(photoModels) .addTo(this); }`

denison-chua commented 4 years ago

Figured it out by following answer in #813 . Thanks.

idrisadetunmbi commented 4 years ago

Hi @denison-chua, I am also trying to get this, and I have not been able to get it from the referenced issue. How were you able to get the current item position, please? Thank you.

denison-chua commented 4 years ago

Hi @denison-chua, I am also trying to get this, and I have not been able to get it from the referenced issue. How were you able to get the current item position, please? Thank you.

Hi, I'll post my solution tomorrow, I'm currently away from my laptop. Thanks

idrisadetunmbi commented 4 years ago

Alright. Thank you. If it is easier, you can just give me an idea of how to go about it and I would take it from there. Thanks again.

denison-chua commented 4 years ago

Hi @idrisadetunmbi , what I did was create a subclass of Carousel and then override addOnScrollListener and set a RecyclerView.OnScrollListener on your EpoxyController.

Here is my code for my Carousel subclass: ` @ModelView(saveViewState = true, autoLayout = ModelView.Size.MATCH_WIDTH_WRAP_HEIGHT) public class CustomEpoxyCarousel extends Carousel {

private static SnapHelperFactory defaultGlobalSnapHelperFactory =
        new SnapHelperFactory() {

            @Override
            @NonNull
            public SnapHelper buildSnapHelper(Context context) {
                return new LinearSnapHelper();
            }
        };

@ModelProp(options = ModelProp.Option.DoNotHash)
@Override
public void addOnScrollListener(@NotNull OnScrollListener onScrollListener) {
    super.addOnScrollListener(onScrollListener);
}

@Nullable
@Override
public LayoutManager getLayoutManager() {
    return super.getLayoutManager();
}

@Nullable
@Override
protected SnapHelperFactory getSnapHelperFactory() {
    return defaultGlobalSnapHelperFactory;
}

public CustomEpoxyCarousel(Context context) {
    super(context);
}

} `

And here is the code snippet inside my EpoxyController: CustomEpoxyCarouselModel_ walletCarouselModel; walletCarouselModel = new CustomEpoxyCarouselModel_() .id("carouselWallet") .models(walletEpoxyModel_list) .padding(Carousel.Padding.dp( 10, //left 0, //top 10, //right 0, //bottom 0 //itemspacing )) .addOnScrollListener(getWalletScrollListener()) .numViewsToShowOnScreen(numViewsToShow); walletCarouselModel.addTo(this);

idrisadetunmbi commented 4 years ago

Thanks, @denison-chua. I did something simpler by just overriding onScrollStateChanged and calling a callback prop in it when the Recycler view state is idle.