gtomato / carouselview

A wonderful library to display 2D fancy carousels for Android.
MIT License
96 stars 35 forks source link

OnItemClickListener's Callback is not returning proper position values #2

Open ivujosevic opened 6 years ago

ivujosevic commented 6 years ago

Hi. I've noticed that onItemClick Callback isn't returning proper position values. I have 3 items total in my CarouselView. Callback onItemSelected is returning the proper positions but onItemClick is returning valid positions only for the first item.

Here is my code:

carousel.setOnItemSelectedListener(new CarouselView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(CarouselView carouselView, int position, int adapterPosition, RecyclerView.Adapter adapter) {
                System.out.println("onItemSelected: position=" + position + ", adapterPosition=" + adapterPosition);
            }

            @Override
            public void onItemDeselected(CarouselView carouselView, int position, int adapterPosition, RecyclerView.Adapter adapter) {
            }
        });
carousel.setOnItemClickListener(new CarouselView.OnItemClickListener() {
            @Override
            public void onItemClick(RecyclerView.Adapter adapter, View view, int position, int adapterPosition) {
                System.out.println("onItemClick: position=" + position + ", adapterPosition=" + adapterPosition);
            }
        });

And here are the Logs:

sunny-chung commented 6 years ago

Hi! I have added your OnItemClickListener to the demo project and cannot reproduce the issue. Would you please provide more information on the CarouselView setup, e.g. transformers, flags?

ivujosevic commented 6 years ago

Hi. I've been implementing a custom solution that was pretty complex so by the time that I got the answer (I mean no offense by that), I've refactored the code a couple of times. Now I also can't reproduce the problem and now I'm receiving the proper values. It might have been something else that caused this issue a week ago. Sorry for the inconvenience.

neeraj91github commented 6 years ago

Hi, I am facing the same issue actually. I have three items showing at once in the carousel. The middle one appears bigger (hence can be deemed as "selected") with one relatively smaller item on each of its side. So I've my items placed like this -

0  -------   1  --------- 2

When I click the middle one it returns me the correct position i.e. 1. But when I click items on either sides it again returns position as 1 which is incorrect, it should return me 0 and 2 respectively.

Here's my adapter -

public class MyCarouselAdapter extends CarouselView.Adapter<MyCarouselAdapter.MyViewHolder> {

    private Context context;
    private List<Place> placeList;
    private View.OnClickListener favoriteListener;

    public MyCarouselAdapter(Context context, List<Place> placeList,  View.OnClickListener 
favoriteListener) {
        this.context = context;
        this.placeList =placeList;
        this.favoriteListener = favoriteListener;
}

    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.item_view, parent, false);

        return new MyViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(MyViewHolder holder, int position) {

        Place place = placeList.get(position);

        holder.textViewName.setText(place.getName());
        ImageUtility.loadTopCornerRoundedImage(context, holder.imageView, place.getCover());

    }

    @Override
    public int getItemCount() {
        return placeList.size();
    }

    public class MyViewHolder extends CarouselView.ViewHolder implements View.OnClickListener {

        TextView textViewName;
        ImageView imageView;

        public MyViewHolder(View view) {

            super(view);

            textViewName = (TextView) itemView.findViewById(R.id.textViewName);
            imageView = (ImageView) itemView.findViewById(R.id.imageView);

        }
    }
}

And this is how I am setting my itemClick listener -

private CarouselView.OnItemClickListener placeOnItemClickListener = new 
CarouselView.OnItemClickListener() {

        @Override
        public void onItemClick(RecyclerView.Adapter adapter, View view, int position, int 
adapterPosition) {

            // My Logic
        }
    };

carouselPlace.setOnItemClickListener(placeOnItemClickListener);
sunny-chung commented 6 years ago

There are few things you may want to try:

  1. Make sure the root view of the item view is not MATCH_PARENT / FILL_PARENT.
  2. Check out CarouselLayoutManager#setDrawOrder(CarouselView.DrawOrder) and implementation of FlatMerryGoRoundTransformer. For the example @neeraj91github mentions, you may set CenterFront as the draw order when attaching the custom transformer.

CarouselView basically layouts item views like FrameLayout. Calling CarouselView#setOnItemClickListener is a shortcut of calling setOnItemClickListener to the root item view at onCreateViewHolder and onBindViewHolder. Hence, drawing order / visibility of partially / fully transparent views affect the order of intercepting events, even though they look visually correct.

If that does not help, it would be best if a minimal example of Transformer implementation and settings of CarouselView can be provided to reproduce the issue.

carlosvaccari commented 5 years ago

Hi, I had the same problem, but the problem was related to my CustomTransform that I seted to the CarouselView. As I was seting alpha's value but not changing the view's visibility to GONE, the first view was always VISIBLE althoug transparent. So, if anyone still have this problem:

public class CustomTransform implements CarouselView.ViewTransformer {
    ...
    @Override
    public void transform(View view, float position) {
       ...

        view.setVisibility(view.getAlpha() < 0.1 ? View.GONE : View.VISIBLE);
    }