Skip to content

Commit 9f50f6e

Browse files
Add Room database lesson
1 parent 2cad84d commit 9f50f6e

File tree

11 files changed

+263
-0
lines changed

11 files changed

+263
-0
lines changed

app/build.gradle

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,8 @@ dependencies {
9696
implementation libs.codeview
9797
implementation libs.hilt.android
9898
annotationProcessor libs.hilt.compiler
99+
implementation libs.androidx.room.runtime
100+
annotationProcessor libs.androidx.room.compiler
99101

100102
// Testing
101103
testImplementation libs.junit

app/src/main/AndroidManifest.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,12 @@
304304
android:label="@string/navigation_drawer"
305305
android:parentActivityName=".ui.screens.main.MainActivity" />
306306

307+
<activity
308+
android:name=".ui.screens.android.lessons.data.room.RoomActivity"
309+
android:exported="false"
310+
android:label="@string/room_database"
311+
android:parentActivityName=".ui.screens.main.MainActivity" />
312+
307313
<activity
308314
android:name=".ui.screens.settings.SettingsActivity"
309315
android:exported="false"
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package com.d4rk.androidtutorials.java.ui.screens.android.lessons.data.room;
2+
3+
import android.content.Context;
4+
5+
import androidx.room.Database;
6+
import androidx.room.Room;
7+
import androidx.room.RoomDatabase;
8+
9+
/**
10+
* The Room database that holds the notes.
11+
*/
12+
@Database(entities = {Note.class}, version = 1)
13+
public abstract class AppDatabase extends RoomDatabase {
14+
private static volatile AppDatabase INSTANCE;
15+
16+
public abstract NoteDao noteDao();
17+
18+
public static AppDatabase getInstance(Context context) {
19+
if (INSTANCE == null) {
20+
synchronized (AppDatabase.class) {
21+
if (INSTANCE == null) {
22+
INSTANCE = Room.databaseBuilder(context.getApplicationContext(),
23+
AppDatabase.class, "notes_db").build();
24+
}
25+
}
26+
}
27+
return INSTANCE;
28+
}
29+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package com.d4rk.androidtutorials.java.ui.screens.android.lessons.data.room;
2+
3+
import androidx.room.Entity;
4+
import androidx.room.PrimaryKey;
5+
6+
/**
7+
* Simple Note entity stored in the Room database.
8+
*/
9+
@Entity(tableName = "notes")
10+
public class Note {
11+
@PrimaryKey(autoGenerate = true)
12+
public int id;
13+
public String text;
14+
15+
public Note(String text) {
16+
this.text = text;
17+
}
18+
19+
public String getText() {
20+
return text;
21+
}
22+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package com.d4rk.androidtutorials.java.ui.screens.android.lessons.data.room;
2+
3+
import androidx.room.Dao;
4+
import androidx.room.Insert;
5+
import androidx.room.Query;
6+
7+
import java.util.List;
8+
9+
/**
10+
* Data Access Object for {@link Note}.
11+
*/
12+
@Dao
13+
public interface NoteDao {
14+
@Insert
15+
void insert(Note note);
16+
17+
@Query("SELECT * FROM notes")
18+
List<Note> getAll();
19+
}
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
package com.d4rk.androidtutorials.java.ui.screens.android.lessons.data.room;
2+
3+
import android.view.LayoutInflater;
4+
import android.view.View;
5+
import android.view.ViewGroup;
6+
import android.os.Bundle;
7+
8+
import androidx.annotation.NonNull;
9+
import androidx.recyclerview.widget.LinearLayoutManager;
10+
import androidx.recyclerview.widget.RecyclerView;
11+
12+
import com.d4rk.androidtutorials.java.R;
13+
import com.d4rk.androidtutorials.java.databinding.ActivityRoomBinding;
14+
import com.d4rk.androidtutorials.java.ui.components.navigation.UpNavigationActivity;
15+
import com.d4rk.androidtutorials.java.utils.EdgeToEdgeDelegate;
16+
import com.google.android.material.textview.MaterialTextView;
17+
18+
import java.util.ArrayList;
19+
import java.util.List;
20+
import java.util.concurrent.ExecutorService;
21+
import java.util.concurrent.Executors;
22+
23+
/**
24+
* Demonstrates basic Room usage by inserting and reading notes.
25+
*/
26+
public class RoomActivity extends UpNavigationActivity {
27+
private ActivityRoomBinding binding;
28+
private NotesAdapter adapter;
29+
private AppDatabase db;
30+
private final ExecutorService executor = Executors.newSingleThreadExecutor();
31+
32+
@Override
33+
protected void onCreate(Bundle savedInstanceState) {
34+
super.onCreate(savedInstanceState);
35+
binding = ActivityRoomBinding.inflate(getLayoutInflater());
36+
setContentView(binding.getRoot());
37+
38+
EdgeToEdgeDelegate edgeToEdgeDelegate = new EdgeToEdgeDelegate(this);
39+
edgeToEdgeDelegate.applyEdgeToEdge(binding.constraintLayout);
40+
41+
db = AppDatabase.getInstance(this);
42+
43+
binding.recyclerView.setLayoutManager(new LinearLayoutManager(this));
44+
adapter = new NotesAdapter();
45+
binding.recyclerView.setAdapter(adapter);
46+
47+
loadNotes();
48+
49+
binding.buttonAdd.setOnClickListener(v -> {
50+
String text = String.valueOf(binding.editTextNote.getText()).trim();
51+
if (!text.isEmpty()) {
52+
executor.execute(() -> {
53+
db.noteDao().insert(new Note(text));
54+
runOnUiThread(() -> {
55+
binding.editTextNote.setText("");
56+
loadNotes();
57+
});
58+
});
59+
}
60+
});
61+
}
62+
63+
private void loadNotes() {
64+
executor.execute(() -> {
65+
List<Note> notes = db.noteDao().getAll();
66+
runOnUiThread(() -> adapter.setNotes(notes));
67+
});
68+
}
69+
70+
private static class NotesAdapter extends RecyclerView.Adapter<NotesAdapter.NoteViewHolder> {
71+
private List<Note> notes = new ArrayList<>();
72+
73+
void setNotes(List<Note> notes) {
74+
this.notes = notes;
75+
notifyDataSetChanged();
76+
}
77+
78+
@NonNull
79+
@Override
80+
public NoteViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
81+
View view = LayoutInflater.from(parent.getContext())
82+
.inflate(R.layout.item_note, parent, false);
83+
return new NoteViewHolder(view);
84+
}
85+
86+
@Override
87+
public void onBindViewHolder(@NonNull NoteViewHolder holder, int position) {
88+
holder.textView.setText(notes.get(position).getText());
89+
}
90+
91+
@Override
92+
public int getItemCount() {
93+
return notes.size();
94+
}
95+
96+
static class NoteViewHolder extends RecyclerView.ViewHolder {
97+
final MaterialTextView textView;
98+
99+
NoteViewHolder(View itemView) {
100+
super(itemView);
101+
textView = itemView.findViewById(R.id.textViewNote);
102+
}
103+
}
104+
}
105+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
3+
xmlns:app="http://schemas.android.com/apk/res-auto"
4+
android:id="@+id/constraintLayout"
5+
android:layout_width="match_parent"
6+
android:layout_height="match_parent">
7+
8+
<com.google.android.material.textview.MaterialTextView
9+
android:id="@+id/textViewSummary"
10+
android:layout_width="0dp"
11+
android:layout_height="wrap_content"
12+
android:padding="16dp"
13+
android:text="@string/summary_room_database"
14+
app:layout_constraintEnd_toEndOf="parent"
15+
app:layout_constraintStart_toStartOf="parent"
16+
app:layout_constraintTop_toTopOf="parent" />
17+
18+
<com.google.android.material.textfield.TextInputLayout
19+
android:id="@+id/textInputLayout"
20+
android:layout_width="0dp"
21+
android:layout_height="wrap_content"
22+
android:layout_marginStart="16dp"
23+
android:layout_marginTop="16dp"
24+
android:layout_marginEnd="16dp"
25+
app:layout_constraintEnd_toEndOf="parent"
26+
app:layout_constraintStart_toStartOf="parent"
27+
app:layout_constraintTop_toBottomOf="@id/textViewSummary">
28+
29+
<com.google.android.material.textfield.TextInputEditText
30+
android:id="@+id/editTextNote"
31+
android:layout_width="match_parent"
32+
android:layout_height="wrap_content"
33+
android:hint="@string/enter_note" />
34+
</com.google.android.material.textfield.TextInputLayout>
35+
36+
<com.google.android.material.button.MaterialButton
37+
android:id="@+id/buttonAdd"
38+
style="@style/Widget.Material3.Button.ElevatedButton"
39+
android:layout_width="wrap_content"
40+
android:layout_height="wrap_content"
41+
android:layout_marginTop="16dp"
42+
android:text="@string/add_note"
43+
app:layout_constraintEnd_toEndOf="parent"
44+
app:layout_constraintStart_toStartOf="parent"
45+
app:layout_constraintTop_toBottomOf="@id/textInputLayout" />
46+
47+
<androidx.recyclerview.widget.RecyclerView
48+
android:id="@+id/recyclerView"
49+
android:layout_width="0dp"
50+
android:layout_height="0dp"
51+
android:layout_marginTop="16dp"
52+
app:layout_constraintBottom_toBottomOf="parent"
53+
app:layout_constraintEnd_toEndOf="parent"
54+
app:layout_constraintStart_toStartOf="parent"
55+
app:layout_constraintTop_toBottomOf="@id/buttonAdd" />
56+
</androidx.constraintlayout.widget.ConstraintLayout>
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<com.google.android.material.textview.MaterialTextView xmlns:android="http://schemas.android.com/apk/res/android"
3+
android:id="@+id/textViewNote"
4+
android:layout_width="match_parent"
5+
android:layout_height="wrap_content"
6+
android:padding="16dp" />

app/src/main/res/values/strings.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,10 @@
138138

139139
<string name="predictive_back_gesture">Predictive back gesture</string>
140140

141+
<string name="room_database">Room database</string>
142+
<string name="enter_note">Enter note</string>
143+
<string name="add_note">Add note</string>
144+
141145
<string name="layouts">Layouts and views</string>
142146

143147
<string name="linear_layout">Linear layout</string>
@@ -342,6 +346,8 @@
342346
<string name="summary_preference_android_studio_permissions">Permissions are important in Android as you can\'t do tasks, that require permissions, without requesting permissions.</string>
343347
<string name="summary_preference_android_studio_per_app_language_preferences">Learn how to use per-app languages to make your app more accessible and user-friendly. This feature lets you choose a different language for each app on your device, without the user changing their device language.</string>
344348
<string name="summary_preference_android_studio_predictive_back_gesture">Android 13 (API level 33) introduces a predictive back gesture for Android devices such as phones, large screens, and foldables. It is part of a multi-year release; when fully implemented, this feature will let users preview the destination or other result of a back gesture before fully completing it, allowing them to decide whether to continue or stay in the current view.</string>
349+
<string name="summary_preference_android_studio_room_database">Persist simple notes using Room, an abstraction layer over SQLite.</string>
350+
<string name="summary_room_database">Room is a persistence library that provides an object mapping layer on top of SQLite. This example shows how to save and display notes.</string>
345351
<string name="summary_preference_android_studio_linear_layout">A linear layout is a view group that arranges its children in a single, linear direction, either horizontally or vertically. The orientation of the layout can be specified using the android:orientation attribute. A linear layout can be used to create a variety of user interfaces, such as lists, buttons, and text fields.</string>
346352
<string name="summary_preference_android_studio_relative_layout">A relative layout is a layout manager in Android that positions its child views relative to each other or to the parent layout. This makes it a very versatile layout manager, as it can be used to create a wide variety of layouts.</string>
347353
<string name="summary_preference_android_studio_table_layout">Table layout is the process of arranging the cells, rows, and columns of a table in a visually appealing and functional way.</string>

app/src/main/res/xml/preferences_android_studio.xml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,15 @@
7878
android:action="android.intent.action.VIEW"
7979
android:data="https://developer.android.com/guide/navigation/predictive-back-gesture" />
8080
</androidx.preference.Preference>
81+
<androidx.preference.Preference
82+
app:icon="@drawable/ic_data_thresholding"
83+
app:summary="@string/summary_preference_android_studio_room_database"
84+
app:title="@string/room_database">
85+
<intent
86+
android:action="android.intent.action.VIEW"
87+
android:targetClass="com.d4rk.androidtutorials.java.ui.screens.android.lessons.data.room.RoomActivity"
88+
android:targetPackage="com.d4rk.androidtutorials.java" />
89+
</androidx.preference.Preference>
8190
</androidx.preference.PreferenceCategory>
8291
<androidx.preference.PreferenceCategory
8392
app:icon="@drawable/ic_category_layout_tinted"

0 commit comments

Comments
 (0)