使用 ViewPager2 时 MapView/SupportMapFragment 图形故障

Posted

技术标签:

【中文标题】使用 ViewPager2 时 MapView/SupportMapFragment 图形故障【英文标题】:MapView/SupportMapFragment graphic glitch while using ViewPager2 【发布时间】:2020-06-15 20:15:53 【问题描述】:

我一直在尝试在 ViewPager 片段中使用 MapView,但遇到了一个奇怪的错误。 MapView 不断出现故障,就像它试图重新渲染和奇怪地拉伸地图一样;但是,在使用缩放/手势时,这很好。在它停止移动的那一刻,它又开始出现故障。 在 Nexus 7 SDK 22 模拟器上它工作正常,而在大多数其他模拟器/物理设备上似乎都失败了。看来这是硬件问题而不是 SDK 问题。 我还尝试在 ViewPager 中放置一个 SupportMapFragment,它的行为方式完全相同。 在清单中禁用硬件加速可以减少问题,但并不能消除它。国家名称不断闪烁,整个屏幕每隔几秒就会出现一次黑色闪烁,而不是在没有硬件加速解决方法的情况下发生的弹性/故障错误。

地图视图片段

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

【问题讨论】:

【参考方案1】:

通过完全移除 viewpager 并手动填充片段来解决。

【讨论】:

以上是关于使用 ViewPager2 时 MapView/SupportMapFragment 图形故障的主要内容,如果未能解决你的问题,请参考以下文章

ViewPager2 中的片段在返回父片段时被重新创建

以编程方式滑动时更改 ViewPager2 滚动速度

修改子项时 ViewPager2 转到第一页

ViewPager2 中未显示图像(片段重新打开时)

ViewPager2 崩溃

焦点在 EditText 上时 ViewPager2 片段内容消失