viewPagerAdapter.getItem возвращает фрагмент, активность которого равна нулю - PullRequest
0 голосов
/ 05 ноября 2018
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
    }

У меня проблема с моими фрагментами внутри bottomNavigation.setOnNavigationItemSelectedListener с viewPagerAdapter. После изменения ориентации это условие: if(viewPagerAdapter.getItem(1).activity == null) равно true. Я проверил, что активность остается нулевой во всех фрагментах внутри viewPagerAdapter Я не прикреплял код с настройкой адаптера, потому что не думаю, что это актуально. Не могли бы вы объяснить, почему это происходит?

1 Ответ

0 голосов
/ 05 ноября 2018

Это потому, что getItem ( должен ) всегда создает новый экземпляр Fragment и не фиксирует их в транзакции. ViewPager получает фрагменты из instantiateItem или getItem и фиксирует их в транзакциях, и в конечном итоге они будут присоединены к действию.

Итак, вот фрагмент 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 вызывает instantiateItem для получения фрагментов, и в рамках метода он проверяет, существуют ли фрагменты, а затем возвращает фрагменты, в противном случае он вызывает getItem, чтобы создать их новый экземпляр.

Это объясняет, почему ваша активность равна нулю getItem. Но если ваш getItem не ( всегда ) возвращает новый экземпляр Fragment, то, скорее всего, ваше приложение не будет работать, поскольку активность фрагмента может не пережить изменение конфигурации, например поворот экрана.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...