android - viewPagerAdapter.getItem 返回 Activity 为空的 fragment

标签 android kotlin

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.setOnNavigationItemSelectedListenerviewPagerAdapter 中的 fragment 有问题。 更改方向后,此条件:if(viewPagerAdapter.getItem(1).activity == null)true。 我检查了 viewPagerAdapter 内的所有 fragment 中的 Activity 是否保持为空 我没有在设置适配器时附加代码,因为我认为它不相关。 你能解释一下为什么会这样吗?

最佳答案

那是因为 getItem(应该)总是创建一个新的 Fragment 实例并且不将它们提交给事务。 ViewPagerinstantiateItemgetItem 中获取 fragment 并将它们提交到事务中,最终它们将附加到 Activity 中。

下面是 FragmentPagerAdapter.instantiateItem 的 fragment :

@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 获取 fragment ,方法内检查 fragment 是否存在,返回 fragment ,否则调用getItem 创建它们的新实例。

这解释了为什么您的 Activity 在 getItem 上为空。但是,如果您的 getItem 不(总是)返回 Fragment 的新实例,那么您的应用很可能会失败,因为 fragment 的 Activity 可能无法存活配置更改,比如屏幕旋转。

关于android - viewPagerAdapter.getItem 返回 Activity 为空的 fragment ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53161317/

相关文章:

java - kotlin协程可以像java Timer一样使用吗?

android - 键盘打开时动 Canvas 局调整大小

Android L(5.0)在eclipse中不搜索 “armeabi”或 "armeabi-v7a"文件夹(UnsatisfiedLinkError)中的原生库

java - 在 Kotlin 中使用 setter 实现 Java getter 接口(interface)

更新到 Kotlin 1.4 后,Android Gradle 构建失败 dexBuilderDebug 任务

android - Dagger 2 没有注入(inject) sharedPreference

java - 在 Android 项目中处理 AWS 凭证的正确方法是什么?

android - 如何android Z顺序?

android - 如何使用 google map api v2 在建筑物或特定地点周围创建折线/多边形?

android - 可选双人房