MapView/SupportMapFragment 使用 ViewPager2 时出现图形故障
MapView/SupportMapFragment graphic glitch while using ViewPager2
我一直在尝试在 ViewPager 片段中使用 MapView,但遇到了一个奇怪的错误。 MapView 一直出现故障,就像它试图重新渲染和奇怪地拉伸地图一样;但是,在使用 zoom/gestures 时没问题。它停止移动的那一刻,它又开始出现故障。
在 Nexus 7 SDK 22 模拟器上它工作正常,而在大多数其他 emulators/physical 设备上似乎失败。看来这是硬件问题而不是 SDK 问题。
我还尝试将 SupportMapFragment 放入 ViewPager 中,它的行为方式完全相同。
在清单中禁用硬件加速会减少问题,但不会消除它。国家名称不断闪烁,整个屏幕每隔几秒就有一次黑色闪烁,而不是在没有硬件加速解决方案的情况下发生的 stretchy/glitchy 错误。
MapViewFragment
public class RealisedVisitsMapFragment extends Fragment implements OnMapReadyCallback {
private FragmentRealisationVisitsMapBinding binding;
public static RealisedVisitsMapFragment newInstance(LocalDate date) {
RealisedVisitsMapFragment fragment = new RealisedVisitsMapFragment();
return fragment;
}
private static final String MAPVIEW_BUNDLE_KEY = "MapViewBundleKey";
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
binding = FragmentRealisationVisitsMapBinding.inflate(inflater);
return binding.getRoot();
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
Bundle mapViewBundle = null;
if (savedInstanceState != null) {
mapViewBundle = savedInstanceState.getBundle(MAPVIEW_BUNDLE_KEY);
}
binding.mapView.onCreate(mapViewBundle);
binding.mapView.getMapAsync(this);
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
Bundle mapViewBundle = outState.getBundle(MAPVIEW_BUNDLE_KEY);
if (mapViewBundle == null) {
mapViewBundle = new Bundle();
outState.putBundle(MAPVIEW_BUNDLE_KEY, mapViewBundle);
}
binding.mapView.onSaveInstanceState(mapViewBundle);
}
@Override
public void onResume() {
super.onResume();
binding.mapView.onResume();
}
@Override
public void onStart() {
super.onStart();
binding.mapView.onStart();
}
@Override
public void onStop() {
super.onStop();
binding.mapView.onStop();
}
@Override
public void onMapReady(GoogleMap map) {
map.addMarker(new MarkerOptions().position(new LatLng(0, 0)).title("Marker"));
}
@Override
public void onPause() {
binding.mapView.onPause();
super.onPause();
}
@Override
public void onDestroy() {
binding.mapView.onDestroy();
super.onDestroy();
}
@Override
public void onLowMemory() {
super.onLowMemory();
binding.mapView.onLowMemory();
}
}
PagerAdapter
public class VisitsFragmentAdapter extends FragmentStateAdapter {
public VisitsFragmentAdapter(@NonNull FragmentManager fragmentManager, @NonNull Lifecycle lifecycle) {
super(fragmentManager, lifecycle);
}
public VisitsFragmentAdapter(@NonNull Fragment fragment) {
super(fragment);
}
@NonNull
@Override
public Fragment createFragment(int position) {
switch (position) {
case 0:
return SupportMapFragment.newInstance();
case 1:
return new RealisedVisitsMapFragment();
default:
return null;
}
}
@Override
public int getItemCount() {
return 2;
}
}
用于设置 viewpager 的托管片段函数
private void setupViewPager() {
VisitsFragmentAdapter pagerAdapter = new VisitsFragmentAdapter(getChildFragmentManager(), getLifecycle());
binding.vpVisitsRealization.setUserInputEnabled(false);
binding.vpVisitsRealization.setAdapter(pagerAdapter);
binding.vpVisitsRealization.requestTransparentRegion(binding.vpVisitsRealization);
new TabLayoutMediator(binding.tabLayoutRealization, binding.vpVisitsRealization, (this::setTextByPosition)).attach();
}
Visual Glitch 1
Visual glitch 2
已通过完全删除 viewpager 并手动扩充片段来解决。
我一直在尝试在 ViewPager 片段中使用 MapView,但遇到了一个奇怪的错误。 MapView 一直出现故障,就像它试图重新渲染和奇怪地拉伸地图一样;但是,在使用 zoom/gestures 时没问题。它停止移动的那一刻,它又开始出现故障。 在 Nexus 7 SDK 22 模拟器上它工作正常,而在大多数其他 emulators/physical 设备上似乎失败。看来这是硬件问题而不是 SDK 问题。 我还尝试将 SupportMapFragment 放入 ViewPager 中,它的行为方式完全相同。 在清单中禁用硬件加速会减少问题,但不会消除它。国家名称不断闪烁,整个屏幕每隔几秒就有一次黑色闪烁,而不是在没有硬件加速解决方案的情况下发生的 stretchy/glitchy 错误。
MapViewFragment
public class RealisedVisitsMapFragment extends Fragment implements OnMapReadyCallback {
private FragmentRealisationVisitsMapBinding binding;
public static RealisedVisitsMapFragment newInstance(LocalDate date) {
RealisedVisitsMapFragment fragment = new RealisedVisitsMapFragment();
return fragment;
}
private static final String MAPVIEW_BUNDLE_KEY = "MapViewBundleKey";
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
binding = FragmentRealisationVisitsMapBinding.inflate(inflater);
return binding.getRoot();
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
Bundle mapViewBundle = null;
if (savedInstanceState != null) {
mapViewBundle = savedInstanceState.getBundle(MAPVIEW_BUNDLE_KEY);
}
binding.mapView.onCreate(mapViewBundle);
binding.mapView.getMapAsync(this);
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
Bundle mapViewBundle = outState.getBundle(MAPVIEW_BUNDLE_KEY);
if (mapViewBundle == null) {
mapViewBundle = new Bundle();
outState.putBundle(MAPVIEW_BUNDLE_KEY, mapViewBundle);
}
binding.mapView.onSaveInstanceState(mapViewBundle);
}
@Override
public void onResume() {
super.onResume();
binding.mapView.onResume();
}
@Override
public void onStart() {
super.onStart();
binding.mapView.onStart();
}
@Override
public void onStop() {
super.onStop();
binding.mapView.onStop();
}
@Override
public void onMapReady(GoogleMap map) {
map.addMarker(new MarkerOptions().position(new LatLng(0, 0)).title("Marker"));
}
@Override
public void onPause() {
binding.mapView.onPause();
super.onPause();
}
@Override
public void onDestroy() {
binding.mapView.onDestroy();
super.onDestroy();
}
@Override
public void onLowMemory() {
super.onLowMemory();
binding.mapView.onLowMemory();
}
}
PagerAdapter
public class VisitsFragmentAdapter extends FragmentStateAdapter {
public VisitsFragmentAdapter(@NonNull FragmentManager fragmentManager, @NonNull Lifecycle lifecycle) {
super(fragmentManager, lifecycle);
}
public VisitsFragmentAdapter(@NonNull Fragment fragment) {
super(fragment);
}
@NonNull
@Override
public Fragment createFragment(int position) {
switch (position) {
case 0:
return SupportMapFragment.newInstance();
case 1:
return new RealisedVisitsMapFragment();
default:
return null;
}
}
@Override
public int getItemCount() {
return 2;
}
}
用于设置 viewpager 的托管片段函数
private void setupViewPager() {
VisitsFragmentAdapter pagerAdapter = new VisitsFragmentAdapter(getChildFragmentManager(), getLifecycle());
binding.vpVisitsRealization.setUserInputEnabled(false);
binding.vpVisitsRealization.setAdapter(pagerAdapter);
binding.vpVisitsRealization.requestTransparentRegion(binding.vpVisitsRealization);
new TabLayoutMediator(binding.tabLayoutRealization, binding.vpVisitsRealization, (this::setTextByPosition)).attach();
}
Visual Glitch 1 Visual glitch 2
已通过完全删除 viewpager 并手动扩充片段来解决。