Skip to content

Commit 31fcf6d

Browse files
Add Room lesson code snippets and fix lint
1 parent 9f50f6e commit 31fcf6d

File tree

10 files changed

+288
-7
lines changed

10 files changed

+288
-7
lines changed

app/src/main/AndroidManifest.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,12 @@
310310
android:label="@string/room_database"
311311
android:parentActivityName=".ui.screens.main.MainActivity" />
312312

313+
<activity
314+
android:name=".ui.screens.android.lessons.data.room.RoomCodeActivity"
315+
android:exported="false"
316+
android:label="@string/room_database"
317+
android:parentActivityName=".ui.screens.android.lessons.data.room.RoomActivity" />
318+
313319
<activity
314320
android:name=".ui.screens.settings.SettingsActivity"
315321
android:exported="false"

app/src/main/java/com/d4rk/androidtutorials/java/ui/screens/android/lessons/data/room/AppDatabase.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
/**
1010
* The Room database that holds the notes.
1111
*/
12-
@Database(entities = {Note.class}, version = 1)
12+
@Database(entities = {Note.class}, version = 1, exportSchema = false)
1313
public abstract class AppDatabase extends RoomDatabase {
1414
private static volatile AppDatabase INSTANCE;
1515

app/src/main/java/com/d4rk/androidtutorials/java/ui/screens/android/lessons/data/room/RoomActivity.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
package com.d4rk.androidtutorials.java.ui.screens.android.lessons.data.room;
22

3+
import android.content.Intent;
4+
import android.os.Bundle;
5+
import android.os.Handler;
36
import android.view.LayoutInflater;
47
import android.view.View;
58
import android.view.ViewGroup;
6-
import android.os.Bundle;
79

810
import androidx.annotation.NonNull;
911
import androidx.recyclerview.widget.LinearLayoutManager;
@@ -24,6 +26,7 @@
2426
* Demonstrates basic Room usage by inserting and reading notes.
2527
*/
2628
public class RoomActivity extends UpNavigationActivity {
29+
private final Handler handler = new Handler();
2730
private ActivityRoomBinding binding;
2831
private NotesAdapter adapter;
2932
private AppDatabase db;
@@ -58,6 +61,10 @@ protected void onCreate(Bundle savedInstanceState) {
5861
});
5962
}
6063
});
64+
65+
binding.floatingButtonShowSyntax.setOnClickListener(v ->
66+
startActivity(new Intent(RoomActivity.this, RoomCodeActivity.class)));
67+
handler.postDelayed(() -> binding.floatingButtonShowSyntax.shrink(), 5000);
6168
}
6269

6370
private void loadNotes() {
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
package com.d4rk.androidtutorials.java.ui.screens.android.lessons.data.room;
2+
3+
import android.os.Bundle;
4+
5+
import androidx.annotation.NonNull;
6+
import androidx.annotation.Nullable;
7+
import androidx.fragment.app.Fragment;
8+
import androidx.fragment.app.FragmentStateAdapter;
9+
10+
import com.d4rk.androidtutorials.java.R;
11+
import com.d4rk.androidtutorials.java.databinding.ActivityTabLayoutBinding;
12+
import com.d4rk.androidtutorials.java.ui.components.navigation.UpNavigationActivity;
13+
import com.d4rk.androidtutorials.java.ui.screens.android.lessons.data.room.tabs.RoomTabCodeFragment;
14+
import com.d4rk.androidtutorials.java.ui.screens.android.lessons.data.room.tabs.RoomTabLayoutFragment;
15+
import com.d4rk.androidtutorials.java.utils.EdgeToEdgeDelegate;
16+
import com.google.android.material.tabs.TabLayoutMediator;
17+
18+
import java.util.ArrayList;
19+
20+
/**
21+
* Displays Java and XML snippets for the Room database example.
22+
*/
23+
public class RoomCodeActivity extends UpNavigationActivity {
24+
private ActivityTabLayoutBinding binding;
25+
26+
@Override
27+
protected void onCreate(@Nullable Bundle savedInstanceState) {
28+
super.onCreate(savedInstanceState);
29+
binding = ActivityTabLayoutBinding.inflate(getLayoutInflater());
30+
setContentView(binding.getRoot());
31+
32+
EdgeToEdgeDelegate edgeToEdgeDelegate = new EdgeToEdgeDelegate(this);
33+
edgeToEdgeDelegate.applyEdgeToEdge(binding.appBarLayout);
34+
35+
setupViewPager();
36+
37+
new TabLayoutMediator(binding.tabs, binding.viewpager, (tab, position) -> {
38+
ViewPagerAdapter adapter = (ViewPagerAdapter) binding.viewpager.getAdapter();
39+
if (adapter != null) {
40+
tab.setText(adapter.getPageTitle(position));
41+
}
42+
}).attach();
43+
}
44+
45+
private void setupViewPager() {
46+
ViewPagerAdapter adapter = new ViewPagerAdapter(this);
47+
adapter.addFragment(new RoomTabCodeFragment(), getString(R.string.code_java));
48+
adapter.addFragment(new RoomTabLayoutFragment(), getString(R.string.layout_xml));
49+
binding.viewpager.setAdapter(adapter);
50+
}
51+
52+
private static class ViewPagerAdapter extends FragmentStateAdapter {
53+
private final ArrayList<Fragment> fragmentList = new ArrayList<>();
54+
private final ArrayList<String> fragmentTitleList = new ArrayList<>();
55+
56+
ViewPagerAdapter(@NonNull UpNavigationActivity activity) {
57+
super(activity);
58+
}
59+
60+
void addFragment(@NonNull Fragment fragment, @NonNull String title) {
61+
fragmentList.add(fragment);
62+
fragmentTitleList.add(title);
63+
}
64+
65+
@NonNull
66+
@Override
67+
public Fragment createFragment(int position) {
68+
return fragmentList.get(position);
69+
}
70+
71+
@Override
72+
public int getItemCount() {
73+
return fragmentList.size();
74+
}
75+
76+
CharSequence getPageTitle(int position) {
77+
return fragmentTitleList.get(position);
78+
}
79+
}
80+
}
81+
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package com.d4rk.androidtutorials.java.ui.screens.android.lessons.data.room.tabs;
2+
3+
import android.content.SharedPreferences;
4+
import android.graphics.Typeface;
5+
import android.os.Bundle;
6+
import android.util.Log;
7+
import android.view.LayoutInflater;
8+
import android.view.View;
9+
import android.view.ViewGroup;
10+
11+
import androidx.annotation.NonNull;
12+
import androidx.fragment.app.Fragment;
13+
import androidx.preference.PreferenceManager;
14+
15+
import com.d4rk.androidtutorials.java.R;
16+
import com.d4rk.androidtutorials.java.databinding.FragmentCodeBinding;
17+
import com.d4rk.androidtutorials.java.utils.CodeHighlighter;
18+
import com.d4rk.androidtutorials.java.utils.CodeViewUtils;
19+
import com.d4rk.androidtutorials.java.utils.FontManager;
20+
import com.google.android.gms.ads.AdRequest;
21+
22+
import java.io.BufferedReader;
23+
import java.io.IOException;
24+
import java.io.InputStream;
25+
import java.io.InputStreamReader;
26+
27+
import me.zhanghai.android.fastscroll.FastScrollerBuilder;
28+
29+
/**
30+
* Shows the Java implementation for the Room example.
31+
*/
32+
public class RoomTabCodeFragment extends Fragment {
33+
34+
@Override
35+
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
36+
FragmentCodeBinding binding = FragmentCodeBinding.inflate(inflater, container, false);
37+
new FastScrollerBuilder(binding.scrollView).useMd2Style().build();
38+
binding.adView.loadAd(new AdRequest.Builder().build());
39+
40+
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(requireContext());
41+
Typeface monospaceFont = FontManager.getMonospaceFont(requireContext(), prefs);
42+
CodeViewUtils.applyDefaults(monospaceFont, binding.codeView);
43+
44+
StringBuilder builder = new StringBuilder();
45+
InputStream inputStream = getResources().openRawResource(R.raw.text_room_java);
46+
try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) {
47+
String line;
48+
while ((line = reader.readLine()) != null) {
49+
builder.append(line).append('\n');
50+
}
51+
binding.codeView.setText(builder.toString());
52+
CodeHighlighter.applyJavaTheme(binding.codeView);
53+
} catch (IOException e) {
54+
Log.e("RoomTabCode", "Error reading code", e);
55+
}
56+
return binding.getRoot();
57+
}
58+
}
59+
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package com.d4rk.androidtutorials.java.ui.screens.android.lessons.data.room.tabs;
2+
3+
import android.content.SharedPreferences;
4+
import android.graphics.Typeface;
5+
import android.os.Bundle;
6+
import android.util.Log;
7+
import android.view.LayoutInflater;
8+
import android.view.View;
9+
import android.view.ViewGroup;
10+
11+
import androidx.annotation.NonNull;
12+
import androidx.fragment.app.Fragment;
13+
import androidx.preference.PreferenceManager;
14+
15+
import com.d4rk.androidtutorials.java.R;
16+
import com.d4rk.androidtutorials.java.databinding.FragmentLayoutBinding;
17+
import com.d4rk.androidtutorials.java.utils.CodeHighlighter;
18+
import com.d4rk.androidtutorials.java.utils.CodeViewUtils;
19+
import com.d4rk.androidtutorials.java.utils.FontManager;
20+
import com.google.android.gms.ads.AdRequest;
21+
22+
import java.io.BufferedReader;
23+
import java.io.IOException;
24+
import java.io.InputStream;
25+
import java.io.InputStreamReader;
26+
27+
import me.zhanghai.android.fastscroll.FastScrollerBuilder;
28+
29+
/**
30+
* Shows the XML layout for the Room example.
31+
*/
32+
public class RoomTabLayoutFragment extends Fragment {
33+
34+
@Override
35+
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
36+
FragmentLayoutBinding binding = FragmentLayoutBinding.inflate(inflater, container, false);
37+
new FastScrollerBuilder(binding.scrollView).useMd2Style().build();
38+
binding.adView.loadAd(new AdRequest.Builder().build());
39+
40+
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(requireContext());
41+
Typeface monospaceFont = FontManager.getMonospaceFont(requireContext(), prefs);
42+
CodeViewUtils.applyDefaults(monospaceFont, binding.codeView);
43+
44+
StringBuilder builder = new StringBuilder();
45+
InputStream inputStream = getResources().openRawResource(R.raw.text_room_xml);
46+
try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) {
47+
String line;
48+
while ((line = reader.readLine()) != null) {
49+
builder.append(line).append('\n');
50+
}
51+
binding.codeView.setText(builder.toString());
52+
CodeHighlighter.applyXmlTheme(binding.codeView);
53+
} catch (IOException e) {
54+
Log.e("RoomTabLayout", "Error reading layout", e);
55+
}
56+
return binding.getRoot();
57+
}
58+
}
59+

app/src/main/res/layout/activity_room.xml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,23 @@
4949
android:layout_width="0dp"
5050
android:layout_height="0dp"
5151
android:layout_marginTop="16dp"
52+
android:layout_marginBottom="80dp"
5253
app:layout_constraintBottom_toBottomOf="parent"
5354
app:layout_constraintEnd_toEndOf="parent"
5455
app:layout_constraintStart_toStartOf="parent"
5556
app:layout_constraintTop_toBottomOf="@id/buttonAdd" />
57+
58+
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
59+
android:id="@+id/floating_button_show_syntax"
60+
style="@style/Widget.Material3.ExtendedFloatingActionButton.Icon.Surface"
61+
android:layout_width="wrap_content"
62+
android:layout_height="wrap_content"
63+
android:layout_margin="24dp"
64+
android:contentDescription="@string/tooltip_show_java_code_snippet"
65+
android:text="@string/show_code"
66+
android:textSize="14sp"
67+
android:tooltipText="@string/tooltip_show_java_code_snippet"
68+
app:icon="@drawable/ic_code"
69+
app:layout_constraintBottom_toBottomOf="parent"
70+
app:layout_constraintEnd_toEndOf="parent" />
5671
</androidx.constraintlayout.widget.ConstraintLayout>
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// Define a Note entity with auto-generated id
2+
@Entity
3+
public class Note {
4+
@PrimaryKey(autoGenerate = true)
5+
public int id;
6+
public String text;
7+
}
8+
9+
// Data access object to insert and query notes
10+
@Dao
11+
public interface NoteDao {
12+
@Insert
13+
void insert(Note note);
14+
15+
@Query("SELECT * FROM note")
16+
List<Note> getAll();
17+
}
18+
19+
// Database that holds the notes
20+
@Database(entities = {Note.class}, version = 1, exportSchema = false)
21+
public abstract class AppDatabase extends RoomDatabase {
22+
public abstract NoteDao noteDao();
23+
}
24+
25+
// Usage inside an Activity
26+
AppDatabase db = Room.databaseBuilder(this, AppDatabase.class, "notes.db").build();
27+
db.noteDao().insert(new Note("Hello Room!"));
28+
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<androidx.constraintlayout.widget.ConstraintLayout
2+
xmlns:android="http://schemas.android.com/apk/res/android"
3+
xmlns:app="http://schemas.android.com/apk/res-auto"
4+
android:layout_width="match_parent"
5+
android:layout_height="match_parent">
6+
7+
<com.google.android.material.textfield.TextInputEditText
8+
android:id="@+id/editTextNote"
9+
android:layout_width="0dp"
10+
android:layout_height="wrap_content"
11+
android:hint="Enter note"
12+
app:layout_constraintEnd_toEndOf="parent"
13+
app:layout_constraintStart_toStartOf="parent"
14+
app:layout_constraintTop_toTopOf="parent" />
15+
16+
<androidx.recyclerview.widget.RecyclerView
17+
android:id="@+id/recyclerView"
18+
android:layout_width="0dp"
19+
android:layout_height="0dp"
20+
app:layout_constraintTop_toBottomOf="@id/editTextNote"
21+
app:layout_constraintBottom_toBottomOf="parent"
22+
app:layout_constraintStart_toStartOf="parent"
23+
app:layout_constraintEnd_toEndOf="parent" />
24+
25+
</androidx.constraintlayout.widget.ConstraintLayout>
26+

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -138,9 +138,9 @@
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>
141+
<string name="room_database" translatable="false">Room database</string>
142+
<string name="enter_note" translatable="false">Enter note</string>
143+
<string name="add_note" translatable="false">Add note</string>
144144

145145
<string name="layouts">Layouts and views</string>
146146

@@ -346,8 +346,8 @@
346346
<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>
347347
<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>
348348
<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>
349+
<string name="summary_preference_android_studio_room_database" translatable="false">Persist simple notes using Room, an abstraction layer over SQLite.</string>
350+
<string name="summary_room_database" translatable="false">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>
351351
<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>
352352
<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>
353353
<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>

0 commit comments

Comments
 (0)