Ошибка переполнения стека при попытке связать navGraph с NavHostFragment при использовании навигации, фабрики фрагментов и Dagger 2? - PullRequest
0 голосов
/ 12 марта 2020
class FragmentProviderFactory @Inject constructor(
    private val providers: Map<Class<out Fragment>, @JvmSuppressWildcards Provider<Fragment>>
) : FragmentFactory() {

    override fun instantiate(classLoader: ClassLoader, className: String): Fragment {
        val fragmentClass = loadFragmentClass(classLoader, className)

        val provider = providers[fragmentClass] ?:
            providers.asIterable().firstOrNull(){
                fragmentClass.isAssignableFrom(it.key)
            }?.value ?: throw IllegalArgumentException("unknown fragment class $fragmentClass")
        return try {
            provider.get()
        } catch (e: Exception) {
            throw RuntimeException(e)
        }
    }
}

@Module
abstract class MainFragmentModule {

    @MainScope
    @Binds
    @IntoMap
    @FragmentKey(NotificationFragment::class)
    abstract fun provideNotificationFragment(fragment: NotificationFragment): Fragment

    @MainScope
    @Binds
    abstract fun bindFragmentProviderFactory(
        fragmentProviderFactory: FragmentProviderFactory
    ): FragmentFactory
}

@MainScope
@Subcomponent(
    modules = [MainModule::class, MainFragmentModule::class, MainViewModelModule::class]
)
interface MainComponent {
    fun inject(activity: MainActivity)
}

class MainActivity : AppCompatActivity() {

    @Inject lateinit var fragmentProviderFactory: FragmentProviderFactory

    override fun onCreate(savedInstanceState: Bundle?) {
        (applicationContext as MyApplication).appComponent.mainComponent().inject(this)
        supportFragmentManager.fragmentFactory = fragmentProviderFactory
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }
}

class NotificationFragment @Inject
                constructor(provider: Provider<MainViewModel>,
                            private val fragmentFactory: FragmentProviderFactory): NavHostFragment() {

    private val mainViewModel: MainViewModel by activityViewModelWithProvider {
        provider.get()
    }

    private val DIALOG_FRAGMENT = 1

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        // Inflate the layout for this fragment
            val view = inflater.inflate(R.layout.fragment_notification, container, false)
        return view.rootView
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        btn_start.setOnClickListener{
            val action = NotificationFragmentDirections.actionNotificationFragmentToNotificationDialogFragment()
            navController.navigate(action)
        }
    }
}

Теперь этот код выше работает для рендеринга фактического фрагмента NotificationFragment, но когда я пытаюсь перейти с действием в OnClickListener моего btn, текущий узел навигации отсутствует. Я уверен, что мне нужно связать навигационный график с этим NavHostFragment. Моя XML для MainActivity выглядит следующим образом:

<fragment
        android:id="@+id/nav_host_fragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:name="com.gcgsauce.notify.ui.NotificationFragment"/>

Если я попытаюсь добавить (app: defaultNavHost = "true" и app: navGraph = "@ navigation / nav_main") к этому, я буду получить ошибку переполнения стека. Если я пытаюсь добавить его в фактический фрагмент NotificationFragment (который расширяет NavHostFragment):

 override fun onCreateNavController(navController: NavController) {
        super.onCreateNavController(navController)
        navController.graph = (navController.navInflater).inflate(R.navigation.nav_main)
    }

, я получаю ту же ошибку (также пытался установить график в OnViewCreated). Подробности ошибки StackOverflow следующие:

There is some kind of infinite loop when checking for menus and isMenuAvailable when associating a NavGraph

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...