Android SharedPreferences Tutorial and Example

Styling buttons with shape drawable and selector in Android

Material guidelines give every Button widget a sensible default, yet that default rarely reflects what a product team actually wants. Bootcamp students in Sydney and Melbourne, including those working through assignments at General Assembly, soon notice how restrictive the stock button looks when stacked beside branded cards and coloured surfaces.

XML resources offer a cleaner route than rewriting Java or Kotlin views from scratch. A shape drawable defines the geometry — colour, gradient, corners, padding — while a selector file picks the right drawable based on the current state such as pressed, focused, or disabled. Wired together, they produce buttons that feel handcrafted rather than handed out by the platform, the kind of polish that helps an app stand out in the Australian Google Play Store.

The walkthrough below starts with the fundamentals, compares drawable types through a side-by-side breakdown, then layers in selectors, gradient fills, and accessibility-aware states. The closing example also touches on saving the user's preferred style, which pairs naturally with the SharedPreferences patterns covered in earlier tutorials.

Getting comfortable with shape drawable

A shape drawable is an XML file describing a geometric figure. The rectangle variant is the workhorse for button styling because it fills the available area and accepts solid colours, gradients, border strokes, and corner radii.

The root element is <shape>, placed inside the res/drawable/ folder. Child elements include <solid>, <gradient>, <stroke>, <corners>, <padding>, and <size>. Each carries attributes reminiscent of CSS, so developers familiar with web styling adapt quickly.

Used alone, a shape drawable produces a static look. To make the button react when tapped, it must be paired with a selector resource. The combination forms the styling backbone of nearly every custom button shipped in production-grade apps.

Choosing between shape, nine-patch, and vector drawables

Different drawables suit different jobs, and the wrong choice leads to scaling surprises down the track. Here is how they compare for button work:

Feature Shape drawable Nine-patch Vector drawable
Scales to any size Yes Yes Yes
Supports gradients Yes No No
Per-state styling With selector With selector Limited
Best for icons No No Yes
File type .xml .9.png .xml

For solid, rounded, or gradient buttons, the shape drawable paired with a selector remains the lightest option. Nine-patch images shine when stretched pixel art is needed, which suits retro-styled apps. Vector drawables cover icon-only buttons where crisp scaling matters more than colour fills.

Writing a selector resource

A selector is a state list — XML that maps a button's current condition to a specific drawable. The <selector> root contains <item> children carrying attributes such as state_pressed, state_focused, state_enabled, and state_selected.

Item order matters because the system reads top to bottom and applies the first match. Pressed and focused entries should sit above the default item, which always remains as the fallback. Skipping this ordering is a frequent reason a tapped button looks identical to its idle state.

Selectors are drawable-agnostic, so a shape drawable can serve the default state while a darker version handles the pressed state. That mix-and-match flexibility is what makes the resource reusable across screens without duplicating files.

Building rounded and gradient buttons

Rounded corners and gradients give shape drawables their visual punch. Setting <corners android:radius="12dp"/> produces a soft, modern edge popular among Australian fintech and lifestyle apps. Gradients arrive via <gradient> with start, centre, and end colour stops.

Try a vertical gradient moving from #1976D2 to #0D47A1 with a 16dp radius — the deep ocean-blue pairs well with white text on light backgrounds. For dark themes, swap to slate tones and lift the radius to 20dp for a friendlier profile.

If the gradient appears flat on certain devices, check that android:angle is a multiple of 45. OEM skins on phones sold through retailers such as JB Hi-Fi and Officeworks sometimes render gradients inconsistently when the angle falls outside that range.

Reacting to pressed, focused, and disabled states

State handling is where a static coloured block becomes something that feels alive. Three states deserve dedicated treatment:

  • Pressed — apply a darker fill or a subtle inset shadow
  • Focused — useful for D-pad navigation on Android TV and tablets common in living rooms across Brisbane and Adelaide
  • Disabled — drop opacity or apply a muted grey fill so the button reads as inactive

Each state maps to an <item> entry in the selector. Forgetting android:state_enabled="false" is a classic bug; the button looks interactive even when the activity decides otherwise. Pairing visual cues with content descriptions also helps screen reader users navigate confidently — a convention most AU government apps follow.

Keeping performance and memory in check

Shape drawables and selectors are lightweight, yet small oversights compound inside a complex layout. Watch for these habits:

  • Reuse a single drawable across multiple buttons rather than duplicating XML
  • Keep gradient stops to two or three colours to limit overdraw
  • Cache selectors inside RecyclerView items instead of inflating each row fresh
  • Avoid stacking many <layer-list> elements on top of one shape

When views inflate repeatedly — for example, across a list of stations in the Sydney Metro network — these adjustments cut noticeable frame drops. Most Brisbane startup teams profile first, then optimise, because overdraw hides until the busiest moment hits.

Bringing it all together in a sample app

Imagine a small activity that lets users pick their favourite Australian city and persist the choice. The button uses a rounded shape drawable by default, a darker variant when pressed, and a muted fill when focused through a D-pad. The selection can be stored through the SharedPreferences APIs covered in the SharedPreferences store list walkthrough.

The same styling pattern adapts to a settings screen or a bottom-sheet action. Once the structure clicks, other surfaces tend to follow the same blueprint — gradient fills, rounded corners, and thoughtful state feedback — which is what most Android users expect when tapping a control on a handset bought from a carrier store in Parramatta, Geelong, or Subiaco.