问题描述
我的应用程序由一个ViewPager
组成,其中包含相同类型的9 Fragments
。如下所示,此片段在其构造函数中采用一个参数。
NewsFragment.kt
class NewsFragment(section: NewsSection) : Fragment() {
//...
}
CategoryFragmentPagerAdapter.kt
class CategoryFragmentPagerAdapter(fm: FragmentManager)
: FragmentPagerAdapter(fm,BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {
override fun getItem(position: Int): Fragment =
NewsFragment(NewsSection.getItem(position))
override fun getCount(): Int = NewsSection.values().size
override fun getPageTitle(position: Int): CharSequence =
NewsSection.getItem(position).sectionName
}
此片段包含一些应将用户导航到其他片段的操作。
我尝试使用Jetpack Navigation Component
方法来实现导航,但是由于导航图无法接受带有参数的片段,因此看起来它会出错。
在这种情况下如何实施Navigation
的任何想法?
编辑
这是我在活动FragmentContainerView
中的XML layout
<androidx.fragment.app.FragmentContainerView
android:id="@+id/fragment_container"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="@navigation/navigation" />
这就是我在活动中实现navController
的方式
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setupDataBinding()
val navHostFragment = supportFragmentManager.findFragmentById(R.id.fragment_container) as NavHostFragment
val navController = navHostFragment.navController
}
我没有添加任何其他配置,这是运行应用程序时弹出的error
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.domain.news/com.domain.news.ui.activities.MainActivity}: android.view.InflateException: Binary XML file line #18 in com.domain.news:layout/activity_main: Binary XML file line #22 in com.domain.news:layout/content_main: Error inflating class androidx.fragment.app.FragmentContainerView
at android.app.ActivityThread.performlaunchActivity(ActivityThread.java:3307)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3446)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2043)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:224)
at android.app.ActivityThread.main(ActivityThread.java:7548)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:539)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950)
Caused by: android.view.InflateException: Binary XML file line #18 in com.domain.news:layout/activity_main: Binary XML file line #22 in com.domain.news:layout/content_main: Error inflating class androidx.fragment.app.FragmentContainerView
Caused by: android.view.InflateException: Binary XML file line #22 in com.domain.news:layout/content_main: Error inflating class androidx.fragment.app.FragmentContainerView
Caused by: androidx.fragment.app.Fragment$InstantiationException: Unable to instantiate fragment com.domain.news.ui.fragments.news.NewsFragment: Could not find Fragment constructor
at androidx.fragment.app.Fragment.instantiate(Fragment.java:563)
at androidx.fragment.app.FragmentContainer.instantiate(FragmentContainer.java:57)
at androidx.fragment.app.FragmentManager$3.instantiate(FragmentManager.java:390)
at androidx.navigation.fragment.FragmentNavigator.instantiateFragment(FragmentNavigator.java:132)
at androidx.navigation.fragment.FragmentNavigator.navigate(FragmentNavigator.java:162)
at androidx.navigation.fragment.FragmentNavigator.navigate(FragmentNavigator.java:58)
at androidx.navigation.NavGraphNavigator.navigate(NavGraphNavigator.java:71)
at androidx.navigation.NavGraphNavigator.navigate(NavGraphNavigator.java:28)
at androidx.navigation.NavController.navigate(NavController.java:1049)
at androidx.navigation.NavController.onGraphCreated(NavController.java:633)
at androidx.navigation.NavController.setGraph(NavController.java:586)
at androidx.navigation.NavController.setGraph(NavController.java:551)
at androidx.navigation.NavController.setGraph(NavController.java:533)
at androidx.navigation.fragment.NavHostFragment.onCreate(NavHostFragment.java:238)
at androidx.fragment.app.Fragment.performCreate(Fragment.java:2684)
at androidx.fragment.app.FragmentStateManager.create(FragmentStateManager.java:280)
at androidx.fragment.app.FragmentManager.movetoState(FragmentManager.java:1175)
at androidx.fragment.app.FragmentManager.addAddedFragments(FragmentManager.java:2224)
at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:1997)
at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:1953)
at androidx.fragment.app.FragmentManager.execSingleAction(FragmentManager.java:1818)
at androidx.fragment.app.BackStackRecord.commitNowAllowingStateLoss(BackStackRecord.java:303)
at androidx.fragment.app.FragmentContainerView.<init>(FragmentContainerView.java:166)
at androidx.fragment.app.FragmentLayoutInflaterFactory.onCreateView(FragmentLayoutInflaterFactory.java:51)
2020-09-19 20:39:22.012 16179-16179/com.domain.news E/AndroidRuntime: at androidx.fragment.app.FragmentController.onCreateView(FragmentController.java:135)
at androidx.fragment.app.FragmentActivity.dispatchFragmentsOnCreateView(FragmentActivity.java:356)
at androidx.fragment.app.FragmentActivity.onCreateView(FragmentActivity.java:335)
at android.view.LayoutInflater.tryCreateView(LayoutInflater.java:1073)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:1001)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:965)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:1127)
at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:1088)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:1130)
at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:1088)
at android.view.LayoutInflater.parseInclude(LayoutInflater.java:1267)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:1123)
at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:1088)
at android.view.LayoutInflater.parseInclude(LayoutInflater.java:1267)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:1123)
at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:1088)
at android.view.LayoutInflater.inflate(LayoutInflater.java:686)
at android.view.LayoutInflater.inflate(LayoutInflater.java:538)
at android.view.LayoutInflater.inflate(LayoutInflater.java:481)
at androidx.appcompat.app.AppCompatDelegateImpl.setContentView(AppCompatDelegateImpl.java:696)
at androidx.appcompat.app.AppCompatActivity.setContentView(AppCompatActivity.java:170)
at androidx.databinding.DataBindingUtil.setContentView(DataBindingUtil.java:303)
at androidx.databinding.DataBindingUtil.setContentView(DataBindingUtil.java:284)
at com.domain.news.utils.delegates.ActivityBindingProperty.createActivityBinding(Databinding.kt:20)
at com.domain.news.utils.delegates.ActivityBindingProperty.getValue(Databinding.kt:16)
at com.domain.news.ui.activities.MainActivity.getBinding(UnkNown Source:10)
at com.domain.news.ui.activities.MainActivity.setupBinding(MainActivity.kt:42)
at com.domain.news.ui.activities.MainActivity.onCreate(MainActivity.kt:34)
at android.app.Activity.performCreate(Activity.java:7893)
at android.app.Activity.performCreate(Activity.java:7880)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1307)
at android.app.ActivityThread.performlaunchActivity(ActivityThread.java:3282)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3446)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2043)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:224)
at android.app.ActivityThread.main(ActivityThread.java:7548)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:539)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950)
Caused by: java.lang.NoSuchMethodException: com.domain.news.ui.fragments.news.NewsFragment.<init> []
at java.lang.class.getConstructor0(Class.java:2332)
at java.lang.class.getConstructor(Class.java:1728)
at androidx.fragment.app.Fragment.instantiate(Fragment.java:548)
... 66 more
最后三行显示原因是片段构造器
解决方法
首先,打开您的
app:navGraph="@navigation/navigation
错误明确指出,该错误无法使您的XMl膨胀((可能是@ navigation / navigation XML文件的第18行中的某处)
您需要在片段的参数束中而不是在构造函数中传递数据。
为此,NewsSection
需要实现Parcelable
在导航xml中,您可以执行以下操作:
<fragment
android:id="@+id/newsFragment"
android:name="com.example.NewsFragment"
android:label="ProductListerFragment"
tools:layout="@layout/fragment_news_secion">
<argument
android:name="newsSection"
app:argType="com.example.NewsSection" />
在片段中,您要从以下位置导航:
val newsSection = NewsSection(....)
val bundle = bundleOf("newsSection" to newsSection)
view.findNavController().navigate(R.id.newsAction,bundle)
在NewsFragment
中:
val newsSection = arguments?.getParcelable("newsSection") as? NewsSection
有关更多详细信息,请参见https://developer.android.com/guide/navigation/navigation-pass-data。