超过三个选项卡导致 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 被销毁之前不会被销毁。
我正在使用 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 被销毁之前不会被销毁。