- 3.2 the band and the logo
- 3.3 the title and the card
- 3.5 the count, the card’s last row, the list
Before you start
By the end you can
- drag views and give them ids;
- tie a view to the parent or to another view; use
0dp; - explain why a view without constraints jumps; preview other sizes.
- Layout Design · Code · Split
- Emulator
Red or yellow marks: advice, not build errors.
Behind, or a fresh project? Start from here about 4 min
The project: your own from Part 2, or a fresh one: Part 0, steps 0.3 and 0.4 (about 5 minutes).
Your package name, for the code of this page:
Without JavaScript, the code says com.yourname.notes: replace yourname by the name you chose.
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 linesplugins { 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)}
lab1-part3-res.zip zip · 2.1 KBresand manifest: download the pack and open it in Explorer. Drag itsappfolder onto your project folder (C:\Users\<you>\), 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.AndroidStudioProjects\ Notes 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: typeMainActivity, then press Enter.kotlin+java › com.yourname.notes › MainActivity.javaReplace the whole filepackage 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); }}▶. You are ready when the phone shows “Hello, Notes!” with no bar.
Step 1 of 6
Open the layout editor
Goal Find the editor’s tools, then empty the screen.
- Layout res › layout › activity_main.xml · Design
-
The layout file, in Design.
- In the Project window, double-click res › layout › activity_main.xml.
- It opens in Design: Palette top left, Component Tree under it, Attributes on the right.
Layout editor The whole windowFull size
- Code · Split · Design: the editor opens in Design.
- Component Tree: the views, nested. A view is one element of the screen: a text, a field, a button, a container.
- Palette: the views to drag.
- Attributes: the selected view’s attributes.
-
The XML behind it.
- At the top right of the editor, click Code.
res › layout › activity_main.xmlRead only<?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">
<TextView android:id="@+id/textHello" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello, Notes!" android:textSize="24sp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>- The root, a
ConstraintLayout.android:marks Android’s own attributes. app:marks a library’s attributes: here ConstraintLayout’s, added in Part 1.tools:is for the editor only:tools:context, and thetools:layout_editor_…lines a drag may write. The app never sees them.- Keep this line from Part 2: the screen stays out from under the status bar.
- Lines 16–19: four constraints tie
textHelloto the four edges of its parent. The editor draws them as springs.
-
An empty screen.
- Click Design, two buttons to the right of Code.
- In Component Tree, click
textHello. - Press Delete. Keep the root,
ConstraintLayout.
Done I see an empty screen: only ConstraintLayout in Component Tree.
Stuck? 3 symptoms · the file
- Two screens side by side in the preview The second one is the blueprint. In the first menu of the preview’s toolbar, pick Design.
- The preview is tiny, or cut off Click the bottom-right button of the preview: it zooms to fit.
- The root, or its
fitsSystemWindowsline, is gone Paste this file over yours.
The files at the end of this step
<?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">
</androidx.constraintlayout.widget.ConstraintLayout>The four layouts
In Notes: the card
LinearLayout
One row or one column. layout_weight shares the free space.
In Notes: the list
FrameLayout
Layers, one over the other. A ScrollView is a FrameLayout that scrolls.
Older
RelativeLayout
Each view beside the parent or a sibling. ConstraintLayout replaced it.
In Notes: the screen
ConstraintLayout
Each edge tied to another edge, in a flat tree.
- From Swing:
BoxLayout≈LinearLayout·BorderLayout: no Android twin ·SpringLayout≈ConstraintLayout·JLabel,JTextField,JButton≈TextView,EditText,Button·addActionListener≈setOnClickListener(Part 7).
ViewGroup) that places the views inside it.Step 2 of 6
Place the header and the logo
Goal Tie a band to the screen’s top, and a logo to the band.
- Layout activity_main.xml · Design · Code
-
The band: a View.
- Drag a View from PaletteWidgets onto the screen. It fills the whole screen.
- In Attributes, click the id field, type
header, then press Enter. - A Rename window opens: click Refactor.
Rename A dialogFull size
- The new id:
header. - Refactor: renames the id everywhere it is used.
-
Tie it to three edges, then size it.
- In Attributes, under Layout, find the Constraint Widget: a square with a + on each side.
- Click its + on top, then the one on the left, then the one on the right.
- A margin box appears beside each one. In each box, select the value with Ctrl+A, type
16, then press Enter. - In layout_width, type
0dp, then press Enter: the band stretches between its constraints. - In layout_height, type
168dp, then press Enter.
Attributes › Layout Layout editor · centre -
The logo: an ImageView.
- Drag an ImageView from PaletteCommon to the screen’s top left corner.
- A Pick a Resource window opens: click
ic_launcher_foreground, then OK.
-
Type The band’s colour, in Code.
- Click Code, at the top right of the editor.
- Make
headermatch the panel: type the line marked +.
res › layout › activity_main.xmlEdit the marked lineschange the struck partdelete the linetype the linewhat your drop wrotetop to bottom: the line numbers are then Android Studio’s
<?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> header <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="wrap_content36dp" android:layout_height="wrap_content36dp" android:layout_marginStart="16dp" android:layout_marginTop="20dp" app:layout_constraintStart_toStartOf="@id/header" app:layout_constraintTop_toTopOf="@id/header" app:srcCompat="@drawable/ic_launcher_foreground" />empty line
</androidx.constraintlayout.widget.ConstraintLayout> -
Type The logo, in Code.
- Make
imageLogomatch the panel, mark by mark. A code line without a mark is already in your file. - Your ImageView has
tools:layout_editor_…lines? Your drop was not in the corner: delete them too.
res › layout › activity_main.xmlEdit the marked lineschange the struck partdelete the linetype the linewhat your drop wrotetop to bottom: the line numbers are then Android Studio’s
<?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> imageLogo <ImageView android:id="…@+id/imageLogo" android:layout_width="wrap_content36dp" android:layout_height="wrap_content36dp" android:layout_marginStart="16dp" android:layout_marginTop="20dp" app:layout_constraintStart_toStartOf="@id/header" app:layout_constraintTop_toTopOf="@id/header" app:srcCompat="@drawable/ic_launcher_foreground" />empty line
</androidx.constraintlayout.widget.ConstraintLayout>@+id/headercreates the id;@id/headerpoints to it.dp: a size that looks the same on every screen. - Make
Done In Design, I see an orange band, the robot at its top left.
Stuck? 4 symptoms · the file
- The ImageView got
tools:layout_editor_…lines Your drop was not in the corner. Delete those lines, then end theapp:srcCompatline with/>. - A value in Attributes went wrong Type it in Code instead: the file below shows each attribute of the band.
@id/headeris red The band’s id is not exactlyheader. In the band’s<View, the id line readsandroid:id="@+id/header".- The XML turns red after you typed A view ends with no
/>, or with two: a deleted line took it, or you typed it twice. Keep one, at the end of the view’s last line, as in the file below.
The files at the end of this step
<?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" app:layout_constraintStart_toStartOf="@id/header" app:layout_constraintTop_toTopOf="@id/header" app:srcCompat="@drawable/ic_launcher_foreground" />
</androidx.constraintlayout.widget.ConstraintLayout>Step 3 of 6
Add the title and the card
Goal Add the title, then a white card that holds three views.
- Layout activity_main.xml · Design · Code
-
The title: a TextView.
- Click Design. Drag a TextView from PaletteCommon to just under the logo.
- In Attributes, type the id
textAppTitle, then press Enter. - Rename opens: click Refactor.
-
The card: a vertical LinearLayout.
- Drag a LinearLayout (vertical) from PaletteLayouts to under the band. Two read LinearLa…: take the second, with the rows icon.
- In Attributes, type the id
composer, then press Enter. No Rename this time: the view had no id.
-
Three views in the card, one table row at a time.
- Drag the view from its Palette tab onto the row in Drop it onto, in Component Tree.
- Click what Then click names: the new row.
- In Attributes, type its id, press Enter, then click Refactor.
The three views of the card, in order View (Palette tab) → id Drop it onto Then click 1 Plain Text (Text) → editTitlethe composerrowcomposer’s ›, then the new row inside it2 Multiline Text (Text) → editBodythe lower half of the editTitlerowthe new row, under editTitle3 Button (Common) → buttonAddthe lower half of the editBodyrowthe new row, under editBodyPalette · Component Tree Layout editor · centre -
Type The title, in Code.
- Click Code. Make
textAppTitlematch the panel, mark by mark.
res › layout › activity_main.xmlEdit the marked lineschange the struck partdelete the linetype the linewhat your drop wrotetop to bottom: the line numbers are then Android Studio’s
<?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" app:layout_constraintStart_toStartOf="@id/header" app:layout_constraintTop_toTopOf="@id/header" app:srcCompat="@drawable/ic_launcher_foreground" />
<TextView> textAppTitle <TextView android:id="@+id/textAppTitle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="4dp" android:text="TextViewNotes" tools:layout_editor_absoluteX="…" tools:layout_editor_absoluteY="…" /> android:textColor="#FFFFFF" android:textSize="30sp" app:layout_constraintStart_toStartOf="@id/imageLogo" app:layout_constraintTop_toBottomOf="@id/imageLogo" />
<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" tools:layout_editor_absoluteX="…" tools:layout_editor_absoluteY="…"> 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:ems="10" android:hint="Title" android:inputType="text" /> android:text="Name" />
<EditText android:id="@+id/editBody" android:layout_width="match_parent" android:layout_height="wrap_content" android:ems="10" android:gravity="start|top" android:hint="Write something…" android:inputType="textMultiLine" />
<Button android:id="@+id/buttonAdd" android:layout_width="match_parentwrap_content" android:layout_height="wrap_content" android:text="ButtonAdd" /> </LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>wrap_content: as big as the content.match_parent: as big as the parent.sp: a text size that also follows the phone’s font size. - Click Code. Make
-
Type The card, in Code.
- Make
composermatch the panel, mark by mark.
res › layout › activity_main.xmlEdit the marked lineschange the struck partdelete the linetype the linewhat your drop wrotetop to bottom: the line numbers are then Android Studio’s
<?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" 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="TextViewNotes" tools:layout_editor_absoluteX="…" tools:layout_editor_absoluteY="…" /> android:textColor="#FFFFFF" android:textSize="30sp" app:layout_constraintStart_toStartOf="@id/imageLogo" app:layout_constraintTop_toBottomOf="@id/imageLogo" />
<LinearLayout> composer <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" tools:layout_editor_absoluteX="…" tools:layout_editor_absoluteY="…"> android:padding="16dp" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="@id/header">Android Studio may write</LinearLayout>right after this>: delete it. The card closes after the button.
<EditText android:id="@+id/editTitle" android:layout_width="match_parent" android:layout_height="wrap_content" android:ems="10" android:hint="Title" android:inputType="text" /> android:text="Name" />
<EditText android:id="@+id/editBody" android:layout_width="match_parent" android:layout_height="wrap_content" android:ems="10" android:gravity="start|top" android:hint="Write something…" android:inputType="textMultiLine" />
<Button android:id="@+id/buttonAdd" android:layout_width="match_parentwrap_content" android:layout_height="wrap_content" android:text="ButtonAdd" /> </LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout> - Make
-
Type The card’s three views.
- Make
editTitle,editBodyandbuttonAddmatch the panel.
res › layout › activity_main.xmlEdit the marked lineschange the struck partdelete the linetype the linewhat your drop wrotetop to bottom: the line numbers are then Android Studio’s
<?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" 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="TextViewNotes" tools:layout_editor_absoluteX="…" tools:layout_editor_absoluteY="…" /> android:textColor="#FFFFFF" android:textSize="30sp" app:layout_constraintStart_toStartOf="@id/imageLogo" app:layout_constraintTop_toBottomOf="@id/imageLogo" />
<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" tools:layout_editor_absoluteX="…" tools:layout_editor_absoluteY="…"> android:padding="16dp" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="@id/header">
<EditText> editTitle <EditText android:id="@+id/editTitle" android:layout_width="match_parent" android:layout_height="wrap_content" android:ems="10" android:hint="Title" android:inputType="text" /> android:text="Name" />
<EditText> editBody <EditText android:id="@+id/editBody" android:layout_width="match_parent" android:layout_height="wrap_content" android:ems="10" android:gravity="start|top" android:hint="Write something…" android:inputType="textMultiLine" />
<Button> buttonAdd <Button android:id="@+id/buttonAdd" android:layout_width="match_parentwrap_content" android:layout_height="wrap_content" android:text="ButtonAdd" /> </LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout> - Make
Done In Design, I see the white card overlapping the band.
Stuck? 7 symptoms · the file
- “Name” shows in the first field The line
android:text="Name"is still there. Delete it, and end the line above it with/>, as the panel shows. - The XML turns red after you typed A closing went with a deleted line, you typed it twice, or Android Studio added a
</LinearLayout>aftercomposer’s>.textAppTitleand each field end with one/>;composer’s last attribute ends with>only. - The three views are not in the table’s order A drop onto the open
composerrow puts the view first. Click the view’s row, then drag it onto the lower half of the row it must follow. - No Rename window opens after an id The view had no id yet: the id is written at once. Go on.
- A view is not where the page says in the Palette Click the magnifier at the top of the Palette and type its name. In Layouts, both LinearLayouts read LinearLa…: hover one to read its full name; the vertical one has the rows icon.
- A field or the button sits outside the white card In Component Tree, it is beside
composer, not inside it: click its row, then drag it onto the row the table names (column Drop it onto). @id/imageLogois red The logo’s id is not exactlyimageLogo: its id line must readandroid:id="@+id/imageLogo".
The files at the end of this step
<?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" 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" />
<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:inputType="text" />
<EditText android:id="@+id/editBody" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="start|top" android:hint="Write something…" android:inputType="textMultiLine" />
<Button android:id="@+id/buttonAdd" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Add" /> </LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>Step 4 of 6
Break a constraint
Goal Remove the card’s top constraint; see where the phone puts it.
- Layout activity_main.xml · Split
- Emulator
Predict first
Without its top constraint, where is the card on the phone?
See the answer
At the top: with no vertical constraint, the phone draws a view at the top of its parent (rule 1, under the result). The editor shows another place only if a drag left a tools: position, which the phone never sees.
-
Type Delete the card’s top constraint.
- Click Split, at the top right of the editor.
- In
composer, delete the struck part of the marked line. Keep its>: it closes the tag.
res › layout › activity_main.xmlEdit the marked lineschange the struck partdelete the linetype the linetop to bottom: the line numbers are then Android Studio’s
<?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" 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" />
<LinearLayout> composer <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:inputType="text" />
<EditText android:id="@+id/editBody" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="start|top" android:hint="Write something…" android:inputType="textMultiLine" />
<Button android:id="@+id/buttonAdd" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Add" /> </LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout> -
▶ Run 'app'.
-
Put it back.
- Click in the code, then press Ctrl+Z: the line comes back.
- ▶ again: the card is back under the band.

You should see After b, the card at the top, in the editor too (red in Component Tree). After c, the card under the band again.
Done I see the card jump, then come back.
What happened
It builds and runs: ▶ does not run lint, Android Studio’s code checker. Lint marks the card in red, with this message:
You should seeThis view is not constrained vertically: at runtime it will jump to the top unless you add a vertical constraint
Rule 1: the phone draws the card at the top. Ctrl+Z puts the line back.
- Rule 1. Every view needs one horizontal and one vertical constraint, or the phone draws it at the top left.
- Rule 2.
0dp= stretch between my constraints. For a direct child of aConstraintLayout, nevermatch_parent. - Rule 3. A margin acts only on a side that has a constraint.
Stuck? 2 symptoms · the file
- The XML turns red after the delete The
>went with the line. Press Ctrl+Z, then select fromapp:to the last quote only, and delete. - Ctrl+Z does not bring the line back Paste this file over yours, then ▶.
The files at the end of this step
<?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" 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" />
<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:inputType="text" />
<EditText android:id="@+id/editBody" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="start|top" android:hint="Write something…" android:inputType="textMultiLine" />
<Button android:id="@+id/buttonAdd" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Add" /> </LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>Step 5 of 6
Add the rest of the skeleton
Goal Choose a way: A pastes the rest, B builds it by hand. Both give the same file.
- Layout activity_main.xml · Design · Code
- Emulator
A Paste the file 5 min · in class
-
Paste Replace the whole file.
- Click Copy the file, at the top right of the panel below.
- In Code, click in the text, 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="#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="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>The new file gives each new view an id, and adds a
LinearLayoutwithout one. Your seven views keep their ids;buttonAddnow sits in thatLinearLayout. Whole file shows the file, the new lines marked.
B Build it by hand about 1 h · optional: at home, or if you finish early
Start from your file after 3.4: 3.3’s. In doubt, first paste the file in 3.4’s Stuck?. Six parts, in order. Tick each part when it is done: when you come back, the first part not ticked is already open.
B1 The count beside the title 8 min
-
A TextView under the title, in Component Tree.
- Click Design. Drag a TextView from PaletteCommon onto the lower half of the
textAppTitlerow in Component Tree: a line shows under it. - Click the new row, just under
textAppTitle. - In Attributes, type the id
textCount, press Enter, then click Refactor.
- Click Design. Drag a TextView from PaletteCommon onto the lower half of the
-
Type The logo and the count, in Code.
- Click Code. Make
imageLogoandtextCountmatch the panel.
res › layout › activity_main.xmlEdit the marked lineschange the struck partdelete the linetype the linetop to bottom: the line numbers are then Android Studio’s
<?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> imageLogo <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> textCount <TextView android:id="@+id/textCount" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="8dp" android:text="TextView0"/>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:inputType="text" />
<EditText android:id="@+id/editBody" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="start|top" android:hint="Write something…" android:inputType="textMultiLine" />
<Button android:id="@+id/buttonAdd" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Add" /> </LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>Baseline: the
0sits on the title’s line of text. - Click Code. Make
You should see In Design, a small white 0 right of Notes, on the same line.
Stuck? 2 symptoms
textCountis not just undertextAppTitlein Component Tree Click its row, then drag it onto the lower half of thetextAppTitlerow. Delete anytools:layout_editor_…line it got.- The
0is not right of Notes One oftextCount’s twoapp:layout_constraint…lines is missing or misspelt: both name@id/textAppTitle.
B2 The fields and the error line 12 min
-
A TextView under the second field.
- Click Design.
- In Component Tree, drag a TextView from PaletteCommon onto the lower half of the
editBodyrow. - Click the new row, just under
editBody. - In Attributes, type the id
textError, press Enter, then click Refactor.
-
Type The two fields, in Code.
- Click Code. Make
editTitleandeditBodymatch the panel.
res › layout › activity_main.xmlEdit the marked lineschange the struck partdelete the linetype the linetop to bottom: the line numbers are then Android Studio’s
<?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> editTitle <EditText android:id="@+id/editTitle" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="Title" android:importantForAutofill="no" android:inputType="texttextCapSentences" />
<EditText> editBody <EditText android:id="@+id/editBody" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="8dp" android:gravity="start|toptop" android:hint="Write something…" android:importantForAutofill="no" android:inputType="textMultiLinetextMultiLine|textCapSentences"/>android:maxLength="140" android:minLines="3" />
<TextView android:id="@+id/textError" android:layout_width="match_parentwrap_content" android:layout_height="wrap_content" android:layout_marginTop="8dp" android:text="TextViewGive your note a title first."/>android:textSize="14sp" android:visibility="gone" />
<Button android:id="@+id/buttonAdd" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Add" /> </LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>The
|: AltGr+6 on an AZERTY keyboard. - Click Code. Make
-
Type The error line.
- Make
textErrormatch the panel.
res › layout › activity_main.xmlEdit the marked lineschange the struck partdelete the linetype the linetop to bottom: the line numbers are then Android Studio’s
<?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="texttextCapSentences" />
<EditText android:id="@+id/editBody" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="8dp" android:gravity="start|toptop" android:hint="Write something…" android:importantForAutofill="no" android:inputType="textMultiLinetextMultiLine|textCapSentences"/>android:maxLength="140" android:minLines="3" />
<TextView> textError <TextView android:id="@+id/textError" android:layout_width="match_parentwrap_content" android:layout_height="wrap_content" android:layout_marginTop="8dp" android:text="TextViewGive your note a title first."/>android:textSize="14sp" android:visibility="gone" />
<Button android:id="@+id/buttonAdd" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Add" /> </LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>gone: hidden, and it takes no room. - Make
You should see In Design, the second field is three lines tall. textError is in Component Tree, not on the screen: it is gone.
Stuck? 2 symptoms
textErroris not just undereditBodyIn Component Tree, click its row, then drag it onto the lower half of theeditBodyrow.- The XML turns red after you typed A closing went with an edit, or you typed it twice: each view’s last line ends with one
/>, as in the panels.
B3 The card’s last row 12 min
-
A row under the error line. It needs no id.
- Click Design.
- In Component Tree, drag a LinearLayout (horizontal) from PaletteLayouts onto the lower half of the
textErrorrow. It is the first LinearLa….
-
Two views in the row.
- Drag a TextView from PaletteCommon onto the new
LinearLayoutrow. - Click the › at the left of that row: it opens.
- Drag a Button from PaletteCommon onto the lower half of the new TextView row, under the new
LinearLayout.
- Drag a TextView from PaletteCommon onto the new
-
Their ids.
- Click the new TextView row, under the new
LinearLayout. - In Attributes, type the id
textCounter, press Enter, then click Refactor. - Click the new Button row, under it.
- In Attributes, type the id
buttonClear, press Enter, then click Refactor.
- Click the new TextView row, under the new
-
Move Add into the row.
- In Component Tree, click the
buttonAddrow. - Drag it onto the lower half of the
buttonClearrow: it moves into the row, last.
Component Tree Layout editor · centre - In Component Tree, click the
-
Type The row, in Code.
- Click Code. Make the row and its three views match the panel.
res › layout › activity_main.xmlEdit the marked lineschange the struck partdelete the linetype the linetop to bottom: the line numbers are then Android Studio’s
<?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> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parentwrap_content" android:layout_marginTop="8dp" android:gravity="center_vertical" android:orientation="horizontal">
<TextView> textCounter <TextView android:id="@+id/textCounter" android:layout_width="wrap_content0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="TextView0 / 140"/>android:textSize="12sp" />
<Button> buttonClear <Button android:id="@+id/buttonClear" style="@style/Widget.Material3.Button.TextButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:text="ButtonClear" />
<Button> buttonAdd <Button android:id="@+id/buttonAdd" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="4dp" android:text="Add" /> </LinearLayout>empty line </LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>style=takes noandroid:.
You should see In Design, one row at the card’s bottom: 0 / 140 at the left, then Clear and Add.
Stuck? 3 symptoms
- The three views stand one under the other The row is a vertical
LinearLayout: in itsandroid:orientationline, changeverticaltohorizontal. - Add is not last in the row In Component Tree, click
buttonAdd, then drag it onto the lower half ofbuttonClear’s row, not onto theLinearLayoutrow. error: attribute android:style not found.InbuttonClear, writestyle=withoutandroid:.
B4 The list’s title and hint 15 min
-
Two TextViews under the card.
- Click Design. Drag a TextView from PaletteCommon to the empty screen under the card, at the left.
- In Attributes, type the id
textListTitle, press Enter, then click Refactor. - Drag another TextView to its right.
- In Attributes, type the id
textListHint, press Enter, then click Refactor.
-
Type The list’s title, in Code.
- Click Code. Make
textListTitlematch the panel.
res › layout › activity_main.xmlEdit the marked lineschange the struck partdelete the linetype the linetop to bottom: the line numbers are then Android Studio’s
<?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="Add" /> </LinearLayout> </LinearLayout>
<TextView> textListTitle <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="TextViewYOUR NOTES" tools:layout_editor_absoluteX="…" tools:layout_editor_absoluteY="…" /> 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="wrap_content0dp" android:layout_height="wrap_content" android:layout_marginStart="16dp" android:layout_marginEnd="32dp" android:gravity="end" android:text="TextViewTap to open · hold to delete" tools:layout_editor_absoluteX="…" tools:layout_editor_absoluteY="…" /> android:textSize="12sp" app:layout_constraintBaseline_toBaselineOf="@id/textListTitle" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toEndOf="@id/textListTitle" />
</androidx.constraintlayout.widget.ConstraintLayout> - Click Code. Make
-
Type The hint.
- Make
textListHintmatch the panel. No·key? Select it in the panel, then press Ctrl+C.
res › layout › activity_main.xmlEdit the marked lineschange the struck partdelete the linetype the linetop to bottom: the line numbers are then Android Studio’s
<?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="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="TextViewYOUR NOTES" tools:layout_editor_absoluteX="…" tools:layout_editor_absoluteY="…" /> android:textSize="12sp" android:textStyle="bold" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/composer" />
<TextView> textListHint <TextView android:id="@+id/textListHint" android:layout_width="wrap_content0dp" android:layout_height="wrap_content" android:layout_marginStart="16dp" android:layout_marginEnd="32dp" android:gravity="end" android:text="TextViewTap to open · hold to delete" tools:layout_editor_absoluteX="…" tools:layout_editor_absoluteY="…" /> android:textSize="12sp" app:layout_constraintBaseline_toBaselineOf="@id/textListTitle" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toEndOf="@id/textListTitle" />
</androidx.constraintlayout.widget.ConstraintLayout>0dp: the hint stretches to the right edge. - Make
You should see In Design, YOUR NOTES in bold under the card, at the left; the hint on the same line, against the right edge.
Stuck? 2 symptoms
- A TextView went into the white card In Component Tree it sits inside
composer. Press Ctrl+Z, then drop it lower, on the empty screen. @id/composeror@id/textListTitleis red An id is misspelt: the card’s iscomposer, the list title’stextListTitle.
B5 The list and its empty message 18 min
-
The list: a ScrollView.
- Click Design.
- Drag a ScrollView from PaletteCommon to under YOUR NOTES.
- In Attributes, type the id
scrollNotes, then press Enter. No Rename: it had no id. - In Component Tree, click the › of the
scrollNotesrow, then the LinearLayout row inside it. - In Attributes, type the id
notesContainer, then press Enter.
-
The empty message: a TextView.
- Drag a TextView from PaletteCommon onto the orange band, right of Notes. Over the card it would go inside it; over the list, nothing happens.
- In Attributes, type the id
textEmpty, press Enter, then click Refactor.
Palette · Layout editor Layout editor · centre -
Type The list, in Code.
- Click Code. Make
scrollNotesandnotesContainermatch the panel.
res › layout › activity_main.xmlEdit the marked lineschange the struck partdelete the linetype the linewhat your drop wrotetop to bottom: the line numbers are then Android Studio’s
<?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="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> scrollNotes <ScrollView android:id="@+id/scrollNotes" android:layout_width="…0dp" android:layout_height="…0dp" tools:layout_editor_absoluteX="…" tools:layout_editor_absoluteY="…"> 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> notesContainer <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="TextViewNo notes yet.\nWrite your first one above." tools:layout_editor_absoluteX="…" tools:layout_editor_absoluteY="…" /> 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> - Click Code. Make
-
Type The empty message.
- Make
textEmptymatch the panel.
res › layout › activity_main.xmlEdit the marked lineschange the struck partdelete the linetype the linewhat your drop wrotetop to bottom: the line numbers are then Android Studio’s
<?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="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" tools:layout_editor_absoluteX="…" tools:layout_editor_absoluteY="…"> 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> textEmpty <TextView android:id="@+id/textEmpty" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="48dp" android:gravity="center" android:text="TextViewNo notes yet.\nWrite your first one above." tools:layout_editor_absoluteX="…" tools:layout_editor_absoluteY="…" /> 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>\nis a backslash (AltGr+8 on AZERTY) thenn, not Enter. - Make
You should see In Design, nothing new under YOUR NOTES: the list is empty, textEmpty is gone. Click scrollNotes in Component Tree: its frame reaches the bottom.
Stuck? 3 symptoms
- The
ScrollViewholds noLinearLayoutin Component Tree Drop a LinearLayout (vertical) ontoscrollNotesthere, then give it the idnotesContainer. textEmptylanded inside the card Press Ctrl+Z, then drop it on the orange band, right of Notes.- The XML turns red after you typed
scrollNotes’s last line ends with>(itsLinearLayoutsits inside it);notesContainerandtextEmptyend with/>.
B6 Compare your file with the full file 3 min
-
Compare, without pasting.
- Click Copy the file on the panel below. Its message says to paste: don’t, only compare.
- In Code, click once in the text, then right-click and choose Compare with Clipboard.
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="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>
You should see A tab Clipboard vs activity_main.xml opens: Contents are identical. Your file is the full file, line for line. Close that tab.
Stuck? 2 symptoms
- The tab lists differences Fix each one in your file, or paste the full file over yours: Part 4 cites its line numbers.
- Only the
…or the·differs One was typed by hand: copy it from the full file’s panel.
-
Then, way A or B: ▶ Run 'app'.

Done I see the skeleton: band, card, YOUR NOTES.
Stuck? 4 symptoms · the file
- The XML is red everywhere after the paste The old text is still there. Press Ctrl+A, then paste again.
- Red and yellow marks on the fields, the buttons and the
ScrollViewAccessibility and text checks: real advice, not build errors. The app still runs. - Way B: a view landed in the wrong place in Component Tree Press Ctrl+Z, then drop it again as its part says.
- Way B: lost, or the compare lists many differences Paste the full file (way A) over yours: the same views, and the line numbers Part 4 cites.
The file at the end of this step is way A’s panel: Copy the file.
Go deeper The new attributes, one line each 2 min
<?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="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>- Baseline: the count’s text sits on the same line as the title’s.
hint: the grey text shown while the field is empty.importantForAutofill="no"turns autofill off here. Without it, lint warnsMissing autofillHints attribute.inputTypesets the keyboard’s mode. Here, several lines and a capital at each sentence.maxLengthstops the field at 140 characters.visibility="gone"hides it, and it takes no room. Java shows it in Part 7.layout_weight="1"gives the counter the row’s free space; Clear and Add keep their size.style=takes no prefix:android:styledoes not exist.0dp: the hint stretches from the label to the right edge. A long hint wraps in its own column.- The list hangs from the hint’s bottom: a hint on two lines pushes it down.
Step 6 of 6
Preview other screen sizes
Goal Show the screen on a tablet, then on the phone, upright.
- Layout activity_main.xml · Design
-
A tablet.
- Above the preview, click the device menu: it shows the phone’s name, here Pixel.
- Choose Medium Tablet: the preview turns landscape.
The preview’s device menu A menuFull size
- The device menu (here Pixel).
- Medium Tablet: 1280 × 800 dp.
-
The phone, upright.
- Click the device menu again, then choose AVD: Pixel 7.
- The phone stays on its side: click the orientation menu, left of the device menu.
- Choose Portrait.
The orientation menu A menuFull size
- The orientation menu.
- Portrait · Landscape.
Done I see the card stretch; nothing jumps.
Stuck? 2 symptoms
- The phone preview stays on its side A tablet pick turned it to landscape. In the orientation menu, pick Portrait.
- No AVD: Pixel 7 in the device menu It lists your virtual phones: create the Pixel 7 first (Part 0, step 0.2).
No file changes in this step.
Now you
Run it on a tablet
Run the app on Part 0’s Medium Tablet. Stop the phone first: ■ in Device Manager.
See the answer
In the device menu of the toolbar, pick the tablet, then ▶. The band and the card stretch; nothing jumps. Why stop the phone? Two emulators at once can freeze a laptop. No tablet yet? In Device Manager, add a Medium Tablet as in Part 0’s Now you: no download.

If it doesn’t work
- A view jumps to the top on the phone It misses a constraint. Give it one horizontal and one vertical (rule 1).
match_parentgives odd results For a direct child of theConstraintLayout, use0dpbetween two constraints (rule 2).- A view went wrong after many drags Right-click it, then Clear Constraints of Selection, and tie it again. Avoid Infer Constraints: it guesses for you.
error: attribute android:style not found.Writestyle=withoutandroid:.- An attribute you typed is underlined in red The drag had already written it. Keep one copy, with the panel’s value.
- The XML turns red after you type A tag ends with one
>(or/>). Type new attributes before it, never after.
End of the part
Recap
The editor keeps a view where you drop it; the phone follows its constraints: one horizontal, one vertical per view.
- drag views and give them ids;
- tie a view to the parent or to another view; use
0dp; - explain why a view without constraints jumps; preview other sizes.
