You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何让Flutter中PageView.Builder()的滚动动画从卡顿变得极其流畅

Fixing PageView Scroll Jank Issues in Flutter

Hey there, let's break down why your PageView is janking—especially on mid-range devices like your Snapdragon 636. The core issue in your code is the massive amount of text being rendered synchronously on each page—generating and laying out 1000 lines of text all at once is killing performance, even in release mode. Here's how to fix it step by step:


1. Fix PageController Management (Switch to Stateful Widget)

You're defining a PageController directly in a StatelessWidget, which can lead to unnecessary controller re-creations and state leaks. Switch to a StatefulWidget to properly initialize and clean up the controller:

class PageViewScreen extends StatefulWidget {
  @override
  _PageViewScreenState createState() => _PageViewScreenState();
}

class _PageViewScreenState extends State<PageViewScreen> {
  final _colorList = [Colors.white, Colors.lightBlue, Colors.lightGreen, Colors.limeAccent];
  late PageController _pageController;

  @override
  void initState() {
    super.initState();
    _pageController = PageController(initialPage: 1);
  }

  @override
  void dispose() {
    _pageController.dispose(); // Clean up to avoid memory leaks
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return PageView.builder(
      itemCount: 5,
      controller: _pageController,
      itemBuilder: (context, index) {
        return PageContent(color: _colorList[index % _colorList.length]);
      },
    );
  }
}

2. Optimize Text Rendering (Lazy Load Instead of Bulk Render)

Your fillText() method generates one giant string and shoves it into a single Text widget—Flutter has to layout every line at once, which is a huge CPU hit. Replace this with ListView.builder to lazy-load only the text lines visible on screen:

class PageContent extends StatelessWidget {
  final Color color;

  const PageContent({required this.color, Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
      color: color,
      child: ListView.builder(
        itemCount: 1000,
        itemBuilder: (context, lineIndex) {
          return Padding(
            padding: const EdgeInsets.symmetric(horizontal: 8.0),
            child: Text(' allan $lineIndex'),
          );
        },
      ),
    );
  }
}

This way, only 10-20 lines of text are rendered at a time (depending on your screen size), drastically reducing layout and rendering overhead during PageView scrolls.

3. Add Extra Performance Safeguards

Even with the above fixes, these tweaks can smooth things out further:

  • Wrap scrollable content with RepaintBoundary: If any part of your page repaints frequently, wrapping it in a RepaintBoundary prevents the entire page from being redrawn:
    return Container(
      color: color,
      child: RepaintBoundary(
        child: ListView.builder(...),
      ),
    );
    
  • Test with a proper release build: Make sure you're using flutter build apk --release for testing—debug mode adds significant overhead that's not present in production.
  • Adjust preloaded pages: PageView defaults to preloading 1 adjacent page, which is usually fine, but if you need to tweak it, adjust viewportFraction or use PageController(keepPage: true) to maintain state correctly.

With these changes, your PageView should scroll smoothly on your Snapdragon 636 device. The key fix is moving away from bulk text rendering to lazy loading—this eliminates the single biggest performance bottleneck in your code.

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

火山引擎 最新活动