126 lines
4.1 KiB
Dart
126 lines
4.1 KiB
Dart
part of 'home_page.dart';
|
||
|
||
typedef OnLikeCallback = void Function(String title, bool isLiked)?;
|
||
|
||
class _GameCard extends StatefulWidget {
|
||
final String name;
|
||
final int price;
|
||
final String? image;
|
||
final String? description;
|
||
|
||
//OnLikeCallback - пользовательский тип, ф-ия
|
||
final OnLikeCallback onLike;
|
||
final VoidCallback? onTap;
|
||
|
||
//обычный конструктор
|
||
const _GameCard({
|
||
super.key,
|
||
required this.name,
|
||
required this.price,
|
||
this.image,
|
||
this.description,
|
||
this.onLike,
|
||
this.onTap,
|
||
});
|
||
|
||
//именованный конструктор
|
||
factory _GameCard.fromData(GameData data,
|
||
{OnLikeCallback onLike, VoidCallback? onTap}) =>
|
||
_GameCard(
|
||
name: data.name,
|
||
price: data.price,
|
||
image: data.image,
|
||
description: data.description,
|
||
onLike: onLike,
|
||
onTap: onTap,
|
||
);
|
||
|
||
//Переход в stateful
|
||
@override
|
||
State<_GameCard> createState() => _GameCardState();
|
||
}
|
||
|
||
//extends - переход в stateful
|
||
class _GameCardState extends State<_GameCard> {
|
||
//доп. поле, которое будет меняться; состояние того, нравится игра или нет
|
||
bool isLiked = false;
|
||
|
||
@override
|
||
Widget build(BuildContext context) {
|
||
return Container(
|
||
margin: const EdgeInsets.all(10),
|
||
padding: const EdgeInsets.only(top: 3, bottom: 3, left: 10, right: 10),
|
||
// constraints: const BoxConstraints(minHeight: 350),
|
||
//форма карточки
|
||
decoration: BoxDecoration(
|
||
color: const Color.fromARGB(255, 56, 90, 128),
|
||
borderRadius: BorderRadius.circular(5),
|
||
),
|
||
child: IntrinsicHeight(
|
||
child: Column(
|
||
//Выравнивание по середине
|
||
crossAxisAlignment: CrossAxisAlignment.center,
|
||
children: [
|
||
Row(
|
||
mainAxisAlignment: MainAxisAlignment.end,
|
||
children: [
|
||
Padding(
|
||
padding: EdgeInsets.only(bottom: 4, top: 2),
|
||
child: GestureDetector(
|
||
onTap: () {
|
||
setState(() {
|
||
isLiked = !isLiked;
|
||
});
|
||
widget.onLike?.call(widget.name, isLiked);
|
||
},
|
||
child: AnimatedSwitcher(
|
||
duration: const Duration(milliseconds: 175),
|
||
child: isLiked
|
||
? const Icon(Icons.favorite,
|
||
color: Colors.pink, key: ValueKey(0))
|
||
: const Icon(Icons.favorite_border,
|
||
color: Colors.white, key: ValueKey(1))))),
|
||
],
|
||
),
|
||
//ClipRRect для скругления краёв фото
|
||
ClipRRect(
|
||
borderRadius: BorderRadius.circular(4.0),
|
||
child: SizedBox(
|
||
height: 200,
|
||
width: MediaQuery.of(context).size.width,
|
||
child: Image.network(
|
||
widget.image ?? '',
|
||
fit: BoxFit.fill,
|
||
errorBuilder: (_, __, ___) => const Placeholder(),
|
||
),
|
||
),
|
||
),
|
||
// Название игры
|
||
GestureDetector(
|
||
onTap: widget.onTap,
|
||
child:
|
||
Text(
|
||
widget.name,
|
||
style: const TextStyle(
|
||
color: Colors.white,
|
||
fontWeight: FontWeight.bold,
|
||
fontSize: 32,
|
||
),
|
||
textAlign: TextAlign.center,
|
||
)
|
||
),
|
||
// Цена игры
|
||
Text(
|
||
'${widget.price} руб.',
|
||
style: const TextStyle(
|
||
color: Colors.white,
|
||
fontWeight: FontWeight.bold,
|
||
fontSize: 24,
|
||
),
|
||
),
|
||
],
|
||
),
|
||
));
|
||
}
|
||
}
|