gabrielemariotti / cardslib

Android Library to build a UI Card
4.66k stars 1.19k forks source link

crash after slide to bottom when using CardArrayAdapter on android.support.v7.app.AppCompatActivity; #516

Open marekyggdrasil opened 9 years ago

marekyggdrasil commented 9 years ago

I am not sure if it qualifies as issue, my example app crashes when I use CardArrayAdapter. Issue occurs when my Activity extends import android.support.v7.app.AppCompatActivity, in case of android.app.Activity it seems to work fine. What happends is: when I put 5 cards and slide screen down it crashes with following stack trace:

11-10 16:58:08.192    8205-8205/my.package E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: my.package, PID: 8205
    java.lang.NullPointerException
            at it.gmariotti.cardslib.library.view.component.CardThumbnailView.cancelPotentialWork(CardThumbnailView.java:422)
            at it.gmariotti.cardslib.library.view.component.CardThumbnailView.loadBitmap(CardThumbnailView.java:287)
            at it.gmariotti.cardslib.library.view.component.CardThumbnailView.setupInnerView(CardThumbnailView.java:251)
            at it.gmariotti.cardslib.library.view.component.CardThumbnailView.buildUI(CardThumbnailView.java:230)
            at it.gmariotti.cardslib.library.view.component.CardThumbnailView.addCardThumbnail(CardThumbnailView.java:217)
            at it.gmariotti.cardslib.library.view.CardView.setupThumbnailView(CardView.java:399)
            at it.gmariotti.cardslib.library.view.CardView.buildUI(CardView.java:285)
            at it.gmariotti.cardslib.library.view.CardView.setCard(CardView.java:242)
            at it.gmariotti.cardslib.library.internal.CardArrayAdapter.getView(CardArrayAdapter.java:171)
            at android.widget.AbsListView.obtainView(AbsListView.java:2257)
            at android.widget.ListView.makeAndAddView(ListView.java:1790)
            at android.widget.ListView.fillUp(ListView.java:725)
            at android.widget.ListView.fillGap(ListView.java:664)
            at android.widget.AbsListView.trackMotionScroll(AbsListView.java:5193)
            at android.widget.AbsListView.scrollIfNeeded(AbsListView.java:3245)
            at android.widget.AbsListView.onTouchMove(AbsListView.java:3612)
            at android.widget.AbsListView.onTouchEvent(AbsListView.java:3434)
            at android.view.View.dispatchTouchEvent(View.java:7714)
            at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2210)
            at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1945)
            at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2216)
            at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1959)
            at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2216)
            at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1959)
            at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2216)
            at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1959)
            at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2216)
            at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1959)
            at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2216)
            at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1959)
            at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2216)
            at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1959)
            at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:2068)
            at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1515)
            at android.app.Activity.dispatchTouchEvent(Activity.java:2476)
            at android.support.v7.internal.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:60)
            at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:2016)
            at android.view.View.dispatchPointerEvent(View.java:7894)
            at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:3995)
            at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:3874)
            at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3435)
            at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3485)
            at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3454)
            at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3561)
            at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3462)
            at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:3618)
            at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3435)
            at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3485)
            at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3454)
            at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3462)
            at android.view.ViewRootImpl$InputStage.d

It occurs both with release 2.1.0 as well as with stable 1.9.1. Example is inspired by this tutorial.

Here is my activity:

package my.package;
import it.gmariotti.cardslib.library.internal.Card;
import it.gmariotti.cardslib.library.internal.CardArrayAdapter;
import it.gmariotti.cardslib.library.internal.CardHeader;
import it.gmariotti.cardslib.library.internal.CardThumbnail;
import it.gmariotti.cardslib.library.view.CardListView;
import it.gmariotti.cardslib.library.view.CardView;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import java.util.ArrayList;

public class CardsActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_cards);
        ArrayList<Card> cards = new ArrayList<Card>();
        for (int i = 0; i<5; i++) {
            // Create a Card
            Card card = new Card(this, R.layout.row_card);
            // Create a CardHeader
            CardHeader header = new CardHeader(this);
            header.setTitle("Hello world");
            card.setTitle("Simple card demo");
            CardThumbnail thumb = new CardThumbnail(this);
            card.addCardThumbnail(thumb);
            // Add Header to card
            card.addCardHeader(header);
            cards.add(card);
        }
        // Set card in the cardView
        CardArrayAdapter mCardArrayAdapter = new CardArrayAdapter(this, cards);
        CardListView listView = (CardListView) this.findViewById(R.id.myList);
        if (listView != null) {
            listView.setAdapter(mCardArrayAdapter);
        }
    }
}

And here are the layouts: activity_cards.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    xmlns:card="http://schemas.android.com/apk/res-auto" >
    <it.gmariotti.cardslib.library.view.CardListView
        android:id="@+id/myList"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        card:list_card_layout_resourceID="@layout/list_card_thumbnail_layout"
        style="@style/list_card.thumbnail"/>
</RelativeLayout>

Here is row_card.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="10dp" >
    <TextView
        android:id="@+id/card_main_inner_simple_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Large Text"
        android:textAppearance="?android:attr/textAppearanceLarge" />
    <TextView
        android:id="@+id/card_main_inner_secondary_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Cardslib"
        android:textAppearance="?android:attr/textAppearanceMedium" />
</LinearLayout>
gabrielemariotti commented 9 years ago

It seems a bug

marekyggdrasil commented 9 years ago

Also, I just noticed, that if I use android.app.Activity it works fine until I rotate the screen, then after slide down it crashes with following stack trace.

11-10 17:31:19.668  26792-26792/my.package E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: my.package, PID: 26792
    java.lang.NullPointerException
            at it.gmariotti.cardslib.library.view.component.CardThumbnailView.cancelPotentialWork(CardThumbnailView.java:422)
            at it.gmariotti.cardslib.library.view.component.CardThumbnailView.loadBitmap(CardThumbnailView.java:287)
            at it.gmariotti.cardslib.library.view.component.CardThumbnailView.setupInnerView(CardThumbnailView.java:251)
            at it.gmariotti.cardslib.library.view.component.CardThumbnailView.buildUI(CardThumbnailView.java:230)
            at it.gmariotti.cardslib.library.view.component.CardThumbnailView.addCardThumbnail(CardThumbnailView.java:217)
            at it.gmariotti.cardslib.library.view.CardView.setupThumbnailView(CardView.java:385)
            at it.gmariotti.cardslib.library.view.CardView.buildUI(CardView.java:274)
            at it.gmariotti.cardslib.library.view.CardView.setCard(CardView.java:231)
            at it.gmariotti.cardslib.library.internal.CardArrayAdapter.getView(CardArrayAdapter.java:170)
            at android.widget.AbsListView.obtainView(AbsListView.java:2257)
            at android.widget.ListView.makeAndAddView(ListView.java:1790)
            at android.widget.ListView.fillDown(ListView.java:691)
            at android.widget.ListView.fillGap(ListView.java:655)
            at android.widget.AbsListView.trackMotionScroll(AbsListView.java:5193)
            at android.widget.AbsListView.scrollIfNeeded(AbsListView.java:3245)
            at android.widget.AbsListView.onTouchMove(AbsListView.java:3612)
            at android.widget.AbsListView.onTouchEvent(AbsListView.java:3434)
            at android.view.View.dispatchTouchEvent(View.java:7714)
            at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2210)
            at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1945)
            at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2216)
            at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1959)
            at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2216)
            at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1959)
            at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2216)
            at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1959)
            at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2216)
            at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1959)
            at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:2068)
            at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1515)
            at android.app.Activity.dispatchTouchEvent(Activity.java:2476)
            at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:2016)
            at android.view.View.dispatchPointerEvent(View.java:7894)
            at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:3995)
            at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:3874)
            at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3435)
            at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3485)
            at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3454)
            at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3561)
            at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3462)
            at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:3618)
            at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3435)
            at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3485)
            at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3454)
            at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3462)
            at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3435)
            at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:5580)
            at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:5560)
            at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:5531)
            at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:5660)
            at android.view.InputEventReceiver.dispatchInputEvent