Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android - Building a list of cards

I want my application to have a list of cards that users can scroll through, click actions, etc. Specifically, I want to use the android.design.CardView class in the support library.

As far as I'm aware, there are questions about this on SO, but it does not solve my problem. The solutions on the question I saw either say to use a list and add card-like backgrounds to each item, briefly mention CardViews (i.e. only mention the existence of them) or rely on a third party library.

I want to know if it is possible using only the core android API's and support libraries to vertical scrolling lists of cards either by themselves of in a RecyclerView. (but removing any dividers or other things that make it look like a list is behind the cards) Is this possible?

like image 479
James Parsons Avatar asked Jan 04 '16 23:01

James Parsons


2 Answers

Well based on that you would like to have a List of CardViews....you can define in your row_layout.xml the code like this:

<?xml version="1.0" encoding="utf-8"?>
    <android.support.v7.widget.CardView
        android:background="?android:attr/selectableItemBackground"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/cv">

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:focusable="true"
            android:clickable="true"
            android:padding="16dp">

            <ImageView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:id="@+id/person_photo"
                android:layout_alignParentLeft="true"
                android:layout_alignParentTop="true"
                android:layout_marginRight="16dp"
                />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:id="@+id/person_name"
                android:layout_toRightOf="@+id/person_photo"
                android:layout_alignParentTop="true"
                android:textSize="30sp"
                />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:id="@+id/person_age"
                android:layout_toRightOf="@+id/person_photo"
                android:layout_below="@+id/person_name"
                />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text=" €"
                android:id="@+id/textView"
                android:layout_marginLeft = "10dp"
                android:layout_below="@+id/person_name"
                android:layout_toEndOf="@+id/person_age" />

        </RelativeLayout>

    </android.support.v7.widget.CardView>

Then your layout containing the RecyclerView:

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    tools:context=".MainActivity">

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <include android:id="@+id/toolBar" layout="@layout/toolbar_top" app:layout_scrollFlags="scroll|enterAlways|snap"/>
    </android.support.design.widget.AppBarLayout>

    <android.support.v4.widget.SwipeRefreshLayout
        android:layout_width="match_parent"
        android:id="@+id/swipe"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"
        android:layout_height="wrap_content">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recyclerList"
        android:layout_width="match_parent"
        android:background="@color/colorAccent"
        android:layout_height="wrap_content"/>
    </android.support.v4.widget.SwipeRefreshLayout>
</android.support.design.widget.CoordinatorLayout>

and In your Adapter CardView can be defined as root element:

public class Adapter extends RecyclerView.Adapter<Adapter.StockViewHolder>{

    List<Stock> stocks;

    public Adapter(List<Stock> stocks){
        this.stocks = stocks;
    }

    @Override
    public StockViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_layout, parent, false);
        StockViewHolder pvh = new StockViewHolder(v);
        return pvh;
    }

    @Override
    public void onBindViewHolder(StockViewHolder holder, int position) {
        holder.stockName.setText(stocks.get(position).getName());
        holder.stockPrice.setText(stocks.get(position).getPrice());
        Ion.with(holder.stockPhoto).error(R.mipmap.ic_launcher).load(stocks.get(position).getPhotoId());
    }

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

    @Override
    public void onAttachedToRecyclerView(RecyclerView recyclerView) {
        super.onAttachedToRecyclerView(recyclerView);
    }

    public static class StockViewHolder extends RecyclerView.ViewHolder {
        CardView cv;
        TextView stockName;
        TextView stockPrice;
        ImageView stockPhoto;

        StockViewHolder(View itemView) {
            super(itemView);
            cv = (CardView)itemView.findViewById(R.id.cv);
            stockName = (TextView)itemView.findViewById(R.id.person_name);
            stockPrice = (TextView)itemView.findViewById(R.id.person_age);
            stockPhoto = (ImageView)itemView.findViewById(R.id.person_photo);
        }
    }

}

and this will give you this result:

enter image description here

which is an actual list of CardViews.

Hope it helps!

like image 162
Kostas Drak Avatar answered Oct 14 '22 20:10

Kostas Drak


I would recommend you to check out these links:

https://github.com/Suleiman19/Masonry

https://guides.codepath.com/android/using-the-recyclerview

The Codepath guide has a very good example on how to implement the onClick on each item:

public class ContactsAdapter extends RecyclerView.Adapter<ContactsAdapter.ViewHolder> {
    // ...

    // Used to cache the views within the item layout for fast access
    public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
        public TextView tvName;
        public TextView tvHometown;
        private Context context;

        public ViewHolder(Context context, View itemView) {
            super(itemView);
            this.tvName = (TextView) itemView.findViewById(R.id.tvName);
            this.tvHometown = (TextView) itemView.findViewById(R.id.tvHometown);
            // Store the context
            this.context = context;
            // Attach a click listener to the entire row view
            itemView.setOnClickListener(this);
        }

        // Handles the row being being clicked
        @Override
        public void onClick(View view) {
            int position = getLayoutPosition(); // gets item position
            User user = users.get(position);
            // We can access the data within the views
            Toast.makeText(context, tvName.getText(), Toast.LENGTH_SHORT).show();
        }
    }

    // ...
}

The Masonry one is related to a more advance use of a RecyclerView with CardView (getting a StaggeredGrid).

like image 37
Evin1_ Avatar answered Oct 14 '22 20:10

Evin1_