Android SharedPreferences Tutorial and Example

Crafting CardView layouts with elevation and corner radius

CardView is a foundational component of Material Design layouts on Android, giving any view container that distinctive raised, rounded appearance users expect from polished apps. When paired with elevation and corner radius, the widget behaves like a real piece of layered paper, casting soft shadows that react to touch. Australian developers shipping to local audiences have a growing appetite for these refined surfaces, whether the project is a fitness tracker built in a Brisbane studio or a loyalty app for a Melbourne café chain.

Getting the visual balance right matters just as much as the code. A card with too much elevation looks heavy on a Pixel device in Sydney's afternoon sunlight, while corners that are too tight feel clinical rather than welcoming. The trick lies in tuning both attributes together and respecting platform guidelines, including the dp-based metrics that Android applies uniformly across regions and screen sizes.

This guide walks through the practical steps of styling CardView, drawing on patterns that work well in everyday Android Studio projects. Readers who want to combine their shiny new cards with persistent data can later explore a separate walkthrough on SQLite database setup.

What CardView brings to modern Android UI

CardView extends FrameLayout and lives in the AndroidX library, which means it inherits solid layout behaviour while adding its own paint properties. The widget renders rounded corners using a clipping mask and draws a shadow whose size is tied to its current elevation. Because these visual elements are computed on the UI thread, you can animate them with ObjectAnimator just like any other property.

Material Design 3 calls for cards to communicate hierarchy, and the elevation property is how that hierarchy is expressed numerically. Smaller values suit dense lists such as a contact roster for a Sydney real-estate agency, whereas larger values help flagship actions stand out, like the checkout button in an Adelaide-based grocery delivery app. Pairing elevation with a thoughtful corner radius completes the look, transforming flat rectangles into approachable surfaces.

Beyond aesthetics, cards create clear tap targets. By wrapping content inside a CardView and registering a single click listener, you avoid the common bug of nested listeners fighting over the same touch event. That alone is reason enough to adopt the widget in any new project.

Adding the CardView dependency in Gradle

Before any XML magic can happen, the dependency has to be present in the module-level build.gradle file. The current line to add is implementation 'androidx.cardview:cardview:1.0.0', and you should also confirm that androidx.appcompat:appcompat is at a compatible version. Australian teams often pin these versions in a project-level gradle.properties file so that every contributor in Brisbane, Perth, and Hobart pulls the same artefact.

After editing Gradle, Android Studio may prompt a sync. Accept the prompt or run the Sync action from the File menu. If you are working behind a corporate proxy in Melbourne's CBD, make sure your gradle.properties also includes the correct systemProp.https.proxyHost value, otherwise the dependency download will stall silently.

Once the sync finishes, the CardView class becomes available to your XML layouts and Kotlin or Java source files. You can verify the import by typing androidx.cardview.widget.CardView in a layout file and confirming that the autocomplete resolves without errors.

Defining corner radius and background colour

Corner radius is the property that turns a stiff rectangle into a friendly card. In XML, it is set through app:cardCornerRadius, expressed in dp so the value scales correctly on tablets and foldables alike. A good starting point is 8dp for compact cards in a recipe app designed for a Perth food blogger, while 16dp works beautifully for hero cards in a travel app showcasing Queensland's reef tours.

The background colour interacts with the radius to define the card's identity. Use app:cardBackgroundColor and pick a tone that contrasts with the parent surface. Material's tonal palette recommends light grey for elevated cards and pure white for the highest level, but localising colours to reflect Australian brand palettes is perfectly acceptable. For example, a fintech app from Sydney's startup district might use a deep navy that ties back to the harbour at dusk.

Be mindful that setting a custom background drawable can override the corner clipping. If you need an image inside the card, place the ImageView as a child rather than assigning a drawable to the card itself, otherwise the corners will appear square. This is a subtle pitfall that wastes hours for new developers.

Working with elevation and shadows

Elevation is controlled by the app:cardElevation attribute and is what tells the rendering engine how heavy the shadow should be. The Material guideline of 2dp for resting state and 8dp for pressed state works in most Australian apps, whether you are building a Sydney news reader or a cricket scoring utility used in Adelaide Oval's media box. The translation Z property can also be animated independently of elevation, allowing cards to lift during a drag gesture.

One detail that catches many developers off guard is that shadow rendering is disabled on older API levels unless the card has a non-null background. Setting app:cardBackgroundColor to anything other than transparent wakes the shadow pipeline up, and the same goes for programmatic elevation changes through setCardElevation. If your shadows refuse to appear, this is almost always the cause.

For apps that need more dramatic effects, you can combine CardView with a custom OutlineProvider, but this is rarely necessary in production. The default Material shadow already respects device DPI and orientation, so manual tuning is usually reserved for special branded components.

Handling ripple feedback and click events

A card that does not react to touch feels broken, which is why click feedback is essential. Setting android:clickable="true" on the CardView turns the ripple on automatically when the parent theme inherits from a Material theme. For apps that have not migrated to Material 3 yet, adding android:foreground="?attr/selectableItemBackground" ensures the ripple still appears.

Developers building inclusive apps for the Australian market should also respect accessibility settings. Honour the system font scale by avoiding fixed text heights inside the card, and ensure that the touch target spans at least 48dp. Many Sydney-based agencies bake these checks into their QA matrix so that older users on the Central Coast can still tap accurately.

If the card needs a more complex click behaviour, attach the listener with setOnClickListener in your Activity or Fragment. Remember to avoid nesting clickable children inside the card unless they handle a distinct action, otherwise the event dispatch chain becomes ambiguous.

Performance tips and common pitfalls

Although CardView is hardware-accelerated, overusing it inside long scrollable lists can still cause frame drops. The standard remedy is to set app:cardUseCompatPadding="true" so that older devices reserve the same outer space the shadow needs to render. Pair this with app:cardPreventCornerOverlap="true" when child views include custom shapes that bleed past the radius.

Animating elevation on every list item during a scroll is another common trap. The renderer redraws the shadow each frame, which multiplies the GPU cost across visible items. A more efficient pattern, popular among Melbourne-based performance engineers, is to animate only the focused or pressed card while leaving the rest at their resting elevation.

Finally, keep an eye on theme inheritance. Some legacy themes strip shadow rendering entirely, leaving your carefully crafted cards looking flat on devices as modern as a Pixel 7 in a Sydney showroom. Forcing the parent to Theme.MaterialComponents or its DayNight variant brings shadows back without the need for additional code.

Attribute XML form Programmatic setter Visual effect
cardCornerRadius app:cardCornerRadius setRadius(float) Smooths card edges
cardElevation app:cardElevation setCardElevation(float) Controls shadow depth
cardBackgroundColor app:cardBackgroundColor setCardBackgroundColor(int) Defines card surface colour
cardUseCompatPadding app:cardUseCompatPadding setUseCompatPadding(boolean) Reserves space for shadow
cardPreventCornerOverlap app:cardPreventCornerOverlap setPreventCornerOverlap(boolean) Avoids child view overlap with corners

Quick wins and common slip-ups

Common mistakes when working with CardView include:

  • Forgetting to set a non-transparent background colour, which silently disables shadows
  • Hard-coding corner radius in pixels rather than dp, breaking the layout on larger screens
  • Nesting clickable children without forwarding setOnClickListener calls correctly
  • Animating elevation inside a RecyclerView during scroll, causing noticeable jank

Practical adjustments for cleaner results:

  • Stick to the Material 2dp and 8dp elevation values unless branding demands otherwise
  • Use cardUseCompatPadding on devices below API 21 for consistent shadow space
  • Place background images as child ImageViews rather than card drawables
  • Verify the parent theme inherits from a Material Components theme