带有片段的TabBar活动 - 滑动和制表符之间的片段生命周期不同

时间:2016-02-20 12:04:05

标签: android android-fragments android-viewpager android-tabs fragmentmanager

我最近对我的代码进行了重构,以便使用工具栏 TabLayout TabLayout Tab < / strong> this tutorial之后的对象。主要结构(滑动和标签)完美地工作,因为我能够像我期待的那样在它们之间移动。

在片段之间移动时,我使用 setUserVisibleHint 方法检查片段是否可见,以及使用来自Web服务的新数据更新UI。

最近我收到了一些客户的错误报告,他们抱怨在点击Tab元素时没有显示新数据的碎片,而在使用滑动时,一切都按预期工作。

做了一些研究我发现了:

  

ViewPager 实际上一次加载三个片段,调用 onResume()。它加载了它的两个邻居的可见片段(左边的那个和右边的一个。它是片段之间流畅滑动所需要的。

我已经通过在我的片段中调用 onCreateView onResume 时记录一行来确认这一点。

如果我滑动一切按预期工作,因为碎片按顺序加载,但如果我通过点击它们(例如从位置中的标签)在远距离标签(距离大于1)之间跳转0到位置4中的选项卡)后者片段默认情况下未加载 ViewPager ,因此需要再次加载(在这种情况下,位置4中的片段)。

我已经解决了创建 viewPagerAdapter 后立即添加此说明的问题:

viewPager.setOffscreenPageLimit(viewPagerAdapter.getCount());

基本上我强迫适配器加载所有片段。我不相信这一点,因为我认为这可能会导致性能问题。

我读过this SO question这看起来很有趣,但我也发现问题可能是我每次在ViewPagerAdapter的getItem()方法中创建一个新的Fragment实例时都会创建。 其他人建议在片段的onCreateView中使用setRetainInstance(true)。

我发现情况有点令人困惑,我不知道是否继续上述修复或实施其中一条建议。

下面是TabBarActivity中Tab制作和ViewPager的代码。

在TabBarActivity的 onCreate()方法中调用

setApplicationContentView()

private void setApplicationContentView() {

    setContentView(R.layout.activity_tab_bar);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    tabLayout = (TabLayout) findViewById(R.id.tabs);
    viewPager = (ViewPager) findViewById(R.id.pager);

    setSupportActionBar(toolbar);

    if (getSupportActionBar() != null) {
        getSupportActionBar().setDisplayHomeAsUpEnabled(false);
    }

    final ViewPagerAdapter viewPagerAdapter = new ViewPagerAdapter(getSupportFragmentManager(), TabBarActivity.this);
    viewPager.setAdapter(viewPagerAdapter);
    // Temp fix for fragments loading issue
    viewPager.setOffscreenPageLimit(viewPagerAdapter.getCount());
    tabLayout.setupWithViewPager(viewPager);

    // Custom tab layout
    setCustomTabLayout(0, R.raw.home);
    setCustomTabLayout(1, R.raw.map_location);
    setCustomTabLayout(2, R.raw.calendar);
    setCustomTabLayout(3, R.raw.warning);
    setCustomTabLayout(4, R.raw.tags);
}

ViewPagerAdapter

class ViewPagerAdapter extends FragmentPagerAdapter {

    private TabBarActivity tabBarActivity;

    public ViewPagerAdapter(FragmentManager manager, TabBarActivity tabBarActivity) {
        super(manager);
        this.tabBarActivity = tabBarActivity;
    }

    @Override
    public Fragment getItem(int position) {

        switch (position) {

            case 0:
                homeFragment = HomeFragment.newInstance(tabBarActivity);
                return homeFragment;
            case 1:
                mapFragment = MapFragment.newInstance(tabBarActivity);
                return mapFragment;
            case 2:
                calendarFragment = CalendarFragment.newInstance(tabBarActivity);
                return calendarFragment;
            case 3:
                warningsFragment = WarningsFragment.newInstance(tabBarActivity);
                return warningsFragment;
            case 4:
                assignedFragment = AssignedFragment.newInstance(tabBarActivity);
                return assignedFragment;
            default:
                return null;
        }
    }

    @Override
    public int getCount() {

        return MPConstants.NUM_OF_FRAGMENTS;
    }

    @Override
    public CharSequence getPageTitle(int position) {

        Locale currentLocale = Locale.getDefault();

        switch (position) {

            case 0:
                return getString(R.string.title_fragment_home).toUpperCase(currentLocale);
            case 1:
                return getString(R.string.title_fragment_map).toUpperCase(currentLocale);
            case 2:
                return getString(R.string.title_fragment_event_list).toUpperCase(currentLocale);
            case 3:
                return getString(R.string.title_fragment_warnings).toUpperCase(currentLocale);
            case 4:
                return getString(R.string.title_fragment_assigned).toUpperCase(currentLocale);
            default:
                return null;
        }
    }
}

提前致谢!

0 个答案:

没有答案