hilt dependency injection

Using Hilt Dependency Injection in Android App | Notes App

Hilt is a dependency injection framework for Android that is built on top of Dagger 2. Hilt is the newest dependency injection tool. It comes with built-in support for injection in Android classes. We’ll look at how to use Room with Hilt in this article. If you don’t know what is room database then please refer to the Room Database Android Example- Building a Notes App.

Hilt is an opinionated Android dependency injection library that reduces the boilerplate associated with using manual DI in your project. Manual dependency injection necessitates manually constructing each class and its dependencies, as well as using containers to reuse and manage dependencies. Hilt is simpler than Dagger.

Hilt offers a standardized method for incorporating Dagger dependency injection into an Android application. Hilt’s goals are as follows: to simplify Dagger-related infrastructure for Android apps. To develop a standard set of components and scopes to facilitate app setup, readability/understanding, and code sharing. Another thing to keep in mind is that Hilt works with Jetpack components like ViewModel and WorkManager.

Output:

Enable the Hilt dependency injection:

To enable the Hilt dependency injection in our project, first, we have to add dependency or plugin of it in our builld.gradle files.

-Add the plugin in build.gradle(Module:app) file.

plugins {
    ...
    id 'kotlin-kapt'
    id 'dagger.hilt.android.plugin'

}

-Add dependencies in build.gradle(Module:app) file.

dependencies {
    ...
    //Hilt
    implementation "com.google.dagger:hilt-android:2.38.1"
    kapt "com.google.dagger:hilt-compiler:2.38.1"

}

-Now add the dependencies in your build.gradle(project:app) file.

   dependencies {
    ...
        classpath 'com.google.dagger:hilt-android-gradle-plugin:2.38.1'

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }

Annotations in Hilt dependency injection

@HiltAndroidApp:

@HiltAndroidApp: In your Application class, this annotation enables member injection (i.e. field and method injection). If you understand how the Application class uses Dagger 2 to inject dependencies, you’ll see why the @HiltAndroidApp annotation is necessary. @HiltAndroidApp will create the component class and link all of the module classes for you.

@HiltAndroidApp
class Myapplication: Application() {

}
package com.example.room_database_100.di

import android.app.Application
import dagger.hilt.android.HiltAndroidApp


@HiltAndroidApp
class Myapp: Application() {

}

When you first build your project with the above code snippet, the Hilt framework will create a base class called Hilt SpaceXApplication that the annotated class SpaceXApplication should extend, but you don’t have to explicitly extend Hilt SpaceXApplication because the Hilt Gradle plugin will take care of that. This base class will inject the required dependencies into its children.

@AndroidEntryPoint

@AndroidEntryPoint: This annotation is used in Android Components like activities, fragments, views, services, and broadcast receivers to enable member injection. If your Android Components aren’t annotated with @AndroidEntryPoint, you won’t be able to inject any fields or methods (i.e., you won’t be able to use the @Inject annotation). While scrolling down, you’ll learn more about the @Inject annotation.

This annotation, like @HiltAndroidApp, will generate a base class Hilt SpaceXLaunchListActivity that the annotated class should extend, but you do not need to explicitly extend the base class because the Hilt Gradle plugin will take care of it.


@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
…….
}
}
package com.example.room_database_100

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.navigation.findNavController
import androidx.navigation.fragment.NavHostFragment
import androidx.navigation.ui.setupActionBarWithNavController
import dagger.hilt.android.AndroidEntryPoint

@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
.......
      }
}

@HiltViewModel

In ViewModels, we previously used @ViewModelInject with the Assisted annotation to get a SavedStateHandle. However, @HiltViewModel was introduced in Hilt 2.31, and we use it and inject instead of ViewModelInject and Assisted.
Hilt View Models are Jetpack ViewModels that constructor injected by Hilt. Use the @HiltViewModel annotation to allow Hilt to inject a ViewModel.


@HiltViewModel
class UserViewModel @Inject constructor(application: Application, dao: UserDao) : AndroidViewModel(application) {

}
@HiltViewModel
class UserViewModel @Inject constructor(application: Application, dao: UserDao) : AndroidViewModel(application) {
...


}

@Inject

@Inject annotation is used by the Dagger framework to identify not only injectable constructors but also injectable methods and fields. In simply put, @ViewModelInject can only be used before the ViewModel constructor, whereas @Inject can be used before the constructor, fields, and methods of any class.


class UserViewModel @Inject constructor(application: Application, dao: UserDao) : AndroidViewModel(application) {

}
@HiltViewModel
class UserViewModel @Inject constructor(application: Application, dao: UserDao) : AndroidViewModel(application) {
 ...
}

@Module

@Module: Dagger provided us with the @Module annotation, which allows us to create a class and populate it with all of the framework’s required objects, the object cannot be automatically provided by the Dagger using constructor injection. And it’s clear from the dependency graph that this interface object is critical to the entire flow. As a result, we should assist Dagger by providing the required object by creating a @Module-annotated class.

@Module
class RoomModule {

}
@Module
class RoomModule {
...
}

@Provide

@Provide: Even though we have a class annotated with @Module, the framework is still unable to retrieve the dependent object. To be prepared, we must write a method that returns the dependent object and annotate it with the @Provide annotation so that the framework recognizes it as a dependency object provider.

@Provides
fun provideDao(database: UserDatabase): UserDao {
return database.userDao()
}
    @Provides
    fun provideDao(database: UserDatabase): UserDao {
        return database.userDao()
    }

@InstallIn

Knowing that the class annotated with @Module is used to provide dependency objects, we can scope the use of the dependent objects provided by this module class to a specific android component by annotating the same module class with @InstallIn. For example, to insert, update, or delete data, everyone in the application will require a database object. Let’s look at an example: if I annotate the RoomModule class with @InstallIn(ApplicationComponent::class), the UserDatabase object will be available for the duration of the app.

Similarly, I must annotate the RoomModule class with @InstallIn(ActivityComponent::class) if I want it available only for the duration of the activity.

@InstallIn(SingletonComponent::class)
@Module
class RoomModule {

}
@InstallIn(SingletonComponent::class)
@Module
class RoomModule {
...
}
  • Hilt currently supports seven components for use with the @InstallIn annotation. We signal the hilt framework that the dependent object provided by the module class can be injected and made available only for the lifetime of the respective component that we have mentioned in the @InstallIn annotation by specifying these components in the class annotated with @Module.
@InstallIn(ApplicationComponent) Present throughout the application’s lifespan.
@InstallIn(ActivityComponent) Present throughout the Activity’s lifetime.
@InstallIn(ActivityRetainedComponent) Just like the ViewModel, this component is present for the lifetime of a configuration surviving activity (i.e. surviving orientation changes).
@InstallIn(FragmentComponent) Present throughout the fragment’s lifetime.
@InstallIn(ServiceComponent)Present throughout the service’s lifetime.
@InstallIn(ViewComponent) This property is active for the duration of the view that is directly inside an activity.
@InstallIn(ViewWithFragmentComponent) The view will be present for the duration of the fragment.

Using Hilt Dependency Injection in Room Database Example

Step by Step Explanation:

Step 1: Create a New Project in Android Studio(Empty Activity).

Step 2: The first thing we’ll do is add all of the necessary dependencies in build.gradle(Module:app) and plugins as given below:

plugins {
    id 'com.android.application'
    id 'kotlin-android'
    id 'kotlin-kapt'
    id 'dagger.hilt.android.plugin'
}

android {
    compileSdkVersion 30
    buildToolsVersion "30.0.3"

    defaultConfig {
        applicationId "com.example.notes_app_"
        minSdkVersion 16
        targetSdkVersion 30
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }
    packagingOptions {
        exclude 'META-INF/atomicfu.kotlin_module'
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    kotlinOptions {
        jvmTarget = '1.8'
    }
}

dependencies {
    implementation "androidx.appcompat:appcompat:$rootProject.appCompatVersion"
    implementation "androidx.activity:activity-ktx:$rootProject.activityVersion"

    // Dependencies for working with Architecture components
    // You'll probably have to update the version numbers in build.gradle (Project)

    // Room components
    implementation "androidx.room:room-ktx:$rootProject.roomVersion"
    kapt "androidx.room:room-compiler:$rootProject.roomVersion"
    androidTestImplementation "androidx.room:room-testing:$rootProject.roomVersion"

    // Lifecycle components
    implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$rootProject.lifecycleVersion"
    implementation "androidx.lifecycle:lifecycle-livedata-ktx:$rootProject.lifecycleVersion"
    implementation "androidx.lifecycle:lifecycle-common-java8:$rootProject.lifecycleVersion"

    // Kotlin components
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
    api "org.jetbrains.kotlinx:kotlinx-coroutines-core:$rootProject.coroutines"
    api "org.jetbrains.kotlinx:kotlinx-coroutines-android:$rootProject.coroutines"

    // UI
    implementation "androidx.constraintlayout:constraintlayout:$rootProject.constraintLayoutVersion"
    implementation "com.google.android.material:material:$rootProject.materialVersion"

    implementation "androidx.recyclerview:recyclerview:1.2.1"
    // For control over item selection of both touch and mouse driven selection
    implementation "androidx.recyclerview:recyclerview-selection:1.1.0"
    // Testing
    testImplementation "junit:junit:$rootProject.junitVersion"
    androidTestImplementation "androidx.arch.core:core-testing:$rootProject.coreTestingVersion"
    androidTestImplementation ("androidx.test.espresso:espresso-core:$rootProject.espressoVersion", {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    androidTestImplementation "androidx.test.ext:junit:$rootProject.androidxJunitVersion"
    //Hilt
    implementation "com.google.dagger:hilt-android:2.38.1"
    kapt "com.google.dagger:hilt-compiler:2.38.1"
}

-Add dependencies in your build.gradle(Project:app) as shown in below.

// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
    ext.kotlin_version = "1.5.21"
    repositories {
        google()
        mavenCentral()
    }
    dependencies {
        classpath "com.android.tools.build:gradle:4.2.1"
        classpath 'com.google.dagger:hilt-android-gradle-plugin:2.38.1'

        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        google()
        mavenCentral()
        jcenter() // Warning: this repository is going to shut down soon
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}
ext {
    activityVersion = '1.2.3'
    appCompatVersion = '1.3.0'
    constraintLayoutVersion = '2.0.4'
    coreTestingVersion = '2.1.0'
    coroutines = '1.5.0'
    lifecycleVersion = '2.3.1'
    materialVersion = '1.3.0'
    roomVersion = '2.3.0'
    // testing
    junitVersion = '4.13.2'
    espressoVersion = '3.1.0'
    androidxJunitVersion = '1.1.2'
}

Sync your project after adding the above dependencies, and you’re ready to go.

Step 3: Update the AndroidManifest.xml file.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.notes_app_">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:name=".di.Myapp" ///<-Add this attribute
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.NOTES_APP_">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

Step 4: Create a new class and name it Myapp and extend it from the Application class as shown below.

package com.example.notes_app_.di

import android.app.Application
import dagger.hilt.android.HiltAndroidApp


@HiltAndroidApp
class Myapp : Application() {

}

Step 5: Now create a new class for Module, name it as RoomModule and add the code given below.

package com.example.notes_app_.di

import android.content.Context
import androidx.room.Room
import com.example.notes_app_.NoteDao
import com.example.notes_app_.NoteDatabase
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.components.SingletonComponent
import javax.inject.Singleton

@InstallIn(SingletonComponent::class)
@Module
class RoomModule {

    @Provides
    @Singleton
    fun provideDatabase(@ApplicationContext context: Context): NoteDatabase {
        return Room.databaseBuilder(
            context,
            NoteDatabase::class.java,
            "note_db"

        ).build()
    }

    @Provides
    fun provideDao(database: NoteDatabase): NoteDao {
        return database.getNoteDao()
    }

}

Step: 6 Now comes to the important part: we must construct an entity for each table we require.  Create a new class for an entity, name it as Note, and add the code given below into it.

package com.example.notes_app_

import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey

@Entity(tableName = "notes_table")
data class Note(
    @ColumnInfo(name = "text")
    var text: String,

    @ColumnInfo(name = "phone")
    var Phone: String,

    @ColumnInfo(name = "Amount")
    var Amount:String

) {
    @PrimaryKey(autoGenerate = true)
    var id = 0
}

  • As you can see in the above code we have annotated the class with @Entity this is our table, and for the column id we have used @PrimaryKey(autoGenerate = true) this means this id will be auto increment, for other columns we used @ColumnInfo(name = “columnname”).

Step 7: Create a new class for Dao (Data Access Object). To create an interface named it as NoteDao and add the code given below into it.

package com.example.notes_app_

import androidx.lifecycle.LiveData
import androidx.room.*


@Dao
interface NoteDao {


    @Insert(onConflict = OnConflictStrategy.IGNORE)
    suspend fun insert(note: Note)

    @Delete
    suspend fun delete(note: Note)

    @Query("Select  * from notes_table order by id ASC")
    fun getAllNotes(): LiveData<List<Note>>

}

  • You can see above we defined all the methods needed for the Create, Read, and Delete operation.

Step 8: Create a database class, name it as NoteDatabase, and add the code given below into it.

package com.example.notes_app_

import androidx.room.Database
import androidx.room.RoomDatabase

@Database(entities = [Note::class], version = 1, exportSchema = false)
abstract class NoteDatabase : RoomDatabase() {

    abstract fun getNoteDao(): NoteDao

}


Step 9: Create a new repository class, name it as NoteRepository and add the given below code into it.

package com.example.notes_app_


import androidx.lifecycle.LiveData

class NoteRepository(private val noteDao: NoteDao) {
    val allNotes: LiveData<List<Note>> = noteDao.getAllNotes()

    suspend fun insert(note: Note) {
        noteDao.insert(note)

    }

    suspend fun delete(note: Note) {
        noteDao.delete(note)
    }

}

Step 10: Create a new class for ViewModel and name it as NoteViewModel, annotate with @HiltViewModel and add the code given below into it.

android, hilt Dependency Injection in android, hilt Dependency Injection in android, hilt Dependency Injection in android, hilt Dependency Injection in android, hilt Dependency Injection in android, hilt Dependency Injection in android, hilt Dependency Injection in android, hilt in android, hilt in android app, hilt dependency injection

package com.example.notes_app_

import android.app.Application
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.LiveData
import androidx.lifecycle.viewModelScope
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import javax.inject.Inject

@HiltViewModel
class NoteViewModel @Inject constructor(application: Application,dao: NoteDao) : AndroidViewModel(application) {
    private val repository: NoteRepository = NoteRepository(dao)
    val allNotes: LiveData<List<Note>> = repository.allNotes


    fun deleteNote(note: Note) = viewModelScope.launch(Dispatchers.IO) {
        repository.delete(note)

    }

    fun insertNote(note: Note) = viewModelScope.launch(Dispatchers.IO) {
        repository.insert(note)
    }

}

Step 11: In the activity_main.xml file, design a layout for the notes application so add the code given below into it.

room database
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <EditText
        android:id="@+id/input"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="16dp"
        android:hint="Enter Name here"
        android:textSize="16sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.001" />


    <EditText
        android:id="@+id/inputphone"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="16dp"
        android:hint="Enter Number here"
        android:inputType="number"
        android:textSize="16sp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@id/input"

        />
    <EditText
        android:id="@+id/inputAmount"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="16dp"
        android:hint="Enter Amount here"
        android:inputType="number"
        android:textSize="16sp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@id/inputphone"

        />

    <Button
        android:id="@+id/addbtn"
        style="@style/TextAppearance.AppCompat.Widget.Button.Inverse"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="16dp"
        android:background="@color/teal_200"
        android:onClick="submitData"
        android:text="submit"
        android:textColor="#FFFFFF"
        app:layout_constraintTop_toBottomOf="@id/inputAmount" />

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_marginTop="16dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toBottomOf="@id/addbtn"
        app:layout_constraintVertical_bias="1.0"
        tools:listitem="@layout/item_note" />


</androidx.constraintlayout.widget.ConstraintLayout>

Step 12: RecyclerView Layout design– We will display all the tasks added in a RecyclerView, and for this, we need one more layout file. To create a layout file and name it item_note and write the following XML code inside.

room database
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_margin="12dp"
    android:background="#abcdef">

    <TextView
        android:id="@+id/textitem"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:padding="12dp"
        tools:text="Sagar"
        android:textColor="#212121"
        android:textSize="16sp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toLeftOf="@id/deletebtn"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/textitemphone"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:padding="12dp"
        android:textColor="#212121"
        android:textSize="16sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="@+id/textitem"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/textitem"
        app:layout_constraintVertical_bias="0.115"
        tools:text="1234567890" />

    <TextView
        android:id="@+id/textitemAmount"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:padding="12dp"
        tools:text="50$"
        android:textColor="#212121"
        android:textSize="16sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="@+id/textitem"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/textitemphone" />

    <ImageView
        android:id="@+id/deletebtn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="16dp"
        android:src="@drawable/ic_baseline_delete_24"
        app:layout_constraintBottom_toBottomOf="@id/textitem"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="@id/textitem" />

</androidx.constraintlayout.widget.ConstraintLayout>

Step 13: Create an Adapter class for recyclerView, name it as NoteRVAdapter, and add the code given below into it. 

hilt Dependency Injection in android, hilt Dependency Injection in android, hilt Dependency Injection in android, hilt Dependency Injection in android, hilt Dependency Injection in android, hilt Dependency Injection in android, hilt Dependency Injection in android, hilt Dependency Injection in android, hilt Dependency Injection in android, hilt Dependency Injection in android

package com.example.notes_app_

import android.content.Context
import android.view.LayoutInflater
import android.view.OrientationEventListener
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import org.w3c.dom.Text


class NotesRVAdapter(private val context: Context, private val listener: INotesRVAdapter) :
    RecyclerView.Adapter<NotesRVAdapter.NoteViewHolder>() {

    private val allNotes = ArrayList<Note>()


    inner class NoteViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        val textView: TextView = itemView.findViewById<TextView>(R.id.textitem)
        val phoneView: TextView = itemView.findViewById<TextView>(R.id.textitemphone)
        val deleteButton: ImageView = itemView.findViewById<ImageView>(R.id.deletebtn)
        val AmountView: TextView = itemView.findViewById(R.id.textitemAmount)

        fun bind(note: Note) {
            textView.text = note.text
            phoneView.text = note.Phone
            AmountView.text= note.Amount
        }


    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): NoteViewHolder {
        val viewHolder =
            NoteViewHolder(LayoutInflater.from(context).inflate(R.layout.item_note, parent, false))
        viewHolder.deleteButton.setOnClickListener {
            listener.onItemClicked(allNotes[viewHolder.adapterPosition])
        }
        return viewHolder

    }

    override fun onBindViewHolder(holder: NoteViewHolder, position: Int) {
        val currentNote = allNotes[position]
        holder.bind(currentNote)
//        holder.textView.text = currentNote.text
//        holder.phoneView.text = currentNote.Phone


    }

    fun updateList(newList: List<Note>) {
        allNotes.clear()
        allNotes.addAll(newList)
        notifyDataSetChanged()
    }

    override fun getItemCount(): Int {
        return allNotes.size

    }
}

interface INotesRVAdapter {
    fun onItemClicked(note: Note)

}

Step 14: Now come to the MainActivity file, annotate it with @AndroidEntryPoint and add the code given below into it.

package com.example.notes_app_

import android.os.Bundle
import android.view.View
import android.widget.EditText
import android.widget.Toast
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import dagger.hilt.android.AndroidEntryPoint

@AndroidEntryPoint
class MainActivity : AppCompatActivity(), INotesRVAdapter {
    private val viewModel: NoteViewModel by viewModels()
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        findViewById<RecyclerView>(R.id.recyclerView).layoutManager = LinearLayoutManager(this)
        val adapter = NotesRVAdapter(this, this)
        findViewById<RecyclerView>(R.id.recyclerView).adapter = adapter
        viewModel.allNotes.observe(this, Observer { list ->
            list?.let {
                adapter.updateList(it)

            }
        })


    }

    override fun onItemClicked(note: Note) {
        viewModel.deleteNote(note)
       Toast.makeText(this,"${note.text} DELETED ",Toast.LENGTH_LONG).show()
    }

    fun submitData(view: View) {
        val noteText = findViewById<EditText>(R.id.input).text.toString()
        val phoneText =findViewById<EditText>(R.id.inputphone).text.toString()
        val AmountText = findViewById<EditText>(R.id.inputAmount).text.toString()



        if (noteText.isNotEmpty()){
            viewModel.insertNote(Note(noteText,phoneText,AmountText))
            Toast.makeText(this,"$noteText ,$phoneText SUBMITED  ",Toast.LENGTH_LONG).show()

        }
    }
}

Run the application now. You will get the output shown in the output section.

Source Code:

We’ve completed the development of the Notes application using Hilt dependency injection. You can get the Source code from the given below button.

  • We hope that this guide will assist you in understanding all about the concepts of Hilt dependency injection in android with room database application example. We have concentrated on making a basic, meaningful and easy-to -learn guide to the concepts of Hilt dependency injection with suitable examples. Still if you have any problems regarding this, please post them in the comments section, we will be glad to assist you.

This Post Has One Comment

Leave a Reply