現象:ViewPager 滑動正常,但點擊 RadioButton 切換後,滑動失效。原因是在點擊事件中直接操作 ViewPager,卻未將 Fragment 正確加入 Adapter,導致狀態不同步。
| 錯誤做法 | 正確做法 |
|---|---|
| 在 RadioButton `OnClickListener` 中手動 `viewPager.setCurrentItem()`,且每個 Case 都 `new Fragment()` | 所有 Fragment 預先加入 Adapter,RadioGroup 只負責 `setCurrentItem`,ViewPager 滑動監聽器回寫 RadioButton 狀態 |
class MainActivity : AppCompatActivity() {
private lateinit var viewPager: ViewPager
private lateinit var radioGroup: RadioGroup
private val fragments = listOf(HomeFragment(), FindFragment(), MineFragment())
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
viewPager = findViewById(R.id.viewPager)
radioGroup = findViewById(R.id.radioGroup)
// 1. Adapter 裝載所有 Fragment
viewPager.adapter = object : FragmentStateAdapter(this) {
override fun getItemCount() = fragments.size
override fun createFragment(position: Int) = fragments[position]
}
// 2. RadioGroup 點擊 -> ViewPager
radioGroup.setOnCheckedChangeListener { _, checkedId ->
val index = when (checkedId) {
R.id.rb_home -> 0
R.id.rb_find -> 1
R.id.rb_mine -> 2
else -> 0
}
viewPager.currentItem = index
}
// 3. ViewPager 滑動 -> RadioGroup 同步
viewPager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
override fun onPageSelected(position: Int) {
radioGroup.check(radioGroup.getChildAt(position).id)
}
})
}
}
FragmentStateAdapter(ViewPager2)或 FragmentPagerAdapter(舊版),避免記憶體洩漏。遵循此模式,滑動與點擊雙向同步,不再出現「點擊後滑動失效」問題。