import 'package:flutter/material.dart'; import 'package:fl_chart/fl_chart.dart'; import 'StockCategory.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( title: 'Gerimovich demo', theme: ThemeData( colorScheme: ColorScheme.fromSeed(seedColor: Colors.red), useMaterial3: true, ), home: const MyHomePage(title: 'Gerimovich Ilya Maximovich'), ); } } class MyHomePage extends StatefulWidget { const MyHomePage({super.key, required this.title}); final String title; @override State createState() => _MyHomePageState(); } class _MyHomePageState extends State { @override void initState() { super.initState(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( backgroundColor: Theme.of(context).colorScheme.inversePrimary, title: Text(widget.title), ), body: const StocksWidget(), ); } } class Stock { final String? name; final double? price; final String? imageUrl; final StockCategory? category; Stock({ this.name, this.price, this.imageUrl, this.category, }); } class StocksWidget extends StatefulWidget { const StocksWidget({super.key}); @override State createState() => _StocksWidgetState(); } class _StocksWidgetState extends State { final List prices = [52.90, 77, 89, 111, 135.43, 157.50, 111.11]; Future _fetchNewPrice() async { await Future.delayed(const Duration(seconds: 1)); setState(() { prices.add(prices.last + (prices.last * 0.1)); //if (prices.length > 5) { // prices.removeAt(0); //} }); } @override Widget build(BuildContext context) { final stocks = [ Stock( name: 'Алроса', price: 52.90, imageUrl: 'https://data.cbonds.info/organisations_logos/18/1617957662ALROSA_Rus_COLOUR_RGB.jpg', category: StockCategory.mining), Stock( name: 'Газпром', price: 135.431111, imageUrl: 'https://data.cbonds.info/organisations_logos/21/21.png', category: StockCategory.oilgas), Stock( name: 'Сбербанк', imageUrl: 'https://data.cbonds.info/organisations_logos/313/1615279834sberbank__2-01.png', category: StockCategory.finance), Stock(), ]; return Center( child: SingleChildScrollView( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ ...stocks.map((e) => StockCard(stock: e)), const SizedBox(height: 20), ElevatedButton( onPressed: _fetchNewPrice, child: const Text('Добавить новую цену'), ), const SizedBox(height: 20), SizedBox( height: 300, child: LineChart( LineChartData( lineBarsData: [ LineChartBarData( spots: prices .asMap() .map((index, price) => MapEntry(index.toDouble(), FlSpot(index.toDouble(), price))) .values .toList(), isCurved: true, color: Colors.blue, barWidth: 3, dotData: const FlDotData(show: false), ), ], ), ), ), ], ), ), ); } } class StockCard extends StatelessWidget { final Stock stock; const StockCard({super.key, required this.stock}); @override Widget build(BuildContext context) { return Card( margin: const EdgeInsets.all(8.5), child: Padding( padding: const EdgeInsets.all(20), child: Row( children: [ Image.network( stock.imageUrl ?? 'https://img.freepik.com/premium-vector/vector-illustration-about-concept-of-no-result-data-or-document-or-file-not-found_675567-5734.jpg', width: 85, height: 85, ), const SizedBox(width: 20), Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( stock.name ?? '', style: Theme.of(context).textTheme.headlineSmall, ), Text( '${stock.price?.toStringAsFixed(2)} р', style: Theme.of(context).textTheme.bodyLarge, ), Text( stock.category?.name ?? '', style: Theme.of(context).textTheme.bodySmall, ), ], ), ], ), ), ); } }