вроде 5 готова
This commit is contained in:
parent
f50f089d2a
commit
d64abe5ff6
@ -1,41 +0,0 @@
|
|||||||
import 'package:json_annotation/json_annotation.dart';
|
|
||||||
|
|
||||||
part 'characters_dto.g.dart';
|
|
||||||
|
|
||||||
@JsonSerializable(createToJson: false)
|
|
||||||
class CharactersDto {
|
|
||||||
final List<CharacterDataDto>? data;
|
|
||||||
|
|
||||||
const CharactersDto({this.data});
|
|
||||||
|
|
||||||
factory CharactersDto.fromJson(Map<String, dynamic> json) => _$CharactersDtoFromJson(json);
|
|
||||||
}
|
|
||||||
|
|
||||||
@JsonSerializable(createToJson: false)
|
|
||||||
class CharacterDataDto {
|
|
||||||
final String? id;
|
|
||||||
final String? type;
|
|
||||||
final CharacterAttributesDataDto? attributes; //составной элемент
|
|
||||||
|
|
||||||
const CharacterDataDto({this.id, this.type, this.attributes});
|
|
||||||
|
|
||||||
factory CharacterDataDto.fromJson(Map<String, dynamic> json) {
|
|
||||||
print('CharacterDataDto.fromJson: $json');
|
|
||||||
return _$CharacterDataDtoFromJson(json);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@JsonSerializable(createToJson: false)
|
|
||||||
class CharacterAttributesDataDto {
|
|
||||||
final String? fullName;
|
|
||||||
final String? title;
|
|
||||||
final String? family;
|
|
||||||
final String? imageUrl;
|
|
||||||
|
|
||||||
const CharacterAttributesDataDto({this.fullName, this.title, this.family, this.imageUrl});
|
|
||||||
|
|
||||||
factory CharacterAttributesDataDto.fromJson(Map<String, dynamic> json) {
|
|
||||||
print('CharacterAttributesDataDto.fromJson: $json');
|
|
||||||
return _$CharacterAttributesDataDtoFromJson(json);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,33 +0,0 @@
|
|||||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
|
||||||
|
|
||||||
part of 'characters_dto.dart';
|
|
||||||
|
|
||||||
// **************************************************************************
|
|
||||||
// JsonSerializableGenerator
|
|
||||||
// **************************************************************************
|
|
||||||
|
|
||||||
CharactersDto _$CharactersDtoFromJson(Map<String, dynamic> json) =>
|
|
||||||
CharactersDto(
|
|
||||||
data: (json['data'] as List<dynamic>?)
|
|
||||||
?.map((e) => CharacterDataDto.fromJson(e as Map<String, dynamic>))
|
|
||||||
.toList(),
|
|
||||||
);
|
|
||||||
|
|
||||||
CharacterDataDto _$CharacterDataDtoFromJson(Map<String, dynamic> json) =>
|
|
||||||
CharacterDataDto(
|
|
||||||
id: json['id'] as String?,
|
|
||||||
type: json['type'] as String?,
|
|
||||||
attributes: json['attributes'] == null
|
|
||||||
? null
|
|
||||||
: CharacterAttributesDataDto.fromJson(
|
|
||||||
json['attributes'] as Map<String, dynamic>),
|
|
||||||
);
|
|
||||||
|
|
||||||
CharacterAttributesDataDto _$CharacterAttributesDataDtoFromJson(
|
|
||||||
Map<String, dynamic> json) =>
|
|
||||||
CharacterAttributesDataDto(
|
|
||||||
fullName: json['fullName'] as String?,
|
|
||||||
title: json['title'] as String?,
|
|
||||||
family: json['family'] as String?,
|
|
||||||
imageUrl: json['imageUrl'] as String?,
|
|
||||||
);
|
|
@ -4,7 +4,7 @@ part 'thrones_character_dto.g.dart';
|
|||||||
|
|
||||||
@JsonSerializable(createToJson: false)
|
@JsonSerializable(createToJson: false)
|
||||||
class ThronesCharacterDto {
|
class ThronesCharacterDto {
|
||||||
final String id;
|
final int id;
|
||||||
final String firstName;
|
final String firstName;
|
||||||
final String lastName;
|
final String lastName;
|
||||||
final String fullName;
|
final String fullName;
|
||||||
|
@ -8,7 +8,7 @@ part of 'thrones_character_dto.dart';
|
|||||||
|
|
||||||
ThronesCharacterDto _$ThronesCharacterDtoFromJson(Map<String, dynamic> json) =>
|
ThronesCharacterDto _$ThronesCharacterDtoFromJson(Map<String, dynamic> json) =>
|
||||||
ThronesCharacterDto(
|
ThronesCharacterDto(
|
||||||
id: json['id'] as String,
|
id: (json['id'] as num).toInt(),
|
||||||
firstName: json['firstName'] as String,
|
firstName: json['firstName'] as String,
|
||||||
lastName: json['lastName'] as String,
|
lastName: json['lastName'] as String,
|
||||||
fullName: json['fullName'] as String,
|
fullName: json['fullName'] as String,
|
||||||
|
@ -6,9 +6,14 @@ const _imagePlaceholder =
|
|||||||
|
|
||||||
extension ThronesCharacterDtoToModel on ThronesCharacterDto {
|
extension ThronesCharacterDtoToModel on ThronesCharacterDto {
|
||||||
CardData toDomain() => CardData(
|
CardData toDomain() => CardData(
|
||||||
fullName,
|
|
||||||
imageUrl: imageUrl,
|
|
||||||
descriptionText: _makeDescriptionText(title, family),
|
descriptionText: _makeDescriptionText(title, family),
|
||||||
|
imageUrl: imageUrl,
|
||||||
|
firstName: firstName,
|
||||||
|
lastName: lastName,
|
||||||
|
title: title,
|
||||||
|
family: family,
|
||||||
|
fullName: fullName,
|
||||||
|
text: '',
|
||||||
);
|
);
|
||||||
|
|
||||||
String _makeDescriptionText(String? title, String? family) {
|
String _makeDescriptionText(String? title, String? family) {
|
||||||
|
@ -3,14 +3,9 @@ import 'package:flutter_app/data/dtos/thrones_character_dto.dart';
|
|||||||
import 'package:flutter_app/data/mappers/characters_mapper.dart';
|
import 'package:flutter_app/data/mappers/characters_mapper.dart';
|
||||||
import 'package:flutter_app/data/repositories/api_interface.dart';
|
import 'package:flutter_app/data/repositories/api_interface.dart';
|
||||||
import 'package:flutter_app/domain/models/card.dart';
|
import 'package:flutter_app/domain/models/card.dart';
|
||||||
import 'package:pretty_dio_logger/pretty_dio_logger.dart';
|
|
||||||
|
|
||||||
class ThronesRepository extends ApiInterface {
|
class ThronesRepository extends ApiInterface {
|
||||||
static final Dio _dio = Dio()
|
static final Dio _dio = Dio();
|
||||||
..interceptors.add(PrettyDioLogger(
|
|
||||||
requestHeader: true,
|
|
||||||
requestBody: true,
|
|
||||||
));
|
|
||||||
|
|
||||||
static const String _baseUrl = 'https://thronesapi.com';
|
static const String _baseUrl = 'https://thronesapi.com';
|
||||||
|
|
||||||
@ -29,8 +24,10 @@ class ThronesRepository extends ApiInterface {
|
|||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
final List<CardData> data = characters
|
final List<CardData> data = characters
|
||||||
|
.where((character) => q == null || character.fullName.toLowerCase().contains(q.toLowerCase()))
|
||||||
.map((e) => e.toDomain())
|
.map((e) => e.toDomain())
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
} on DioException catch (e) {
|
} on DioException catch (e) {
|
||||||
onError?.call(e.response?.statusMessage);
|
onError?.call(e.response?.statusMessage);
|
||||||
|
@ -7,60 +7,68 @@ class MockRepository extends ApiInterface {
|
|||||||
Future<List<CardData>?> loadData({OnErrorCallback? onError}) async {
|
Future<List<CardData>?> loadData({OnErrorCallback? onError}) async {
|
||||||
return [
|
return [
|
||||||
CardData(
|
CardData(
|
||||||
'Daenerys Targaryen',
|
fullName: 'Daenerys Targaryen',
|
||||||
descriptionText: 'Mother of Dragons',
|
descriptionText: 'Mother of Dragons',
|
||||||
icon: Icons.favorite,
|
icon: Icons.favorite,
|
||||||
imageUrl:
|
imageUrl:
|
||||||
'https://thronesapi.com/assets/images/daenerys.jpg',
|
'https://thronesapi.com/assets/images/daenerys.jpg',
|
||||||
|
text: '', firstName: '', lastName: '', title: '', family: '',
|
||||||
),
|
),
|
||||||
CardData(
|
CardData(
|
||||||
'Samwell Tarly',
|
fullName: 'Samwell Tarly',
|
||||||
descriptionText: 'Maester',
|
descriptionText: 'Maester',
|
||||||
icon: Icons.favorite,
|
icon: Icons.favorite,
|
||||||
imageUrl:
|
imageUrl:
|
||||||
'https://thronesapi.com/assets/images/sam.jpg',
|
'https://thronesapi.com/assets/images/sam.jpg',
|
||||||
|
text: '', firstName: '', lastName: '', title: '', family: '',
|
||||||
),
|
),
|
||||||
CardData(
|
CardData(
|
||||||
'Jon Snow',
|
fullName: 'Jon Snow',
|
||||||
descriptionText: 'King of the North',
|
descriptionText: 'King of the North',
|
||||||
icon: Icons.favorite,
|
icon: Icons.favorite,
|
||||||
imageUrl:
|
imageUrl:
|
||||||
'https://thronesapi.com/assets/images/jon-snow.jpg',
|
'https://thronesapi.com/assets/images/jon-snow.jpg',
|
||||||
|
text: '', firstName: '', lastName: '', title: '', family: '',
|
||||||
),
|
),
|
||||||
CardData(
|
CardData(
|
||||||
'Arya Stark',
|
fullName: 'Arya Stark',
|
||||||
descriptionText: 'No One',
|
descriptionText: 'No One',
|
||||||
icon: Icons.favorite,
|
icon: Icons.favorite,
|
||||||
imageUrl:
|
imageUrl:
|
||||||
'https://thronesapi.com/assets/images/arya-stark.jpg',
|
'https://thronesapi.com/assets/images/arya-stark.jpg',
|
||||||
|
text: '', firstName: '', lastName: '', title: '', family: '',
|
||||||
),
|
),
|
||||||
CardData(
|
CardData(
|
||||||
'Sansa Stark',
|
fullName: 'Sansa Stark',
|
||||||
descriptionText: 'Lady of Winterfell',
|
descriptionText: 'Lady of Winterfell',
|
||||||
icon: Icons.favorite,
|
icon: Icons.favorite,
|
||||||
imageUrl:
|
imageUrl:
|
||||||
'https://thronesapi.com/assets/images/sansa-stark.jpeg',
|
'https://thronesapi.com/assets/images/sansa-stark.jpeg',
|
||||||
|
text: '', firstName: '', lastName: '', title: '', family: '',
|
||||||
),
|
),
|
||||||
CardData(
|
CardData(
|
||||||
'Brandon Stark',
|
fullName: 'Brandon Stark',
|
||||||
descriptionText: 'Lord of Winterfell',
|
descriptionText: 'Lord of Winterfell',
|
||||||
icon: Icons.favorite,
|
icon: Icons.favorite,
|
||||||
imageUrl:
|
imageUrl:
|
||||||
'https://thronesapi.com/assets/images/bran-stark.jpg',
|
'https://thronesapi.com/assets/images/bran-stark.jpg',
|
||||||
|
text: '', firstName: '', lastName: '', title: '', family: '',
|
||||||
),
|
),
|
||||||
CardData(
|
CardData(
|
||||||
'Ned Stark',
|
fullName: 'Ned Stark',
|
||||||
descriptionText: 'Lord of Winterfell',
|
descriptionText: 'Lord of Winterfell',
|
||||||
icon: Icons.favorite,
|
icon: Icons.favorite,
|
||||||
imageUrl:
|
imageUrl:
|
||||||
'https://thronesapi.com/assets/images/ned-stark.jpg',
|
'https://thronesapi.com/assets/images/ned-stark.jpg',
|
||||||
|
text: '', firstName: '', lastName: '', title: '', family: '',
|
||||||
),
|
),
|
||||||
CardData(
|
CardData(
|
||||||
'Robert Baratheon',
|
fullName: 'Robert Baratheon',
|
||||||
descriptionText: 'Lord of the Seven Kingdoms',
|
descriptionText: 'Lord of the Seven Kingdoms',
|
||||||
icon: Icons.favorite,
|
icon: Icons.favorite,
|
||||||
imageUrl:
|
imageUrl:
|
||||||
'https://thronesapi.com/assets/images/robert-baratheon.jpeg',
|
'https://thronesapi.com/assets/images/robert-baratheon.jpeg',
|
||||||
|
text: '', firstName: '', lastName: '', title: '', family: '',
|
||||||
),
|
),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
@ -5,11 +5,21 @@ class CardData {
|
|||||||
final String descriptionText;
|
final String descriptionText;
|
||||||
final IconData icon;
|
final IconData icon;
|
||||||
final String? imageUrl;
|
final String? imageUrl;
|
||||||
|
final String firstName;
|
||||||
|
final String lastName;
|
||||||
|
final String fullName;
|
||||||
|
final String title;
|
||||||
|
final String family;
|
||||||
|
|
||||||
CardData(
|
CardData({
|
||||||
this.text, {
|
required this.text,
|
||||||
required this.descriptionText,
|
required this.descriptionText,
|
||||||
this.icon = Icons.catching_pokemon,
|
this.icon = Icons.people,
|
||||||
this.imageUrl,
|
this.imageUrl,
|
||||||
});
|
required this.firstName,
|
||||||
|
required this.lastName,
|
||||||
|
required this.fullName,
|
||||||
|
required this.title,
|
||||||
|
required this.family,
|
||||||
|
});
|
||||||
}
|
}
|
@ -11,9 +11,10 @@ class DetailsPage extends StatelessWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(),
|
appBar: AppBar(),
|
||||||
body: Padding(
|
body: Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 16.0),
|
padding: const EdgeInsets.symmetric(horizontal: 16.0),
|
||||||
|
child: SingleChildScrollView(
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
@ -32,11 +33,11 @@ class DetailsPage extends StatelessWidget {
|
|||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.only(bottom: 4.0),
|
padding: const EdgeInsets.only(bottom: 4.0),
|
||||||
child: Text(
|
child: Text(
|
||||||
data.text,
|
data.fullName,
|
||||||
style: Theme.of(context).textTheme.bodyLarge?.copyWith(
|
style: Theme.of(context).textTheme.bodyLarge?.copyWith(
|
||||||
fontSize: 27.0,
|
fontSize: 27.0,
|
||||||
fontFamily: 'Times New Roman',
|
fontFamily: 'Times New Roman',
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
@ -45,10 +46,32 @@ class DetailsPage extends StatelessWidget {
|
|||||||
fontSize: 20.0,
|
fontSize: 20.0,
|
||||||
fontFamily: 'Times New Roman',
|
fontFamily: 'Times New Roman',
|
||||||
),
|
),
|
||||||
)
|
),
|
||||||
|
const SizedBox(height: 16.0),
|
||||||
|
Text(
|
||||||
|
'First Name: ${data.firstName}',
|
||||||
|
style: Theme.of(context).textTheme.bodyMedium,
|
||||||
|
),
|
||||||
|
const SizedBox(height: 8.0),
|
||||||
|
Text(
|
||||||
|
'Last Name: ${data.lastName}',
|
||||||
|
style: Theme.of(context).textTheme.bodyMedium,
|
||||||
|
),
|
||||||
|
const SizedBox(height: 8.0),
|
||||||
|
Text(
|
||||||
|
'Title: ${data.title}',
|
||||||
|
style: Theme.of(context).textTheme.bodyMedium,
|
||||||
|
),
|
||||||
|
const SizedBox(height: 8.0),
|
||||||
|
Text(
|
||||||
|
'Family: ${data.family}',
|
||||||
|
style: Theme.of(context).textTheme.bodyMedium,
|
||||||
|
),
|
||||||
|
const SizedBox(height: 8.0),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
)
|
),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -5,6 +5,7 @@ typedef OnLikeCallback = void Function(String title, bool isLiked)?;
|
|||||||
class _Card extends StatefulWidget {
|
class _Card extends StatefulWidget {
|
||||||
final String text;
|
final String text;
|
||||||
final String descriptionText;
|
final String descriptionText;
|
||||||
|
final String fullName;
|
||||||
final IconData icon;
|
final IconData icon;
|
||||||
final String? imageUrl;
|
final String? imageUrl;
|
||||||
final OnLikeCallback onLike;
|
final OnLikeCallback onLike;
|
||||||
@ -14,6 +15,7 @@ class _Card extends StatefulWidget {
|
|||||||
this.text, {
|
this.text, {
|
||||||
this.icon = Icons.catching_pokemon,
|
this.icon = Icons.catching_pokemon,
|
||||||
required this.descriptionText,
|
required this.descriptionText,
|
||||||
|
required this.fullName,
|
||||||
this.imageUrl,
|
this.imageUrl,
|
||||||
this.onLike,
|
this.onLike,
|
||||||
this.onTap,
|
this.onTap,
|
||||||
@ -27,6 +29,7 @@ class _Card extends StatefulWidget {
|
|||||||
_Card(
|
_Card(
|
||||||
data.text,
|
data.text,
|
||||||
descriptionText: data.descriptionText,
|
descriptionText: data.descriptionText,
|
||||||
|
fullName: data.fullName,
|
||||||
icon: data.icon,
|
icon: data.icon,
|
||||||
imageUrl: data.imageUrl,
|
imageUrl: data.imageUrl,
|
||||||
onLike: onLike,
|
onLike: onLike,
|
||||||
@ -44,92 +47,74 @@ class _CardState extends State<_Card> {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
onTap: widget.onTap,
|
onTap: widget.onTap,
|
||||||
child: Container(
|
child: Card(
|
||||||
margin: const EdgeInsets.all(16),
|
margin: const EdgeInsets.all(8.0),
|
||||||
constraints: const BoxConstraints(minHeight: 140),
|
child: Column(
|
||||||
decoration: BoxDecoration(
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
color: Colors.white70,
|
children: [
|
||||||
borderRadius: BorderRadius.circular(20),
|
ClipRRect(
|
||||||
border: Border.all(color: Colors.grey.shade200),
|
borderRadius: BorderRadius.circular(15),
|
||||||
boxShadow: [
|
child: SizedBox(
|
||||||
BoxShadow(
|
height: 250,
|
||||||
color: Colors.grey.withOpacity(.5),
|
width: double.infinity,
|
||||||
spreadRadius: 4,
|
child: Image.network(
|
||||||
offset: const Offset(0, 5),
|
widget.imageUrl ?? '',
|
||||||
blurRadius: 8,
|
fit: BoxFit.cover,
|
||||||
|
errorBuilder: (_, __, ___) => const Placeholder(),
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
],
|
Padding(
|
||||||
),
|
padding: const EdgeInsets.all(8.0),
|
||||||
child: IntrinsicHeight(
|
child: Column(
|
||||||
child: Column(
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
children: [
|
||||||
children: [
|
Text(
|
||||||
ClipRRect(
|
widget.fullName,
|
||||||
borderRadius: const BorderRadius.only(
|
style: Theme.of(context).textTheme.bodyLarge?.copyWith(
|
||||||
bottomLeft: Radius.circular(20),
|
fontSize: 20.0,
|
||||||
topLeft: Radius.circular(20),
|
fontFamily: 'Times New Roman',
|
||||||
),
|
|
||||||
child: SizedBox(
|
|
||||||
height: double.infinity,
|
|
||||||
width: 160,
|
|
||||||
child: Image.network(
|
|
||||||
widget.imageUrl ?? '',
|
|
||||||
fit: BoxFit.cover,
|
|
||||||
errorBuilder: (_, __, ___) => const Placeholder(),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Expanded(
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.only(left: 16.0),
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
widget.text,
|
|
||||||
style: Theme.of(context).textTheme.headlineLarge,
|
|
||||||
),
|
|
||||||
Text(
|
|
||||||
widget.descriptionText,
|
|
||||||
style: Theme.of(context).textTheme.bodyLarge,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Align(
|
|
||||||
alignment: Alignment.bottomRight,
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.only(
|
|
||||||
left: 8.0,
|
|
||||||
right: 16.0,
|
|
||||||
bottom: 16.0,
|
|
||||||
),
|
|
||||||
child: GestureDetector(
|
|
||||||
onTap: () {
|
|
||||||
setState(() {
|
|
||||||
isLiked = !isLiked;
|
|
||||||
});
|
|
||||||
widget.onLike?.call(widget.text, isLiked);
|
|
||||||
},
|
|
||||||
child: AnimatedSwitcher(
|
|
||||||
duration: const Duration(milliseconds: 300),
|
|
||||||
child: isLiked
|
|
||||||
? const Icon(
|
|
||||||
Icons.favorite,
|
|
||||||
color: Colors.redAccent,
|
|
||||||
key: ValueKey<int>(0),
|
|
||||||
)
|
|
||||||
: const Icon(
|
|
||||||
Icons.favorite_border,
|
|
||||||
key: ValueKey<int>(1),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
Text(
|
||||||
|
widget.descriptionText,
|
||||||
|
style: Theme.of(context).textTheme.bodyMedium,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Align(
|
||||||
|
alignment: Alignment.bottomRight,
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.only(
|
||||||
|
left: 8.0,
|
||||||
|
right: 16.0,
|
||||||
|
bottom: 16.0,
|
||||||
|
),
|
||||||
|
child: GestureDetector(
|
||||||
|
onTap: () {
|
||||||
|
setState(() {
|
||||||
|
isLiked = !isLiked;
|
||||||
|
});
|
||||||
|
widget.onLike?.call(widget.fullName, isLiked);
|
||||||
|
},
|
||||||
|
child: AnimatedSwitcher(
|
||||||
|
duration: const Duration(milliseconds: 300),
|
||||||
|
child: isLiked
|
||||||
|
? const Icon(
|
||||||
|
Icons.favorite,
|
||||||
|
color: Colors.redAccent,
|
||||||
|
key: ValueKey<int>(0),
|
||||||
|
)
|
||||||
|
: const Icon(
|
||||||
|
Icons.favorite_border,
|
||||||
|
key: ValueKey<int>(1),
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
),
|
||||||
),
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -30,7 +30,7 @@ class Body extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _BodyState extends State<Body> {
|
class _BodyState extends State<Body> {
|
||||||
final searchController = TextEditingController();
|
late TextEditingController searchController;
|
||||||
late Future<List<CardData>?> data;
|
late Future<List<CardData>?> data;
|
||||||
|
|
||||||
final repo = ThronesRepository();
|
final repo = ThronesRepository();
|
||||||
@ -38,7 +38,14 @@ class _BodyState extends State<Body> {
|
|||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
data = repo.loadData();
|
data = repo.loadData();
|
||||||
super.initState();
|
searchController = TextEditingController();
|
||||||
|
data = repo.loadData();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
searchController.dispose();
|
||||||
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -75,6 +82,7 @@ class _BodyState extends State<Body> {
|
|||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return ListView.builder(
|
return ListView.builder(
|
||||||
|
shrinkWrap: true,
|
||||||
itemCount: snapshot.data!.length,
|
itemCount: snapshot.data!.length,
|
||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
final cardData = snapshot.data![index];
|
final cardData = snapshot.data![index];
|
||||||
@ -90,7 +98,7 @@ class _BodyState extends State<Body> {
|
|||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user