flutter_gemini 0.0.1-dev-4 flutter_gemini: ^0.0.1-dev-4 copied to clipboard
Flutter Google Gemini SDK. Google Gemini is a set of cutting-edge large language models (LLMs) designed to be the driving force behind Google's future AI initiatives.
import 'package:flutter/material.dart';
import 'package:flutter_gemini/flutter_gemini.dart';
import 'package:flutter_markdown/flutter_markdown.dart';
import 'package:lottie/lottie.dart';
void main() {
Gemini.init(apiKey: '--- Your Gemini Api Key ---');
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Gemini',
themeMode: ThemeMode.dark,
debugShowCheckedModeBanner: false,
darkTheme: ThemeData.dark(
useMaterial3: true,
).copyWith(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue),
cardTheme: CardTheme(color: Colors.blue.shade900)),
home: const MyHomePage(title: 'Flutter Gemini'),
);
}
}
class PageItem {
final int index;
final String title;
final Widget widget;
PageItem(this.index, this.title, this.widget);
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _selectedItem = 0;
final _pages = <PageItem>[
PageItem(0, 'text', const SectionTextInput()),
PageItem(1, 'textAndImage', const SectionTextAndImageInput()),
];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title: Text(widget.title),
actions: [
PopupMenuButton<int>(
initialValue: _selectedItem,
onSelected: (value) => setState(() => _selectedItem = value),
itemBuilder: (context) => _pages.map((e) {
return PopupMenuItem<int>(value: e.index, child: Text(e.title));
}).toList(),
child: const Icon(Icons.more_vert_rounded),
)
],
),
body: IndexedStack(
index: _selectedItem,
children: _pages.map((e) => e.widget).toList(),
),
);
}
}
class SectionTextInput extends StatefulWidget {
const SectionTextInput({super.key});
@override
State<SectionTextInput> createState() => _SectionTextInputState();
}
class _SectionTextInputState extends State<SectionTextInput> {
final controller = TextEditingController();
final gemini = Gemini.instance;
String? searchedText, result;
bool _loading = false;
bool get loading => _loading;
set loading(bool set) => setState(() => _loading = set);
@override
Widget build(BuildContext context) {
return Column(
children: [
if (searchedText != null)
MaterialButton(
color: Colors.blue.shade700,
onPressed: () {
setState(() {
searchedText = null;
result = null;
});
},
child: Text('search: $searchedText')),
Expanded(
child: loading
? Lottie.asset('assets/lottie/ai.json')
: result != null
? Padding(
padding: const EdgeInsets.all(8.0),
child: Markdown(data: result!),
)
: const Center(child: Text('Search something!'))),
Card(
margin: const EdgeInsets.all(12),
child: Row(
children: [
Expanded(
child: TextField(
controller: controller,
decoration: const InputDecoration(
contentPadding: EdgeInsets.symmetric(horizontal: 12),
hintText: 'write something ...',
border: InputBorder.none,
),
onTapOutside: (event) =>
FocusManager.instance.primaryFocus?.unfocus(),
)),
Padding(
padding: const EdgeInsets.only(right: 8.0),
child: IconButton(
onPressed: () {
if (controller.text.isNotEmpty) {
searchedText = controller.text;
controller.clear();
loading = true;
gemini.text(searchedText!).then((value) {
result = value?.content?.parts?.last.text;
loading = false;
});
}
},
icon: const Icon(Icons.send_rounded)),
)
],
),
)
],
);
}
}
class SectionTextAndImageInput extends StatelessWidget {
const SectionTextAndImageInput({super.key});
@override
Widget build(BuildContext context) {
return const Placeholder();
}
}