ShamylZakariya / StickyHeaders

Adapter and LayoutManager for Android RecyclerView which enables sticky header positioning.
MIT License
1.4k stars 185 forks source link

May I ask why this error occurred? #11

Open y2t opened 8 years ago

y2t commented 8 years ago

First of all thanks for this lib, it's great!

I don't know why this error occurs. i just click on the item very quickly.

java.lang.NullPointerException at org.zakariya.stickyheaders.StickyHeaderLayoutManager.getViewViewHolder(StickyHeaderLayoutManager.java:599) at org.zakariya.stickyheaders.StickyHeaderLayoutManager.getViewAdapterPosition(StickyHeaderLayoutManager.java:603) at org.zakariya.stickyheaders.StickyHeaderLayoutManager.getBottommostChildView(StickyHeaderLayoutManager.java:447) at org.zakariya.stickyheaders.StickyHeaderLayoutManager.scrollVerticallyBy(StickyHeaderLayoutManager.java:274) at android.support.v7.widget.RecyclerView.scrollByInternal(RecyclerView.java:1529) at android.support.v7.widget.RecyclerView.onTouchEvent(RecyclerView.java:2486) at android.view.View.dispatchTouchEvent(View.java:7758) at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2224) at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1959) at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2230) at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1973) at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2230) at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1973) at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2230) at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1973) at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2230) at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1973) at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2230) at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1973) at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2230) at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1973) at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2230) at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1973) at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2230) at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1973) at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2230) at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1973) at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2230) at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1973) at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:2071) at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1518) at android.app.Activity.dispatchTouchEvent(Activity.java:2531) at android.support.v7.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:60) at android.support.v7.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:60)

Thanks in advance

ShamylZakariya commented 8 years ago

When you say "I just click on the item very quickly" can you clarify? Is the list being modified -- items being added or removed?

y2t commented 8 years ago

This is ItemViewHolder class.

`public class ItemViewHolder extends SectioningAdapter.ItemViewHolder implements View.OnClickListener { TextView personNameTextView; TextView detailTextView;

    public ItemViewHolder(View itemView) {
        super(itemView);
        personNameTextView = (TextView) itemView.findViewById(R.id.personNameTextView);
        detailTextView = (TextView) itemView.findViewById(R.id.detail);
        itemView.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {

        int sectionIndex = getSectionForAdapterPosition(getAdapterPosition());
        int itemIndex = getPositionOfItemInSection(sectionIndex, getAdapterPosition());
        int position = getAdapterPositionForSectionItem(sectionIndex, itemIndex);

        sections.get(sectionIndex).people.get(itemIndex).name.first = "Ann";
        if (sections.get(sectionIndex).people.get(itemIndex).isShowDetail) {
            sections.get(sectionIndex).people.get(itemIndex).isShowDetail = false;
        }
        else {
            sections.get(sectionIndex).people.get(itemIndex).isShowDetail = true;
        }

        notifySectionItemChanged(sectionIndex, itemIndex);

    }
}

`

This is onBindItemViewHolder. @Override public void onBindItemViewHolder(SectioningAdapter.ItemViewHolder viewHolder, int sectionIndex, int itemIndex) { Section s = sections.get(sectionIndex); ItemViewHolder ivh = (ItemViewHolder) viewHolder; Person person = s.people.get(itemIndex); ivh.personNameTextView.setText(capitalize(person.name.last) + ", " + capitalize(person.name.first));

    if (sections.get(sectionIndex).people.get(itemIndex).isShowDetail) {
        ivh.detailTextView.setVisibility(View.VISIBLE);
    }
    else {
        ivh.detailTextView.setVisibility(View.GONE);
    }
}

This is list_item_addressbook_person.xml

<TextView
    android:id="@+id/personNameTextView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:padding="16dp"
    android:text="Medium Text"
    android:textAppearance="?android:attr/textAppearanceMedium"
    android:layout_gravity="start|center_vertical"
    />

<View
    android:layout_width="match_parent"
    android:layout_height="1dp"
    android:background="@color/divider"/>

<TextView
    android:id="@+id/detail"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:textSize="20sp"
    android:padding="10dp"
    android:visibility="gone"
    android:gravity="center"
    android:textColor="@android:color/holo_red_dark"
    android:text="Detail view"/>

screenshot_2016-06-08-09-47-40

Thanks in advance

PACordonnier commented 8 years ago

Hey, I think my bug is linked, here is the stacktrace

java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object android.view.View.getTag(int)' on a null object reference at org.zakariya.stickyheaders.StickyHeaderLayoutManager.getViewViewHolder(StickyHeaderLayoutManager.java:730) at org.zakariya.stickyheaders.StickyHeaderLayoutManager.getViewAdapterPosition(StickyHeaderLayoutManager.java:734) at org.zakariya.stickyheaders.StickyHeaderLayoutManager.getBottommostChildView(StickyHeaderLayoutManager.java:578) at org.zakariya.stickyheaders.StickyHeaderLayoutManager.scrollVerticallyBy(StickyHeaderLayoutManager.java:354) at android.support.v7.widget.RecyclerView$ViewFlinger.run(RecyclerView.java:4061) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:871) at android.view.Choreographer.doCallbacks(Choreographer.java:683) at android.view.Choreographer.doFrame(Choreographer.java:616) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:857) at android.os.Handler.handleCallback(Handler.java:751) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:154) at android.app.ActivityThread.main(ActivityThread.java:6077) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)

The bug occurs when I'm modifying one element of the recyclerview (and calling notifySectionItemChanged) while scrolling. More precisely, I resume to the activity which contains my recyclerview, I start a task and the callback of this task modify an object of the list and call notifySectionItemChanged on the element that changed. If I scroll very fast before the method is called it causes a bug.

I can also write my own issue as well if you prefer but this looks very similar to me ;)

EDIT: calling notifyAllSectionsDataSetChanged instead of notifySectionItemChanged allows me to avoid the bug even if it's not ideal, my list is relatively small. Thx

ShamylZakariya commented 8 years ago

@Meldoyo this is very similar (if not identical) to a bug I encountered while implementing paged loading. Since I just (hopefully) fixed issue #18 I will put this at the top of my queue. Any chance you could whip up a simple demo app to reproduce this?

PACordonnier commented 8 years ago

Sure i'll try to find some time to do it today or this week.