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,
|
|||
|
),
|
|||
|
),
|
|||
|
],
|
|||
|
),
|
|||
|
));
|
|||
|
}
|
|||
|
}
|