Android开发:ListView跳转至含RecyclerView的Fragment问题求助
解决Fragment无法通过Intent启动的问题
你核心的问题是错误地用Intent启动Fragment——Fragment是依赖Activity存在的组件,必须通过FragmentManager来完成加载,不能像Activity那样用startActivity启动。下面是具体的修复步骤:
步骤1:给Activity添加Fragment容器
首先确保activity_animal_habitats.xml里有一个用于承载Fragment的容器(通常用FrameLayout):
<!-- 在activity_animal_habitats.xml中添加 --> <FrameLayout android:id="@+id/fragment_container" android:layout_width="match_parent" android:layout_height="match_parent" />
步骤2:修改AnimalHabitats的点击事件逻辑
把原来用Intent启动Fragment的代码,替换成Fragment事务的代码:
class AnimalHabitats : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_animal_habitats) val itemClickListener = OnItemClickListener { listView, v, position, id -> if (position == 0) { // 创建Fragment实例 val savannaFragment = SavannaFragment() // 获取FragmentManager并开启事务 supportFragmentManager.beginTransaction() // 把Fragment替换到容器中 .replace(R.id.fragment_container, savannaFragment) // 添加到返回栈(可选,按返回键会回到ListView界面) .addToBackStack(null) // 提交事务 .commit() } } val listView = findViewById<View>(R.id.listAnimal) as ListView listView.onItemClickListener = itemClickListener } }
步骤3:优化SavannaFragment的代码(可选但推荐)
原来的Fragment代码直接把RecyclerView作为根View,虽然能运行,但更规范的写法是先加载整个Fragment布局,再从中找到RecyclerView:
class SavannaFragment : Fragment() { override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { // 先加载Fragment的布局文件 val rootView = inflater.inflate(R.layout.fragment_savanna, container, false) // 从布局中找到RecyclerView val savannaRecyclerView = rootView.findViewById<RecyclerView>(R.id.savanna_recycler_view) val savannaAnimalsName = arrayOfNulls<String>(Savanna.savannaArray.size) for (i in savannaAnimalsName.indices) { savannaAnimalsName[i] = Savanna.savannaArray[i].name } val savannaAnimalsImage = IntArray(Savanna.savannaArray.size) for (i in savannaAnimalsImage.indices) { savannaAnimalsImage[i] = Savanna.savannaArray[i].imageResourcesId } val adapter = RecyclerViewAdapter(savannaAnimalsName, savannaAnimalsImage) savannaRecyclerView.adapter = adapter val layoutManager = GridLayoutManager(activity, 2) savannaRecyclerView.layoutManager = layoutManager adapter.setListener(object : RecyclerViewAdapter.Listener { override fun onClick(position: Int) { val intent = Intent(activity, SavannaDetailActivity::class.java) intent.putExtra(SavannaDetailActivity.EXTRA_ANIMAL_ID, position) activity?.startActivity(intent) } }) return rootView } }
注意:需要确保fragment_savanna.xml里的RecyclerView id是savanna_recycler_view,和代码对应上。
关键说明
- Fragment必须依附于Activity,所以必须通过
FragmentManager的事务来添加/替换到Activity的布局容器中。 addToBackStack(null)是可选的,如果添加,用户按返回键会回到之前的ListView界面;如果不添加,返回键会直接退出Activity。- 代码中用
supportFragmentManager是因为继承的是AppCompatActivity,如果是普通Activity则用fragmentManager(API 28及以上)。
内容的提问来源于stack exchange,提问作者joj
相关产品推荐
相关产品推荐

