ViewPager加载ViewNotesFragment失败,提示找不到视图ID求助
问题:ViewPager加载Fragment时出现视图ID找不到的致命异常
致命异常信息
FATAL EXCEPTION: main Process: io.lionpswn.kodular.notepad, PID: 24071 java.lang.IllegalArgumentException: No view found for id 0x7f08021a (io.lionpswn.kodular.notepad:id/viewPager) for fragment ViewToDo{df73341} (911e855d-2d18-427e-b76e-f31ad6ae5083 id=0x7f08021a tag=android:switcher:2131231258:1) at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:547) at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:272) at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:1943) at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:1839) at androidx.fragment.app.FragmentManager.execSingleAction(FragmentManager.java:1751) at androidx.fragment.app.BackStackRecord.commitNowAllowingStateLoss(BackStackRecord.java:323) at androidx.fragment.app.FragmentPagerAdapter.finishUpdate(FragmentPagerAdapter.java:249) at androidx.viewpager.widget.ViewPager.populate(ViewPager.java:1244) at androidx.viewpager.widget.ViewPager.populate(ViewPager.java:1092) at androidx.viewpager.widget.ViewPager.onMeasure(ViewPager.java:1622) at android.view.View.measure(View.java:26010) at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:7105) at androidx.coordinatorlayout.widget.CoordinatorLayout.onMeasureChild(CoordinatorLayout.java:760) at androidx.coordinatorlayout.widget.CoordinatorLayout.onMeasure(CoordinatorLayout.java:833) at android.view.View.measure(View.java:26010) at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:7105) at android.widget.FrameLayout.onMeasure(FrameLayout.java:194) at androidx.appcompat.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:145) at android.view.View.measure(View.java:26010) at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:7105) at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1552) at android.widget.LinearLayout.measureVertical(LinearLayout.java:842) at android.widget.LinearLayout.onMeasure(LinearLayout.java:721) at android.view.View.measure(View.java:26010) at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:7105) at android.widget.FrameLayout.onMeasure(FrameLayout.java:194) at android.view.View.measure(View.java:26010) at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:7105) at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1552) at android.widget.LinearLayout.measureVertical(LinearLayout.java:842) at android.widget.LinearLayout.onMeasure(LinearLayout.java:721) at android.view.View.measure(View.java:26010) at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:7105) at android.widget.FrameLayout.onMeasure(FrameLayout.java:194) at com.android.internal.policy.DecorView.onMeasure(DecorView.java:767) at android.view.View.measure(View.java:26010) at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:3629) at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:2407) at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2673) at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:2129) at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:8625) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1034) at android.view.Choreographer.doCallbacks(Choreographer.java:858) at android.view.Choreographer.doFrame(Choreographer.java:789) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1019) at android.os.Handler.handleCallback(Handler.java:938) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:236) at android.app.ActivityThread.main(ActivityThread.java:7912) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:620) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1011)
问题描述
使用ViewPager加载ViewNotesFragment时,运行时无法正确填充布局,抛出上述异常。其他空白Fragment可正常加载,但ViewNotesFragment不行,布局文件本身无误,却提示找不到视图ID。
相关代码
ViewPagerAdapter
package io.lionpswn.kodular.notepad import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentManager import androidx.fragment.app.FragmentPagerAdapter import androidx.viewpager.widget.PagerAdapter import io.lionpswn.kodular.notepad.presenter.viewNotes.ViewNotes class PagerAdapter(val fm: FragmentManager) : FragmentPagerAdapter(fm) { override fun getItem(position: Int): Fragment{ return when(position){ 0 -> addToDo() 1 -> ViewToDo() else -> ViewToDo() } } override fun getCount(): Int { return 2 } override fun getPageTitle(position: Int): CharSequence? { return when(position){ 0 -> "ViewNotes()1" 1 -> "ViewToDo()2" else -> "ViewToDo()3" } } }
ViewNotes Fragment
package io.lionpswn.kodular.notepad.presenter.viewNotes import android.os.Bundle import android.util.Log import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.databinding.DataBindingUtil import androidx.fragment.app.Fragment import androidx.fragment.app.viewModels import androidx.recyclerview.widget.LinearLayoutManager import dagger.hilt.android.AndroidEntryPoint import io.lionpswn.kodular.notepad.R import io.lionpswn.kodular.notepad.databinding.FragmentViewnotesBinding import io.lionpswn.kodular.notepad.domain.model.Note @AndroidEntryPoint class ViewNotes : Fragment() { var isAdNotShown:Boolean=true val viewModel: ViewNotesViewModel by viewModels() override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { val binding: FragmentViewnotesBinding =DataBindingUtil.setContentView(this.requireActivity(), R.layout.fragment_viewnotes) var context=this val recyclerView=binding.recyclerview var list:List<Note> = mutableListOf() viewModel.onEvent(event.loadAd(this.requireContext(), binding.adView)) var adapter = RecyclerViewAdapter(list) recyclerView.setHasFixedSize(true) recyclerView.adapter = adapter recyclerView.layoutManager = LinearLayoutManager(this.requireContext()) viewModel.list.observe(viewLifecycleOwner,{ Log.d("check",it.toString()) list=it var adapter = RecyclerViewAdapter(list) recyclerView.adapter = adapter adapter.notifyDataSetChanged() }) binding.fab.setOnClickListener { viewModel.onEvent(event.newNoteFab(this.requireContext())) } return binding.root }}
解决方案
核心问题
ViewNotes的onCreateView中错误使用了DataBindingUtil.setContentView,这个方法是用来给Activity设置整个内容视图的,调用它会把Fragment的布局直接替换掉Activity原本包含ViewPager的布局,导致FragmentManager找不到ViewPager的ID,从而抛出异常。
修复代码
将ViewNotes中布局绑定的代码替换为DataBindingUtil.inflate,这是Fragment中正确的布局填充方式:
override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { // 替换原来的setContentView为inflate val binding: FragmentViewnotesBinding = DataBindingUtil.inflate( inflater, R.layout.fragment_viewnotes, container, false // 不要直接附加到container,ViewPager会负责添加 ) // 剩余代码保持不变 val recyclerView=binding.recyclerview var list:List<Note> = mutableListOf() viewModel.onEvent(event.loadAd(this.requireContext(), binding.adView)) var adapter = RecyclerViewAdapter(list) recyclerView.setHasFixedSize(true) recyclerView.adapter = adapter recyclerView.layoutManager = LinearLayoutManager(this.requireContext()) viewModel.list.observe(viewLifecycleOwner,{ Log.d("check",it.toString()) list=it var adapter = RecyclerViewAdapter(list) recyclerView.adapter = adapter adapter.notifyDataSetChanged() }) binding.fab.setOnClickListener { viewModel.onEvent(event.newNoteFab(this.requireContext())) } return binding.root }
额外优化建议
- 数据更新时不需要每次创建新的
RecyclerViewAdapter,可以在Adapter中添加更新数据的方法,避免不必要的对象创建:
// 在RecyclerViewAdapter中添加方法 fun updateData(newList: List<Note>) { this.list = newList notifyDataSetChanged() } // 在Fragment的观察者中调用 viewModel.list.observe(viewLifecycleOwner,{ Log.d("check",it.toString()) adapter.updateData(it) })
var context=this可以直接用requireContext()代替,无需额外声明。
内容的提问来源于stack exchange,提问作者jiji solaman
相关产品推荐
相关产品推荐

