You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ViewPager切换卡顿及ProfileFragment中Google Maps加载优化问题

Hey, let's fix those two issues you're facing with ViewPager and Google Maps step by step!

1. Stop Preloading Unneeded Fragments When Tabs Are Clicked

First, let's address the root of your preloading problem: your current setup creates all 5 Fragment instances upfront and adds them to the adapter immediately. This forces ViewPager to initialize them early, even if they're not visible. Plus, ViewPager defaults to preloading 1 adjacent fragment (left and right) for smooth transitions. Here's how to fix this:

Fix 1: Rewrite Your ViewPagerAdapter

Instead of pre-creating Fragments and adding them to a list, create them only when needed inside the getItem() method. Also, use the AndroidX BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT flag to ensure only the active Fragment stays in the RESUMED state (others pause, preventing unnecessary work):

public class ViewPagerAdapter extends FragmentPagerAdapter {
    public ViewPagerAdapter(FragmentManager fm) {
        // This flag ensures only the current fragment is RESUMED
        super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
    }

    @Override
    public Fragment getItem(int position) {
        // Create fragments on-demand, not upfront
        switch (position) {
            case 0: return new CalendarFragment();
            case 1: return new ServicesFragment();
            case 2: return new ReviewsFragment();
            case 3: return new NotificationFragment();
            case 4: return new ProfileFragment();
            default: throw new IllegalArgumentException("Invalid tab position");
        }
    }

    @Override
    public int getCount() {
        return 5;
    }
}

Fix 2: Reduce Offscreen Page Limit

Tell ViewPager to minimize preloading by setting the offscreen limit to 0. Note that some older ViewPager versions might ignore 0 and fallback to 1, but combining this with lazy loading (see next section) will still help:

private void setupViewPager(ViewPager viewPager) {
    ViewPagerAdapter viewPagerAdapter = new ViewPagerAdapter(getSupportFragmentManager());
    viewPager.setAdapter(viewPagerAdapter);
    // Try to disable preloading entirely
    viewPager.setOffscreenPageLimit(0);
}

2. Optimize Google Maps Loading in ProfileFragment

The Google Maps Fragment is heavy, so loading it when the Fragment is first created (even if it's not visible) will block the main thread. Let's make it load only when the Fragment is actually visible to the user:

Fix 1: Lazy Load the Map Fragment

First, replace the static <fragment> tag in your layout with a FrameLayout (so we can add the Map Fragment dynamically later):

<!-- Replace your static map fragment with this -->
<FrameLayout
    android:id="@+id/map_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

Then, modify your ProfileFragment to load the Map only when it's visible and resumed:

public class ProfileFragment extends Fragment implements OnMapReadyCallback {
    private SupportMapFragment mapFragment;
    private GoogleMap mMap;
    private boolean isMapLoaded = false; // Track if map is already initialized

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_profile, container, false);
    }

    @Override
    public void onResume() {
        super.onResume();
        // Only load the map if it's not already loaded AND the fragment is visible
        if (!isMapLoaded && isResumed() && isVisible()) {
            loadMap();
        }
    }

    private void loadMap() {
        if (mapFragment == null && getView() != null) {
            // Create and add the map fragment dynamically
            mapFragment = SupportMapFragment.newInstance();
            getChildFragmentManager().beginTransaction()
                    .replace(R.id.map_container, mapFragment)
                    .commitNow(); // Use commitNow to ensure fragment is added immediately
            
            mapFragment.getMapAsync(this);
        }
    }

    @Override
    public void onMapReady(GoogleMap googleMap) {
        mMap = googleMap;
        isMapLoaded = true;
        
        // Add your map initialization code here (markers, camera position, etc.)
        // Example:
        // mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(37.7749, -122.4194), 12));
    }
}

Fix 2: Remove Unnecessary Delays

Your original code uses a Handler with a 1-second delay, which isn't needed anymore with dynamic loading. The getMapAsync() method is already asynchronous, so it won't block the main thread once triggered at the right time.


内容的提问来源于stack exchange,提问作者No Name

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:46:20