Before you start
By the end you can
- set a view’s text and visibility from Java, at the right moment;
- build a view in Java, or inflate it from XML;
- say when to use each way.
- Java MainActivity.java
- Layout res › layout
- Resources res › values · res › drawable
- Emulator
Behind, or a fresh project? Start from here about 4 min
The project: your own from Part 5, 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)}Restarting this part? First delete res › layout › item_note.xml and every res › drawable › bg_note_*.xml (right-click, Delete…, OK). Red marks in MainActivity until you paste the Java: normal.
lab1-part6-res.zip zip · 6.3 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 android.util.Log;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "Lifecycle";
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Log.d(TAG, "Main onCreate"); }
@Override protected void onStart() { super.onStart(); Log.d(TAG, "Main onStart"); }
@Override protected void onResume() { super.onResume(); Log.d(TAG, "Main onResume"); }
@Override protected void onPause() { super.onPause(); Log.d(TAG, "Main onPause"); }
@Override protected void onStop() { super.onStop(); Log.d(TAG, "Main onStop"); }
@Override protected void onRestart() { super.onRestart(); Log.d(TAG, "Main onRestart"); }
@Override protected void onDestroy() { super.onDestroy(); Log.d(TAG, "Main onDestroy"); }}▶. You are ready when the phone shows the notes screen, the pill at 0 and an empty list.
Step 1 of 5
Get your views, then count the cards
Goal Reach three views from Java; make the pill count the cards.
- Java kotlin+java › com.yourname.notes › MainActivity.java
- Emulator
-
Type Three instance variables, above
onCreate().- In MainActivity.java, click at the end of the
TAGline. - Press Enter twice: the first makes the marked empty line.
- Type the 3 marked lines, with Enter after the first two.
- A red name (
TextView,LinearLayout)? Click it, press Alt+Enter, then choose Import class in the list that opens.
kotlin+java › com.yourname.notes › MainActivity.javaAdd the marked linespackage com.yourname.notes;
import android.os.Bundle;import android.util.Log;import android.view.View;import android.widget.LinearLayout;import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "Lifecycle";
private TextView textCount; private TextView textEmpty; private LinearLayout notesContainer;
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Log.d(TAG, "Main onCreate");
textCount = findViewById(R.id.textCount); textEmpty = findViewById(R.id.textEmpty); notesContainer = findViewById(R.id.notesContainer);
updateCount(); }
private void updateCount() { int count = notesContainer.getChildCount(); textCount.setText(String.valueOf(count)); textEmpty.setVisibility(count == 0 ? View.VISIBLE : View.GONE); }
@Override protected void onStart() { super.onStart(); Log.d(TAG, "Main onStart"); }
@Override protected void onResume() { super.onResume(); Log.d(TAG, "Main onResume"); }
@Override protected void onPause() { super.onPause(); Log.d(TAG, "Main onPause"); }
@Override protected void onStop() { super.onStop(); Log.d(TAG, "Main onStop"); }
@Override protected void onRestart() { super.onRestart(); Log.d(TAG, "Main onRestart"); }
@Override protected void onDestroy() { super.onDestroy(); Log.d(TAG, "Main onDestroy"); }} - In MainActivity.java, click at the end of the
-
Type Fill them in
onCreate(), then callupdateCount().- Click at the end of the
Log.d(…);line. - Press Enter twice, then type the 3 marked
findViewById()lines, with Enter after the first two. - Press Enter twice, then type
updateCount();. It stays red until action c writes the method.
kotlin+java › com.yourname.notes › MainActivity.javaAdd the marked linespackage com.yourname.notes;
import android.os.Bundle;import android.util.Log;import android.view.View;import android.widget.LinearLayout;import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "Lifecycle";
private TextView textCount; private TextView textEmpty; private LinearLayout notesContainer;
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Log.d(TAG, "Main onCreate");
textCount = findViewById(R.id.textCount); textEmpty = findViewById(R.id.textEmpty); notesContainer = findViewById(R.id.notesContainer);
updateCount(); }
private void updateCount() { int count = notesContainer.getChildCount(); textCount.setText(String.valueOf(count)); textEmpty.setVisibility(count == 0 ? View.VISIBLE : View.GONE); }
@Override protected void onStart() { super.onStart(); Log.d(TAG, "Main onStart"); }
@Override protected void onResume() { super.onResume(); Log.d(TAG, "Main onResume"); }
@Override protected void onPause() { super.onPause(); Log.d(TAG, "Main onPause"); }
@Override protected void onStop() { super.onStop(); Log.d(TAG, "Main onStop"); }
@Override protected void onRestart() { super.onRestart(); Log.d(TAG, "Main onRestart"); }
@Override protected void onDestroy() { super.onDestroy(); Log.d(TAG, "Main onDestroy"); }}Lines 25–27:
findViewById()returns the object thatsetContentView()(line 22) built for that id. - Click at the end of the
-
Type The method
updateCount(), underonCreate().- Click right after the
}that endsonCreate(), at the end of its line. - Press Enter twice: the first makes the marked empty line.
- Type
private void updateCount() {: Android Studio adds the}right after it. - Press Enter: the
}moves down a line. - Type the 3 marked lines between the braces.
Viewis red? Click it, press Alt+Enter, then choose Import class.
kotlin+java › com.yourname.notes › MainActivity.javaAdd the marked linespackage com.yourname.notes;
import android.os.Bundle;import android.util.Log;import android.view.View;import android.widget.LinearLayout;import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "Lifecycle";
private TextView textCount; private TextView textEmpty; private LinearLayout notesContainer;
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Log.d(TAG, "Main onCreate");
textCount = findViewById(R.id.textCount); textEmpty = findViewById(R.id.textEmpty); notesContainer = findViewById(R.id.notesContainer);
updateCount(); }
private void updateCount() { int count = notesContainer.getChildCount(); textCount.setText(String.valueOf(count)); textEmpty.setVisibility(count == 0 ? View.VISIBLE : View.GONE); }
@Override protected void onStart() { super.onStart(); Log.d(TAG, "Main onStart"); }
@Override protected void onResume() { super.onResume(); Log.d(TAG, "Main onResume"); }
@Override protected void onPause() { super.onPause(); Log.d(TAG, "Main onPause"); }
@Override protected void onStop() { super.onStop(); Log.d(TAG, "Main onStop"); }
@Override protected void onRestart() { super.onRestart(); Log.d(TAG, "Main onRestart"); }
@Override protected void onDestroy() { super.onDestroy(); Log.d(TAG, "Main onDestroy"); }}Line 33:
getChildCount()is the number of views innotesContainer. Line 34:setText()wants a text, soString.valueOf()turns the number into one. Line 35: a ternary picksVISIBLEat 0 cards,GONEotherwise. - Click right after the
-
▶ Run 'app'.

You should see The empty message, below YOUR NOTES.
Done I see “No notes yet.”
Predict
Without a Run: what if the textCount line came before setContentView()?
See the answer
It builds, then the app closes at launch. Before setContentView(), the screen has no views yet: findViewById() returns null, and calling setText() on null crashes. Logcat says:
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference
Stuck? 3 symptoms · the file
- The app closes at launch:
NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object referenceAfindViewById()line runs beforesetContentView(), or names an id of another layout. Put the 3 lines aftersetContentView(). Resources$NotFoundException: String resource ID #0x0at launchsetText(count)with anintasks for a string resource. WriteString.valueOf(count).TextView,LinearLayoutorViewstays red Its import is missing. Click on the name, press Alt+Enter, then choose Import class.
The files at the end of this step
package com.yourname.notes;
import android.os.Bundle;import android.util.Log;import android.view.View;import android.widget.LinearLayout;import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "Lifecycle";
private TextView textCount; private TextView textEmpty; private LinearLayout notesContainer;
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Log.d(TAG, "Main onCreate");
textCount = findViewById(R.id.textCount); textEmpty = findViewById(R.id.textEmpty); notesContainer = findViewById(R.id.notesContainer);
updateCount(); }
private void updateCount() { int count = notesContainer.getChildCount(); textCount.setText(String.valueOf(count)); textEmpty.setVisibility(count == 0 ? View.VISIBLE : View.GONE); }
@Override protected void onStart() { super.onStart(); Log.d(TAG, "Main onStart"); }
@Override protected void onResume() { super.onResume(); Log.d(TAG, "Main onResume"); }
@Override protected void onPause() { super.onPause(); Log.d(TAG, "Main onPause"); }
@Override protected void onStop() { super.onStop(); Log.d(TAG, "Main onStop"); }
@Override protected void onRestart() { super.onRestart(); Log.d(TAG, "Main onRestart"); }
@Override protected void onDestroy() { super.onDestroy(); Log.d(TAG, "Main onDestroy"); }}Step 2 of 5
Build a card by hand
Goal Way 1: build a card in Java alone, and add it to the list.
- Resources res › values · res › drawable
- Java MainActivity.java
- Emulator
-
Paste The 8 pastel colours, in colors.xml.
- Double-click res › values › colors.xml, in the Project window.
- Click Copy 8 lines, beside After line 12.
- In colors.xml, click at the end of line 12, press Enter, then Ctrl+V.
res › values › colors.xmlAdd the marked lines<?xml version="1.0" encoding="utf-8"?><resources> <color name="brand">#C2410C</color> <color name="on_brand">#FFFFFF</color> <color name="header_end">#E11D48</color> <color name="paper">#FFF8F1</color> <color name="card">#FFFFFF</color> <color name="field">#FBF6F0</color> <color name="line">#E7D9CB</color> <color name="ink">#1F1A17</color> <color name="muted">#6B6159</color> <color name="error">#B91C1C</color> <color name="note_butter">#FFF1C9</color> <color name="note_butter_line">#F2D27A</color> <color name="note_mint">#D9F5E6</color> <color name="note_mint_line">#93D9B4</color> <color name="note_lavender">#ECE6FF</color> <color name="note_lavender_line">#C6B8FA</color> <color name="note_peach">#FFE1D6</color> <color name="note_peach_line">#F7B29A</color></resources> -
Paste The 6 seed strings, in strings.xml.
- Double-click res › values › strings.xml.
- Click Copy 6 lines, beside After line 13.
- In strings.xml, click at the end of line 13, press Enter, then Ctrl+V.
res › values › strings.xmlAdd the marked lines<resources> <string name="app_name">Notes</string> <string name="logo_description">Notes logo</string> <string name="count_start">0</string> <string name="title_hint">Title</string> <string name="body_hint">Write something…</string> <string name="error_no_title">Give your note a title first.</string> <string name="counter_start">0 / 140</string> <string name="clear">Clear</string> <string name="add">Add</string> <string name="your_notes">YOUR NOTES</string> <string name="list_hint">Tap to open · hold to delete</string> <string name="empty">No notes yet.\nWrite your first one above.</string> <string name="seed_title_1">Saturday</string> <string name="seed_body_1">Football at 10, then revise ConstraintLayout.</string> <string name="seed_title_2">Ideas for the app</string> <string name="seed_body_2">Pastel cards, a Share button, maybe a photo one day. Then save the notes, so that turning the phone loses nothing.</string> <string name="seed_title_3">Exam: the lifecycle</string> <string name="seed_body_3">onCreate, onStart, onResume… then onPause, onStop, onDestroy.</string></resources> -
Paste The butter card’s background: a new drawable.
- Right-click res › drawable, then choose NewDrawable Resource File.
- A New Resource File window opens: in File name, type
bg_note_butter. - In Root element, press Ctrl+A to select
selector, then typeshape. - Click OK: bg_note_butter.xml opens in Design: click Code.
- Click Copy the file on the panel below.
- In bg_note_butter.xml, click in the text, press Ctrl+A, then Ctrl+V.
res › drawable › bg_note_butter.xmlNew file<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <solid android:color="@color/note_butter" /> <stroke android:width="1dp" android:color="@color/note_butter_line" /> <corners android:radius="16dp" /></shape> -
Paste The import and the call, in MainActivity.java.
- Click Copy 1 line, beside After line 4.
- In MainActivity.java, click at the end of line 4, press Enter, then Ctrl+V.
- Click Copy 1 line, beside After line 29.
- Click at the end of line 29, press Enter, then Ctrl+V.
kotlin+java › com.yourname.notes › MainActivity.javaAdd the marked linespackage com.yourname.notes;
import android.os.Bundle;import android.util.Log;import android.util.TypedValue;import android.view.View;import android.widget.LinearLayout;import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "Lifecycle";
private TextView textCount; private TextView textEmpty; private LinearLayout notesContainer;
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Log.d(TAG, "Main onCreate");
textCount = findViewById(R.id.textCount); textEmpty = findViewById(R.id.textEmpty); notesContainer = findViewById(R.id.notesContainer);
addCardByHand(getString(R.string.seed_title_1)); updateCount(); }
private void updateCount() { int count = notesContainer.getChildCount(); textCount.setText(String.valueOf(count)); textEmpty.setVisibility(count == 0 ? View.VISIBLE : View.GONE); }
private void addCardByHand(String title) { TextView card = new TextView(this); card.setText(title); card.setTextSize(16); card.setTextColor(getColor(R.color.ink)); card.setBackgroundResource(R.drawable.bg_note_butter); int padding = (int) TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, 16, getResources().getDisplayMetrics()); card.setPadding(padding, padding, padding, padding); notesContainer.addView(card); }
@Override protected void onStart() { super.onStart(); Log.d(TAG, "Main onStart"); }
@Override protected void onResume() { super.onResume(); Log.d(TAG, "Main onResume"); }
@Override protected void onPause() { super.onPause(); Log.d(TAG, "Main onPause"); }
@Override protected void onStop() { super.onStop(); Log.d(TAG, "Main onStop"); }
@Override protected void onRestart() { super.onRestart(); Log.d(TAG, "Main onRestart"); }
@Override protected void onDestroy() { super.onDestroy(); Log.d(TAG, "Main onDestroy"); }} -
Paste The method
addCardByHand(), underupdateCount().- Click Copy 12 lines, beside After line 38.
- Click at the end of line 38, press Enter, then Ctrl+V.
kotlin+java › com.yourname.notes › MainActivity.javaAdd the marked linespackage com.yourname.notes;
import android.os.Bundle;import android.util.Log;import android.util.TypedValue;import android.view.View;import android.widget.LinearLayout;import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "Lifecycle";
private TextView textCount; private TextView textEmpty; private LinearLayout notesContainer;
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Log.d(TAG, "Main onCreate");
textCount = findViewById(R.id.textCount); textEmpty = findViewById(R.id.textEmpty); notesContainer = findViewById(R.id.notesContainer);
addCardByHand(getString(R.string.seed_title_1)); updateCount(); }
private void updateCount() { int count = notesContainer.getChildCount(); textCount.setText(String.valueOf(count)); textEmpty.setVisibility(count == 0 ? View.VISIBLE : View.GONE); }
private void addCardByHand(String title) { TextView card = new TextView(this); card.setText(title); card.setTextSize(16); card.setTextColor(getColor(R.color.ink)); card.setBackgroundResource(R.drawable.bg_note_butter); int padding = (int) TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, 16, getResources().getDisplayMetrics()); card.setPadding(padding, padding, padding, padding); notesContainer.addView(card); }
@Override protected void onStart() { super.onStart(); Log.d(TAG, "Main onStart"); }
@Override protected void onResume() { super.onResume(); Log.d(TAG, "Main onResume"); }
@Override protected void onPause() { super.onPause(); Log.d(TAG, "Main onPause"); }
@Override protected void onStop() { super.onStop(); Log.d(TAG, "Main onStop"); }
@Override protected void onRestart() { super.onRestart(); Log.d(TAG, "Main onRestart"); }
@Override protected void onDestroy() { super.onDestroy(); Log.d(TAG, "Main onDestroy"); }}Line 41: a new view needs a
Context:this, the activity. Line 43:setTextSize(16)is already in sp. Line 44:getColor()turns a colour’s id into the colour. -
▶ Run 'app'.

You should see A card built by Java alone:

Done I see a roomy butter card, and 1 in the pill.
Why setPadding() takes pixels; applyDimension() turns 16 dp into pixels on any phone.
Stuck? 4 symptoms · the files
cannot find symbol … variable seed_title_1The seed strings are missing. Paste the 6 lines into strings.xml.Android resource linking failed … bg_note_butter.xml:4: error: resource color/note_butter … not foundThe pastel colours are missing. Paste the 8 lines into colors.xml.bg_note_butteris red in Java The drawable is missing, or named otherwise. It must be res › drawable › bg_note_butter.xml.TypedValuestays red Its import is missing. Click on the name, press Alt+Enter, then choose Import class.
The files at the end of this step. bg_note_butter.xml is the panel above.
package com.yourname.notes;
import android.os.Bundle;import android.util.Log;import android.util.TypedValue;import android.view.View;import android.widget.LinearLayout;import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "Lifecycle";
private TextView textCount; private TextView textEmpty; private LinearLayout notesContainer;
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Log.d(TAG, "Main onCreate");
textCount = findViewById(R.id.textCount); textEmpty = findViewById(R.id.textEmpty); notesContainer = findViewById(R.id.notesContainer);
addCardByHand(getString(R.string.seed_title_1)); updateCount(); }
private void updateCount() { int count = notesContainer.getChildCount(); textCount.setText(String.valueOf(count)); textEmpty.setVisibility(count == 0 ? View.VISIBLE : View.GONE); }
private void addCardByHand(String title) { TextView card = new TextView(this); card.setText(title); card.setTextSize(16); card.setTextColor(getColor(R.color.ink)); card.setBackgroundResource(R.drawable.bg_note_butter); int padding = (int) TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, 16, getResources().getDisplayMetrics()); card.setPadding(padding, padding, padding, padding); notesContainer.addView(card); }
@Override protected void onStart() { super.onStart(); Log.d(TAG, "Main onStart"); }
@Override protected void onResume() { super.onResume(); Log.d(TAG, "Main onResume"); }
@Override protected void onPause() { super.onPause(); Log.d(TAG, "Main onPause"); }
@Override protected void onStop() { super.onStop(); Log.d(TAG, "Main onStop"); }
@Override protected void onRestart() { super.onRestart(); Log.d(TAG, "Main onRestart"); }
@Override protected void onDestroy() { super.onDestroy(); Log.d(TAG, "Main onDestroy"); }}<?xml version="1.0" encoding="utf-8"?><resources> <color name="brand">#C2410C</color> <color name="on_brand">#FFFFFF</color> <color name="header_end">#E11D48</color> <color name="paper">#FFF8F1</color> <color name="card">#FFFFFF</color> <color name="field">#FBF6F0</color> <color name="line">#E7D9CB</color> <color name="ink">#1F1A17</color> <color name="muted">#6B6159</color> <color name="error">#B91C1C</color> <color name="note_butter">#FFF1C9</color> <color name="note_butter_line">#F2D27A</color> <color name="note_mint">#D9F5E6</color> <color name="note_mint_line">#93D9B4</color> <color name="note_lavender">#ECE6FF</color> <color name="note_lavender_line">#C6B8FA</color> <color name="note_peach">#FFE1D6</color> <color name="note_peach_line">#F7B29A</color></resources><resources> <string name="app_name">Notes</string> <string name="logo_description">Notes logo</string> <string name="count_start">0</string> <string name="title_hint">Title</string> <string name="body_hint">Write something…</string> <string name="error_no_title">Give your note a title first.</string> <string name="counter_start">0 / 140</string> <string name="clear">Clear</string> <string name="add">Add</string> <string name="your_notes">YOUR NOTES</string> <string name="list_hint">Tap to open · hold to delete</string> <string name="empty">No notes yet.\nWrite your first one above.</string> <string name="seed_title_1">Saturday</string> <string name="seed_body_1">Football at 10, then revise ConstraintLayout.</string> <string name="seed_title_2">Ideas for the app</string> <string name="seed_body_2">Pastel cards, a Share button, maybe a photo one day. Then save the notes, so that turning the phone loses nothing.</string> <string name="seed_title_3">Exam: the lifecycle</string> <string name="seed_body_3">onCreate, onStart, onResume… then onPause, onStop, onDestroy.</string></resources>Step 3 of 5
Inflate the card from a layout
Goal Way 2: describe the card once in XML; Java makes one per note.
- Layout res › layout › item_note.xml · Code
- Java MainActivity.java
- Emulator
- A card Way 1 (6.2):
new TextView(this),setText(),setPadding()… Way 2 (6.3):inflate(.R.layout. item_note, notesContainer, false) addView(card, 0)hangs the card innotesContainer; 0 = first place, on topnotesContainera verticalLinearLayout: one card under the other, newest on top
notesContainer holds the cards, its children: addView() adds one; getChildCount() counts them.-
A layout for one card:
item_note.xml.- Right-click res › layout, then choose NewLayout Resource File.
- New Resource File opens: in File name, type
item_note. - In Root element, press Ctrl+A, then type
LinearLayout. - A list opens, LinearLayout first: press Enter.
- Click OK: item_note.xml opens in Design.
- Click Code, top right of the editor.
-
The card’s look, in item_note.xml.
- Click Copy the file on c’s panel.
- In item_note.xml, click in the text, press Ctrl+A, then Ctrl+V.
Its lines 8–9 keep Part 8’s press ripple inside the rounded corners (Android 12+); line 12 tells lint.
-
Paste The file b pastes.
res › layout › item_note.xmlNew file<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="12dp" android:background="@drawable/bg_note_butter" android:clipToOutline="true" android:foreground="?attr/selectableItemBackground" android:orientation="vertical" android:padding="16dp" tools:targetApi="31">
<TextView android:id="@+id/textNoteTitle" android:layout_width="match_parent" android:layout_height="wrap_content" android:textColor="@color/ink" android:textSize="16sp" android:textStyle="bold" tools:text="Ideas for the app" />
<TextView android:id="@+id/textNoteBody" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="4dp" android:ellipsize="end" android:maxLines="2" android:textColor="@color/ink" android:textSize="14sp" tools:text="Pastel cards, a Share button, maybe a photo one day." /></LinearLayout> -
Type The method
addNote(), underaddCardByHand().- In MainActivity.java, click right after the
}endingaddCardByHand(), at the end of its line, then press Enter twice. - Type
private void addNote(String title, String body) {: Android Studio adds the}right after it. - Press Enter: the
}moves down a line. - Type the 7 marked lines between the braces.
LayoutInflateris red? Click it, press Alt+Enter, then choose Import class.
kotlin+java › com.yourname.notes › MainActivity.javaAdd the marked linespackage com.yourname.notes;
import android.os.Bundle;import android.util.Log;import android.util.TypedValue;import android.view.LayoutInflater;import android.view.View;import android.widget.LinearLayout;import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "Lifecycle";
private TextView textCount; private TextView textEmpty; private LinearLayout notesContainer;
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Log.d(TAG, "Main onCreate");
textCount = findViewById(R.id.textCount); textEmpty = findViewById(R.id.textEmpty); notesContainer = findViewById(R.id.notesContainer);
addNote(getString(R.string.seed_title_1), getString(R.string.seed_body_1)); updateCount(); }
private void updateCount() { int count = notesContainer.getChildCount(); textCount.setText(String.valueOf(count)); textEmpty.setVisibility(count == 0 ? View.VISIBLE : View.GONE); }
private void addCardByHand(String title) { TextView card = new TextView(this); card.setText(title); card.setTextSize(16); card.setTextColor(getColor(R.color.ink)); card.setBackgroundResource(R.drawable.bg_note_butter); int padding = (int) TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, 16, getResources().getDisplayMetrics()); card.setPadding(padding, padding, padding, padding); notesContainer.addView(card); }
private void addNote(String title, String body) { View card = LayoutInflater.from(this).inflate(R.layout.item_note, notesContainer, false); TextView cardTitle = card.findViewById(R.id.textNoteTitle); TextView cardBody = card.findViewById(R.id.textNoteBody); cardTitle.setText(title); cardBody.setText(body); cardBody.setVisibility(body.isEmpty() ? View.GONE : View.VISIBLE); notesContainer.addView(card, 0); }
@Override protected void onStart() { super.onStart(); Log.d(TAG, "Main onStart"); }
@Override protected void onResume() { super.onResume(); Log.d(TAG, "Main onResume"); }
@Override protected void onPause() { super.onPause(); Log.d(TAG, "Main onPause"); }
@Override protected void onStop() { super.onStop(); Log.d(TAG, "Main onStop"); }
@Override protected void onRestart() { super.onRestart(); Log.d(TAG, "Main onRestart"); }
@Override protected void onDestroy() { super.onDestroy(); Log.d(TAG, "Main onDestroy"); }}Line 54 turns
item_note.xmlinto objects, likesetContentView();false: “I add the card myself”. Lines 55–56 find the texts on the card. - In MainActivity.java, click right after the
-
Type Call
addNote()instead, inonCreate().- Click at the end of the
addCardByHand(…);line, then press Shift+Home. - Type the marked line over it.
addCardByHand()turns grey: keep it for 6.5.
kotlin+java › com.yourname.notes › MainActivity.javaAdd the marked linespackage com.yourname.notes;
import android.os.Bundle;import android.util.Log;import android.util.TypedValue;import android.view.LayoutInflater;import android.view.View;import android.widget.LinearLayout;import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "Lifecycle";
private TextView textCount; private TextView textEmpty; private LinearLayout notesContainer;
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Log.d(TAG, "Main onCreate");
textCount = findViewById(R.id.textCount); textEmpty = findViewById(R.id.textEmpty); notesContainer = findViewById(R.id.notesContainer);
addNote(getString(R.string.seed_title_1), getString(R.string.seed_body_1)); updateCount(); }
private void updateCount() { int count = notesContainer.getChildCount(); textCount.setText(String.valueOf(count)); textEmpty.setVisibility(count == 0 ? View.VISIBLE : View.GONE); }
private void addCardByHand(String title) { TextView card = new TextView(this); card.setText(title); card.setTextSize(16); card.setTextColor(getColor(R.color.ink)); card.setBackgroundResource(R.drawable.bg_note_butter); int padding = (int) TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, 16, getResources().getDisplayMetrics()); card.setPadding(padding, padding, padding, padding); notesContainer.addView(card); }
private void addNote(String title, String body) { View card = LayoutInflater.from(this).inflate(R.layout.item_note, notesContainer, false); TextView cardTitle = card.findViewById(R.id.textNoteTitle); TextView cardBody = card.findViewById(R.id.textNoteBody); cardTitle.setText(title); cardBody.setText(body); cardBody.setVisibility(body.isEmpty() ? View.GONE : View.VISIBLE); notesContainer.addView(card, 0); }
@Override protected void onStart() { super.onStart(); Log.d(TAG, "Main onStart"); }
@Override protected void onResume() { super.onResume(); Log.d(TAG, "Main onResume"); }
@Override protected void onPause() { super.onPause(); Log.d(TAG, "Main onPause"); }
@Override protected void onStop() { super.onStop(); Log.d(TAG, "Main onStop"); }
@Override protected void onRestart() { super.onRestart(); Log.d(TAG, "Main onRestart"); }
@Override protected void onDestroy() { super.onDestroy(); Log.d(TAG, "Main onDestroy"); }} - Click at the end of the
-
▶ Run 'app'.

You should see A bold title, a text line, space above.
Done I see the card’s new text line.
Stuck? 3 symptoms · the file
- The new file shows a picture, no XML It opened in Design mode. Click Code, at the top right of the editor.
- The app closes at launch:
NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object referenceThe two texts were looked for on the screen. They are on the card: writecard.findViewById(…). LayoutInflaterstays red Its import is missing. Click on the name, press Alt+Enter, then choose Import class.
The files at the end of this step. item_note.xml is the panel above.
package com.yourname.notes;
import android.os.Bundle;import android.util.Log;import android.util.TypedValue;import android.view.LayoutInflater;import android.view.View;import android.widget.LinearLayout;import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "Lifecycle";
private TextView textCount; private TextView textEmpty; private LinearLayout notesContainer;
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Log.d(TAG, "Main onCreate");
textCount = findViewById(R.id.textCount); textEmpty = findViewById(R.id.textEmpty); notesContainer = findViewById(R.id.notesContainer);
addNote(getString(R.string.seed_title_1), getString(R.string.seed_body_1)); updateCount(); }
private void updateCount() { int count = notesContainer.getChildCount(); textCount.setText(String.valueOf(count)); textEmpty.setVisibility(count == 0 ? View.VISIBLE : View.GONE); }
private void addCardByHand(String title) { TextView card = new TextView(this); card.setText(title); card.setTextSize(16); card.setTextColor(getColor(R.color.ink)); card.setBackgroundResource(R.drawable.bg_note_butter); int padding = (int) TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, 16, getResources().getDisplayMetrics()); card.setPadding(padding, padding, padding, padding); notesContainer.addView(card); }
private void addNote(String title, String body) { View card = LayoutInflater.from(this).inflate(R.layout.item_note, notesContainer, false); TextView cardTitle = card.findViewById(R.id.textNoteTitle); TextView cardBody = card.findViewById(R.id.textNoteBody); cardTitle.setText(title); cardBody.setText(body); cardBody.setVisibility(body.isEmpty() ? View.GONE : View.VISIBLE); notesContainer.addView(card, 0); }
@Override protected void onStart() { super.onStart(); Log.d(TAG, "Main onStart"); }
@Override protected void onResume() { super.onResume(); Log.d(TAG, "Main onResume"); }
@Override protected void onPause() { super.onPause(); Log.d(TAG, "Main onPause"); }
@Override protected void onStop() { super.onStop(); Log.d(TAG, "Main onStop"); }
@Override protected void onRestart() { super.onRestart(); Log.d(TAG, "Main onRestart"); }
@Override protected void onDestroy() { super.onDestroy(); Log.d(TAG, "Main onDestroy"); }}Step 4 of 5
Colour the cards in turn
Goal Colour each card in turn, and start the app with three notes.
- Resources res › drawable
- Java MainActivity.java
- Emulator
-
Paste The mint background, a new drawable.
- Right-click res › drawable, then choose NewDrawable Resource File.
- A New Resource File window opens: in File name, type
bg_note_mint. - In Root element, press Ctrl+A to select
selector, then typeshape. - Click OK: bg_note_mint.xml opens in Design: click Code.
- Click Copy the file on the panel below.
- In bg_note_mint.xml, click in the text, press Ctrl+A, then Ctrl+V.
res › drawable › bg_note_mint.xmlNew file<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <solid android:color="@color/note_mint" /> <stroke android:width="1dp" android:color="@color/note_mint_line" /> <corners android:radius="16dp" /></shape> -
Paste Lavender and peach, the same way.
- Do a’s gestures 1 to 6 again for
bg_note_lavender, with the bg_note_lavender.xml panel. - Do them once more for
bg_note_peach, with the bg_note_peach.xml panel.
res › drawable › bg_note_lavender.xmlNew file<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <solid android:color="@color/note_lavender" /> <stroke android:width="1dp" android:color="@color/note_lavender_line" /> <corners android:radius="16dp" /></shape>res › drawable › bg_note_peach.xmlNew file<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <solid android:color="@color/note_peach" /> <stroke android:width="1dp" android:color="@color/note_peach_line" /> <corners android:radius="16dp" /></shape> - Do a’s gestures 1 to 6 again for
-
Paste 4 backgrounds and a counter, at the top of the class.
- Click Copy 6 lines, beside After line 15.
- In MainActivity.java, click at the end of line 15, press Enter, then Ctrl+V.
- Click Copy 1 line, beside After line 25.
- Click at the end of line 25, press Enter, then Ctrl+V.
kotlin+java › com.yourname.notes › MainActivity.javaAdd the marked linespackage com.yourname.notes;
import android.os.Bundle;import android.util.Log;import android.util.TypedValue;import android.view.LayoutInflater;import android.view.View;import android.widget.LinearLayout;import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "Lifecycle"; private static final int[] NOTE_BACKGROUNDS = { R.drawable.bg_note_butter, R.drawable.bg_note_mint, R.drawable.bg_note_lavender, R.drawable.bg_note_peach };
private TextView textCount; private TextView textEmpty; private LinearLayout notesContainer; private int notesAdded = 0;
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Log.d(TAG, "Main onCreate");
textCount = findViewById(R.id.textCount); textEmpty = findViewById(R.id.textEmpty); notesContainer = findViewById(R.id.notesContainer);
addNote(getString(R.string.seed_title_1), getString(R.string.seed_body_1)); addNote(getString(R.string.seed_title_2), getString(R.string.seed_body_2)); addNote(getString(R.string.seed_title_3), getString(R.string.seed_body_3)); updateCount(); }
private void updateCount() { int count = notesContainer.getChildCount(); textCount.setText(String.valueOf(count)); textEmpty.setVisibility(count == 0 ? View.VISIBLE : View.GONE); }
private void addCardByHand(String title) { TextView card = new TextView(this); card.setText(title); card.setTextSize(16); card.setTextColor(getColor(R.color.ink)); card.setBackgroundResource(R.drawable.bg_note_butter); int padding = (int) TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, 16, getResources().getDisplayMetrics()); card.setPadding(padding, padding, padding, padding); notesContainer.addView(card); }
private void addNote(String title, String body) { View card = LayoutInflater.from(this).inflate(R.layout.item_note, notesContainer, false); TextView cardTitle = card.findViewById(R.id.textNoteTitle); TextView cardBody = card.findViewById(R.id.textNoteBody); cardTitle.setText(title); cardBody.setText(body); cardBody.setVisibility(body.isEmpty() ? View.GONE : View.VISIBLE); int background = NOTE_BACKGROUNDS[notesAdded % NOTE_BACKGROUNDS.length]; card.setBackgroundResource(background); notesAdded++;
notesContainer.addView(card, 0); }
@Override protected void onStart() { super.onStart(); Log.d(TAG, "Main onStart"); }
@Override protected void onResume() { super.onResume(); Log.d(TAG, "Main onResume"); }
@Override protected void onPause() { super.onPause(); Log.d(TAG, "Main onPause"); }
@Override protected void onStop() { super.onStop(); Log.d(TAG, "Main onStop"); }
@Override protected void onRestart() { super.onRestart(); Log.d(TAG, "Main onRestart"); }
@Override protected void onDestroy() { super.onDestroy(); Log.d(TAG, "Main onDestroy"); }} -
Paste 2 more seed notes, in
onCreate().- Click Copy 2 lines, beside After line 38.
- Click at the end of line 38, press Enter, then Ctrl+V.
kotlin+java › com.yourname.notes › MainActivity.javaAdd the marked linespackage com.yourname.notes;
import android.os.Bundle;import android.util.Log;import android.util.TypedValue;import android.view.LayoutInflater;import android.view.View;import android.widget.LinearLayout;import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "Lifecycle"; private static final int[] NOTE_BACKGROUNDS = { R.drawable.bg_note_butter, R.drawable.bg_note_mint, R.drawable.bg_note_lavender, R.drawable.bg_note_peach };
private TextView textCount; private TextView textEmpty; private LinearLayout notesContainer; private int notesAdded = 0;
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Log.d(TAG, "Main onCreate");
textCount = findViewById(R.id.textCount); textEmpty = findViewById(R.id.textEmpty); notesContainer = findViewById(R.id.notesContainer);
addNote(getString(R.string.seed_title_1), getString(R.string.seed_body_1)); addNote(getString(R.string.seed_title_2), getString(R.string.seed_body_2)); addNote(getString(R.string.seed_title_3), getString(R.string.seed_body_3)); updateCount(); }
private void updateCount() { int count = notesContainer.getChildCount(); textCount.setText(String.valueOf(count)); textEmpty.setVisibility(count == 0 ? View.VISIBLE : View.GONE); }
private void addCardByHand(String title) { TextView card = new TextView(this); card.setText(title); card.setTextSize(16); card.setTextColor(getColor(R.color.ink)); card.setBackgroundResource(R.drawable.bg_note_butter); int padding = (int) TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, 16, getResources().getDisplayMetrics()); card.setPadding(padding, padding, padding, padding); notesContainer.addView(card); }
private void addNote(String title, String body) { View card = LayoutInflater.from(this).inflate(R.layout.item_note, notesContainer, false); TextView cardTitle = card.findViewById(R.id.textNoteTitle); TextView cardBody = card.findViewById(R.id.textNoteBody); cardTitle.setText(title); cardBody.setText(body); cardBody.setVisibility(body.isEmpty() ? View.GONE : View.VISIBLE); int background = NOTE_BACKGROUNDS[notesAdded % NOTE_BACKGROUNDS.length]; card.setBackgroundResource(background); notesAdded++;
notesContainer.addView(card, 0); }
@Override protected void onStart() { super.onStart(); Log.d(TAG, "Main onStart"); }
@Override protected void onResume() { super.onResume(); Log.d(TAG, "Main onResume"); }
@Override protected void onPause() { super.onPause(); Log.d(TAG, "Main onPause"); }
@Override protected void onStop() { super.onStop(); Log.d(TAG, "Main onStop"); }
@Override protected void onRestart() { super.onRestart(); Log.d(TAG, "Main onRestart"); }
@Override protected void onDestroy() { super.onDestroy(); Log.d(TAG, "Main onDestroy"); }}Lines 38–40: the seed notes, three sample notes the app adds at start.
-
Type Each card takes the next background, in
addNote().- In
addNote(), click at the end of thecardBody.setVisibility(…);line. - Press Enter, then type the 3 marked lines, with Enter between them.
- Press Enter once more: that makes the marked empty line, above
addView.
kotlin+java › com.yourname.notes › MainActivity.javaAdd the marked linespackage com.yourname.notes;
import android.os.Bundle;import android.util.Log;import android.util.TypedValue;import android.view.LayoutInflater;import android.view.View;import android.widget.LinearLayout;import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "Lifecycle"; private static final int[] NOTE_BACKGROUNDS = { R.drawable.bg_note_butter, R.drawable.bg_note_mint, R.drawable.bg_note_lavender, R.drawable.bg_note_peach };
private TextView textCount; private TextView textEmpty; private LinearLayout notesContainer; private int notesAdded = 0;
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Log.d(TAG, "Main onCreate");
textCount = findViewById(R.id.textCount); textEmpty = findViewById(R.id.textEmpty); notesContainer = findViewById(R.id.notesContainer);
addNote(getString(R.string.seed_title_1), getString(R.string.seed_body_1)); addNote(getString(R.string.seed_title_2), getString(R.string.seed_body_2)); addNote(getString(R.string.seed_title_3), getString(R.string.seed_body_3)); updateCount(); }
private void updateCount() { int count = notesContainer.getChildCount(); textCount.setText(String.valueOf(count)); textEmpty.setVisibility(count == 0 ? View.VISIBLE : View.GONE); }
private void addCardByHand(String title) { TextView card = new TextView(this); card.setText(title); card.setTextSize(16); card.setTextColor(getColor(R.color.ink)); card.setBackgroundResource(R.drawable.bg_note_butter); int padding = (int) TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, 16, getResources().getDisplayMetrics()); card.setPadding(padding, padding, padding, padding); notesContainer.addView(card); }
private void addNote(String title, String body) { View card = LayoutInflater.from(this).inflate(R.layout.item_note, notesContainer, false); TextView cardTitle = card.findViewById(R.id.textNoteTitle); TextView cardBody = card.findViewById(R.id.textNoteBody); cardTitle.setText(title); cardBody.setText(body); cardBody.setVisibility(body.isEmpty() ? View.GONE : View.VISIBLE); int background = NOTE_BACKGROUNDS[notesAdded % NOTE_BACKGROUNDS.length]; card.setBackgroundResource(background); notesAdded++;
notesContainer.addView(card, 0); }
@Override protected void onStart() { super.onStart(); Log.d(TAG, "Main onStart"); }
@Override protected void onResume() { super.onResume(); Log.d(TAG, "Main onResume"); }
@Override protected void onPause() { super.onPause(); Log.d(TAG, "Main onPause"); }
@Override protected void onStop() { super.onStop(); Log.d(TAG, "Main onStop"); }
@Override protected void onRestart() { super.onRestart(); Log.d(TAG, "Main onRestart"); }
@Override protected void onDestroy() { super.onDestroy(); Log.d(TAG, "Main onDestroy"); }}%gives the remainder of the division byNOTE_BACKGROUNDS.length, 4: 0, 1, 2, 3, 0… so the colours come back in turn. - In
-
▶ Run 'app'.

You should see Exam on top, Saturday at the bottom, 3 in the pill.
Done I see three pastel cards, newest on top.
Stuck? 4 symptoms · the files
- The cards stick together, with no margin You inflated with
nullas the parent. PassnotesContainer, false. - All three cards are butter
setBackgroundResource(background)ornotesAdded++is missing. Type the marked lines again. - Saturday is on top
addView(card)adds at the end. WriteaddView(card, 0). bg_note_mint,bg_note_lavenderorbg_note_peachis red That drawable is missing, or named otherwise. Create it as actions a and b say.
The files at the end of this step. The 3 drawables are the panels above.
package com.yourname.notes;
import android.os.Bundle;import android.util.Log;import android.util.TypedValue;import android.view.LayoutInflater;import android.view.View;import android.widget.LinearLayout;import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "Lifecycle"; private static final int[] NOTE_BACKGROUNDS = { R.drawable.bg_note_butter, R.drawable.bg_note_mint, R.drawable.bg_note_lavender, R.drawable.bg_note_peach };
private TextView textCount; private TextView textEmpty; private LinearLayout notesContainer; private int notesAdded = 0;
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Log.d(TAG, "Main onCreate");
textCount = findViewById(R.id.textCount); textEmpty = findViewById(R.id.textEmpty); notesContainer = findViewById(R.id.notesContainer);
addNote(getString(R.string.seed_title_1), getString(R.string.seed_body_1)); addNote(getString(R.string.seed_title_2), getString(R.string.seed_body_2)); addNote(getString(R.string.seed_title_3), getString(R.string.seed_body_3)); updateCount(); }
private void updateCount() { int count = notesContainer.getChildCount(); textCount.setText(String.valueOf(count)); textEmpty.setVisibility(count == 0 ? View.VISIBLE : View.GONE); }
private void addCardByHand(String title) { TextView card = new TextView(this); card.setText(title); card.setTextSize(16); card.setTextColor(getColor(R.color.ink)); card.setBackgroundResource(R.drawable.bg_note_butter); int padding = (int) TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, 16, getResources().getDisplayMetrics()); card.setPadding(padding, padding, padding, padding); notesContainer.addView(card); }
private void addNote(String title, String body) { View card = LayoutInflater.from(this).inflate(R.layout.item_note, notesContainer, false); TextView cardTitle = card.findViewById(R.id.textNoteTitle); TextView cardBody = card.findViewById(R.id.textNoteBody); cardTitle.setText(title); cardBody.setText(body); cardBody.setVisibility(body.isEmpty() ? View.GONE : View.VISIBLE); int background = NOTE_BACKGROUNDS[notesAdded % NOTE_BACKGROUNDS.length]; card.setBackgroundResource(background); notesAdded++;
notesContainer.addView(card, 0); }
@Override protected void onStart() { super.onStart(); Log.d(TAG, "Main onStart"); }
@Override protected void onResume() { super.onResume(); Log.d(TAG, "Main onResume"); }
@Override protected void onPause() { super.onPause(); Log.d(TAG, "Main onPause"); }
@Override protected void onStop() { super.onStop(); Log.d(TAG, "Main onStop"); }
@Override protected void onRestart() { super.onRestart(); Log.d(TAG, "Main onRestart"); }
@Override protected void onDestroy() { super.onDestroy(); Log.d(TAG, "Main onDestroy"); }}Step 5 of 5
Compare the two ways, then clean up
Goal Compare the two ways, then delete Way 1.
- Java MainActivity.java
Why XML for how it looks; Java for when, and how many.
Way 1, by hand: the look in Java
package com.yourname.notes;
import android.os.Bundle;import android.util.Log;import android.util.TypedValue;import android.view.LayoutInflater;import android.view.View;import android.widget.LinearLayout;import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "Lifecycle"; private static final int[] NOTE_BACKGROUNDS = { R.drawable.bg_note_butter, R.drawable.bg_note_mint, R.drawable.bg_note_lavender, R.drawable.bg_note_peach };
private TextView textCount; private TextView textEmpty; private LinearLayout notesContainer; private int notesAdded = 0;
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Log.d(TAG, "Main onCreate");
textCount = findViewById(R.id.textCount); textEmpty = findViewById(R.id.textEmpty); notesContainer = findViewById(R.id.notesContainer);
addNote(getString(R.string.seed_title_1), getString(R.string.seed_body_1)); addNote(getString(R.string.seed_title_2), getString(R.string.seed_body_2)); addNote(getString(R.string.seed_title_3), getString(R.string.seed_body_3)); updateCount(); }
private void updateCount() { int count = notesContainer.getChildCount(); textCount.setText(String.valueOf(count)); textEmpty.setVisibility(count == 0 ? View.VISIBLE : View.GONE); }
private void addCardByHand(String title) { TextView card = new TextView(this); card.setText(title); card.setTextSize(16); card.setTextColor(getColor(R.color.ink)); card.setBackgroundResource(R.drawable.bg_note_butter); int padding = (int) TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, 16, getResources().getDisplayMetrics()); card.setPadding(padding, padding, padding, padding); notesContainer.addView(card); }
private void addNote(String title, String body) { View card = LayoutInflater.from(this).inflate(R.layout.item_note, notesContainer, false); TextView cardTitle = card.findViewById(R.id.textNoteTitle); TextView cardBody = card.findViewById(R.id.textNoteBody); cardTitle.setText(title); cardBody.setText(body); cardBody.setVisibility(body.isEmpty() ? View.GONE : View.VISIBLE); int background = NOTE_BACKGROUNDS[notesAdded % NOTE_BACKGROUNDS.length]; card.setBackgroundResource(background); notesAdded++;
notesContainer.addView(card, 0); }
@Override protected void onStart() { super.onStart(); Log.d(TAG, "Main onStart"); }
@Override protected void onResume() { super.onResume(); Log.d(TAG, "Main onResume"); }
@Override protected void onPause() { super.onPause(); Log.d(TAG, "Main onPause"); }
@Override protected void onStop() { super.onStop(); Log.d(TAG, "Main onStop"); }
@Override protected void onRestart() { super.onRestart(); Log.d(TAG, "Main onRestart"); }
@Override protected void onDestroy() { super.onDestroy(); Log.d(TAG, "Main onDestroy"); }}Way 2, inflated: the look in item_note.xml
package com.yourname.notes;
import android.os.Bundle;import android.util.Log;import android.util.TypedValue;import android.view.LayoutInflater;import android.view.View;import android.widget.LinearLayout;import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "Lifecycle"; private static final int[] NOTE_BACKGROUNDS = { R.drawable.bg_note_butter, R.drawable.bg_note_mint, R.drawable.bg_note_lavender, R.drawable.bg_note_peach };
private TextView textCount; private TextView textEmpty; private LinearLayout notesContainer; private int notesAdded = 0;
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Log.d(TAG, "Main onCreate");
textCount = findViewById(R.id.textCount); textEmpty = findViewById(R.id.textEmpty); notesContainer = findViewById(R.id.notesContainer);
addNote(getString(R.string.seed_title_1), getString(R.string.seed_body_1)); addNote(getString(R.string.seed_title_2), getString(R.string.seed_body_2)); addNote(getString(R.string.seed_title_3), getString(R.string.seed_body_3)); updateCount(); }
private void updateCount() { int count = notesContainer.getChildCount(); textCount.setText(String.valueOf(count)); textEmpty.setVisibility(count == 0 ? View.VISIBLE : View.GONE); }
private void addCardByHand(String title) { TextView card = new TextView(this); card.setText(title); card.setTextSize(16); card.setTextColor(getColor(R.color.ink)); card.setBackgroundResource(R.drawable.bg_note_butter); int padding = (int) TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, 16, getResources().getDisplayMetrics()); card.setPadding(padding, padding, padding, padding); notesContainer.addView(card); }
private void addNote(String title, String body) { View card = LayoutInflater.from(this).inflate(R.layout.item_note, notesContainer, false); TextView cardTitle = card.findViewById(R.id.textNoteTitle); TextView cardBody = card.findViewById(R.id.textNoteBody); cardTitle.setText(title); cardBody.setText(body); cardBody.setVisibility(body.isEmpty() ? View.GONE : View.VISIBLE); int background = NOTE_BACKGROUNDS[notesAdded % NOTE_BACKGROUNDS.length]; card.setBackgroundResource(background); notesAdded++;
notesContainer.addView(card, 0); }
@Override protected void onStart() { super.onStart(); Log.d(TAG, "Main onStart"); }
@Override protected void onResume() { super.onResume(); Log.d(TAG, "Main onResume"); }
@Override protected void onPause() { super.onPause(); Log.d(TAG, "Main onPause"); }
@Override protected void onStop() { super.onStop(); Log.d(TAG, "Main onStop"); }
@Override protected void onRestart() { super.onRestart(); Log.d(TAG, "Main onRestart"); }
@Override protected void onDestroy() { super.onDestroy(); Log.d(TAG, "Main onDestroy"); }}-
Delete Way 1: the grey method, then its import.
- In MainActivity.java, click just left of
private void addCardByHand(line 50), not on the grey usages hint. - Hold Shift and click just left of
private void addNote(line 62). - Lines 50 to 61 are selected: press Delete.
- Click in line 5,
import android.util.TypedValue;, grey now. - Press Ctrl+Y: the line goes.
- In MainActivity.java, click just left of
Done I see no grey method left.
Stuck? 2 symptoms · the file
- Red marks after the delete A brace went with the method, or one stayed. Replace the whole file with this one.
TypedValueis red The method is still there. Delete it too.
The files at the end of this step
package com.yourname.notes;
import android.os.Bundle;import android.util.Log;import android.view.LayoutInflater;import android.view.View;import android.widget.LinearLayout;import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "Lifecycle"; private static final int[] NOTE_BACKGROUNDS = { R.drawable.bg_note_butter, R.drawable.bg_note_mint, R.drawable.bg_note_lavender, R.drawable.bg_note_peach };
private TextView textCount; private TextView textEmpty; private LinearLayout notesContainer; private int notesAdded = 0;
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Log.d(TAG, "Main onCreate");
textCount = findViewById(R.id.textCount); textEmpty = findViewById(R.id.textEmpty); notesContainer = findViewById(R.id.notesContainer);
addNote(getString(R.string.seed_title_1), getString(R.string.seed_body_1)); addNote(getString(R.string.seed_title_2), getString(R.string.seed_body_2)); addNote(getString(R.string.seed_title_3), getString(R.string.seed_body_3)); updateCount(); }
private void updateCount() { int count = notesContainer.getChildCount(); textCount.setText(String.valueOf(count)); textEmpty.setVisibility(count == 0 ? View.VISIBLE : View.GONE); }
private void addNote(String title, String body) { View card = LayoutInflater.from(this).inflate(R.layout.item_note, notesContainer, false); TextView cardTitle = card.findViewById(R.id.textNoteTitle); TextView cardBody = card.findViewById(R.id.textNoteBody); cardTitle.setText(title); cardBody.setText(body); cardBody.setVisibility(body.isEmpty() ? View.GONE : View.VISIBLE); int background = NOTE_BACKGROUNDS[notesAdded % NOTE_BACKGROUNDS.length]; card.setBackgroundResource(background); notesAdded++;
notesContainer.addView(card, 0); }
@Override protected void onStart() { super.onStart(); Log.d(TAG, "Main onStart"); }
@Override protected void onResume() { super.onResume(); Log.d(TAG, "Main onResume"); }
@Override protected void onPause() { super.onPause(); Log.d(TAG, "Main onPause"); }
@Override protected void onStop() { super.onStop(); Log.d(TAG, "Main onStop"); }
@Override protected void onRestart() { super.onRestart(); Log.d(TAG, "Main onRestart"); }
@Override protected void onDestroy() { super.onDestroy(); Log.d(TAG, "Main onDestroy"); }}Go deeper Real lists, and View Binding 1 min
A real list of hundreds of notes uses RecyclerView, which reuses a few cards as you scroll; View Binding replaces findViewById. Both build on what you just did.
Now you
A fourth seed
Change nothing: which colour and place would a fourth seed note get?
See the answer
Peach, on top. notesAdded is then 3, and 3 % 4 = 3: the fourth background. addView(card, 0) puts it first. Part 7 shows it: the first note you add there is peach.
If it doesn’t work
Android resource linking failed … resource color/note_butter … not found, after a restart The pack replacedcolors.xml, but your Part 6 files stayed. Delete them as “Behind?” says, at the top.- A grey, ALL CAPS button made in Java
new Button(this)is not themed. Inflate the button from XML instead. - Alt+Enter offers nothing Android Studio is still indexing: the bar at the bottom of the window. Wait for it to end.
End of the part
Recap
Java now fills the pill and the list. A card comes from Java alone, or from item_note.xml: the app keeps the layout.
- set a view’s text and visibility from Java, at the right moment;
- build a view in Java, or inflate it from XML;
- say when to use each way.
