yuyakaido / CardStackView

📱Tinder like swipeable card view for Android
Apache License 2.0
2.38k stars 452 forks source link

IndexOutOfBoundsException in CardStackLayoutManager #141

Closed cnmicha closed 5 years ago

cnmicha commented 5 years ago

Hi, I am getting an IndexOutOfBoundsException as soon as I start dragging a card. Here's the stack trace:

java.lang.IndexOutOfBoundsException: Invalid item position -1(-1). Item count:1 com.myapp.android.cardstackview.CardStackView{d339082 VFED..... ......ID 0,0-1080,1437 #7f090054 app:id/fragment_post_swipe_card_stack_view}, adapter:com.myapp.android.cardstackview.PostCardAdapter@b885393, layout:com.myapp.android.cardstackview.CardStackLayoutManager@9348fd0, context:com.myapp.android.MainActivity@4985aae at android.support.v7.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:5779) at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5752) at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5748) at com.myapp.android.cardstackview.CardStackLayoutManager.update(CardStackLayoutManager.java:208) at com.myapp.android.cardstackview.CardStackLayoutManager.onLayoutChildren(CardStackLayoutManager.java:51) at android.support.v7.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:3812) at android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:3529) at android.support.v7.widget.RecyclerView.onLayout(RecyclerView.java:4082) at android.view.View.layout(View.java:20672) at android.view.ViewGroup.layout(ViewGroup.java:6194) at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1812) at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1656) at android.widget.LinearLayout.onLayout(LinearLayout.java:1565) at android.view.View.layout(View.java:20672) at android.view.ViewGroup.layout(ViewGroup.java:6194) at android.support.v4.widget.SwipeRefreshLayout.onLayout(SwipeRefreshLayout.java:606) at android.view.View.layout(View.java:20672) at android.view.ViewGroup.layout(ViewGroup.java:6194) at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323) at android.widget.FrameLayout.onLayout(FrameLayout.java:261) at android.view.View.layout(View.java:20672) at android.view.ViewGroup.layout(ViewGroup.java:6194) at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1812) at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1656) at android.widget.LinearLayout.onLayout(LinearLayout.java:1565) at android.view.View.layout(View.java:20672) at android.view.ViewGroup.layout(ViewGroup.java:6194) at android.support.design.widget.CoordinatorLayout.layoutChild(CoordinatorLayout.java:1191) at android.support.design.widget.CoordinatorLayout.onLayoutChild(CoordinatorLayout.java:876) at android.support.design.widget.CoordinatorLayout.onLayout(CoordinatorLayout.java:895) at android.view.View.layout(View.java:20672) at android.view.ViewGroup.layout(ViewGroup.java:6194) at android.widget.RelativeLayout.onLayout(RelativeLayout.java:1083) at android.view.View.layout(View.java:20672) at android.view.ViewGroup.layout(ViewGroup.java:6194) at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323) at android.widget.FrameLayout.onLayout(FrameLayout.java:261) at android.view.View.layout(View.java:20672) at android.view.ViewGroup.layout(ViewGroup.java:6194) at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1812) at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1656) at android.widget.LinearLayout.onLayout(LinearLayout.java:1565) at android.view.View.layout(View.java:20672) at android.view.ViewGroup.layout(ViewGroup.java:6194) at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323) at android.widget.FrameLayout.onLayout(FrameLayout.java:261) at android.view.View.layout(View.java:20672) at android.view.ViewGroup.layout(ViewGroup.java:6194) at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1812) at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1656) at android.widget.LinearLayout.onLayout(LinearLayout.java:1565) at android.view.View.layout(View.java:20672) 2018-11-11 18:30:16.406 16342-16342/com.myapp.android E/AndroidRuntime: at android.view.ViewGroup.layout(ViewGroup.java:6194) at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323) at android.widget.FrameLayout.onLayout(FrameLayout.java:261) at com.android.internal.policy.DecorView.onLayout(DecorView.java:753) at android.view.View.layout(View.java:20672) at android.view.ViewGroup.layout(ViewGroup.java:6194) at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2792) at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2319) at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1460) at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:7183) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:949) at android.view.Choreographer.doCallbacks(Choreographer.java:761) at android.view.Choreographer.doFrame(Choreographer.java:696) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:935) at android.os.Handler.handleCallback(Handler.java:873) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:193) at android.app.ActivityThread.main(ActivityThread.java:6669) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)

The Adapter:

public class PostCardAdapter extends RecyclerView.Adapter<PostCardAdapter.ViewHolder> {
private LayoutInflater inflater;
private List<Post> posts;

public PostCardAdapter(Context context) {
    this.inflater = LayoutInflater.from(context);
    this.posts = new ArrayList<>();
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        return new ViewHolder(inflater.inflate(R.layout.card_item_post, parent, false));
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
        Post post = posts.get(position);

        // TODO adapt and fill with neutral color so that always the whole image is shown!
        holder.image.setImageBitmap(post.getImage());
    }

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

    public void addAll(List<Post> posts) {
        this.posts.addAll(posts);
    }

    public void add(Post post) {
        posts.add(post);
    }

    public void remove(Post post) {
        posts.remove(post);
    }

    public void clear() {
        posts.clear();
    }

    public static class ViewHolder extends RecyclerView.ViewHolder {
        ImageView image;

        ViewHolder(View view) {
            super(view);
            this.image = view.findViewById(R.id.item_post_card_image);
        }
    }
}

The Activity:

CardStackLayoutManager manager = new CardStackLayoutManager(getContext(), new CardStackListener() {
           // All methods overridden but left out for readability, onCardDragging is empty
        });
       manager.setStackFrom(StackFrom.Bottom);
        manager.setVisibleCount(3);
        manager.setTranslationInterval(8.0f);
        manager.setScaleInterval(0.95f);
        manager.setSwipeThreshold(0.2f);
        manager.setMaxDegree(20.0f);
        manager.setDirections(Direction.HORIZONTAL);
        manager.setCanScrollHorizontal(true);
        manager.setCanScrollVertical(false);
        adapter = new PostCardAdapter(getContext());
        cardStackView.setAdapter(adapter);
        cardStackView.setLayoutManager(manager);
yuyakaido commented 5 years ago

@cnmicha I can't reproduce this issue. Can you send a sample project to reproduce the issue?

cnmicha commented 5 years ago

Solved. I forgot adding adapter.notifyDataSetChanged(); after adapter.add(p);.

rastrish commented 5 years ago

hey i am getting the same issue when adding more item to the list..

rastrish commented 5 years ago

private fun createSpots(): List { spots.add(Spot(userId = 1,name = "Yasaka Shrine", city = "Kyoto", url = "https://source.unsplash.com/Xq1ntWruZQI/600x800",imageSec ="null",imageThird = "null",imageFourth = "null",imageFifth = "null",imageSixth ="null", about = "about",basicinfo = listOf(BasicInfo(code = 0,basicInfoAns = "ans")),profileAnswer = listOf(ProfileAnswer(order = 0,question = "null",answer = "null")),interest = listOf("null"))) spots.add(Spot(userId = 1,name = "Fushimi Inari Shrine", city = "Kyoto", url = "https://source.unsplash.com/NYyCqdBOKwc/600x800",imageSec ="null",imageThird = "null",imageFourth = "null",imageFifth = "null",imageSixth ="null",about = "about",basicinfo = listOf(BasicInfo(code = 0,basicInfoAns = "ans")),profileAnswer = listOf(ProfileAnswer(order = 0,question = "null",answer = "null")),interest = listOf("null"))) spots.add(Spot(userId = 1,name = "Louvre Museum", city = "Paris", url = "https://source.unsplash.com/LrMWHKqilUw/600x800",imageSec ="null",imageThird = "null",imageFourth = "null",imageFifth = "null",imageSixth ="null",about = "about",basicinfo = listOf(BasicInfo(code = 0,basicInfoAns = "ans")),profileAnswer = listOf(ProfileAnswer(order = 0,question = "null",answer = "null")),interest = listOf("null"))) spots.add(Spot(userId = 1,name = "Louvre Museum", city = "Paris", url = "https://source.unsplash.com/LrMWHKqilUw/600x800",imageSec ="null",imageThird = "null",imageFourth = "null",imageFifth = "null",imageSixth ="null",about = "about",basicinfo = listOf(BasicInfo(code = 0,basicInfoAns = "ans")),profileAnswer = listOf(ProfileAnswer(order = 0,question = "null",answer = "null")),interest = listOf("null"))) spots.add(Spot(userId = 1,name = "Bamboo Forest", city = "Kyoto", url = "https://source.unsplash.com/buF62ewDLcQ/600x800",imageSec ="null",imageThird = "null",imageFourth = "null",imageFifth = "null",imageSixth ="null",about = "about",basicinfo = listOf(BasicInfo(code = 0,basicInfoAns = "ans")),profileAnswer = listOf(ProfileAnswer(order = 0,question = "null",answer = "null")),interest = listOf("null"))) spots.add(Spot(userId = 1,name = "Brooklyn Bridge", city = "New York", url = "https://source.unsplash.com/THozNzxEP3g/600x800",imageSec ="null",imageThird = "null",imageFourth = "null",imageFifth = "null",imageSixth ="null",about = "about",basicinfo = listOf(BasicInfo(code = 0,basicInfoAns = "ans")),profileAnswer = listOf(ProfileAnswer(order = 0,question = "null",answer = "null")),interest = listOf("null"))) spots.add(Spot(userId = 1,name = "Big Ben", city = "London", url = "https://source.unsplash.com/CdVAUADdqEc/600x800",imageSec ="null",imageThird = "null",imageFourth = "null",imageFifth = "null",imageSixth ="null",about = "about",basicinfo = listOf(BasicInfo(code = 0,basicInfoAns = "ans")),profileAnswer = listOf(ProfileAnswer(order = 0,question = "null",answer = "null")),interest = listOf("null"))) spots.add(Spot(userId = 1,name = "Empire State Building", city = "New York", url = "https://source.unsplash.com/USrZRcRS2Lw/600x800",imageSec ="null",imageThird = "null",imageFourth = "null",imageFifth = "null",imageSixth ="null",about = "about",basicinfo = listOf(BasicInfo(code = 0,basicInfoAns = "ans")),profileAnswer = listOf(ProfileAnswer(order = 0,question = "null",answer = "null")),interest = listOf("null"))) spots.add(Spot(userId = 1,name = "The statue of Liberty", city = "New York", url = "https://source.unsplash.com/PeFk7fzxTdk/600x800",imageSec ="null",imageThird = "null",imageFourth = "null",imageFifth = "null",imageSixth ="null",about = "about",basicinfo = listOf(BasicInfo(code = 0,basicInfoAns = "ans")),profileAnswer = listOf(ProfileAnswer(order = 0,question = "null",answer = "null")),interest = listOf("null")))

    getProfile()

    return spots
}
rastrish commented 5 years ago
                            for (image in user.user_photos)
                            {
                                if (image.image_url != null)
                                {
                                    Log.e("all variables",imageSec + imageThird +imageFourth+ imageFifth)
                                    imageUrl = image.image_url.toString()
                                    Log.e("firstname", firstName)
                                    Log.e("firstImage", imageUrl)
                                    Log.e("Profile Answer",profileAnswer.toString())
                                    Log.e("second image varr", imageSec)
                                    Log.e("interest",interest.toString())
                                    spots.add(Spot(userId = userid,name = firstName, city = "$job_title at $company", url = imageUrl!!,imageSec = imageSec!! ,imageThird = imageThird!! ,imageFourth = imageFourth!! ,imageFifth = imageFifth!!, imageSixth = imageSixth!!, about = about!!,basicinfo = basicInfo,profileAnswer = profileAnswer,interest = interest))
                                    Log.e("Spot",spots.toString())

                                }
                            }
cnmicha commented 5 years ago

Did you call adapter.notifyDataSetChanged()? I can't see it in your code.