Search code examples
androidmaterial-designpicassocardslib

Generate cards with cardslib and load images with picasso


I am using cardslib (https://github.com/gabrielemariotti/cardslib) to create a project with cards and use picasso (http://square.github.io/picasso/), in order to dynamically create cards and load pictures into them with urls that I retrieve from Parse in a for loop.

The problem I have is that even though I retrieve the correct data from Parse, only one image is loaded in all of the cards. The titles, subtitles etc are loaded correctly for each separate card, only the image is the same everywhere.

My code is :

final ArrayList<Card> cards = new ArrayList<Card>();


    final    CardArrayAdapter mCardArrayAdapter = new CardArrayAdapter(this,cards);

    mRecyclerView = (CardListView) this.findViewById(R.id.carddemo_largeimage_text);



    AnimationAdapter animCardArrayAdapter = new SwingBottomInAnimationAdapter(mCardArrayAdapter);
    animCardArrayAdapter.setAbsListView(mRecyclerView);
    mRecyclerView.setExternalAdapter(animCardArrayAdapter, mCardArrayAdapter);




    ParseQuery<ParseObject> query = ParseQuery.getQuery("places");

    query.findInBackground(new FindCallback<ParseObject>() {
        public void done(List<ParseObject> List, ParseException e) {
            if (e == null) {

                for ( i=0; i<List.size();i++){
                    id=new String();
                    id=List.get(i).getString("picture");
                    System.out.println(i+"        "+ id);


                    MaterialLargeImageCard card =
                            MaterialLargeImageCard.with(mContext)
                                    .setTextOverImage(List.get(i).getString("place_id"))
                                    .setTitle(List.get(i).getString("subtitle"))
                                    .setSubTitle(List.get(i).getString("description"))
                                    .useDrawableExternal(new MaterialLargeImageCard.DrawableExternal() {
                                        @Override
                                        public void setupInnerViewElements(ViewGroup parent, View viewImage) {

                                            Picasso.with(mContext).setIndicatorsEnabled(true);  //only for debug tests
                                            Picasso.with(mContext)
                                                    .load(id)
                                                    .error(R.drawable.ic_launcher)
                                                    .into((ImageView) viewImage);
                                        }
                                    })
                                    .setupSupplementalActions(R.layout.carddemo_native_material_supplemental_actions_large, actions)
                                    .build();
                    cards.add(card);
                    mCardArrayAdapter.notifyDataSetChanged();


                    card.setOnClickListener(new Card.OnCardClickListener() {
                        @TargetApi(Build.VERSION_CODES.LOLLIPOP)
                        @Override
                        public void onClick(Card card, View view) {
                            Toast.makeText(mContext, " Click on ActionArea ", Toast.LENGTH_SHORT).show();
                            onClickStart();
                            Intent myIntent = new Intent(MainActivity.this, ParallaxToolbarScrollViewActivity.class);
                            //yIntent.putExtra("key", value); //Optional parameters

                            MainActivity.this.startActivity(myIntent);

                        }
                    });



                }

            } else {
                Log.d("score", "Error: " + e.getMessage());
            }
        }
    });

The layouts I use are: activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:card="http://schemas.android.com/apk/res-auto"
xmlns:pew="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"

tools:context=".MainActivity">


<it.gmariotti.cardslib.library.view.CardListView
    android:id="@+id/carddemo_largeimage_text"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    card:list_card_layout_resourceID="@layout/rowcard"
    style="@style/card_external"
    /></RelativeLayout>

rowcard.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:card="http://schemas.android.com/apk/res-auto"
xmlns:pew="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"

tools:context=".MainActivity">
<it.gmariotti.cardslib.library.view.CardViewNative
    android:id="@+id/list_cardId"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    card:card_layout_resourceID="@layout/native_material_largeimage_text_card"
    style="@style/card_external"
    /></RelativeLayout>

native_material_largeimage_text_card.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card="http://schemas.android.com/apk/res-auto"
xmlns:pew="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<!-- Card visible layout -->
<it.gmariotti.cardslib.library.view.ForegroundLinearLayout
    android:id="@+id/card_main_layout"
    style="@style/card.native.main_layout_foreground"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >
    <it.gmariotti.cardslib.library.view.component.CardThumbnailView
        style="@style/card.native.card_thumbnail_outer_layout"
        android:id="@+id/card_thumbnail_layout"
        android:layout_width="match_parent"
        card:card_thumbnail_layout_resourceID="@layout/native_thumbnail_largematerial"
        android:layout_height="match_parent"/>
    <!-- Main Content View -->
    <FrameLayout
        android:id="@+id/card_main_content_layout"
        style="@style/card.native.material_large_image_content_outer_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</it.gmariotti.cardslib.library.view.ForegroundLinearLayout>
<View
    android:layout_width="fill_parent"
    android:layout_height="1dp"
    android:background="@color/greydiv"/>
<ViewStub
    android:id="@+id/card_supplemental_actions_vs"
    android:inflatedId="@+id/card_supplemental_actions"


    android:layout_width="match_parent"
    android:layout_height="wrap_content"/></LinearLayout>

And native_thumbnail_largematerial.xml

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="@dimen/card_material_largeimage_height">
<com.fmsirvent.ParallaxEverywhere.PEWImageView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/card_thumbnail_image"
    android:transitionName="test"
    android:layout_height="match_parent"
    android:layout_width="match_parent"
    android:scaleType="centerCrop"
    style="@style/card.native.card_thumbnail_image"/>
<FrameLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingRight="@dimen/card_thumbnail_image_text_over_padding_right"
    android:paddingLeft="@dimen/card_thumbnail_image_text_over_padding_left"
    android:paddingTop="@dimen/card_thumbnail_image_text_over_padding_top"
    android:paddingBottom="@dimen/card_thumbnail_image_text_over_padding_bottom">
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom"
        android:fontFamily="@string/card_font_fontFamily_image_text_over"
        android:id="@+id/card_thumbnail_image_text_over"
        style="@style/card_thumbnail_image_text_over_textstyle"
        />
</FrameLayout></FrameLayout>

Solution

  • I use CardsLib and picasso together for almost all my cards. What I recommend you is to make a CustomCard which extends card and receives a ParseObject as a parameter for the card.

    It would make your code much simpler as well as you would add your cards to the list this way:

    for(ParseObject p : List) {
        cards.add(new MyCustomCard(mContext, p));
    }
    

    Your custom card would look something like this:

    public class MyCustomCard extends Card implements Card.OnCardClickListener {
    
        private static final String LOG_TAG = MyCustomCard.class.getSimpleName();
        private ParseObject parseObject;
    
        public MyCustomCard(Context context, ParseObject data) {
            super(context, R.layout.my_custom_layout);
            this.parseObject = data;
            this.setOnClickListener(this);
        }
    
        @Override
        public void setupInnerViewElements(ViewGroup parent, View view) {
            super.setupInnerViewElements(parent, view);
    
            ImageView imageView = (ImageView)         view.findViewById(R.id.data_thumbnail);
            TextView title = (TextView) view.findViewById(R.id.title);
            TextView text = (TextView) view.findViewById(R.id.text);
    
            if(parseObject != null) {
                Picasso.with(getContext()).load(parseObject.getString("picture")).fit().into(imageView);
                title.setText(parseObject.getString("title"));
                text.setText(parseObject.getString("text"));
            }
        }
    
        @Override
        public void onClick(Card card, View view) {
           // in case your cards need to click on something. You don't need to 
           // override onCLick if you don't wish to have click functionality on the cards
    
        }
    }
    

    You could even extend the MaterialLargeImageCard and use it's own XML instead of making your own.

    I have some custom cards with Picasso examples in a few of my projects on github: check this project for more examples