Add decomposition to lec4
This commit is contained in:
parent
58a81e14eb
commit
62b87de295
@ -1,8 +1,13 @@
|
||||
part of 'home_page.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:test_app/domain/card.dart';
|
||||
|
||||
part 'card_image.dart';
|
||||
part 'card_like.dart';
|
||||
part 'card_text.dart';
|
||||
|
||||
typedef OnLikeCallback = void Function(String title, bool isLiked)?;
|
||||
|
||||
class _Card extends StatefulWidget {
|
||||
class HomeCard extends StatelessWidget {
|
||||
final String text;
|
||||
final String descriptionText;
|
||||
final IconData icon;
|
||||
@ -10,21 +15,22 @@ class _Card extends StatefulWidget {
|
||||
final OnLikeCallback onLike;
|
||||
final VoidCallback? onTap;
|
||||
|
||||
const _Card(
|
||||
const HomeCard(
|
||||
this.text, {
|
||||
this.icon = Icons.ac_unit_outlined,
|
||||
required this.descriptionText,
|
||||
this.imageUrl,
|
||||
this.onLike,
|
||||
this.onTap,
|
||||
super.key,
|
||||
});
|
||||
|
||||
factory _Card.fromData(
|
||||
factory HomeCard.fromData(
|
||||
CardData data, {
|
||||
OnLikeCallback? onLike,
|
||||
VoidCallback? onTap,
|
||||
}) =>
|
||||
_Card(
|
||||
HomeCard(
|
||||
data.text,
|
||||
descriptionText: data.descriptionText,
|
||||
icon: data.icon,
|
||||
@ -33,17 +39,10 @@ class _Card extends StatefulWidget {
|
||||
onTap: onTap,
|
||||
);
|
||||
|
||||
@override
|
||||
State<_Card> createState() => _CardState();
|
||||
}
|
||||
|
||||
class _CardState extends State<_Card> {
|
||||
bool _isLiked = false;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return GestureDetector(
|
||||
onTap: widget.onTap,
|
||||
onTap: onTap,
|
||||
child: Container(
|
||||
margin: const EdgeInsets.only(top: 8, bottom: 8),
|
||||
constraints: const BoxConstraints(minHeight: 140),
|
||||
@ -63,94 +62,14 @@ class _CardState extends State<_Card> {
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
ClipRRect(
|
||||
borderRadius: const BorderRadius.only(
|
||||
bottomLeft: Radius.circular(20),
|
||||
topLeft: Radius.circular(20),
|
||||
),
|
||||
child: SizedBox(
|
||||
height: double.infinity,
|
||||
width: 115,
|
||||
child: Stack(
|
||||
children: [
|
||||
Positioned.fill(
|
||||
child: Image.network(
|
||||
widget.imageUrl ?? '',
|
||||
fit: BoxFit.cover,
|
||||
errorBuilder: (_, __, ___) => const Placeholder(),
|
||||
),
|
||||
),
|
||||
Align(
|
||||
alignment: Alignment.bottomLeft,
|
||||
child: Container(
|
||||
decoration: const BoxDecoration(
|
||||
color: Colors.orangeAccent,
|
||||
borderRadius: BorderRadius.only(
|
||||
topRight: Radius.circular(20),
|
||||
),
|
||||
),
|
||||
padding: const EdgeInsets.fromLTRB(8, 2, 8, 2),
|
||||
child: Text(
|
||||
'скидка 20%',
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.bodyMedium
|
||||
?.copyWith(color: Colors.black),
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
_CardImage(imageUrl ?? ''),
|
||||
_CardText(
|
||||
text,
|
||||
descriptionText: descriptionText,
|
||||
),
|
||||
Expanded(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(left: 8),
|
||||
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,
|
||||
right: 16,
|
||||
bottom: 16,
|
||||
),
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
setState(() {
|
||||
_isLiked = !_isLiked;
|
||||
});
|
||||
widget.onLike?.call(widget.text, _isLiked);
|
||||
},
|
||||
child: AnimatedSwitcher(
|
||||
duration: const Duration(milliseconds: 200),
|
||||
child: _isLiked
|
||||
? const Icon(
|
||||
Icons.favorite,
|
||||
color: Colors.redAccent,
|
||||
key: ValueKey(0),
|
||||
)
|
||||
: const Icon(
|
||||
Icons.favorite_border,
|
||||
key: ValueKey(1),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
_CardLike(
|
||||
onLike,
|
||||
text: text,
|
||||
)
|
||||
],
|
||||
),
|
||||
|
51
lec4/lib/view/home_page/card_image.dart
Normal file
51
lec4/lib/view/home_page/card_image.dart
Normal file
@ -0,0 +1,51 @@
|
||||
part of 'card.dart';
|
||||
|
||||
class _CardImage extends StatelessWidget {
|
||||
final String imageUrl;
|
||||
|
||||
const _CardImage(this.imageUrl);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ClipRRect(
|
||||
borderRadius: const BorderRadius.only(
|
||||
bottomLeft: Radius.circular(20),
|
||||
topLeft: Radius.circular(20),
|
||||
),
|
||||
child: SizedBox(
|
||||
height: double.infinity,
|
||||
width: 115,
|
||||
child: Stack(
|
||||
children: [
|
||||
Positioned.fill(
|
||||
child: Image.network(
|
||||
imageUrl,
|
||||
fit: BoxFit.cover,
|
||||
errorBuilder: (_, __, ___) => const Placeholder(),
|
||||
),
|
||||
),
|
||||
Align(
|
||||
alignment: Alignment.bottomLeft,
|
||||
child: Container(
|
||||
decoration: const BoxDecoration(
|
||||
color: Colors.orangeAccent,
|
||||
borderRadius: BorderRadius.only(
|
||||
topRight: Radius.circular(20),
|
||||
),
|
||||
),
|
||||
padding: const EdgeInsets.fromLTRB(8, 2, 8, 2),
|
||||
child: Text(
|
||||
'скидка 20%',
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.bodyMedium
|
||||
?.copyWith(color: Colors.black),
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
50
lec4/lib/view/home_page/card_like.dart
Normal file
50
lec4/lib/view/home_page/card_like.dart
Normal file
@ -0,0 +1,50 @@
|
||||
part of 'card.dart';
|
||||
|
||||
class _CardLike extends StatefulWidget {
|
||||
final OnLikeCallback onLike;
|
||||
final String text;
|
||||
|
||||
const _CardLike(this.onLike, {required this.text});
|
||||
|
||||
@override
|
||||
State<_CardLike> createState() => _CardLikeState();
|
||||
}
|
||||
|
||||
class _CardLikeState extends State<_CardLike> {
|
||||
bool _isLiked = false;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Align(
|
||||
alignment: Alignment.bottomRight,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
left: 8,
|
||||
right: 16,
|
||||
bottom: 16,
|
||||
),
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
setState(() {
|
||||
_isLiked = !_isLiked;
|
||||
});
|
||||
widget.onLike?.call(widget.text, _isLiked);
|
||||
},
|
||||
child: AnimatedSwitcher(
|
||||
duration: const Duration(milliseconds: 200),
|
||||
child: _isLiked
|
||||
? const Icon(
|
||||
Icons.favorite,
|
||||
color: Colors.redAccent,
|
||||
key: ValueKey(0),
|
||||
)
|
||||
: const Icon(
|
||||
Icons.favorite_border,
|
||||
key: ValueKey(1),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
33
lec4/lib/view/home_page/card_text.dart
Normal file
33
lec4/lib/view/home_page/card_text.dart
Normal file
@ -0,0 +1,33 @@
|
||||
part of 'card.dart';
|
||||
|
||||
class _CardText extends StatelessWidget {
|
||||
final String text;
|
||||
final String descriptionText;
|
||||
|
||||
const _CardText(
|
||||
this.text, {
|
||||
required this.descriptionText,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Expanded(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(left: 8),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
text,
|
||||
style: Theme.of(context).textTheme.headlineLarge,
|
||||
),
|
||||
Text(
|
||||
descriptionText,
|
||||
style: Theme.of(context).textTheme.bodyLarge,
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -1,8 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:test_app/domain/card.dart';
|
||||
import 'package:test_app/view/details_page/details_page.dart';
|
||||
|
||||
part 'card.dart';
|
||||
import 'package:test_app/view/home_page/card.dart';
|
||||
|
||||
class MyHomePage extends StatefulWidget {
|
||||
const MyHomePage({super.key, required this.title});
|
||||
@ -62,7 +61,7 @@ class Body extends StatelessWidget {
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: data
|
||||
.map((data) => _Card.fromData(
|
||||
.map((data) => HomeCard.fromData(
|
||||
data,
|
||||
onLike: (String title, bool isLiked) =>
|
||||
_showSnackBar(context, title, isLiked),
|
||||
|
Loading…
Reference in New Issue
Block a user