超过三个选项卡导致 Google 地图重新加载

More than three tabs causes Google map to reload

我正在使用 Jack Wharton 的 ViewPagerIndicator 并发现当我有四个选项卡时,我的 Google 地图将在我访问最后一个选项卡和地图选项卡后重新加载。 例如,只有 HOME |地图 | SEARCH,我可以切换到 HOME,然后切换到 MAP,或者切换到 SEARCH,然后切换到 MAP,在任何一种情况下,地图都不会加载任何内容。但是有了 HOME |地图 |搜寻 |关于,如果我选择关于,然后选择地图,整个地图都会重绘。这是一个巨大的内存泄漏。 这是我对 PagerAdapter 的实现:

public class TabsPagerAdapter extends FragmentPagerAdapter {

  private String[] titles = {"Home", "Map", "Search", "About"};

  public TabsPagerAdapter(FragmentManager fm) {
      super(fm);
  }

  @Override
  public Fragment getItem(int index) {

      switch (index) {
          case 0:
              return new HomeFragment();
          case 1:
              return new MapFragment();
          case 2:
              return new SearchListFragment();
          case 3:
              return new AboutFragment();
      }

      return null;
  }

  @Override
  public int getCount() {
      return titles.length;
  }

  @Override
  public CharSequence getPageTitle(int position) {
      return titles[position].toUpperCase();
  }
}

我已经更改了选项卡的顺序,但是当有四个选项卡时,如果我在地图之前去最后一个选项卡会导致重新加载。

标签源 TabPagerIndicator.java 有一个有趣的方法,可能是重绘地图的候选方法。

    @Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
    final boolean lockedExpanded = widthMode == MeasureSpec.EXACTLY;
    setFillViewport(lockedExpanded);

    final int childCount = mTabLayout.getChildCount();
    if (childCount > 1 && (widthMode == MeasureSpec.EXACTLY || widthMode == MeasureSpec.AT_MOST)) {
        if (childCount > 2) {
            mMaxTabWidth = (int)(MeasureSpec.getSize(widthMeasureSpec) * 0.4f);
        } else {
            mMaxTabWidth = MeasureSpec.getSize(widthMeasureSpec) / 2;
        }
    } else {
        mMaxTabWidth = -1;
    }

    final int oldWidth = getMeasuredWidth();
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    final int newWidth = getMeasuredWidth();

    if (lockedExpanded && oldWidth != newWidth) {
        // Recenter the tab display if we're at a new (scrollable) size.
        setCurrentItem(mSelectedTabIndex);
    }
}

但是我无法对此进行调试,因为 Android Studio 在定位库时遇到问题。

Warning:Unable to find module with Gradle path ':libs/tabLibrary' (needed by module 'app'.)
Linking to library 'libs/tabLibrary-unspecified' instead.

这不完全是内存泄漏。默认情况下 ViewPager 将当前页、上一页和下一页保留在内存中。它会销毁所有其他页面以优化内存。想象一下,如果 ViewPgaer 中有数百个页面,并且如果所有页面都保存在内存中,应用程序将由于 OutOfMemory 异常而崩溃 :)

但是在您的情况下,由于只有 4 个选项卡,您可以将所有 4 个选项卡保留在内存中。您可以通过设置 offScreenPageLimit

来实现
mViewPager.setOffscreenPageLimit(4);

请注意,通过这样做,ViewPager 的所有四个页面将被一次加载,并且在 activity 被销毁之前不会被销毁。