Mehdi Tmimi Mobile

Mobile Development Lab 1 Part 4 of 8

Make it beautiful: resources

You typed #C2410C and #FFFFFF into the layout. Change a colour? You hunt for every copy.

The emulator at the end of Part 3: the skeleton, an orange band with the launcher robot and “Notes 0”, a white card with a purple Add.
Where you start

Before you start

By the end you can

  • name each text and each colour once, in res/values;
  • draw shapes, a gradient and a vector icon;
  • set the theme’s colours and tell a theme from a style.
  • Layout Split
  • Resources res › values · res › drawable
  • Emulator
Behind, or a fresh project? Start from here about 4 min
  1. The project: your own from Part 3, or a fresh one: Part 0, steps 0.3 and 0.4 (about 5 minutes).

  2. Your package name, for the code of this page:

    Without JavaScript, the code says com.yourname.notes: replace yourname by the name you chose.

  3. Gradle: check these 3 lines. Add any that is missing, then click Sync Now. Keep your own version numbers.

    Gradle Scripts › libs.versions.tomlAdd the marked lines
    [versions]agp = "9.5.0"junit = "4.13.2"junitVersion = "1.3.0"espressoCore = "3.7.0"appcompat = "1.8.0"material = "1.14.0"constraintlayout = "2.2.2"
    [libraries]junit = { group = "junit", name = "junit", version.ref = "junit" }ext-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" }appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" }material = { group = "com.google.android.material", name = "material", version.ref = "material" }constraintlayout = { group = "androidx.constraintlayout", name = "constraintlayout", version.ref = "constraintlayout" }
    [plugins]android-application = { id = "com.android.application", version.ref = "agp" }
    Gradle Scripts › build.gradle.kts (Module :app)Add the marked lines
    plugins {    alias(libs.plugins.android.application)}
    android { namespace = "com.yourname.notes" compileSdk { version = release(37) }
    defaultConfig { applicationId = "com.yourname.notes" minSdk = 24 targetSdk = 37 versionCode = 1 versionName = "1.0"
    testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" }
    buildTypes { release { optimization { enable = true packageScope = setOf("androidx.**", "kotlin.**", "kotlinx.**") } } } compileOptions { sourceCompatibility = JavaVersion.VERSION_11 targetCompatibility = JavaVersion.VERSION_11 }}
    dependencies { implementation(libs.appcompat) implementation(libs.material) implementation(libs.constraintlayout) testImplementation(libs.junit) androidTestImplementation(libs.espresso.core) androidTestImplementation(libs.ext.junit)}
  4. res and manifest: download the pack and open it in Explorer. Drag its app folder onto your project folder (C:\Users\<you>\AndroidStudioProjects\Notes), then choose Replace the files in the destination. Not Extract All: it makes a folder inside and replaces nothing. Then, in res › values › themes, delete themes.xml (night) if it is still there.

    lab1-part4-res.zip zip · 3.0 KB
  5. Java: open MainActivity.java, select all, then paste this file. Missing? First right-click kotlin+java › com.yourname.notes, the one without (test), then NewJava Class: type MainActivity, then press Enter.

    kotlin+java › com.yourname.notes › MainActivity.javaReplace the whole file
    package com.yourname.notes;
    import android.os.Bundle;
    import androidx.appcompat.app.AppCompatActivity;
    public class MainActivity extends AppCompatActivity {
    @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); }}
  6. ▶. You are ready when the phone shows the skeleton: an orange band, the robot, a white card.

Step 1 of 6

Move the texts into strings.xml

5 min

Goal Give every text of the screen a name in strings.xml.

  • Layout res › layout › activity_main.xml · Split
  • Resources res › values › strings.xml
  1. The Add button’s text, in the layout’s code.

    1. Open res › layout › activity_main.xml.
    2. Click Split, at the top right of the editor.
    3. In the code, scroll to line 125: android:text="Add", the Add button’s text.
  2. The Add button’s text, made a resource.

    1. Click inside "Add", then press Alt+Enter.
    2. A popup opens: click Extract string resource, its first choice.
    activity_main.xml Editor · centreFull size
    The layout code with the caret on "Add": the Alt+Enter popup offers Extract string resource first, then Suppress: Add tools:ignore="HardcodedText" attribute.
    1. "Add": click it, then Alt+Enter.
    2. Extract string resource.
  3. The string add, in strings.xml.

    1. An Extract Resource window opens. Resource name already says add: keep it.
    2. File name says strings.xml, values is ticked. If values-night is listed, leave it unticked.
    3. Click OK.
    Extract Resource A dialogFull size
    The Extract Resource dialog: Resource name add, Resource value Add, Source set main, File name strings.xml, the directory values ticked and values-night not ticked, then OK.
    1. Resource name: add.
    2. File name: strings.xml.
    3. values ticked, values-night not.
    4. OK.
  4. Paste Every text of the screen, named in strings.xml.

    1. Open res › values › strings.xml: add is in it.
    2. Click Copy the file, at the top right of the panel below.
    3. In strings.xml, click in the text, press Ctrl+A, then Ctrl+V.
    res › values › strings.xmlReplace the whole file
    <resources>    <string name="app_name">Notes</string>    <string name="logo_description">Notes logo</string>    <string name="count_start">0</string>    <string name="title_hint">Title</string>    <string name="body_hint">Write something…</string>    <string name="error_no_title">Give your note a title first.</string>    <string name="counter_start">0 / 140</string>    <string name="clear">Clear</string>    <string name="add">Add</string>    <string name="your_notes">YOUR NOTES</string>    <string name="list_hint">Tap to open · hold to delete</string>    <string name="empty">No notes yet.\nWrite your first one above.</string></resources>

    In the layout, @string/add means “the string named add, in strings.xml”.

  5. The reference to add, in the layout.

    1. Click the activity_main.xml tab: line 125 now says @string/add.
    2. It still shows "Add", in grey? Click it: Android Studio was folding the reference.

Done I see @string/add on the Add button’s line.

Stuck? 2 symptoms · the files
  • The line still reads "Add", in grey Android Studio folds @string/add to show its text. Click "Add": the reference appears.
  • Failed to flatten XML for resource '…' with error: Invalid unicode escape sequence in string A string holds a straight '. Write ’ or \' instead.

strings.xml is the panel above. The layout at the end of this step:

res › layout › activity_main.xmlReplace the whole file
<?xml version="1.0" encoding="utf-8"?><androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:fitsSystemWindows="true"    tools:context=".MainActivity">
<View android:id="@+id/header" android:layout_width="0dp" android:layout_height="168dp" android:layout_marginStart="16dp" android:layout_marginTop="16dp" android:layout_marginEnd="16dp" android:background="#C2410C" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" />
<ImageView android:id="@+id/imageLogo" android:layout_width="36dp" android:layout_height="36dp" android:layout_marginStart="16dp" android:layout_marginTop="20dp" android:contentDescription="Notes logo" app:layout_constraintStart_toStartOf="@id/header" app:layout_constraintTop_toTopOf="@id/header" app:srcCompat="@drawable/ic_launcher_foreground" />
<TextView android:id="@+id/textAppTitle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="4dp" android:text="Notes" android:textColor="#FFFFFF" android:textSize="30sp" app:layout_constraintStart_toStartOf="@id/imageLogo" app:layout_constraintTop_toBottomOf="@id/imageLogo" />
<TextView android:id="@+id/textCount" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="8dp" android:text="0" android:textColor="#FFFFFF" android:textSize="14sp" app:layout_constraintBaseline_toBaselineOf="@id/textAppTitle" app:layout_constraintStart_toEndOf="@id/textAppTitle" />
<LinearLayout android:id="@+id/composer" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginStart="32dp" android:layout_marginTop="120dp" android:layout_marginEnd="32dp" android:background="#FFFFFF" android:orientation="vertical" android:padding="16dp" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="@id/header">
<EditText android:id="@+id/editTitle" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="Title" android:importantForAutofill="no" android:inputType="textCapSentences" />
<EditText android:id="@+id/editBody" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="8dp" android:gravity="top" android:hint="Write something…" android:importantForAutofill="no" android:inputType="textMultiLine|textCapSentences" android:maxLength="140" android:minLines="3" />
<TextView android:id="@+id/textError" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="8dp" android:text="Give your note a title first." android:textSize="14sp" android:visibility="gone" />
<LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="8dp" android:gravity="center_vertical" android:orientation="horizontal">
<TextView android:id="@+id/textCounter" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="0 / 140" android:textSize="12sp" />
<Button android:id="@+id/buttonClear" style="@style/Widget.Material3.Button.TextButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Clear" />
<Button android:id="@+id/buttonAdd" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="4dp" android:text="@string/add" /> </LinearLayout> </LinearLayout>
<TextView android:id="@+id/textListTitle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="32dp" android:layout_marginTop="24dp" android:text="YOUR NOTES" android:textSize="12sp" android:textStyle="bold" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/composer" />
<TextView android:id="@+id/textListHint" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginStart="16dp" android:layout_marginEnd="32dp" android:gravity="end" android:text="Tap to open · hold to delete" android:textSize="12sp" app:layout_constraintBaseline_toBaselineOf="@id/textListTitle" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toEndOf="@id/textListTitle" />
<ScrollView android:id="@+id/scrollNotes" android:layout_width="0dp" android:layout_height="0dp" android:layout_marginTop="8dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/textListHint">
<LinearLayout android:id="@+id/notesContainer" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:paddingStart="16dp" android:paddingEnd="16dp" android:paddingBottom="16dp" /> </ScrollView>
<TextView android:id="@+id/textEmpty" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="48dp" android:gravity="center" android:text="No notes yet.\nWrite your first one above." android:textSize="16sp" android:visibility="gone" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="@id/scrollNotes" />
</androidx.constraintlayout.widget.ConstraintLayout>

Step 2 of 6

Name the colours, then give them to the theme

6 min

Goal Name each colour by role; let the theme paint the app.

  • Resources res › values › colors.xml · themes.xml
  • Layout Split
  1. Paste The colours, each named by its role.

    1. Open res › values › colors.xml.
    2. Click Copy the file, at the top right of the panel below.
    3. In colors.xml, click in the text, press Ctrl+A, then Ctrl+V.
    res › values › colors.xmlReplace the whole file
    <?xml version="1.0" encoding="utf-8"?><resources>    <color name="brand">#C2410C</color>    <color name="on_brand">#FFFFFF</color>    <color name="header_end">#E11D48</color>    <color name="paper">#FFF8F1</color>    <color name="card">#FFFFFF</color>    <color name="field">#FBF6F0</color>    <color name="line">#E7D9CB</color>    <color name="ink">#1F1A17</color>    <color name="muted">#6B6159</color>    <color name="error">#B91C1C</color></resources>
  2. Paste The theme, painted with those colours.

    1. Open res › values › themes.xml.
    2. Click Copy the file on the panel below.
    3. In themes.xml, click in the text, press Ctrl+A, then Ctrl+V.
    res › values › themes.xmlReplace the whole file
    <resources>    <style name="Theme.Notes" parent="Theme.Material3.Light.NoActionBar">        <item name="android:windowLightStatusBar">true</item>        <item name="android:windowBackground">@color/paper</item>        <item name="colorPrimary">@color/brand</item>        <item name="colorOnPrimary">@color/on_brand</item>        <item name="colorControlActivated">@color/brand</item>        <item name="colorOutline">@color/muted</item>    </style></resources>

    colorPrimary: the buttons. colorOnPrimary: their text. colorControlActivated: the cursor and the focused field. colorOutline: outlined buttons (Part 8). windowBackground: the paper.

  3. The theme, in the layout’s preview.

    1. Click the activity_main.xml tab: its preview shows the theme.
    2. No preview? Click Split, at the top right of the editor.
    Split previewFull size
    The preview after the colours and the theme: an orange header, a white card with Title, Write something…, 0 / 140, Clear and an orange Add, on a paper background.

Why Under Material, Google’s design system, a <Button> is a MaterialButton, coloured by colorPrimary.

Done I see Add in orange, on paper.

Stuck? 2 symptoms · the files
  • themes.xml: Error: Can't determine type for tag '<item name="colorPrimary">@color/brand</item>' The lines sit outside the <style>. Replace the whole file again.
  • Twelve lines like values-night-v8.xml:…: error: resource color/purple_200 (aka com.yourname.notes:color/purple_200) not found. themes.xml (night) still exists. Delete it, as in step 2.5.

The files at the end of this step are the two panels above: Copy the file on each.

Step 3 of 6

Draw a rounded field, then style both fields

8 min

Goal Draw a rounded field in XML, then dress both fields with one style.

  • Resources res › drawable › bg_field.xml · res › values › themes.xml
  • Layout Split
  1. A new drawable file: bg_field.xml.

    1. In the Project window, right-click res › drawable, then choose NewDrawable Resource File.
    2. A New Resource File window opens. In File name, type bg_field.
    3. In Root element, which says selector, select the text with Ctrl+A, then type shape.
    4. Leave Directory name on drawable. Click OK: bg_field.xml opens in Design: click Code.
    New Resource File A dialogFull size
    The New Resource File dialog for a drawable: File name bg_field, Root element shape, Source set main, Directory name drawable.
    1. File name: bg_field.
    2. Root element: type shape (it starts on selector).
    3. Directory name: drawable.
  2. Type The shape: a rectangle, its fill, its border, its corners.

    1. In bg_field.xml, line 2 is <shape xmlns:android="…">: click just before its >, then press Enter.
    2. Type android:shape="rectangle": the > now ends line 3, as in the panel.
    3. Click in the empty line 4 under it, then press Tab.
    4. Type the marked lines 4 to 8. Ctrl+Space completes a name; if a list is open, press Esc before Enter.
    res › drawable › bg_field.xmlNew file
    <?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android"    android:shape="rectangle">    <solid android:color="@color/field" />    <stroke        android:width="1dp"        android:color="@color/line" />    <corners android:radius="12dp" /></shape>

    Grey lines: Android Studio writes them, line 2 with its > until b1. solid: the fill. stroke: the border. corners: the rounding.

  3. Paste A style for the fields, NotesField, in themes.xml.

    1. Open res › values › themes.xml.
    2. Click Copy the file on the panel below.
    3. In themes.xml, click in the text, press Ctrl+A, then Ctrl+V.
    res › values › themes.xmlReplace the whole file
    <resources>    <style name="Theme.Notes" parent="Theme.Material3.Light.NoActionBar">        <item name="android:windowLightStatusBar">true</item>        <item name="android:windowBackground">@color/paper</item>        <item name="colorPrimary">@color/brand</item>        <item name="colorOnPrimary">@color/on_brand</item>        <item name="colorControlActivated">@color/brand</item>        <item name="colorOutline">@color/muted</item>    </style>
    <style name="NotesField"> <item name="android:background">@drawable/bg_field</item> <item name="android:paddingStart">14dp</item> <item name="android:paddingEnd">14dp</item> <item name="android:paddingTop">12dp</item> <item name="android:paddingBottom">12dp</item> <item name="android:textColor">@color/ink</item> <item name="android:textColorHint">@color/muted</item> <item name="android:textSize">16sp</item> </style></resources>

    Why A theme dresses the app (the manifest names it); a style, only the views that name it.

  4. Type Both fields, dressed by the style.

    1. Click the activity_main.xml tab.
    2. Click at the end of line 70, android:id="@+id/editTitle", then press Enter.
    3. Type style="@style/NotesField".
    4. Click at the end of line 79, android:id="@+id/editBody", then press Enter.
    5. Type style="@style/NotesField" again: in the preview, both fields are rounded.
    Split previewFull size
    The preview after bg_field: the Title and Write something… fields have rounded corners and a thin border.
    res › layout › activity_main.xmlAdd the marked lines
    <?xml version="1.0" encoding="utf-8"?><androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:fitsSystemWindows="true"    tools:context=".MainActivity">
    <View android:id="@+id/header" android:layout_width="0dp" android:layout_height="168dp" android:layout_marginStart="16dp" android:layout_marginTop="16dp" android:layout_marginEnd="16dp" android:background="#C2410C" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" />
    <ImageView android:id="@+id/imageLogo" android:layout_width="36dp" android:layout_height="36dp" android:layout_marginStart="16dp" android:layout_marginTop="20dp" android:contentDescription="Notes logo" app:layout_constraintStart_toStartOf="@id/header" app:layout_constraintTop_toTopOf="@id/header" app:srcCompat="@drawable/ic_launcher_foreground" />
    <TextView android:id="@+id/textAppTitle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="4dp" android:text="Notes" android:textColor="#FFFFFF" android:textSize="30sp" app:layout_constraintStart_toStartOf="@id/imageLogo" app:layout_constraintTop_toBottomOf="@id/imageLogo" />
    <TextView android:id="@+id/textCount" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="8dp" android:text="0" android:textColor="#FFFFFF" android:textSize="14sp" app:layout_constraintBaseline_toBaselineOf="@id/textAppTitle" app:layout_constraintStart_toEndOf="@id/textAppTitle" />
    <LinearLayout android:id="@+id/composer" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginStart="32dp" android:layout_marginTop="120dp" android:layout_marginEnd="32dp" android:background="#FFFFFF" android:orientation="vertical" android:padding="16dp" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="@id/header">
    <EditText android:id="@+id/editTitle" style="@style/NotesField" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="Title" android:importantForAutofill="no" android:inputType="textCapSentences" />
    <EditText android:id="@+id/editBody" style="@style/NotesField" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="8dp" android:gravity="top" android:hint="Write something…" android:importantForAutofill="no" android:inputType="textMultiLine|textCapSentences" android:maxLength="140" android:minLines="3" />
    <TextView android:id="@+id/textError" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="8dp" android:text="Give your note a title first." android:textSize="14sp" android:visibility="gone" />
    <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="8dp" android:gravity="center_vertical" android:orientation="horizontal">
    <TextView android:id="@+id/textCounter" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="0 / 140" android:textSize="12sp" />
    <Button android:id="@+id/buttonClear" style="@style/Widget.Material3.Button.TextButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Clear" />
    <Button android:id="@+id/buttonAdd" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="4dp" android:text="@string/add" /> </LinearLayout> </LinearLayout>
    <TextView android:id="@+id/textListTitle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="32dp" android:layout_marginTop="24dp" android:text="YOUR NOTES" android:textSize="12sp" android:textStyle="bold" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/composer" />
    <TextView android:id="@+id/textListHint" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginStart="16dp" android:layout_marginEnd="32dp" android:gravity="end" android:text="Tap to open · hold to delete" android:textSize="12sp" app:layout_constraintBaseline_toBaselineOf="@id/textListTitle" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toEndOf="@id/textListTitle" />
    <ScrollView android:id="@+id/scrollNotes" android:layout_width="0dp" android:layout_height="0dp" android:layout_marginTop="8dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/textListHint">
    <LinearLayout android:id="@+id/notesContainer" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:paddingStart="16dp" android:paddingEnd="16dp" android:paddingBottom="16dp" /> </ScrollView>
    <TextView android:id="@+id/textEmpty" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="48dp" android:gravity="center" android:text="No notes yet.\nWrite your first one above." android:textSize="16sp" android:visibility="gone" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="@id/scrollNotes" />
    </androidx.constraintlayout.widget.ConstraintLayout>

Done I see rounded fields with a thin border.

Stuck? 3 symptoms · the files
  • One field still has a plain underline Its <EditText> has no style="@style/NotesField". Type it there too.
  • error: attribute android:style not found. / error: failed linking file resources. Write style= without android:.
  • bg_field.xml starts with <selector Root element stayed on selector. Replace the whole file with the one below.

themes.xml is the panel above. The shape and the layout at the end of this step:

res › drawable › bg_field.xmlNew file
<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android"    android:shape="rectangle">    <solid android:color="@color/field" />    <stroke        android:width="1dp"        android:color="@color/line" />    <corners android:radius="12dp" /></shape>
res › layout › activity_main.xmlReplace the whole file
<?xml version="1.0" encoding="utf-8"?><androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:fitsSystemWindows="true"    tools:context=".MainActivity">
<View android:id="@+id/header" android:layout_width="0dp" android:layout_height="168dp" android:layout_marginStart="16dp" android:layout_marginTop="16dp" android:layout_marginEnd="16dp" android:background="#C2410C" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" />
<ImageView android:id="@+id/imageLogo" android:layout_width="36dp" android:layout_height="36dp" android:layout_marginStart="16dp" android:layout_marginTop="20dp" android:contentDescription="Notes logo" app:layout_constraintStart_toStartOf="@id/header" app:layout_constraintTop_toTopOf="@id/header" app:srcCompat="@drawable/ic_launcher_foreground" />
<TextView android:id="@+id/textAppTitle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="4dp" android:text="Notes" android:textColor="#FFFFFF" android:textSize="30sp" app:layout_constraintStart_toStartOf="@id/imageLogo" app:layout_constraintTop_toBottomOf="@id/imageLogo" />
<TextView android:id="@+id/textCount" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="8dp" android:text="0" android:textColor="#FFFFFF" android:textSize="14sp" app:layout_constraintBaseline_toBaselineOf="@id/textAppTitle" app:layout_constraintStart_toEndOf="@id/textAppTitle" />
<LinearLayout android:id="@+id/composer" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginStart="32dp" android:layout_marginTop="120dp" android:layout_marginEnd="32dp" android:background="#FFFFFF" android:orientation="vertical" android:padding="16dp" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="@id/header">
<EditText android:id="@+id/editTitle" style="@style/NotesField" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="Title" android:importantForAutofill="no" android:inputType="textCapSentences" />
<EditText android:id="@+id/editBody" style="@style/NotesField" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="8dp" android:gravity="top" android:hint="Write something…" android:importantForAutofill="no" android:inputType="textMultiLine|textCapSentences" android:maxLength="140" android:minLines="3" />
<TextView android:id="@+id/textError" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="8dp" android:text="Give your note a title first." android:textSize="14sp" android:visibility="gone" />
<LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="8dp" android:gravity="center_vertical" android:orientation="horizontal">
<TextView android:id="@+id/textCounter" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="0 / 140" android:textSize="12sp" />
<Button android:id="@+id/buttonClear" style="@style/Widget.Material3.Button.TextButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Clear" />
<Button android:id="@+id/buttonAdd" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="4dp" android:text="@string/add" /> </LinearLayout> </LinearLayout>
<TextView android:id="@+id/textListTitle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="32dp" android:layout_marginTop="24dp" android:text="YOUR NOTES" android:textSize="12sp" android:textStyle="bold" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/composer" />
<TextView android:id="@+id/textListHint" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginStart="16dp" android:layout_marginEnd="32dp" android:gravity="end" android:text="Tap to open · hold to delete" android:textSize="12sp" app:layout_constraintBaseline_toBaselineOf="@id/textListTitle" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toEndOf="@id/textListTitle" />
<ScrollView android:id="@+id/scrollNotes" android:layout_width="0dp" android:layout_height="0dp" android:layout_marginTop="8dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/textListHint">
<LinearLayout android:id="@+id/notesContainer" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:paddingStart="16dp" android:paddingEnd="16dp" android:paddingBottom="16dp" /> </ScrollView>
<TextView android:id="@+id/textEmpty" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="48dp" android:gravity="center" android:text="No notes yet.\nWrite your first one above." android:textSize="16sp" android:visibility="gone" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="@id/scrollNotes" />
</androidx.constraintlayout.widget.ConstraintLayout>

Step 4 of 6

Paint the header with a gradient

6 min

Goal Paint the header orange to rose, corner to corner.

  • Resources res › drawable › bg_header.xml
  • Layout Split
  1. A second drawable file, bg_header.xml, as in step 4.3.

    1. Right-click res › drawable, then choose NewDrawable Resource File.
    2. A New Resource File window opens: in File name, type bg_header.
    3. In Root element, select the text with Ctrl+A, then type shape.
    4. Click OK: bg_header.xml opens in Design: click Code.
  2. Type The gradient, orange to rose, with round corners.

    1. Line 2 is <shape xmlns:android="…">: click just before its >, then press Enter.
    2. Type android:shape="rectangle".
    3. Click in the empty line 4 under it, then press Tab.
    4. Type the marked lines 4 to 8, <gradient> and <corners>. A list is open? Press Esc before Enter.
    res › drawable › bg_header.xmlNew file
    <?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android"    android:shape="rectangle">    <gradient        android:angle="315"        android:endColor="@color/header_end"        android:startColor="@color/brand" />    <corners android:radius="28dp" /></shape>

    angle="315": from the top-left corner to the bottom-right one. 0 would run left to right.

  3. Type The header, painted by the drawable.

    1. Click the activity_main.xml tab.
    2. Click at the end of line 17, android:background="#C2410C", then press Shift+Home to select it.
    3. Type android:background="@drawable/bg_header" in its place: the preview shows the gradient.
    Split previewFull size
    The preview after bg_header: the header is a gradient from orange at the top left to rose at the bottom right, with rounded corners.
    res › layout › activity_main.xmlAdd the marked lines
    <?xml version="1.0" encoding="utf-8"?><androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:fitsSystemWindows="true"    tools:context=".MainActivity">
    <View android:id="@+id/header" android:layout_width="0dp" android:layout_height="168dp" android:layout_marginStart="16dp" android:layout_marginTop="16dp" android:layout_marginEnd="16dp" android:background="@drawable/bg_header" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" />
    <ImageView android:id="@+id/imageLogo" android:layout_width="36dp" android:layout_height="36dp" android:layout_marginStart="16dp" android:layout_marginTop="20dp" android:contentDescription="Notes logo" app:layout_constraintStart_toStartOf="@id/header" app:layout_constraintTop_toTopOf="@id/header" app:srcCompat="@drawable/ic_launcher_foreground" />
    <TextView android:id="@+id/textAppTitle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="4dp" android:text="Notes" android:textColor="#FFFFFF" android:textSize="30sp" app:layout_constraintStart_toStartOf="@id/imageLogo" app:layout_constraintTop_toBottomOf="@id/imageLogo" />
    <TextView android:id="@+id/textCount" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="8dp" android:text="0" android:textColor="#FFFFFF" android:textSize="14sp" app:layout_constraintBaseline_toBaselineOf="@id/textAppTitle" app:layout_constraintStart_toEndOf="@id/textAppTitle" />
    <LinearLayout android:id="@+id/composer" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginStart="32dp" android:layout_marginTop="120dp" android:layout_marginEnd="32dp" android:background="#FFFFFF" android:orientation="vertical" android:padding="16dp" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="@id/header">
    <EditText android:id="@+id/editTitle" style="@style/NotesField" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="Title" android:importantForAutofill="no" android:inputType="textCapSentences" />
    <EditText android:id="@+id/editBody" style="@style/NotesField" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="8dp" android:gravity="top" android:hint="Write something…" android:importantForAutofill="no" android:inputType="textMultiLine|textCapSentences" android:maxLength="140" android:minLines="3" />
    <TextView android:id="@+id/textError" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="8dp" android:text="Give your note a title first." android:textSize="14sp" android:visibility="gone" />
    <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="8dp" android:gravity="center_vertical" android:orientation="horizontal">
    <TextView android:id="@+id/textCounter" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="0 / 140" android:textSize="12sp" />
    <Button android:id="@+id/buttonClear" style="@style/Widget.Material3.Button.TextButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Clear" />
    <Button android:id="@+id/buttonAdd" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="4dp" android:text="@string/add" /> </LinearLayout> </LinearLayout>
    <TextView android:id="@+id/textListTitle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="32dp" android:layout_marginTop="24dp" android:text="YOUR NOTES" android:textSize="12sp" android:textStyle="bold" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/composer" />
    <TextView android:id="@+id/textListHint" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginStart="16dp" android:layout_marginEnd="32dp" android:gravity="end" android:text="Tap to open · hold to delete" android:textSize="12sp" app:layout_constraintBaseline_toBaselineOf="@id/textListTitle" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toEndOf="@id/textListTitle" />
    <ScrollView android:id="@+id/scrollNotes" android:layout_width="0dp" android:layout_height="0dp" android:layout_marginTop="8dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/textListHint">
    <LinearLayout android:id="@+id/notesContainer" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:paddingStart="16dp" android:paddingEnd="16dp" android:paddingBottom="16dp" /> </ScrollView>
    <TextView android:id="@+id/textEmpty" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="48dp" android:gravity="center" android:text="No notes yet.\nWrite your first one above." android:textSize="16sp" android:visibility="gone" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="@id/scrollNotes" />
    </androidx.constraintlayout.widget.ConstraintLayout>

    @drawable/bg_header: the file bg_header.xml, in res/drawable.

Done I see orange turn to rose, corner to corner.

Stuck? 2 symptoms · the files
  • The header is still flat orange Line 17 still says #C2410C. Type @drawable/bg_header over it.
  • The gradient runs from left to right android:angle is missing or 0. Set it to 315.

The files at the end of this step

res › drawable › bg_header.xmlNew file
<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android"    android:shape="rectangle">    <gradient        android:angle="315"        android:endColor="@color/header_end"        android:startColor="@color/brand" />    <corners android:radius="28dp" /></shape>
res › layout › activity_main.xmlReplace the whole file
<?xml version="1.0" encoding="utf-8"?><androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:fitsSystemWindows="true"    tools:context=".MainActivity">
<View android:id="@+id/header" android:layout_width="0dp" android:layout_height="168dp" android:layout_marginStart="16dp" android:layout_marginTop="16dp" android:layout_marginEnd="16dp" android:background="@drawable/bg_header" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" />
<ImageView android:id="@+id/imageLogo" android:layout_width="36dp" android:layout_height="36dp" android:layout_marginStart="16dp" android:layout_marginTop="20dp" android:contentDescription="Notes logo" app:layout_constraintStart_toStartOf="@id/header" app:layout_constraintTop_toTopOf="@id/header" app:srcCompat="@drawable/ic_launcher_foreground" />
<TextView android:id="@+id/textAppTitle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="4dp" android:text="Notes" android:textColor="#FFFFFF" android:textSize="30sp" app:layout_constraintStart_toStartOf="@id/imageLogo" app:layout_constraintTop_toBottomOf="@id/imageLogo" />
<TextView android:id="@+id/textCount" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="8dp" android:text="0" android:textColor="#FFFFFF" android:textSize="14sp" app:layout_constraintBaseline_toBaselineOf="@id/textAppTitle" app:layout_constraintStart_toEndOf="@id/textAppTitle" />
<LinearLayout android:id="@+id/composer" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginStart="32dp" android:layout_marginTop="120dp" android:layout_marginEnd="32dp" android:background="#FFFFFF" android:orientation="vertical" android:padding="16dp" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="@id/header">
<EditText android:id="@+id/editTitle" style="@style/NotesField" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="Title" android:importantForAutofill="no" android:inputType="textCapSentences" />
<EditText android:id="@+id/editBody" style="@style/NotesField" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="8dp" android:gravity="top" android:hint="Write something…" android:importantForAutofill="no" android:inputType="textMultiLine|textCapSentences" android:maxLength="140" android:minLines="3" />
<TextView android:id="@+id/textError" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="8dp" android:text="Give your note a title first." android:textSize="14sp" android:visibility="gone" />
<LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="8dp" android:gravity="center_vertical" android:orientation="horizontal">
<TextView android:id="@+id/textCounter" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="0 / 140" android:textSize="12sp" />
<Button android:id="@+id/buttonClear" style="@style/Widget.Material3.Button.TextButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Clear" />
<Button android:id="@+id/buttonAdd" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="4dp" android:text="@string/add" /> </LinearLayout> </LinearLayout>
<TextView android:id="@+id/textListTitle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="32dp" android:layout_marginTop="24dp" android:text="YOUR NOTES" android:textSize="12sp" android:textStyle="bold" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/composer" />
<TextView android:id="@+id/textListHint" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginStart="16dp" android:layout_marginEnd="32dp" android:gravity="end" android:text="Tap to open · hold to delete" android:textSize="12sp" app:layout_constraintBaseline_toBaselineOf="@id/textListTitle" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toEndOf="@id/textListTitle" />
<ScrollView android:id="@+id/scrollNotes" android:layout_width="0dp" android:layout_height="0dp" android:layout_marginTop="8dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/textListHint">
<LinearLayout android:id="@+id/notesContainer" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:paddingStart="16dp" android:paddingEnd="16dp" android:paddingBottom="16dp" /> </ScrollView>
<TextView android:id="@+id/textEmpty" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="48dp" android:gravity="center" android:text="No notes yet.\nWrite your first one above." android:textSize="16sp" android:visibility="gone" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="@id/scrollNotes" />
</androidx.constraintlayout.widget.ConstraintLayout>

Step 5 of 6

Add the logo, then dress every view

7 min

Goal Add a vector logo, two shapes and the finished layout, then run.

  • Resources res › drawable
  • Layout res › layout › activity_main.xml
  • Emulator
  1. The logo: a clip art icon.

    1. Right-click res, then choose NewVector Asset.
    2. An Asset Studio window opens on Configure Vector Asset: click the Clip art button.
    3. A Select Icon window opens: in its search field, type note.
    4. Click sticky note 2, then OK.
    Select Icon A dialogFull size
    The Select Icon dialog: the search field says note; edit note, event note, music note, note, note add, notes, speaker notes, speaker notes off and sticky note 2, which is selected.
    1. The search field: note.
    2. sticky note 2.
  2. Its name and its colour: ic_notes, white.

    1. Back in Asset Studio, in Name, select the text with Ctrl+A, then type ic_notes.
    2. Click Color: a colour picker opens.
    3. In its Hex field, select the value with Ctrl+A, type FFFFFF, then press Enter.
    4. Click Next: Confirm Icon Path shows res/drawable/ic_notes.xml.
    5. Click Finish.
    Asset Studio A dialogFull size
    Asset Studio, Configure Vector Asset: Asset type Clip art, Name ic_notes, the sticky note icon on the Clip art button, Size 24 × 24 dp, Color FFFFFF, Opacity 100 %.
    1. Clip art: opens Select Icon.
    2. Name: ic_notes.
    3. Color: FFFFFF.
  3. Paste Two shapes, as in step 4.3: bg_card.xml and bg_pill.xml.

    1. Right-click res › drawable, then choose NewDrawable Resource File.
    2. A New Resource File window opens: in File name, type bg_card.
    3. Click OK: bg_card.xml opens in Design: click Code.
    4. Click Copy the file on the bg_card.xml panel below.
    5. Click in its text, press Ctrl+A, then Ctrl+V.
    6. Repeat for bg_pill, with the bg_pill.xml panel.
    res › drawable › bg_card.xmlNew file
    <?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android"    android:shape="rectangle">    <solid android:color="@color/card" />    <corners android:radius="20dp" /></shape>
    res › drawable › bg_pill.xmlNew file
    <?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android"    android:shape="rectangle">    <solid android:color="@color/card" />    <corners android:radius="12dp" /></shape>
  4. Paste The finished layout.

    1. Click Copy the file on the panel below.
    2. Click the activity_main.xml tab.
    3. Click in the code, press Ctrl+A, then Ctrl+V.
    res › layout › activity_main.xmlReplace the whole file
    <?xml version="1.0" encoding="utf-8"?><androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:fitsSystemWindows="true"    tools:context=".MainActivity">
    <View android:id="@+id/header" android:layout_width="0dp" android:layout_height="168dp" android:layout_marginStart="16dp" android:layout_marginTop="16dp" android:layout_marginEnd="16dp" android:background="@drawable/bg_header" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" />
    <ImageView android:id="@+id/imageLogo" android:layout_width="36dp" android:layout_height="36dp" android:layout_marginStart="16dp" android:layout_marginTop="20dp" android:contentDescription="@string/logo_description" app:layout_constraintStart_toStartOf="@id/header" app:layout_constraintTop_toTopOf="@id/header" app:srcCompat="@drawable/ic_notes" />
    <TextView android:id="@+id/textAppTitle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="4dp" android:fontFamily="sans-serif-black" android:text="@string/app_name" android:textColor="@color/on_brand" android:textSize="30sp" app:layout_constraintStart_toStartOf="@id/imageLogo" app:layout_constraintTop_toBottomOf="@id/imageLogo" />
    <TextView android:id="@+id/textCount" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="8dp" android:background="@drawable/bg_pill" android:paddingStart="10dp" android:paddingTop="2dp" android:paddingEnd="10dp" android:paddingBottom="2dp" android:text="@string/count_start" android:textColor="@color/brand" android:textSize="14sp" android:textStyle="bold" app:layout_constraintBaseline_toBaselineOf="@id/textAppTitle" app:layout_constraintStart_toEndOf="@id/textAppTitle" />
    <LinearLayout android:id="@+id/composer" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginStart="32dp" android:layout_marginTop="120dp" android:layout_marginEnd="32dp" android:background="@drawable/bg_card" android:elevation="6dp" android:orientation="vertical" android:padding="16dp" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="@id/header">
    <EditText android:id="@+id/editTitle" style="@style/NotesField" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="@string/title_hint" android:importantForAutofill="no" android:inputType="textCapSentences" />
    <EditText android:id="@+id/editBody" style="@style/NotesField" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="8dp" android:gravity="top" android:hint="@string/body_hint" android:importantForAutofill="no" android:inputType="textMultiLine|textCapSentences" android:maxLength="140" android:minLines="3" />
    <TextView android:id="@+id/textError" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="8dp" android:text="@string/error_no_title" android:textColor="@color/error" android:textSize="14sp" android:visibility="gone" />
    <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="8dp" android:gravity="center_vertical" android:orientation="horizontal">
    <TextView android:id="@+id/textCounter" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="@string/counter_start" android:textColor="@color/muted" android:textSize="12sp" />
    <Button android:id="@+id/buttonClear" style="@style/Widget.Material3.Button.TextButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/clear" />
    <Button android:id="@+id/buttonAdd" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="4dp" android:text="@string/add" app:cornerRadius="12dp" /> </LinearLayout> </LinearLayout>
    <TextView android:id="@+id/textListTitle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="32dp" android:layout_marginTop="24dp" android:letterSpacing="0.1" android:text="@string/your_notes" android:textColor="@color/muted" android:textSize="12sp" android:textStyle="bold" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/composer" />
    <TextView android:id="@+id/textListHint" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginStart="16dp" android:layout_marginEnd="32dp" android:gravity="end" android:text="@string/list_hint" android:textColor="@color/muted" android:textSize="12sp" app:layout_constraintBaseline_toBaselineOf="@id/textListTitle" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toEndOf="@id/textListTitle" />
    <ScrollView android:id="@+id/scrollNotes" android:layout_width="0dp" android:layout_height="0dp" android:layout_marginTop="8dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/textListHint">
    <LinearLayout android:id="@+id/notesContainer" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:paddingStart="16dp" android:paddingEnd="16dp" android:paddingBottom="16dp" /> </ScrollView>
    <TextView android:id="@+id/textEmpty" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="48dp" android:gravity="center" android:text="@string/empty" android:textColor="@color/muted" android:textSize="16sp" android:visibility="gone" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="@id/scrollNotes" />
    </androidx.constraintlayout.widget.ConstraintLayout>

    Marked: the logo, the pill’s shape and padding (the count beside Notes), the card’s shape and shadow, and app:cornerRadius, a Material attribute. Every text is a @string/, every colour a @color/.

  5. The styled screen, on the phone.

    1. Click ▶ Run 'app'. The layout’s red marks are accessibility checks, not build errors.
    2. On the phone, tap Title.
The emulator after tapping Title: the gradient header with the white logo and the pill 0, the card floating with its shadow, an orange cursor in Title, the keyboard open, an empty list.

You should see An orange cursor in Title:

The Title field at real size, just tapped: an orange cursor at its start.
The cursor, at real size

Done I see a floating card, the pill “0”, an orange cursor.

Stuck? 4 symptoms · the file
  • Where is Vector Asset? Right-click res itself: New lists it near the end.
    Project › res A menuFull size
    The context menu of res: New is open, with Android Resource File, Android Resource Directory, File, Directory, Image Asset and Vector Asset.
    1. Right-click res › New.
    2. Vector Asset: the logo.
  • No ic_notes.xml under res › drawable Asset Studio stopped before Finish. Do actions a and b again, up to Confirm Icon Path, then click Finish.
    Confirm Icon Path A dialogFull size
    Asset Studio, Confirm Icon Path: Source set main, and the output res, drawable, ic_notes.xml.
    1. res/drawable/ic_notes.xml: the file Finish writes. Keep it as it is, licence comment included.
  • The logo is still the robot The layout was not replaced: line 31 must say @drawable/ic_notes. Paste the whole layout again.
  • Red and yellow marks on the fields and on scrollNotes Accessibility checks, listed in the Problems window: real advice, not build errors. They do not stop the build: ▶.
    Problems Tool window · bottomFull size
    The Problems window, Layout and Qualifiers tab: for activity_main.xml, two errors, No speakable text present (scrollNotes) and Touch target size too small (editTitle); under Layout Validation, two warnings, The text field is too wide (editBody, editTitle).
    1. Layout and Qualifiers: the layout’s checks.
    2. Two errors from the accessibility checks: real advice, not build errors. The app still runs.
    3. Two warnings: Layout Validation.

bg_card.xml, bg_pill.xml and the layout are the panels above. The logo, as Finish writes it:

res › drawable › ic_notes.xmlNew file
<!--  ~ Copyright (C) 2026 The Android Open Source Project  ~  ~ Licensed under the Apache License, Version 2.0 (the "License");  ~ you may not use this file except in compliance with the License.  ~ You may obtain a copy of the License at  ~  ~      http://www.apache.org/licenses/LICENSE-2.0  ~  ~ Unless required by applicable law or agreed to in writing, software  ~ distributed under the License is distributed on an "AS IS" BASIS,  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  ~ See the License for the specific language governing permissions and  ~ limitations under the License.  --><vector xmlns:android="http://schemas.android.com/apk/res/android" android:autoMirrored="true" android:height="24dp" android:tint="#FFFFFF" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp">          <path android:fillColor="@android:color/white" android:pathData="M19,3H4.99C3.89,3 3,3.9 3,5l0.01,14c0,1.1 0.89,2 1.99,2h10l6,-6V5C21,3.9 20.1,3 19,3zM7,8h10v2H7V8zM12,14H7v-2h5V14zM14,19.5V14h5.5L14,19.5z"/>    </vector>

Step 6 of 6

Change the whole look with two lines

3 min

Goal Change two colours: the header and the buttons follow.

  • Resources res › values › colors.xml
  • Layout Split
  1. A new palette for the app.

    1. Open res › values › colors.xml.
    2. Pick a palette in the table: Ocean, Forest or Berry.
    The palettes, with their two colours
    Palettebrand, line 3header_end, line 5
    1Ocean#0369A1#4F46E5
    2Forest#047857#0E7490
    3Berry#BE185D#7C3AED
    4Sunset, the page’s#C2410C#E11D48
  2. Type Its two colours, over the values of lines 3 and 5.

    1. On line 3, brand, select #C2410C: drag from just before its # to just after its last C.
    2. Type your palette’s brand in its place, # included: #0369A1 for Ocean.
    3. On line 5, header_end, select #E11D48 the same way, # included.
    4. Type your palette’s header_end in its place: #4F46E5 for Ocean.
    res › values › colors.xmlAdd the marked lines
    <?xml version="1.0" encoding="utf-8"?><resources>    <color name="brand">#0369A1</color>    <color name="on_brand">#FFFFFF</color>    <color name="header_end">#4F46E5</color>    <color name="paper">#FFF8F1</color>    <color name="card">#FFFFFF</color>    <color name="field">#FBF6F0</color>    <color name="line">#E7D9CB</color>    <color name="ink">#1F1A17</color>    <color name="muted">#6B6159</color>    <color name="error">#B91C1C</color></resources>

    Shown: Ocean. Lines 3 and 5 already exist: only their values change.

  3. The new look, in the preview.

    1. Click the activity_main.xml tab: the header and the buttons follow.
    2. Keep your palette, or type Sunset’s two colours back: they are in the table.
    Split previewFull size
    The preview with the Ocean palette: a blue to violet header with the notes logo, a white card, and Clear and Add in blue.

Done I see the header and the buttons follow.

Stuck? 4 symptoms · the file
  • Only one end of the header changed You changed one line of two. brand starts the gradient, header_end ends it.
  • Your screen no longer matches the page’s captures They use Sunset. Copy the file below to set it back.
  • Found item Color/brand more than one time Lines 3 and 5 were added, not changed. Delete the old brand and header_end lines.
  • A colour reads ##0369A1, or has no # The selection missed the #, or took it while you typed none. Select the whole value, from its # to its last character, then type the palette’s value, # included.

The colours at the end of the part, Sunset:

res › values › colors.xmlReplace the whole file
<?xml version="1.0" encoding="utf-8"?><resources>    <color name="brand">#C2410C</color>    <color name="on_brand">#FFFFFF</color>    <color name="header_end">#E11D48</color>    <color name="paper">#FFF8F1</color>    <color name="card">#FFFFFF</color>    <color name="field">#FBF6F0</color>    <color name="line">#E7D9CB</color>    <color name="ink">#1F1A17</color>    <color name="muted">#6B6159</color>    <color name="error">#B91C1C</color></resources>

Now you

Square the card

Square the card’s corners without touching the layout. Which file, which line?

See the answer

res/drawable/bg_card.xml, line 5: android:radius="0dp". The shadow follows the corners. Then set 20dp back.

Go deeper A border that appears on focus

A <selector> drawable picks a shape by state: give the focused field a 2 dp brand border, a good exercise at home. Dark mode would need a values-night folder; this app stays light, so it has none.

If it doesn’t work

  • 'B' is not a valid file-based resource name character: File-based resource names must contain only lowercase a-z, 0-9, or underscore A file name has a capital letter. Use lowercase, digits and _ only.
  • error: resource drawable/… not found. / error: failed linking file resources. The drawable does not exist yet, or its name has a typo. Create it, or fix the name.
  • A new drawable starts with <selector Root element stayed on selector. Replace the whole file with the step’s panel.
  • My button ignores android:background Material tints it. Add app:backgroundTint="@null", or use app:backgroundTint and app:cornerRadius.

End of the part

Recap

No colour is typed in the layout any more: change brand and header_end in colors.xml, and the screen follows.

  • name each text and each colour once, in res/values;
  • draw shapes, a gradient and a vector icon;
  • set the theme’s colours and tell a theme from a style.

End of session 1.

Your app at the end of Part 4: the styled notes screen, the gradient header with the white logo and the pill at 0, the floating card, an empty list.
Your app now
← Lab 1, all parts