184 lines
5.7 KiB
Dart
184 lines
5.7 KiB
Dart
import 'package:flutter/material.dart';
|
||
import 'character.dart';
|
||
import 'character_service.dart';
|
||
import 'pages/CharacterDetailPage.dart';
|
||
|
||
void main() => runApp(MyApp());
|
||
|
||
class MyApp extends StatelessWidget {
|
||
@override
|
||
Widget build(BuildContext context) {
|
||
return MaterialApp(
|
||
title: 'Identity V Characters',
|
||
home: MyHomePage(title: 'Персонажи Identity V'),
|
||
);
|
||
}
|
||
}
|
||
|
||
class MyHomePage extends StatefulWidget {
|
||
MyHomePage({Key? key, required this.title}) : super(key: key);
|
||
|
||
final String title;
|
||
|
||
@override
|
||
_MyHomePageState createState() => _MyHomePageState();
|
||
}
|
||
|
||
class _MyHomePageState extends State<MyHomePage> {
|
||
final CharacterService _characterService = CharacterService();
|
||
late Future<List<Character>> _futureCharacters;
|
||
final TextEditingController _searchController = TextEditingController();
|
||
|
||
@override
|
||
void initState() {
|
||
super.initState();
|
||
_futureCharacters = _characterService.getCharacters();
|
||
}
|
||
|
||
void _searchCharacters(String query) {
|
||
setState(() {
|
||
_futureCharacters = _characterService.getCharacters(search: query);
|
||
});
|
||
}
|
||
|
||
@override
|
||
Widget build(BuildContext context) {
|
||
return Scaffold(
|
||
appBar: AppBar(
|
||
title: Text(widget.title),
|
||
actions: [
|
||
IconButton(
|
||
icon: Icon(Icons.search),
|
||
onPressed: () {
|
||
showSearch(
|
||
context: context,
|
||
delegate: CharacterSearchDelegate(_searchCharacters),
|
||
);
|
||
},
|
||
),
|
||
],
|
||
),
|
||
body: FutureBuilder<List<Character>>(
|
||
future: _futureCharacters,
|
||
builder: (context, snapshot) {
|
||
if (snapshot.connectionState == ConnectionState.waiting) {
|
||
return Center(child: CircularProgressIndicator());
|
||
} else if (snapshot.hasError) {
|
||
return Center(child: Text('Ошибка: ${snapshot.error}'));
|
||
} else if (!snapshot.hasData || snapshot.data!.isEmpty) {
|
||
return Center(child: Text('Нет персонажей'));
|
||
} else {
|
||
final characters = snapshot.data!;
|
||
|
||
return ListView.builder(
|
||
itemCount: characters.length,
|
||
itemBuilder: (context, index) {
|
||
final character = characters[index];
|
||
return ListTile(
|
||
leading: SizedBox(
|
||
width: 40,
|
||
child: Image.network(character.imageUrl, width: 50, height: 50),
|
||
),
|
||
title: Text(character.name),
|
||
subtitle: Text(character.typeString),
|
||
trailing: IconButton(
|
||
icon: Icon(
|
||
character.isLiked ? Icons.favorite : Icons.favorite_border,
|
||
color: character.isLiked ? Colors.red : null,
|
||
),
|
||
onPressed: () {
|
||
setState(() {
|
||
character.isLiked = !character.isLiked;
|
||
});
|
||
ScaffoldMessenger.of(context).showSnackBar(
|
||
SnackBar(
|
||
content: Text(
|
||
character.isLiked
|
||
? '${character.name} понравился вам!'
|
||
: '${character.name} убран из лайков.',
|
||
),
|
||
duration: Duration(seconds: 2),
|
||
),
|
||
);
|
||
},
|
||
),
|
||
onTap: () {
|
||
Navigator.push(
|
||
context,
|
||
MaterialPageRoute(
|
||
builder: (context) => CharacterDetailPage(character: character),
|
||
),
|
||
);
|
||
},
|
||
);
|
||
},
|
||
);
|
||
}
|
||
},
|
||
),
|
||
);
|
||
}
|
||
}
|
||
|
||
class CharacterSearchDelegate extends SearchDelegate {
|
||
final Function(String) onSearch;
|
||
|
||
CharacterSearchDelegate(this.onSearch);
|
||
|
||
@override
|
||
Widget buildSuggestions(BuildContext context) {
|
||
return ListView();
|
||
}
|
||
|
||
@override
|
||
Widget buildResults(BuildContext context) {
|
||
onSearch(query); // Выполняем поиск
|
||
return FutureBuilder<List<Character>>(
|
||
future: CharacterService().getCharacters(search: query), // Запрашиваем персонажей с фильтром
|
||
builder: (context, snapshot) {
|
||
if (snapshot.connectionState == ConnectionState.waiting) {
|
||
return Center(child: CircularProgressIndicator());
|
||
} else if (snapshot.hasError) {
|
||
return Center(child: Text('Ошибка: ${snapshot.error}'));
|
||
} else if (!snapshot.hasData || snapshot.data!.isEmpty) {
|
||
return Center(child: Text('Нет результатов для "$query"'));
|
||
} else {
|
||
final characters = snapshot.data!;
|
||
return ListView.builder(
|
||
itemCount: characters.length,
|
||
itemBuilder: (context, index) {
|
||
final character = characters[index];
|
||
return ListTile(
|
||
title: Text(character.name),
|
||
subtitle: Text(character.typeString),
|
||
);
|
||
},
|
||
);
|
||
}
|
||
},
|
||
);
|
||
}
|
||
|
||
@override
|
||
List<Widget> buildActions(BuildContext context) {
|
||
return [
|
||
IconButton(
|
||
icon: Icon(Icons.clear),
|
||
onPressed: () {
|
||
query = ''; // Очищаем запрос
|
||
},
|
||
),
|
||
];
|
||
}
|
||
|
||
@override
|
||
Widget buildLeading(BuildContext context) {
|
||
return IconButton(
|
||
icon: Icon(Icons.arrow_back),
|
||
onPressed: () {
|
||
close(context, null); // Закрываем поиск
|
||
},
|
||
);
|
||
}
|
||
}
|