Mobile Development 13 min read

Exploring ChatGPT for Flutter UI: Generating a Yellow Star with Animation

This article recounts a developer's hands‑on experiment using ChatGPT to generate Flutter code for drawing a yellow five‑pointed star, iteratively refining the design, adding explosion particle animation, and reflecting on the strengths and quirks of in‑context learning AI.

Sohu Tech Products
Sohu Tech Products
Sohu Tech Products
Exploring ChatGPT for Flutter UI: Generating a Yellow Star with Animation

ChatGPT has become a popular tool for developers, often replacing traditional search engines for tasks such as writing reports, debugging, and translating documents. The author first introduces two practical extensions—ChatPDF for interacting with PDFs and BiBiGPT for summarising video subtitles—highlighting that ChatGPT’s power stems from its in‑context learning rather than simple statistical modeling.

Motivated to test ChatGPT’s UI capabilities, the author asks it to "draw a yellow five‑pointed star" using Flutter. The initial code generated produces a shape that does not meet the visual expectations, prompting a series of refinements. Throughout the process, the author shares screenshots of the generated UI and the accompanying explanations provided by ChatGPT.

After several iterations, the following core Flutter code is produced (wrapped in tags to preserve the original lines): class YellowStar extends StatefulWidget { @override _YellowStarState createState() => _YellowStarState(); } class _YellowStarState extends State with TickerProviderStateMixin { bool _isExploded = false; late AnimationController _animationController; late Animation _animation; @override void initState() { super.initState(); _animationController = AnimationController( duration: const Duration(milliseconds: 500), vsync: this, ); _animation = CurvedAnimation(parent: _animationController, curve: Curves.easeInOut); } @override void dispose() { _animationController.dispose(); super.dispose(); } void _handleTapDown(TapDownDetails details) { setState(() { _isExploded = true; _animationController.forward(from: 0.0); }); } void _resetStar() { setState(() { _isExploded = false; _animationController.reset(); }); } @override Widget build(BuildContext context) { return GestureDetector( onTapDown: _handleTapDown, onTap: _resetStar, child: AnimatedContainer( duration: const Duration(milliseconds: 500), decoration: BoxDecoration( color: Colors.white, borderRadius: _isExploded ? BorderRadius.circular(50) : BorderRadius.zero, ), child: _isExploded ? _buildParticles() : Container( width: 100, height: 100, child: CustomPaint(painter: YellowStarPainter()), ), ), ); } Widget _buildParticles() { return AnimatedBuilder( animation: _animation, builder: (context, child) { return Container( width: 100, height: 100, child: Stack( children: List.generate(50, (index) { double radius = _animation.value * 50; double angle = 2 * pi * index / 50; double x = 50 + cos(angle) * radius; double y = 50 + sin(angle) * radius; return Positioned( left: x, top: y, child: Container(width: 4, height: 4, decoration: BoxDecoration(shape: BoxShape.circle, color: Colors.yellow)), ); }), ); }, ); } } class YellowStarPainter extends CustomPainter { final double starSizeRatio = 0.4; final double centerOffsetRatio = 0.2; final double rotationOffset = -pi / 2; @override void paint(Canvas canvas, Size size) { double starSize = min(size.width, size.height) * starSizeRatio; double centerX = size.width / 2; double centerY = size.height / 2; double centerOffset = starSize * centerOffsetRatio; Path path = Path(); Paint paint = Paint()..color = Colors.yellow..style = PaintingStyle.fill; for (int i = 0; i < 5; i++) { double radians = 2 * pi / 5 * i + rotationOffset; double x = centerX + cos(radians) * starSize / 2; double y = centerY + sin(radians) * starSize / 2; if (i == 0) path.moveTo(x, y) else path.lineTo(x, y); radians += 2 * pi / 10; x = centerX + cos(radians) * centerOffset; y = centerY + sin(radians) * centerOffset; path.lineTo(x, y); } path.close(); canvas.drawPath(path, paint); } @override bool shouldRepaint(CustomPainter oldDelegate) => false; }

Even after obtaining a syntactically correct star, the shape sometimes appears as a regular pentagon rather than a true star, revealing the model’s occasional misunderstanding of geometric constraints. The author continues to refine the description, eventually achieving a satisfactory visual result and adding a particle‑explosion effect triggered by tapping the star.

A second, more elaborate code block implements the full page with animation control, also wrapped in tags:

class YellowStarPage extends StatefulWidget {
  @override
  _YellowStarPageState createState() => _YellowStarPageState();
}

class _YellowStarPageState extends State
with SingleTickerProviderStateMixin {
  late AnimationController _animationController;
  bool _isExploded = false;

  @override
  void initState() {
    super.initState();
    _animationController = AnimationController(vsync: this, duration: Duration(milliseconds: 500))
      ..addListener(() { setState(() {}); });
  }

  @override
  void dispose() {
    _animationController.dispose();
    super.dispose();
  }

  void _handleStarTap() {
    if (!_isExploded) {
      _isExploded = true;
      _animationController.forward(from: 0);
      Future.delayed(Duration(milliseconds: 500), () { setState(() { _isExploded = false; }); });
    }
    setState(() {});
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Yellow Star')),
      body: Center(
        child: GestureDetector(
          onTap: _handleStarTap,
          child: Container(
            width: 300,
            height: 300,
            child: AnimatedBuilder(
              animation: _animationController,
              builder: (context, child) {
                return CustomPaint(
                  painter: YellowStarPainter(_animationController.value, isExploded: _isExploded),
                );
              },
            ),
          ),
        ),
      ),
    );
  }
}

class YellowStarPainter extends CustomPainter {
  final double starSizeRatio = 0.4;
  final double centerOffsetRatio = 0.2;
  final double rotationOffset = -pi / 2;
  final double animationValue;
  final bool isExploded;

  YellowStarPainter(this.animationValue, {this.isExploded = false});

  @override
  void paint(Canvas canvas, Size size) {
    // (Painting logic similar to the previous painter, with particle effect when exploded)
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) => true;
}

The author concludes that while ChatGPT can surprisingly produce functional UI code, its answers are not deterministic; the same prompt may yield different implementations, some of which are incomplete or incorrect (e.g., placeholder comments like "//TODO 爆炸动画"). This variability underscores the current limitations of large language models and the importance of human oversight.

Finally, the article mentions the release of GPT‑4 with multimodal capabilities, larger context windows, and improved accuracy, expressing optimism that future models may eventually generate flawless graphics such as a perfect Mickey‑mouse drawing.

Fluttermobile developmentAIChatGPTIn-Context Learningui animation
Sohu Tech Products
Written by

Sohu Tech Products

A knowledge-sharing platform for Sohu's technology products. As a leading Chinese internet brand with media, video, search, and gaming services and over 700 million users, Sohu continuously drives tech innovation and practice. We’ll share practical insights and tech news here.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.