Building a UI with CardView and ScrollView
Create a new project in the usual way. Name the project CardView Layout
and choose the Empty Activity project template. Leave all the rest of the settings the same as all the previous projects.
To be able to edit our theme and properly test the result, we need to generate our layout file and edit the Kotlin code to display it by calling the setContentView
function from the onCreate
function. We will design our CardView
masterpiece inside a ScrollView
layout, which, as the name suggests, allows the user to scroll through the content of the layout.
Right-click the layout
folder and select New. Notice that there is an option for Layout resource file. Select Layout resource file and you will see the New Resource File dialog window.
In the File name field, enter main_layout
. The name is arbitrary, but this layout is going to be our main layout, so the name makes that plain.
Notice that it is set to LinearLayout as the Root element option. Change it to ScrollView
. This layout type appears to work just like LinearLayout,
except that, when there is too much content to display on screen, it will allow the user to scroll the content by swiping with their finger.
Click the OK button and Android Studio will generate a new ScrollView
layout in an XML file called main_layout
and place it in the layout
folder ready for us to build our CardView
-based UI.
You can see our new file in this next screenshot:
Android Studio will also open the UI designer ready for action.
Setting the view with Kotlin code
As we have done previously, we will now load the main_layout.xml
file as the layout for our app by calling the setContentView
function in the MainActivity.kt
file.
Select the MainActivity.kt
tab. In the unlikely event the tab isn't there by default, you can find it in the project explorer under app/java/your_package_name
, where your_package_name
is equal to the package name that you chose when you created the project.
Amend the code in the onCreate
function to look exactly like this next code. I have highlighted the line that you need to add:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.main_layout);
}
You could now run the app, but there is nothing to see except an empty ScrollView
layout.
Adding image resources
We are going to need some images for this project. This is so we can demonstrate how to add them into the project (this section) and neatly display and format them in a CardView
layout (next section).
It doesn't really matter where you get your images from. It is the practical hands-on experience that is the purpose of this exercise. To avoid copyright and royalty issues, I am going to use some book images from the Packt Publishing website. This also makes it easy for me to provide you with all the resources you need to complete the project should you not want to go to the bother of acquiring your own images. Feel free to swap the images in the Chapter05/CardViewLayout/res/drawable
folder.
There are three images: image_1.png
, image_2.png
, and image_3.png
. To add them to the project, follow these steps.
- Find the image files using your operating system's file explorer.
- Highlight them all and press Ctrl + C to copy them.
- In the Android Studio project explorer, select the
res/drawable
folder by left-clicking it. - Right-click the
drawable
folder and select Paste. - In the pop-up window that asks you to Choose Destination Directory, click OK to accept the default destination, which is the
drawable
folder. - Click OK again to Copy Specified Files.
You should now be able to see your images in the drawable
folder along with a couple of other files that Android Studio placed there when the project was created, as shown in this next screenshot:
Before we move on to CardView,
let's design what we will put inside them.
Creating the content for the cards
The next thing we need to do is create the content for our cards. It makes sense to separate the content from the layout. What we will do is create three separate layouts, called card_contents_1
, card_contents_2,
and card_contents_3
. They will each contain a LinearLayout
, which will contain the actual image and text.
Let's create three more layouts with LinearLayout
at their root:
- Right-click the
layout
folder and select New layout resource file. - Name the file
card_contents_1
and make sure that LinearLayout is selected as the Root element - Click OK to add the file to the
layout
folder - Repeat steps one through three two more times, changing the filename each time to
card_contents_2
and thencard_contents_3
Now, select the card_contents_1.xml
tab and make sure you are in design view. We will drag and drop some elements to the layout to get the basic structure and then we will add some sp
, dp
, and gravity attributes to make them look nice:
- Drag a
TextView
widget on to the top of the layout. - Drag an
ImageView
widget on to the layout belowTextView
widget. - In the Resources pop-up window, select Project | image_1 and then click OK.
- Drag another two TextView widgets below the image.
- This is how your layout should now appear:
Now, let's use some material design guidelines to make the layout look more appealing.
Tip
It is possible that, as you proceed through these modifications, the UI elements on the bottom of the layout might disappear from the bottom of the design view. If this happens to you, remember you can always select any UI element from the Component Tree window underneath the palette. Or, refer to the next tip.
Another way of minimizing the problem is to use a bigger screen, as explained in the following instructions:
Tip
I changed the default device for the design view to Pixel 2 XL to create the previous screenshot. I will leave this setting for the rest of the book unless I specifically mention that I am changing it. It allows a few more pixels on the layout and means this layout is easier to complete. If you want to do the same, look at the menu bar above the design view, click the device dropdown, and choose your design view device, as shown in the following screenshot:
- Set the
textSize
attribute for theTextView
widget at the top to24sp.
- Set the Layout_Margin | all attribute to
16dp.
- Set the
text
attribute to Learning Java by Building Android Games (or whatever title suits your image). - On the
ImageView
, setlayout_width
andlayout_height
towrap_content.
- On the
ImageView
, setlayout_gravity
tocenter_horizontal.
- On the
TextView
beneath theImageView,
settextSize
to16sp.
- On the same
TextView,
set Layout_Margin | all to16dp.
- On the same
TextView,
set thetext
attribute toLearn Java and Android from scratch by building 6 playable games
(or something that describes your image). - On the bottom
TextView,
change thetext
attribute toBUY NOW.
- On the same
TextView,
set Layout_Margin | all to16dp.
- On the same
TextView,
set thetextSize
attribute to24sp.
- On the same
TextView,
set thetextColor
attribute to@color/colorAccent.
- On the
LinearLayout
holding all the other elements, setpadding
to15dp
. Note that it is easiest to selectLinearLayout
from the Component Tree window. - At this point, your layout will look very similar to the following screenshot:
Now, lay out the other two files (card_contents_2
and card_contents_3)
with the exact same dimensions and colors. When you get the Resources popup to choose an image, use image_2
and image_3
respectively. Also, change all the text
attributes on the first two TextView
elements so that the titles and descriptions are unique. The titles and descriptions don't really matter; it is layout and appearance that we are learning about.
Tip
Note that all the sizes and colors were derived from the material design website at https://material.io/design/introduction, and the Android specific UI guideline at https://developer.android.com/guide/topics/ui/look-and-feel. It is well worth studying alongside this book, or soon after you complete it.
We can now move on to CardView
.
Defining dimensions for CardView
Right-click the values
folder and select New | Values resource file. In the New Resource File pop-up window, name the file dimens.xml
(short for dimensions) and click OK. We will use this file to create some common values that our CardView
object will use by referring to them.
To achieve this, we will edit the XML directly. Edit the dimens.xml
file to be the same as the following code:
<?xml version="1.0" encoding="utf-8"?> <resources> <dimen name="card_corner_radius">16dp</dimen> <dimen name="card_margin">10dp</dimen> </resources>
Be sure to make it exactly the same because a small omission or mistake could cause an error and prevent the project from working.
We have defined two resources, the first called card_corner_radius,
with a value of 16dp,
and the second called card_margin,
with a value of 10dp
.
We will refer to these resources in the main_layout
file and use them to consistently configure our three CardView
elements.
Adding CardView to our layout
Switch to the main_layout.xml
tab and make sure you are in the design view. You probably recall that we are now working with a ScrollView
that will scroll the content of our app, rather like a web browser scrolls the content of a web page that doesn't fit on one screen.
ScrollView
has a limitation – it can only have one direct child layout. We want it to contain three CardView
elements.
To overcome this problem, drag a LinearLayout
from the Layouts
category of the palette. Be sure to pick LinearLayout (vertical), as represented by this icon in the palette:
We will add our three CardView
objects inside LinearLayout
and then the whole thing will scroll nice and smoothly without any errors.
CardView
can be found in the Containers category of the palette, so switch to that and locate CardView
.
Drag a CardView
object onto the LinearLayout
on the design and you will get a pop-up message in Android Studio. This is the message pictured here:
Click the OK button, and Android Studio will do some work behind the scenes and add the necessary parts to the project. Android Studio has added some more classes to the project, specifically, classes that provide CardView
features to older versions of Android that wouldn't otherwise have them.
You should now have a CardView
object on the design. Until there is some content in it, the CardView
object is only easily visible in the Component Tree window.
Select the CardView
object via the Component Tree window and configure the following attributes:
- Set
layout_width
towrap_content
- Set
layout_gravity
tocenter
- Set Layout_Margin | all to
@dimens/card_margin
- Set
cardCornerRadius
to@dimens/card_corner_radius
- Set
cardEleveation
to2dp
Now, switch to the Text tab and you will find you have something very similar to this next code:
<androidx.cardview.widget.CardView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_margin="@dimen/card_margin" app:cardCornerRadius="@dimen/card_corner_radius" app:cardElevation="2dp" />
The previous code listing only shows the code for the CardView
object.
The current problem is that our CardView
object is empty. Let's fix that by adding the content of card_contents_1.xml
. Here is how to do it.
Including layout files inside another layout
We need to edit the code very slightly, and here is why. We need to add an include
element to the code. The include
element is the code that will insert the content from the card_contents_1.xml
layout. The problem is that, to add this code, we need to slightly alter the format of the CardView
XML. The current format starts and concludes the CardView
object with one single tag, as follows:
<androidx.cardview.widget.CardView … …/>
We need to change the format to a separate opening and closing tag like this (don't change anything just yet):
<androidx.cardview.widget.CardView … … </androidx.cardview.widget.CardView>
This change in format will enable us to add the include…
code, and our first CardView
object will be complete. With this in mind, edit the code of CardView
to be exactly the same as the following code. I have highlighted the two new lines of code, but also note that the forward slash that was after the cardElevation
attribute has also been removed:
<androidx.cardview.widget.CardView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_margin="@dimen/card_margin" app:cardCornerRadius="@dimen/card_corner_radius" app:cardElevation="2dp" > <include layout="@layout/card_contents_1" /> </androidx.cardview.widget.CardView>
You can now view the main_layout
file in the visual designer and see the layout inside the CardView
object. The visual designer does not reveal the real aesthetics of CardView
. We will see all the CardView
widgets scrolling nicely in the completed app shortly. Here is a screenshot of where we are up to so far:
Add two more CardView
widgets to the layout and configure them the same as the first, with one exception. On the second CardView
object, set cardElevation
to 22dp
and, on the third CardView
object, set cardElevation
to 42dp
. Also, change the include
code to reference card_contents_2
and card_contents_3
respectively.
Tip
You could do this very quickly by copying and pasting the CardView
XML and simply amending the elevation and the include
code, as mentioned in the previous paragraph.
Now we can run the app and see our three beautiful, elevated CardView
widgets in action. In this next screenshot, I have photoshopped two screenshots to be side by side, so you can see one full CardView
layout in action (on the left) and, in the image on the right, the effect the elevation setting has, which creates a very pleasing depth with a shadow effect:
Note
The image will likely be slightly unclear in the black and white printed version of this book. Be sure to build and run the app for yourself to see this cool effect.
Now we can play around with editing the theme of the app.