Reycler views and card views

The recycler view replaces the good old list view. It provides more flexibility in how the elements of a list are shown, for example, as a grid and as horizontal or vertical items. Instead of rows, we can now choose to display cards wherever it is suitable.

In our app, each card should display some text about the entry and a thumbnail of the picture that we took. This is what this recipe will be all about.

Getting ready

To go through this recipe, you need to have Android up and running. Also make sure that you have installed the latest SDK. (You can check whether you have the latest SDK by opening the SDK manager). To do so, open the Tools menu, choose Android, and next, choose the SDK Manager option.

How to do it...

Let's investigate, using the following steps, how to use recycler views and cards:

  1. Start Android Studio and start a new project. Name your application WaterApp and enter packtpub.com in the Company Domain field. Then, click on the Next button.
  2. Choose Blank Activity in the next dialog box and click on the Next button.
  3. In the following dialog box, click on the Finish button.
  4. Open the build.gradle file within your app folder and add the dependency for the recycler view to the dependencies section as shown in the following code:
    dependencies {
        compile fileTree(dir: 'libs', include: ['*.jar'])
        compile 'com.android.support:appcompat-v7:22.1.1'
        compile 'com.android.support:recyclerview-v7:+'
    }
  5. Change minSdkVersion to at least 21 in the build.gradle file.

    Note

    This does not really have to be the minimal required version, but since the support libraries for backward compatibility purposes do not contain all of the Material design features, I have chosen to pick API level 21 here, just to be on the safe side.

  6. Synchronize your project by clicking on the Sync now label on the yellow bar that appears after we edit the build.gradle file, or in case it does not, click on the Sync Project with Gradle files button on the toolbar.
  7. Open the activity_main.xml layout file, remove the Hello World TextView, and add a RecyclerView tag to the layout, like this:
    <android.support.v7.widget.RecyclerView
        android:id="@+id/main_recycler_view"
        android:scrollbars="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
  8. In your MainActivity class, add the following to the onCreate method just after setContentView:
    RecyclerView recyclerView = (RecyclerView) 
     findViewById(R.id.main_recycler_view);
  9. The RecyclerView class is not a known class yet. Use the Alt + Enter shortcut to add the right import statement or add the following line yourself:
    import android.support.v7.widget.RecyclerView;
  10. We are going to use a linear layout manager for this recipe. Add the following lines after the line we have added in step 9:
    LinearLayoutManager layoutManager = new LinearLayoutManager(this);
    recyclerView.setLayoutManager(layoutManager);
  11. Create a new package and name it models, and within this package, create a new Drink class as follows:
    package com.packt.waterapp.models;import java.util.Date;
    public class Drink {
        public Date dateAndTime;
        public String comments;
        public String imageUri;
    }

    Here, the Date class refers to the java.util.Date package (this is specified since there is also a SQL-related class with the same class name).

  12. Let's create a layout to display the items. Right-click on the layout package in the project tree and create a new resource file. To do so, choose New and New Layout Resource File from the menu. Name it adapter_main.xml and hit the OK button.
  13. Switch the layout to the Text modus, change the orientation of LinearLayout from vertical to horizontal, add some padding to it and add an image view to it, as shown in the following snippet. We will also add a default image so that we have something to look at:
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="horizontal" android:layout_width="match_parent"
    android:padding="8dp" android:layout_height="match_parent">
    <ImageView android:id="@+id/main_image_view"
    android:src="@android:drawable/ic_menu_camera"
    android:scaleType="center"
    android:layout_width="90dp"
    android:layout_height="90dp" />
    </LinearLayout>
  14. Next to the image, we want to display a date and time and the comments using two TextView widgets wrapped in another LinearLayout widget. Add these after the ImageView tag:
    <LinearLayoutandroid:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <TextView
            android:id="@+id/main_date_time_textview"
    		android:layout_marginTop="8dp"
    		android:textSize="12sp"
    		android:textColor="@color/material_blue_grey_800"
    		android:layout_width="match_parent"
    		android:layout_height="wrap_content" />
        <TextView
            android:id="@+id/main_comment_textview"
    		android:layout_marginTop="16dp"
    		android:maxLines="3"
    		android:textSize="16sp"
    		android:textColor="@color/material_deep_teal_500"
    		android:layout_width="match_parent"
    		android:layout_height="wrap_content" />
    	</LinearLayout>
  15. Create another package and name it adapters. Within that package, create the MainAdapter class that will be using a ViewHolder class, helping us to display the data exactly where we want it to appear. We also include all methods that need to be overridden such as the onBindViewHolder method and the getItemCount method:
    public class MainAdapter extends RecyclerView.Adapter<MainAdapter.ViewHolder> {
        private ArrayList<Drink> mDrinks;private Context mContext;public static class ViewHolder extends        RecyclerView.ViewHolder {
            public TextView mCommentTextView;
            public TextView mDateTimeTextView;
            public ImageView mImageView;
            public ViewHolder(View v) {
                super(v);
            }
        }
        public MainAdapter(Context context, 
          ArrayList<Drink> drinks) {
            mDrinks = drinks;
            mContext = context;
        }
        @Override
        public MainAdapter.ViewHolder  
         onCreateViewHolder(ViewGroup parent,  int viewType) {
            View v = LayoutInflater.from(
             parent.getContext()).inflate(
              R.layout.adapter_main, parent, false);
            ViewHolder viewHolder = new ViewHolder(v);
            viewHolder.mDateTimeTextView =  
             (TextView)v.findViewById(
              R.id.main_date_time_textview);
            viewHolder.mCommentTextView =  
             (TextView)v.findViewById(
              R.id.main_comment_textview);
            viewHolder.mImageView = 
             (ImageView)v.findViewById(
              R.id.main_image_view);
            return viewHolder;
        }
        @Override
        public int getItemCount() {
            return mDrinks.size();
        }
    }
  16. We have more things to do. Add the onBindViewHolder method and add the implementation to actually bind the data to the right widgets:
    @Override
    public void onBindViewHolder(ViewHolder holder,int position) {
        Drink currentDrink = mDrinks.get(position);
        holder.mCommentTextView.setText(
         currentDrink.comments);
        holder.mDateTimeTextView.setText(
         currentDrink.dateAndTime.toString());
        if (currentDrink.imageUri != null){
            holder.mImageView.setImageURI(
             Uri.parse(currentDrink.imageUri));
        }
    }
  17. In the MainActivity file, we need to have an instance of the adapter and some data to display. Add a private adapter and a private array list containing the Drink items:
    private MainAdapter mAdapter;private ArrayList<Drink> mDrinks;
  18. At the end of the onCreate method, tell recyclerView which adapter to use and tell the adapter which dataset to use:
    mAdapter = new MainAdapter(this, mDrinks);
    recyclerView.setAdapter(mAdapter);
    
  19. In the MainActivity file, we want to add some dummy data so that we have some idea about what things are going to look like. Add the following to the onCreate method just before the part where we create the MainAdapter class:
    mDrinks = new ArrayList<Drink>();
    Drink firstDrink = new Drink();
    firstDrink.comments = "I like water with bubbles most of the time...";
    firstDrink.dateAndTime = new Date();
    mDrinks.add(firstDrink);Drink secondDrink = new Drink();
    secondDrink.comments = "I also like water without bubbles. It depends on my mood I guess ;-)";
    secondDrink.dateAndTime = new Date();
    mDrinks.add(secondDrink);

    Import the required packages using the Alt + enter shortcut.

Run your app to verify that everything has gone well so far. Your app will display two entries containing the sample data that we have created in the previous step.

Using card views

The app looks okay but I would not want to call it beautiful yet. Let's see if we can improve this a little. The following steps will help us to create the app using card views:

  1. Open the build.gradle file in the app folder and add a CardView dependency, just after the one for the recycler view:
    compile 'com.android.support:cardview-v7:+'

    And synchronize your project again.

    Note

    By the way, if this app was for real, then avoid unpleasant surprises by specifying an exact version instead of using the + sign in the version number for any dependency your app may have. Currently, this is 21.0.0 for this particular dependency, but By the time you read this, a new version might be available.

  2. If an error appears indicating Gradle failed to resolve the card view dependency, then click on the Install Repository and sync project link, accept the license, and click on the Next button. Wait a while until the download is complete and the installation has finished. Once this is done, click on the Finish button. Sync your project again.
  3. Create a new layout and name it adapter_main_card_view.xml. Add some padding to the LinearLayout tag and within the linear layout tag, add a CardView:
    <?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"   
        android:layout_width="match_parent"
        android:padding="4dp"  
        android:layout_height="match_parent">
        <android.support.v7.widget.CardView
            xmlns:card_view=
            "http://schemas.android.com/apk/res-auto"android:id="@+id/card_view"
            android:layout_gravity="center"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"card_view:cardCornerRadius="4dp"></android.support.v7.widget.CardView>
    </LinearLayout>
  4. From the previous layout, the adapter_main.xml file, copy ImageView and the two TextView widgets (but not LinearLayout that contains the two TextView widgets) and paste them within CardView that you have added to the adapter_main_card_view.xml file.
  5. Because CardView behaves as if it is FrameLayout, you need to set the margins for the text labels. Add a left margin to both text views. Also modify the top margin for the TextView comment:
    <TextView
        android:id="@+id/main_date_time_textview"
    	android:layout_marginTop="8dp"
    	android:layout_marginLeft="100dp"
    	android:textSize="12sp"
    	android:textColor="@color/material_blue_grey_800"
    	android:layout_width="match_parent"
    	android:layout_height="wrap_content" />
    <TextView
        android:id="@+id/main_comment_textview"
    	android:layout_marginTop="32dp"
    	android:layout_marginLeft="100dp"
    	android:maxLines="3"
    	android:textSize="16sp"
    	android:textColor="@color/material_deep_teal_500"
    	android:layout_width="match_parent"
    	android:layout_height="wrap_content" />
  6. Now you tell the MainAdapter class to use this layout by changing the layout ID in the onCreateViewHolder method:
    View v = LayoutInflater.from(parent.getContext()). inflate(R.layout.adapter_main_card_view, parent, false);

    Run the app again and we will see what it will look like this time:

    Using card views
  7. In the next recipe, we will add an elevated floating button and we will create a new activity that allows the users of our app to add drinks, comments, and a selfie.

There's more...

There is a lot of documentation about material design. Browse through the various examples that are available on various websites, such as https://www.materialup.com, http://materialdesignblog.com or http://material-design.tumblr.com.

Or, download some of the material designed apps that are available in the Play Store, such as the Inbox, Google+, Wunderlist, Evernote, LocalCast, and SoundCast apps.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset