Reputation: 23
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
setSupportActionBar(toolbar)
Log.d("ACTIVITY MAIN", "CREATED")
setupViewPager(bottom_nav)
}
private fun setupViewPager(bottomNavigationView: BottomNavigationView) {
val viewPagerAdapter = ViewPagerAdapter(supportFragmentManager)
val trainingFragment = TrainingFragment()
val magicMileFragment = MagicMileFragment()
val tournamentFragment = TournamentFragment()
viewPagerAdapter.add(trainingFragment)
viewPagerAdapter.add(magicMileFragment)
viewPagerAdapter.add(tournamentFragment)
bottomNavigationView.setOnNavigationItemSelectedListener {
when (it.itemId) {
R.id.magicMileFragment -> {
viewpager.currentItem = 1
if(viewPagerAdapter.getItem(1).activity == null)
Log.d("NULL ACTIVITY", "NULLL")
}
R.id.trainingFragment -> {
viewpager.currentItem = 0
}
R.id.tournamentFragment -> {
viewpager.currentItem = 2
}
}
false
}
I have problem with my fragments inside bottomNavigation.setOnNavigationItemSelectedListener
with viewPagerAdapter
.
After changing an orientation this condition: if(viewPagerAdapter.getItem(1).activity == null)
is true
.
I checked that activity remain null in all fragments inside viewPagerAdapter
I didn't attach code with setting an adapter because I don't think it's relevant.
Could you explain me why it's happening?
Upvotes: 2
Views: 449
Reputation: 3894
That's because getItem
(should) always create a new instance of Fragment
and does not commit them to transaction. ViewPager
gets fragments from instantiateItem
or getItem
and commits them to transactions, and they will be attached to activity eventually.
So here's the snippet of FragmentPagerAdapter.instantiateItem
:
@Override
public Object instantiateItem(ViewGroup container, int position) {
if (mCurTransaction == null) {
mCurTransaction = mFragmentManager.beginTransaction();
}
final long itemId = getItemId(position);
// Do we already have this fragment?
String name = makeFragmentName(container.getId(), itemId);
Fragment fragment = mFragmentManager.findFragmentByTag(name);
if (fragment != null) {
if (DEBUG) Log.v(TAG, "Attaching item #" + itemId + ": f=" + fragment);
mCurTransaction.attach(fragment);
} else {
fragment = getItem(position);
if (DEBUG) Log.v(TAG, "Adding item #" + itemId + ": f=" + fragment);
mCurTransaction.add(container.getId(), fragment,
makeFragmentName(container.getId(), itemId));
}
if (fragment != mCurrentPrimaryItem) {
fragment.setMenuVisibility(false);
fragment.setUserVisibleHint(false);
}
return fragment;
}
ViewPager
calls instantiateItem
to get fragments, and within the method, it checks if the fragments exist, then return the fragments, otherwise it calls getItem
to create new instance of them.
This explains why your activity is null on getItem
. But if your getItem
does not (always) return new instance of Fragment
, then chances are your app will fail because the fragment's activity may not survive a configuration change, say a screen rotation.
Upvotes: 1