ON THIS PAGE

No sections found

Related Posts

Flutter App Development in 2026: The Complete Engineering Guide

Flutter App Development in 2026: The Complete Engineering Guide

Mar 1, 2026

Flutter Production App Architecture: Clean Architecture, BLoC & Dependency Injection

Flutter Production App Architecture: Clean Architecture, BLoC & Dependency Injection

Mar 20, 2026

Flutter App Performance Optimization: The Complete 2026 Guide

Flutter App Performance Optimization: The Complete 2026 Guide

Mar 15, 2026

Quick Navigation

AboutProjectsEducationExperienceSkillsAwards

Connect

LinkedInXFacebookInstagramMediumRSS

Resources

Developer ToolsBlogDownload CV

Dependencies

Quick Settings TileFlutter Ex KitDotted Line Flutter

Contact

Jaipur, Rajasthan, IndiaSupport
© 2026 Puneet Sharma•All rights reserved
Privacy Policy•Terms of Service•Disclaimer
Last updated: Jan 2026
Made withby Puneet

How to Build AI-Powered Apps with Flutter: Gemini API, Streaming & AI Agents

Published onMarch 5, 2026 (6mo ago)

Artificial Intelligence has transformed mobile software development. Modern Flutter applications go beyond static screens—they offer intelligent chat assistance, ambient recommendations, automated text parsing, and multimodal vision analysis.

In this tutorial, we will build an AI-powered Flutter application using the official Google Gemini SDK, real-time response streaming, structured JSON responses, and responsive UI components.


1. Prerequisites & Project Setup

Start by creating a new Flutter project and adding the official Google AI SDK:

flutter create ai_flutter_demo
cd ai_flutter_demo
flutter pub add google_generative_ai provider

Pubspec Dependencies (pubspec.yaml)

dependencies:
  flutter:
    sdk: flutter
  google_generative_ai: ^0.4.0
  provider: ^6.1.2

2. Configuring the Gemini Service

We create a dedicated service class to handle initialization, prompt generation, and error handling.

import 'package:google_generative_ai/google_generative_ai.dart';
 
class GeminiRepository {
  late final GenerativeModel _textModel;
  late final GenerativeModel _visionModel;
 
  GeminiRepository({required String apiKey}) {
    _textModel = GenerativeModel(
      model: 'gemini-1.5-flash',
      apiKey: apiKey,
    );
    _visionModel = GenerativeModel(
      model: 'gemini-1.5-pro',
      apiKey: apiKey,
    );
  }
 
  /// Streaming token responses for instant user feedback
  Stream<String> streamChatResponse(String userPrompt) async* {
    try {
      final content = [Content.text(userPrompt)];
      final responseStream = _textModel.generateContentStream(content);
 
      await for (final chunk in responseStream) {
        if (chunk.text != null && chunk.text!.isNotEmpty) {
          yield chunk.text!;
        }
      }
    } catch (e) {
      yield 'Error generating response: ${e.toString()}';
    }
  }
}

3. Building a Real-Time Streaming AI Chat UI

Users expect instant, typewriter-style token streaming when interacting with AI chat interfaces. Here is how to implement a clean streaming chat widget in Flutter.

import 'package:flutter/material.dart';
 
class AiChatScreen extends StatefulWidget {
  final GeminiRepository repository;
  const AiChatScreen({super.key, required this.repository});
 
  @override
  State<AiChatScreen> createState() => _AiChatScreenState();
}
 
class _AiChatScreenState extends State<AiChatScreen> {
  final TextEditingController _controller = TextEditingController();
  final List<ChatMessage> _messages = [];
  bool _isGenerating = false;
 
  void _sendMessage() async {
    final text = _controller.text.trim();
    if (text.isEmpty || _isGenerating) return;
 
    _controller.clear();
    setState(() {
      _messages.add(ChatMessage(sender: 'User', text: text));
      _messages.add(ChatMessage(sender: 'AI', text: '...'));
      _isGenerating = true;
    });
 
    final aiMessageIndex = _messages.length - 1;
    StringBuffer fullResponse = StringBuffer();
 
    widget.repository.streamChatResponse(text).listen(
      (chunk) {
        fullResponse.write(chunk);
        setState(() {
          _messages[aiMessageIndex] = ChatMessage(
            sender: 'AI',
            text: fullResponse.toString(),
          );
        });
      },
      onDone: () {
        setState(() {
          _isGenerating = false;
        });
      },
      onError: (err) {
        setState(() {
          _messages[aiMessageIndex] = ChatMessage(
            sender: 'AI',
            text: 'An error occurred. Please try again.',
          );
          _isGenerating = false;
        });
      },
    );
  }
 
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Gemini AI Assistant')),
      body: Column(
        children: [
          Expanded(
            child: ListView.builder(
              padding: const EdgeInsets.all(16.0),
              itemCount: _messages.length,
              itemBuilder: (context, index) {
                final msg = _messages[index];
                final isUser = msg.sender == 'User';
                return Align(
                  alignment: isUser ? Alignment.centerRight : Alignment.centerLeft,
                  child: Container(
                    margin: const EdgeInsets.symmetric(vertical: 4.0),
                    padding: const EdgeInsets.all(12.0),
                    decoration: BoxDecoration(
                      color: isUser ? Colors.blueAccent : Colors.grey[800],
                      borderRadius: BorderRadius.circular(12.0),
                    ),
                    child: Text(
                      msg.text,
                      style: const TextStyle(color: Colors.white),
                    ),
                  ),
                );
              },
            ),
          ),
          Container(
            padding: const EdgeInsets.all(8.0),
            color: Theme.of(context).cardColor,
            child: Row(
              children: [
                Expanded(
                  child: TextField(
                    controller: _controller,
                    decoration: const InputDecoration(
                      hintText: 'Ask Gemini anything...',
                      border: InputBorder.none,
                    ),
                    onSubmitted: (_) => _sendMessage(),
                  ),
                ),
                IconButton(
                  icon: _isGenerating
                      ? const SizedBox(
                          width: 20,
                          height: 20,
                          child: CircularProgressIndicator(strokeWidth: 2),
                        )
                      : const Icon(Icons.send),
                  onPressed: _sendMessage,
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }
}
 
class ChatMessage {
  final String sender;
  final String text;
  ChatMessage({required this.sender, required this.text});
}

4. Multimodal AI Analysis (Images & Vision)

Gemini 1.5 Pro enables image analysis directly within mobile apps. Users can upload images (e.g., receipts, plant identification, document OCR) for real-time analysis.

import 'dart:typed_data';
 
Future<String?> analyzeImage(Uint8List imageBytes, String prompt) async {
  final model = GenerativeModel(
    model: 'gemini-1.5-flash',
    apiKey: 'YOUR_API_KEY',
  );
 
  final content = [
    Content.multi([
      TextPart(prompt),
      DataPart('image/jpeg', imageBytes),
    ])
  ];
 
  final response = await model.generateContent(content);
  return response.text;
}

5. Security & Production Considerations

When deploying AI-powered applications to production:

  1. Never Hardcode API Keys: Proxy API requests through a secure backend (Firebase Cloud Functions, Supabase Edge Functions, or Next.js API Routes).
  2. Rate Limiting & Cost Control: Implement token rate-limiting to prevent billing spikes.
  3. Graceful Fallbacks: Provide clear UI offline indicators when users lose network connectivity.
Previous Post

Flutter App Development in 2026: The Complete Engineering Guide

Next Post

AI Coding Agents for Software Developers: Claude Code, Cursor, Copilot & Modern Workflows