【问题标题】:Hilt: Get Fragment LifecycleOwner and context automagicallyHilt:自动获取 Fragment LifecycleOwner 和上下文
【发布时间】:2021-08-04 11:34:08
【问题描述】:

当我在片段中注入我的依赖项时,我想自动获取片段上下文和生命周期所有者(例如这里的 viewLifecycleOwner)。我的问题是,怎么做,因为没有对应的@FragmentContext,就像有一个@ActivityContext。此外,我想为这个依赖动态分配一个变量。

我的依赖

class LoginDialog(
    context: Context, // get this from fragment
    private val mLifecycleOwner: LifecycleOwner, // get this from fragment
    private val loginTitle: LoginTitle, // define this when injecting
) : AlertDialog(context, R.style.LoginDialogTheme) {
    private var _binding: LoginLoadingScreenBinding? = null
    private val binding: LoginLoadingScreenBinding get() = _binding!!

    override fun onCreate(savedInstanceState: Bundle?) {
        initDialog()
        super.onCreate(savedInstanceState)
    }

    override fun show() {
        if (isShowing) return
        _binding = LoginLoadingScreenBinding.inflate(layoutInflater).apply { lifecycleOwner = mLifecycleOwner }
        super.show()
    }

    override fun dismiss() {
        _binding = null
        super.dismiss()
    }

    /**
     * Calls show internally
     */
    fun onChangeIndicator(mText: String) {
        show()
        binding.indicator = mText
    }

    private fun initDialog() {
        setTitle(loginTitle.title)
        setCancelable(false)
        setView(binding.root)
    }

    sealed class LoginTitle(@StringRes val title: Int) {
        object Login : LoginTitle(R.string.loading_login_title)
        object Registration : LoginTitle(R.string.loading_registration_title)
        object ChangingEmail : LoginTitle(R.string.user_data_changing_email)
    }

}

注入

@AndroidEntryPoint
class FragmentA : Fragment() {

    // here, context is requireContext(), 
    // lifecycleOwner is viewLifecylceOwner
    // and loginTitle is LoginDialog.LoginTitle.Login
    @Inject 
    @LoginTitleLogin
    lateinit var loginDialog: LoginDialog
}

【问题讨论】:

    标签: android kotlin dagger-2 dagger-hilt


    【解决方案1】:

    好的,我已经设法通过创建一个 hilt 模块并稍微更改构造函数来解决这个问题,这里是解决方案:

    依赖

    class LoginDialog(
        private val fragment: Fragment,
        private val loginTitle: LoginTitle,
    ) : AlertDialog(fragment.requireContext(), R.style.LoginDialogTheme) {
        private var _binding: LoginLoadingScreenBinding? = null
        private val binding: LoginLoadingScreenBinding get() = _binding!!
    
        override fun onCreate(savedInstanceState: Bundle?) {
            initDialog()
            super.onCreate(savedInstanceState)
        }
    
        override fun show() {
            if (isShowing) return
            _binding = LoginLoadingScreenBinding.inflate(layoutInflater).apply { lifecycleOwner = fragment.viewLifecycleOwner }
            super.show()
        }
    
        override fun dismiss() {
            _binding = null
            super.dismiss()
        }
    
        /**
         * Calls show internally
         */
        fun onChangeIndicator(mText: String) {
            show()
            binding.indicator = mText
        }
    
        private fun initDialog() {
            setTitle(loginTitle.title)
            setCancelable(false)
            setView(binding.root)
        }
    
        sealed class LoginTitle(@StringRes val title: Int) {
            object Login : LoginTitle(R.string.loading_login_title)
            object Registration : LoginTitle(R.string.loading_registration_title)
            object ChangingEmail : LoginTitle(R.string.user_data_changing_email)
        }
    
    }
    

    模块

    @Module
    @InstallIn(FragmentComponent::class)
    object FragmentModule {
    
        @LoginTitle
        @Provides
        fun provideLoginDialogWithLoginTitle(fragment: Fragment) = LoginDialog(
            fragment,
            LoginDialog.LoginTitle.Login
        )
    
        @RegistrationTitle
        @Provides
        fun provideLoginDialogWithRegistrationTitle(fragment: Fragment) = LoginDialog(
            fragment,
            LoginDialog.LoginTitle.Registration
        )
    
        @ChangingEmailTitle
        @Provides
        fun provideLoginDialogWithChangingEmailTitle(fragment: Fragment) = LoginDialog(
            fragment,
            LoginDialog.LoginTitle.ChangingEmail
        )
    
    }
    
    @Qualifier
    @Retention(AnnotationRetention.RUNTIME)
    annotation class LoginTitle
    
    @Qualifier
    @Retention(AnnotationRetention.RUNTIME)
    annotation class RegistrationTitle
    
    @Qualifier
    @Retention(AnnotationRetention.RUNTIME)
    annotation class ChangingEmailTitle
    

    用法

    @AndroidEntryPoint
    class MyFragment : Fragment() {
    
    
        @Inject
        @LoginTitle
        lateinit var loginDialog: LoginDialog
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-26
      • 1970-01-01
      • 2021-11-18
      • 1970-01-01
      相关资源
      最近更新 更多