Android Studio使用Dagger 2将依赖关系注入到动态创建的片段中

时间:2018-05-27 21:46:02

标签: android android-fragments dependency-injection dagger-2 android-viewmodel

到目前为止,我创建了一个非常小的Android Studio项目,使用位于https://github.com/arranlomas/DaggerViewModelHelper的库将我的ViewModel注入到我的片段中。我想动态地向我的活动添加一个片段,并将片段的依赖项(我之前提到的ViewModel)注入其中,而Activity不需要显式创建这些依赖项。以下是一些澄清的代码:

class MainActivity : AppCompatActivity(), Injectable {

private val mOnNavigationItemSelectedListener = BottomNavigationView.OnNavigationItemSelectedListener { item ->
    when (item.itemId) {
        R.id.navigation_home -> {
            message.setText(R.string.title_home)
            val weeklyFragment = WeeklyFragment.newInstance()
            openFragment(weeklyFragment)
            return@OnNavigationItemSelectedListener true
        }
        R.id.navigation_dashboard -> {
            message.setText(R.string.title_dashboard)
            return@OnNavigationItemSelectedListener true
        }
        R.id.navigation_notifications -> {
            message.setText(R.string.title_notifications)
            return@OnNavigationItemSelectedListener true
        }
    }
    false
}

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    ButterKnife.bind(this)

    val viewModel = ViewModelProviders.of(this, viewModelFactory).get(MyViewModel::class.java)
    navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener)
}

private fun openFragment(fragment: Fragment) {
    val transaction = supportFragmentManager.beginTransaction()
    transaction.replace(R.id.content_container, fragment)
    transaction.addToBackStack(null)
    transaction.commit()
}

我的WeeklyFragment代码:

class WeeklyFragment : Fragment(), Injectable {
// View elements
@BindView(R.id.weekly_text) lateinit var myTextView: TextView

// View Model Factory
@Inject
lateinit var viewModelFactory: ViewModelProvider.Factory

companion object {
    fun newInstance(): WeeklyFragment = WeeklyFragment()
}

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? =
        inflater.inflate(R.layout.fragment_weekly, container, false)

override fun onActivityCreated(savedInstanceState: Bundle?) {
    super.onActivityCreated(savedInstanceState)

    val viewModel = ViewModelProviders.of(this, viewModelFactory).get(MyViewModel::class.java)
    viewModel.makeFooString().observe(this, Observer<String> { myTextView.text = it })
}

}

现在,我可以将MyViewModel注入我的MainActivity并使用它(如果我稍微重新排列代码),但我想将MyViewModel注入WeeklyFragment而无需在MainActivity中声明它。我怀疑我应该改变我实例化的方式和&#34; transaction.replace&#34; WeeklyFragment,但我没有找到关于如何具体实现这一目标的信息。当我运行以下代码时,我得到:

java.lang.IllegalArgumentException: No injector was found for com.dev.myproject.view.weekly.WeeklyFragment
                  at dagger.android.support.AndroidSupportInjection.findHasFragmentInjector(AndroidSupportInjection.java:92)
                  at dagger.android.support.AndroidSupportInjection.inject(AndroidSupportInjection.java:57)
                  at com.arranlomas.daggerviewmodelhelper.AppInjector$handleActivity$1.onFragmentCreated(AppInjector.kt:61)
                  at android.support.v4.app.FragmentManagerImpl.dispatchOnFragmentCreated(FragmentManager.java:3467)
                  at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1387)
                  at android.support.v4.app.FragmentTransition.addToFirstInLastOut(FragmentTransition.java:1188)
                  at android.support.v4.app.FragmentTransition.calculateFragments(FragmentTransition.java:1071)
                  at android.support.v4.app.FragmentTransition.startTransitions(FragmentTransition.java:115)
                  at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2380)
                  at android.support.v4.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2338)
                  at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2245)
                  at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:703)
                  at android.os.Handler.handleCallback(Handler.java:751)
                  at android.os.Handler.dispatchMessage(Handler.java:95)
                  at android.os.Looper.loop(Looper.java:154)
                  at android.app.ActivityThread.main(ActivityThread.java:6077)
                  at java.lang.reflect.Method.invoke(Native Method)
                  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866)
                  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:756)

如何成功将依赖项注入WeeklyFragment?

1 个答案:

答案 0 :(得分:0)

您似乎忘了在@Module中添加@ContributesAndroidInjector方法。 Dagger无法在你的片段中注入任何东西(ViewModel或不是ViewModel)