FragmentPagerAdapter の getItem() で返す Fragment に次のようにログを入れました。
- class SimpleFragment : Fragment() {
- override fun onStart() {
- super.onStart()
- println("$position : onStart")
- }
- override fun onResume() {
- super.onResume()
- println("$position : onResume")
- }
- override fun onPause() {
- super.onPause()
- println("$position : onPause")
- }
- override fun onStop() {
- super.onStop()
- println("$position : onStop")
- }
- }
1. レイアウトより前のタイミング(例えば onCreate())で adapter をセットしている場合
- class MainActivity : AppCompatActivity() {
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- setContentView(R.layout.activity_main)
- viewPager.adapter = MyPager(supportFragmentManager, FragmentPagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT)
- }
- }
- System.out: 0 : onStart
- System.out: 1 : onStart
- System.out: 0 : onResume
- 1. position 0 の Fragment の onStart()
- 2. position 1 の Fragment の onStart()
- 3. position 0 の Fragment の onResume()
2. レイアウトより前のタイミング(例えば onCreate())で adapter をセットし、currentItem を変更している場合
onCreate() で ViewPager に adapter をセットした後 currentItem を 1 にしてみます。
- class MainActivity : AppCompatActivity() {
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- setContentView(R.layout.activity_main)
- viewPager.adapter = MyPager(supportFragmentManager, FragmentPagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT)
- viewPager.currentItem = 1
- }
- }
- System.out: 1 : onStart
- System.out: 0 : onStart
- System.out: 2 : onStart
- System.out: 1 : onResume
- 1. position 1 の Fragment の onStart()
- 2. position 0 の Fragment の onStart()
- 3. position 2 の Fragment の onStart()
- 4. position 1 の Fragment の onResume()
3. レイアウトより後のタイミングで adapter をセットしている場合
- class MainActivity : AppCompatActivity() {
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- setContentView(R.layout.activity_main)
- Handler().postDelayed(
- {
- viewPager.adapter = MyPager(supportFragmentManager, FragmentPagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT)
- },
- 1000
- )
- }
- }
- System.out: 0 : onStart
- System.out: 1 : onStart
- System.out: 0 : onResume
- 1. position 0 の Fragment の onStart()
- 2. position 1 の Fragment の onStart()
- 3. position 0 の Fragment の onResume()
4. レイアウトより後のタイミングで adapter をセットし、currentItem を変更している場合
onCreate() から1秒後に adapter をセットし、currentItem を 1 にしてみます。
- class MainActivity : AppCompatActivity() {
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- setContentView(R.layout.activity_main)
- Handler().postDelayed(
- {
- viewPager.adapter = MyPager(supportFragmentManager, FragmentPagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT)
- viewPager.currentItem = 1
- },
- 1000
- )
- }
- }
- System.out: 0 : onStart
- System.out: 1 : onStart
- System.out: 0 : onResume
- System.out: 2 : onStart
- System.out: 0 : onPause
- System.out: 1 : onResume
まず「3. レイアウトより後のタイミングで adapter をセットしている場合」と同じことが起こります。
つまり
- 1. position 0 の Fragment の onStart()
- 2. position 1 の Fragment の onStart()
- 3. position 0 の Fragment の onResume()
その後
- 4. position 2 の Fragment の onStart()
- 5. position 0 の Fragment の onPause()
- 6. position 1 の Fragment の onResume()
adapter をセットしたタイミングで 1 〜 3 までの流れが起こり、currentItem を 1 にしたタイミングで 4 〜 6 の流れが起こります。
このように、レイアウトよりも後のタイミングで adapter をセットすると、その時点で position 0 の Fragment を PrimaryItem として onResume() まで呼ばれてしまいます。
そのため、レイアウトよりも後のタイミングで adapter をセットして currentItem を 0 以外に変更する場合、「Fragment がユーザーに表示されたタイミングで xx したい」処理のトリガーとして onResume() を使うには注意が必要です。
adapter がセットされている間の onResume() に反応してしまうと、その後 currentItem が変更されて実際にはユーザーにはほぼ見えない Fragment でも処理が走ってしまうため、adapter がセットされている間だけフラグを立てておいて onResume() で反応しないような工夫が必要になります。
0 件のコメント:
コメントを投稿