Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jetpack compose viewModel() is giving error "has no zero argument constructor" with hilt

In my project, compose viewModel() method is giving error "has no zero argument constructor" when I am using hilt.

@Composable
    fun HomeScreen(homeViewModel: HomeViewModel = viewModel()) {
    ...
    }
    
    @HiltViewModel
    class HomeViewModel @Inject constructor(private val repository: Repository) :
        ViewModel() {
    ...
    }
@Module
@InstallIn(ViewModelComponent::class)
abstract class DataModule {
    @Binds
    abstract fun bindRepository(
        fakePuppyRepository: RepositoryImpl
    ): Repository
}

these are my dependencies

implementation 'androidx.core:core-ktx:1.3.2'
    implementation 'androidx.appcompat:appcompat:1.2.0'
    implementation 'com.google.android.material:material:1.3.0'
    implementation "androidx.compose.ui:ui:$compose_version"
    implementation "androidx.compose.material:material:$compose_version"
    implementation "androidx.compose.ui:ui-tooling:$compose_version"
    implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.0'
    implementation 'androidx.activity:activity-compose:1.3.0-alpha03'
    implementation "androidx.navigation:navigation-compose:1.0.0-alpha08"
    implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.3.0'
    implementation 'androidx.compose.runtime:runtime-livedata:1.0.0-beta01'
    implementation "com.google.dagger:hilt-android:$hilt_version"
    implementation 'androidx.hilt:hilt-lifecycle-viewmodel:1.0.0-alpha03'
    kapt "com.google.dagger:hilt-compiler:$hilt_version"
    kapt 'androidx.hilt:hilt-compiler:1.0.0-alpha03'
    testImplementation 'junit:junit:4.13.2'
    androidTestImplementation 'androidx.test.ext:junit:1.1.2'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
like image 524
Vivart Avatar asked Feb 26 '21 17:02

Vivart


3 Answers

Based on your dependencies, I suspect you are using NavController/NavHost.

Add this dependency: androidx.hilt:hilt-navigation-compose:1.0.0-alpha01

Now in your composable which defines NavController, call HomeScreen as follows:

import androidx.compose.runtime.Composable
import androidx.hilt.navigation.compose.hiltNavGraphViewModel
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController

...

@Composable
fun Main() {
  val navController = rememberNavController()
  NavHost(navController, startDestination = "home"){
    composable("home") {
      val model: HomeViewModel = hiltNavGraphViewModel(it)
      HomeScreen(model)
    }
  }
}

...

hiltNavGraphViewModel(...) can also be replaced with viewModel(HiltViewModelFactory(LocalContext.current, backStackEntry)) (from https://github.com/google/dagger/issues/2166#issuecomment-769162910)

like image 106
jeubank12 Avatar answered Oct 19 '22 10:10

jeubank12


The hiltNavGraphViewModel() extension has been deprecated. You can use hiltViewModel() instead if you use Navigation and Hilt.

First, add this dependency:

implementation 'androidx.hilt:hilt-navigation-compose:1.0.0-alpha03'

And now you can use hiltViewModel() together with Navigation.

@Composable
fun MyApp() {
    NavHost(navController, startDestination = startRoute) {
        composable("example") { backStackEntry ->
            // Creates a ViewModel from the current BackStackEntry
            // Available in the androidx.hilt:hilt-navigation-compose artifact
            val exampleViewModel = hiltViewModel<ExampleViewModel>()
            ExampleScreen(exampleViewModel)
        }
        /* ... */
    }
}

More information: Hilt and Navigation

like image 44
Dương Minh Avatar answered Oct 19 '22 10:10

Dương Minh


Happened to me when I set my ViewModel inside a package called new.

Let's say my base package is com.example.appname, I created a new pakage called new and I had com.example.appname.new, every other ViewModel factories were created successfully by Hilt with the exception the one inside of package new.

  1. Rename the package with name new, it looks like it is reserved.
  2. Move your ViewModel to another location.
like image 3
Akhha8 Avatar answered Oct 19 '22 09:10

Akhha8