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

如何在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: // 我不知道这里该写什么
      ),
    );
  }
}

解决方案

核心优化点

  1. 改用PageView.builder实现动态加载,避免一次性创建所有页面
  2. 将状态变量移到State类内部,避免全局状态冲突
  3. 监听滚动事件,自动加载新的随机语录
  4. 修复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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 19:05:15