Final Results
Our revised app/build.gradle
should resemble:
plugins {
id 'com.android.application'
id 'kotlin-android'
id 'androidx.navigation.safeargs.kotlin'
id 'kotlin-kapt'
}
android {
compileSdk 31
defaultConfig {
applicationId "com.commonsware.todo"
minSdk 21
targetSdk 31
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
buildFeatures {
viewBinding true
}
compileOptions {
coreLibraryDesugaringEnabled true
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
packagingOptions {
exclude 'META-INF/AL2.0'
exclude 'META-INF/LGPL2.1'
}
}
dependencies {
implementation 'androidx.core:core-ktx:1.6.0'
implementation 'androidx.appcompat:appcompat:1.3.1'
implementation 'androidx.constraintlayout:constraintlayout:2.1.0'
implementation "androidx.recyclerview:recyclerview:1.2.1"
implementation "androidx.navigation:navigation-fragment-ktx:$nav_version"
implementation "androidx.navigation:navigation-ui-ktx:$nav_version"
implementation "androidx.preference:preference-ktx:1.1.1"
implementation 'com.google.android.material:material:1.4.0'
implementation "io.insert-koin:koin-android:$koin_version"
implementation "com.github.jknack:handlebars:4.1.2"
implementation "androidx.room:room-runtime:$room_version"
implementation "androidx.room:room-ktx:$room_version"
kapt "androidx.room:room-compiler:$room_version"
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5'
testImplementation 'junit:junit:4.13.2'
testImplementation "org.mockito:mockito-inline:3.12.1"
testImplementation "com.nhaarman.mockitokotlin2:mockito-kotlin:2.2.0"
testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.5.1'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
androidTestImplementation "androidx.arch.core:core-testing:2.1.0"
androidTestImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.5.1'
}
Our new prefs
XML resource should contain:
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<EditTextPreference
android:key="@string/web_service_url_key"
android:selectAllOnFocus="true"
android:title="@string/pref_url_title"
app:defaultValue="@string/web_service_url_default" />
</PreferenceScreen>
Our updated strings
resource should look like:
<resources>
<string name="app_name">ToDo</string>
<string name="msg_empty">Click the + icon to add a todo item!</string>
<string name="msg_empty_filtered">Click the + icon to add a todo item, or change your filter to show other items</string>
<string name="menu_about">About</string>
<string name="is_completed">Item is completed</string>
<string name="created_on">Created on:</string>
<string name="menu_edit">Edit</string>
<string name="desc">Description</string>
<string name="notes">Notes</string>
<string name="menu_save">Save</string>
<string name="menu_add">Add</string>
<string name="menu_delete">Delete</string>
<string name="menu_filter">Filter</string>
<string name="menu_filter_all">All</string>
<string name="menu_filter_completed">Completed</string>
<string name="menu_filter_outstanding">Outstanding</string>
<string name="oops">Sorry! Something went wrong!</string>
<string name="report_template"><![CDATA[<h1>To-Do Items</h1>
<h2></h2>
<p><b>COMPLETED</b> — Created on: </p>
<p></p>
]]></string>
<string name="menu_share">Share</string>
<string name="pref_url_title">Web service URL</string>
<string name="web_service_url_key">webServiceUrl</string>
<string name="web_service_url_default">https://commonsware.com/AndExplore/2.0/items.json</string>
<string name="settings">Settings</string>
</resources>
The new PrefsFragment
should contain:
package com.commonsware.todo.ui.prefs
import android.os.Bundle
import androidx.preference.PreferenceFragmentCompat
import com.commonsware.todo.R
class PrefsFragment : PreferenceFragmentCompat() {
override fun onCreatePreferences(state: Bundle?, rootKey: String?) {
setPreferencesFromResource(R.xml.prefs, rootKey)
}
}
The revised nav_graph
navigation resource should resemble:
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/nav_graph.xml"
app:startDestination="@id/rosterListFragment">
<fragment
android:id="@+id/rosterListFragment"
android:name="com.commonsware.todo.ui.roster.RosterListFragment"
android:label="@string/app_name">
<action
android:id="@+id/displayModel"
app:destination="@id/displayFragment" />
<action
android:id="@+id/createModel"
app:destination="@id/editFragment" >
<argument
android:name="modelId"
android:defaultValue="@null" />
</action>
</fragment>
<fragment
android:id="@+id/displayFragment"
android:name="com.commonsware.todo.ui.display.DisplayFragment"
android:label="@string/app_name" >
<argument
android:name="modelId"
app:argType="string" />
<action
android:id="@+id/editModel"
app:destination="@id/editFragment" />
</fragment>
<fragment
android:id="@+id/editFragment"
android:name="com.commonsware.todo.ui.edit.EditFragment"
android:label="@string/app_name" >
<argument
android:name="modelId"
app:argType="string"
app:nullable="true" />
</fragment>
<fragment
android:id="@+id/prefsFragment"
android:name="com.commonsware.todo.ui.prefs.PrefsFragment"
android:label="@string/settings" />
<action android:id="@+id/editPrefs" app:destination="@id/prefsFragment" />
</navigation>
The updated actions
menu resource should look like:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/settings"
android:icon="@drawable/ic_settings"
android:orderInCategory="90"
android:title="@string/settings"
app:showAsAction="never" />
<item
android:id="@+id/about"
android:icon="@drawable/ic_about"
android:orderInCategory="100"
android:title="@string/menu_about"
app:showAsAction="never" />
</menu>
And the updated MainActivity
should contain:
package com.commonsware.todo.ui
import android.content.Intent
import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
import androidx.appcompat.app.AppCompatActivity
import androidx.navigation.findNavController
import androidx.navigation.fragment.findNavController
import androidx.navigation.ui.AppBarConfiguration
import androidx.navigation.ui.NavigationUI.navigateUp
import androidx.navigation.ui.setupActionBarWithNavController
import com.commonsware.todo.R
import com.commonsware.todo.databinding.ActivityMainBinding
class MainActivity : AppCompatActivity() {
private lateinit var appBarConfiguration: AppBarConfiguration
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
setSupportActionBar(binding.toolbar)
supportFragmentManager.findFragmentById(R.id.nav_host)?.findNavController()?.let { nav ->
appBarConfiguration = AppBarConfiguration(nav.graph)
setupActionBarWithNavController(nav, appBarConfiguration)
}
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.actions, menu)
return super.onCreateOptionsMenu(menu)
}
override fun onOptionsItemSelected(item: MenuItem) = when (item.itemId) {
R.id.about -> {
startActivity(Intent(this, AboutActivity::class.java))
true
}
R.id.settings -> {
findNavController(R.id.nav_host).navigate(R.id.editPrefs)
true
}
else -> super.onOptionsItemSelected(item)
}
override fun onSupportNavigateUp() =
navigateUp(findNavController(R.id.nav_host), appBarConfiguration)
}
Prev Table of Contents Next
This book is licensed under the Creative Commons Attribution-ShareAlike 4.0 International license.