如何在Flutter中实现TikTok式随机展示Model中JSON内容的滚动页面
实现TikTok式垂直滚动语录应用
问题背景
我正在开发一款类似TikTok的垂直滚动风格应用,每次滑动时从Model的语录列表中加载一条随机内容。已完成Model层代码,但不知道如何在HomePage的PageView中实现该功能。
现有Model代码(Words.dart)
import 'dart:math' as math; List<Map<String, Object?>> allWords = [ { "ID": 0, "Word": "If you don't put your life on the line, you can't earn your life.", "Author": "Friedrich Schiller", "Image": "", }, { "ID": 2, "Word": "If you can dream it, you can do it.", "Author": "Friedrich Schiller", "Image": "", }, { "ID": 3, "Word": "We don't have to be smarter than others. We have to be more disciplined than others.", "Author": "Warren Buffett", "Image": "", }, // ... 剩余语录条目保持不变 ]; class Words { final int iD; final String word; final String author; final String image; Words({ required this.iD, required this.author, required this.word, required this.image, }); factory Words.fromJson(Map<String, Object?> json) { return Words( iD: json['ID'] as int, author: json['Author'] as String, word: json['Word'] as String, image: json["Image"] as String, ); } factory Words.getRandomWord() { math.Random random = math.Random(); return Words.fromJson(allWords[random.nextInt(allWords.length - 1)]); } }
现有HomePage代码(HomePage.dart)
import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:teenmotivation/Models/Words.dart'; class HomePage extends StatefulWidget { const HomePage({Key? key}) : super(key: key); @override State<HomePage> createState() => _HomePageState(); } PageController pageController = PageController(initialPage: 0); Words words = Words.getRandomWord(); class _HomePageState extends State<HomePage> { @override Widget build(BuildContext context) { return Scaffold( body: PageView( controller: pageController, scrollDirection: Axis.vertical, children: // 我不知道这里该写什么 ), ); } }
解决方案
核心优化点
- 改用
PageView.builder实现动态加载,避免一次性创建所有页面 - 将状态变量移到State类内部,避免全局状态冲突
- 监听滚动事件,自动加载新的随机语录
- 修复Model中随机方法的索引问题,确保覆盖所有语录条目
修改后的完整代码
HomePage.dart
import 'package:flutter/material.dart'; import 'package:teenmotivation/Models/Words.dart'; class HomePage extends StatefulWidget { const HomePage({Key? key}) : super(key: key); @override State<HomePage> createState() => _HomePageState(); } class _HomePageState extends State<HomePage> { late PageController _pageController; final List<Words> _loadedQuotes = []; @override void initState() { super.initState(); _pageController = PageController(initialPage: 0); // 初始加载3条语录,保证启动后有内容可滚动 for (int i = 0; i < 3; i++) { _loadedQuotes.add(Words.getRandomWord()); } } @override void dispose() { _pageController.dispose(); super.dispose(); } // 添加新的随机语录 void _addNewQuote() { setState(() { _loadedQuotes.add(Words.getRandomWord()); }); } // 单条语录页面组件 Widget _buildQuotePage(Words quote) { return Container( padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 40), color: Colors.grey[900], child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.stretch, children: [ Expanded( child: Center( child: Text( quote.word, style: const TextStyle( fontSize: 24, color: Colors.white, fontWeight: FontWeight.w500, height: 1.5, ), textAlign: TextAlign.center, ), ), ), // 仅当作者不为空时显示 if (quote.author.isNotEmpty) Text( "- ${quote.author}", style: const TextStyle( fontSize: 16, color: Colors.grey, fontStyle: FontStyle.italic, ), textAlign: TextAlign.right, ), ], ), ); } @override Widget build(BuildContext context) { return Scaffold( body: PageView.builder( controller: _pageController, scrollDirection: Axis.vertical, itemCount: _loadedQuotes.length, // 滚动到倒数第二页时加载新内容,避免出现空白 onPageChanged: (index) { if (index == _loadedQuotes.length - 2) { _addNewQuote(); } }, itemBuilder: (context, index) { return _buildQuotePage(_loadedQuotes[index]); }, ), ); } }
优化后的Words.dart(仅修改随机方法)
// ... 其他代码保持不变 factory Words.getRandomWord() { math.Random random = math.Random(); // 修复索引范围,覆盖所有语录条目 return Words.fromJson(allWords[random.nextInt(allWords.length)]); } // ... 其他代码保持不变
内容的提问来源于stack exchange,提问作者Emir Bolat
相关产品推荐
相关产品推荐

