lab3 done
This commit is contained in:
parent
57c7532eb0
commit
c244105079
231
lib/main.dart
231
lib/main.dart
@ -22,14 +22,13 @@ class MyApp extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enum для управления состоянием сообщений
|
|
||||||
enum MessageType { noQuotes, newQuoteAdded }
|
|
||||||
|
|
||||||
// Модель цитаты
|
// Модель цитаты
|
||||||
class Quote {
|
class Quote {
|
||||||
final String text;
|
final String text;
|
||||||
final String author;
|
final String author;
|
||||||
Quote(this.text, this.author);
|
final String imagePath;
|
||||||
|
|
||||||
|
Quote(this.text, this.author, this.imagePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Главный экран
|
// Главный экран
|
||||||
@ -42,39 +41,117 @@ class MyHomePage extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _MyHomePageState extends State<MyHomePage> {
|
class _MyHomePageState extends State<MyHomePage> {
|
||||||
|
final TextEditingController quoteTextController = TextEditingController();
|
||||||
|
final TextEditingController quoteAuthorController = TextEditingController();
|
||||||
|
|
||||||
final List<Quote> _quotes = [];
|
final List<Quote> _quotes = [];
|
||||||
MessageType _messageType = MessageType.noQuotes;
|
final String defaultImagePath =
|
||||||
|
'https://cdn-icons-png.flaticon.com/128/17818/17818874.png';
|
||||||
|
|
||||||
// Метод добавления цитаты
|
@override
|
||||||
Future<void> _addQuote() async {
|
void initState() {
|
||||||
final result = await showDialog<Map<String, String>?>(
|
super.initState();
|
||||||
context: context,
|
|
||||||
builder: (BuildContext context) => const AddQuoteDialog(),
|
|
||||||
);
|
|
||||||
|
|
||||||
if (result != null && result['quote'] != '' && result['author'] != '') {
|
// Тестовые цитаты
|
||||||
|
_quotes.add(Quote(
|
||||||
|
'Сила воли — это ключ к успеху.',
|
||||||
|
'Аноним',
|
||||||
|
'https://cdn-icons-png.flaticon.com/128/17818/17818880.png',
|
||||||
|
));
|
||||||
|
_quotes.add(Quote(
|
||||||
|
'Вера в себя — это первый шаг к победе.',
|
||||||
|
'Аноним',
|
||||||
|
'https://cdn-icons-png.flaticon.com/128/17818/17818889.png',
|
||||||
|
));
|
||||||
|
_quotes.add(Quote(
|
||||||
|
'Не бойся быть отличным, бойся быть обычным.',
|
||||||
|
'Аноним',
|
||||||
|
'https://cdn-icons-png.flaticon.com/128/17818/17818899.png',
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
void _addQuote() {
|
||||||
setState(() {
|
setState(() {
|
||||||
_quotes.add(
|
final newQuote = Quote(
|
||||||
Quote(result['quote']!.addQuotesIfMissing(), result['author']!.capitalize()),
|
quoteTextController.text.addQuotesIfMissing().capitalize(),
|
||||||
|
quoteAuthorController.text.capitalize(),
|
||||||
|
defaultImagePath, // Устанавливаем дефолтное изображение
|
||||||
);
|
);
|
||||||
_messageType = MessageType.newQuoteAdded;
|
_quotes.add(newQuote);
|
||||||
|
quoteTextController.clear();
|
||||||
|
quoteAuthorController.clear();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _removeQuote(int index) {
|
||||||
|
setState(() {
|
||||||
|
_quotes.removeAt(index);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
|
title: const Text('Цитаты'),
|
||||||
title: Text(widget.title),
|
backgroundColor: Theme.of(context).colorScheme.primaryContainer,
|
||||||
|
foregroundColor: Theme.of(context).colorScheme.onPrimaryContainer,
|
||||||
),
|
),
|
||||||
body: Stack(
|
body: Stack(
|
||||||
children: [
|
children: [
|
||||||
Center(
|
Column(
|
||||||
child: _messageType == MessageType.noQuotes
|
children: [
|
||||||
? const NoQuotesMessage()
|
const Padding(
|
||||||
: QuoteList(quotes: _quotes),
|
padding: EdgeInsets.all(16.0),
|
||||||
|
child: Text(
|
||||||
|
'Список цитат',
|
||||||
|
style: TextStyle(fontSize: 20, fontWeight: FontWeight.normal),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: _quotes.isEmpty
|
||||||
|
? const Center(
|
||||||
|
child: Text(
|
||||||
|
'Нет добавленных цитат. Добавьте первую!',
|
||||||
|
style: TextStyle(fontSize: 18, color: Colors.grey),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: ListView.builder(
|
||||||
|
itemCount: _quotes.length,
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
final quote = _quotes[index];
|
||||||
|
return Card(
|
||||||
|
margin: const EdgeInsets.symmetric(
|
||||||
|
vertical: 8.0,
|
||||||
|
horizontal: 10.0,
|
||||||
|
),
|
||||||
|
child: ListTile(
|
||||||
|
contentPadding: const EdgeInsets.all(8.0),
|
||||||
|
leading: SizedBox(
|
||||||
|
width: 50.0,
|
||||||
|
child: Image.network(
|
||||||
|
quote.imagePath,
|
||||||
|
fit: BoxFit.cover,
|
||||||
|
errorBuilder: (_, __, ___) =>
|
||||||
|
const Icon(Icons.error, color: Colors.red),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
title: Text(
|
||||||
|
quote.text,
|
||||||
|
style: const TextStyle(
|
||||||
|
fontSize: 18, fontWeight: FontWeight.w500),
|
||||||
|
),
|
||||||
|
subtitle: Text('- ${quote.author}'),
|
||||||
|
trailing: IconButton(
|
||||||
|
icon: const Icon(Icons.delete),
|
||||||
|
onPressed: () => _removeQuote(index),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
Align(
|
Align(
|
||||||
alignment: Alignment.bottomCenter,
|
alignment: Alignment.bottomCenter,
|
||||||
@ -83,46 +160,46 @@ class _MyHomePageState extends State<MyHomePage> {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
floatingActionButton: FloatingActionButton(
|
floatingActionButton: FloatingActionButton(
|
||||||
onPressed: _addQuote,
|
onPressed: () {
|
||||||
tooltip: 'Добавить цитату',
|
showDialog(
|
||||||
child: const Icon(Icons.format_quote),
|
context: context,
|
||||||
|
builder: (context) {
|
||||||
|
return AlertDialog(
|
||||||
|
title: const Text('Новая цитата'),
|
||||||
|
content: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
TextField(
|
||||||
|
controller: quoteTextController,
|
||||||
|
decoration: const InputDecoration(
|
||||||
|
hintText: 'Введите текст цитаты',
|
||||||
),
|
),
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Виджет списка цитат
|
|
||||||
class QuoteList extends StatelessWidget {
|
|
||||||
final List<Quote> quotes;
|
|
||||||
const QuoteList({super.key, required this.quotes});
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return ListView.builder(
|
|
||||||
itemCount: quotes.length,
|
|
||||||
itemBuilder: (context, index) {
|
|
||||||
return ListTile(
|
|
||||||
title: Text(
|
|
||||||
quotes[index].text,
|
|
||||||
style: const TextStyle(fontSize: 18, fontWeight: FontWeight.w500),
|
|
||||||
),
|
),
|
||||||
subtitle: Text('- ${quotes[index].author}'),
|
const SizedBox(height: 8),
|
||||||
|
TextField(
|
||||||
|
controller: quoteAuthorController,
|
||||||
|
decoration: const InputDecoration(
|
||||||
|
hintText: 'Введите автора цитаты',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
actions: [
|
||||||
|
TextButton(
|
||||||
|
onPressed: () {
|
||||||
|
_addQuote();
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
},
|
||||||
|
child: const Text('Добавить'),
|
||||||
|
),
|
||||||
|
],
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
},
|
||||||
}
|
tooltip: 'Добавить цитату',
|
||||||
|
child: const Icon(Icons.format_quote),
|
||||||
// Виджет сообщения "нет цитат"
|
),
|
||||||
class NoQuotesMessage extends StatelessWidget {
|
|
||||||
const NoQuotesMessage({super.key});
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return const Text(
|
|
||||||
'Нет добавленных цитат. Добавь первую!',
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
style: TextStyle(fontSize: 18, color: Colors.grey),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -135,7 +212,7 @@ class QuoteCounter extends StatelessWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: const EdgeInsets.all(30.0),
|
padding: const EdgeInsets.all(16.0),
|
||||||
child: Container(
|
child: Container(
|
||||||
padding: const EdgeInsets.symmetric(vertical: 5, horizontal: 10),
|
padding: const EdgeInsets.symmetric(vertical: 5, horizontal: 10),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
@ -148,50 +225,14 @@ class QuoteCounter extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
child: Text(
|
child: Text(
|
||||||
'Количество цитат: $count',
|
'Количество цитат: $count',
|
||||||
style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Colors.black),
|
style: const TextStyle(
|
||||||
|
fontSize: 16, fontWeight: FontWeight.w600, color: Colors.black),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Диалоговое окно добавления цитаты
|
|
||||||
class AddQuoteDialog extends StatelessWidget {
|
|
||||||
const AddQuoteDialog({super.key});
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
final TextEditingController quoteController = TextEditingController();
|
|
||||||
final TextEditingController authorController = TextEditingController();
|
|
||||||
|
|
||||||
return AlertDialog(
|
|
||||||
title: const Text('Добавить цитату'),
|
|
||||||
content: Column(
|
|
||||||
mainAxisSize: MainAxisSize.min,
|
|
||||||
children: [
|
|
||||||
TextField(
|
|
||||||
controller: quoteController,
|
|
||||||
decoration: const InputDecoration(labelText: 'Цитата'),
|
|
||||||
),
|
|
||||||
TextField(
|
|
||||||
controller: authorController,
|
|
||||||
decoration: const InputDecoration(labelText: 'Автор'),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
actions: [
|
|
||||||
TextButton(
|
|
||||||
onPressed: () => Navigator.of(context).pop({
|
|
||||||
'quote': quoteController.text,
|
|
||||||
'author': authorController.text,
|
|
||||||
}),
|
|
||||||
child: const Text('Добавить'),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Расширение для форматирования текста
|
// Расширение для форматирования текста
|
||||||
extension StringExtension on String {
|
extension StringExtension on String {
|
||||||
String capitalize() {
|
String capitalize() {
|
||||||
|
Loading…
Reference in New Issue
Block a user