lab 4 done
This commit is contained in:
parent
323681f358
commit
904649bae7
BIN
assets/images/bonejamin.png
Normal file
BIN
assets/images/bonejamin.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 130 KiB |
BIN
assets/images/delirium.png
Normal file
BIN
assets/images/delirium.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 180 KiB |
250
lib/main.dart
250
lib/main.dart
@ -1,4 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:pmu_malafeev_pi31/presentation/pages/homepage.dart';
|
||||
import 'package:pmu_malafeev_pi31/presentation/classes/skin.dart';
|
||||
|
||||
void main() {
|
||||
runApp(const MyApp());
|
||||
@ -20,252 +22,4 @@ class MyApp extends StatelessWidget {
|
||||
}
|
||||
}
|
||||
|
||||
class MyHomePage extends StatefulWidget {
|
||||
const MyHomePage({super.key, required this.title});
|
||||
final String title;
|
||||
|
||||
@override
|
||||
State<MyHomePage> createState() => _MyHomePageState();
|
||||
}
|
||||
|
||||
class _MyHomePageState extends State<MyHomePage> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
|
||||
title: Text(widget.title),
|
||||
),
|
||||
body: const MyWidget(),
|
||||
);
|
||||
}
|
||||
}
|
||||
final List<FortniteSkin> skins = [
|
||||
FortniteSkin(
|
||||
imageUrl: 'assets/images/shark.png',
|
||||
name: 'Safety First Steve',
|
||||
description: 'Dont make him blow the whistle.!',
|
||||
rarity: Rarity.epic,
|
||||
),
|
||||
FortniteSkin(
|
||||
imageUrl: 'assets/images/raven.png',
|
||||
name: 'Raven',
|
||||
description: 'Brooding master of dark skies.',
|
||||
rarity: Rarity.legendary,
|
||||
),
|
||||
];
|
||||
class MyWidget extends StatelessWidget{
|
||||
const MyWidget({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Center(
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
for (var skin in skins)
|
||||
_Card(
|
||||
name: skin.name,
|
||||
description: skin.description,
|
||||
imageUrl: skin.imageUrl,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _Card extends StatefulWidget {
|
||||
final String name;
|
||||
final String imageUrl;
|
||||
final String description;
|
||||
|
||||
const _Card({
|
||||
required this.name,
|
||||
required this.description,
|
||||
required this.imageUrl,
|
||||
});
|
||||
|
||||
@override
|
||||
State<_Card> createState() => _CardState();
|
||||
}
|
||||
|
||||
class _CardState extends State<_Card> {
|
||||
bool isLiked = false;
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
margin: const EdgeInsets.all(16),
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.greenAccent,
|
||||
borderRadius: BorderRadius.circular(15),
|
||||
border: Border.all(
|
||||
color: Colors.black,
|
||||
width: 3,
|
||||
)
|
||||
),
|
||||
child: IntrinsicHeight(
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
ClipRRect(
|
||||
borderRadius: const BorderRadius.only(
|
||||
bottomLeft: Radius.circular(20),
|
||||
bottomRight: Radius.circular(20)
|
||||
),
|
||||
child: SizedBox(
|
||||
height: double.infinity,
|
||||
width: 120,
|
||||
child: Image.asset(
|
||||
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.name,
|
||||
style: const TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
|
||||
),
|
||||
Text(
|
||||
widget.description,
|
||||
style: const TextStyle(fontSize: 15),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
//const Spacer(), да не умер он в конце драйва
|
||||
Align(
|
||||
alignment: Alignment.bottomRight,
|
||||
child: (
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(left: 8.0),
|
||||
child: GestureDetector
|
||||
(
|
||||
onTap: () {
|
||||
setState(() {
|
||||
isLiked = !isLiked;
|
||||
/**/ });
|
||||
},
|
||||
child: Icon(
|
||||
isLiked ? Icons.favorite : Icons.favorite_border,
|
||||
color: isLiked ? Colors.red : null,
|
||||
)
|
||||
),
|
||||
)
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class FortniteSkin {
|
||||
final String imageUrl;
|
||||
final String name;
|
||||
final String description;
|
||||
final Rarity rarity;
|
||||
|
||||
FortniteSkin({
|
||||
required this.imageUrl,
|
||||
required this.name,
|
||||
required this.description,
|
||||
required this.rarity,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
enum Rarity {
|
||||
unknown(0),
|
||||
legendary(1),
|
||||
epic(2),
|
||||
rare(3),
|
||||
common(4);
|
||||
|
||||
final int value;
|
||||
|
||||
const Rarity(this.value);
|
||||
}
|
||||
|
||||
String getRarityString(Rarity rarity) {
|
||||
switch (rarity) {
|
||||
case Rarity.unknown:
|
||||
return 'Unknown';
|
||||
case Rarity.legendary:
|
||||
return 'Legendary';
|
||||
case Rarity.epic:
|
||||
return 'Epic';
|
||||
case Rarity.rare:
|
||||
return 'Rare';
|
||||
case Rarity.common:
|
||||
return 'Common';
|
||||
default:
|
||||
return 'Unknown';
|
||||
}
|
||||
}
|
||||
|
||||
void changeSkinNames() {
|
||||
final List<FortniteSkin> skins = [
|
||||
FortniteSkin(
|
||||
imageUrl: 'assets/images/shark.png',
|
||||
name: 'Safety First Steve',
|
||||
description: 'Dont make him blow the whistle.!',
|
||||
rarity: Rarity.epic,
|
||||
),
|
||||
FortniteSkin(
|
||||
imageUrl: 'assets/images/raven.png',
|
||||
name: 'Raven',
|
||||
description: 'Brooding master of dark skies.',
|
||||
rarity: Rarity.legendary,
|
||||
),
|
||||
];
|
||||
final Future aboba = printAboba();
|
||||
print(aboba);
|
||||
final List<FortniteSkin> updatedSkins = [];
|
||||
|
||||
for (var skin in skins) {
|
||||
updatedSkins.add(FortniteSkin(
|
||||
imageUrl: skin.imageUrl,
|
||||
name: '${skin.name} 2',
|
||||
description: skin.description,
|
||||
rarity: skin.rarity,
|
||||
));
|
||||
}
|
||||
|
||||
updatedSkins.forEach((FortniteSkin e) => print(e.name));
|
||||
}
|
||||
|
||||
Future<void> printAboba() async {
|
||||
print("This is how work Future");
|
||||
await Future.delayed(const Duration(seconds: 2));
|
||||
print("This is how work Future");
|
||||
}
|
||||
|
||||
class SoldFortniteSkin extends FortniteSkin {
|
||||
final int price;
|
||||
|
||||
SoldFortniteSkin({
|
||||
required String imageUrl,
|
||||
required String name,
|
||||
required String description,
|
||||
required Rarity rarity,
|
||||
required this.price,
|
||||
}) : super(
|
||||
imageUrl: imageUrl,
|
||||
name: name,
|
||||
description: description,
|
||||
rarity: rarity,
|
||||
);
|
||||
}
|
||||
|
97
lib/presentation/classes/skin.dart
Normal file
97
lib/presentation/classes/skin.dart
Normal file
@ -0,0 +1,97 @@
|
||||
class FortniteSkin {
|
||||
final String imageUrl;
|
||||
final String name;
|
||||
final String description;
|
||||
final Rarity rarity;
|
||||
|
||||
FortniteSkin({
|
||||
required this.imageUrl,
|
||||
required this.name,
|
||||
required this.description,
|
||||
required this.rarity,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
enum Rarity {
|
||||
unknown(0),
|
||||
Legendary(1),
|
||||
Epic(2),
|
||||
Rare(3),
|
||||
Common(4);
|
||||
|
||||
final int value;
|
||||
|
||||
const Rarity(this.value);
|
||||
}
|
||||
|
||||
String getRarityString(Rarity rarity) {
|
||||
switch (rarity) {
|
||||
case Rarity.unknown:
|
||||
return 'Unknown';
|
||||
case Rarity.Legendary:
|
||||
return 'Legendary';
|
||||
case Rarity.Epic:
|
||||
return 'Epic';
|
||||
case Rarity.Rare:
|
||||
return 'Rare';
|
||||
case Rarity.Common:
|
||||
return 'Common';
|
||||
default:
|
||||
return 'Unknown';
|
||||
}
|
||||
}
|
||||
|
||||
void changeSkinNames() {
|
||||
final List<FortniteSkin> skins = [
|
||||
FortniteSkin(
|
||||
imageUrl: 'assets/images/shark.png',
|
||||
name: 'Safety First Steve',
|
||||
description: 'Dont make him blow the whistle.!',
|
||||
rarity: Rarity.Epic,
|
||||
),
|
||||
FortniteSkin(
|
||||
imageUrl: 'assets/images/raven.png',
|
||||
name: 'Raven',
|
||||
description: 'Brooding master of dark skies.',
|
||||
rarity: Rarity.Legendary,
|
||||
),
|
||||
];
|
||||
final Future aboba = printAboba();
|
||||
print(aboba);
|
||||
final List<FortniteSkin> updatedSkins = [];
|
||||
|
||||
for (var skin in skins) {
|
||||
updatedSkins.add(FortniteSkin(
|
||||
imageUrl: skin.imageUrl,
|
||||
name: '${skin.name} 2',
|
||||
description: skin.description,
|
||||
rarity: skin.rarity,
|
||||
));
|
||||
}
|
||||
|
||||
updatedSkins.forEach((FortniteSkin e) => print(e.name));
|
||||
}
|
||||
|
||||
Future<void> printAboba() async {
|
||||
print("This is how work Future");
|
||||
await Future.delayed(const Duration(seconds: 2));
|
||||
print("This is how work Future");
|
||||
}
|
||||
|
||||
class SoldFortniteSkin extends FortniteSkin {
|
||||
final int price;
|
||||
|
||||
SoldFortniteSkin({
|
||||
required String imageUrl,
|
||||
required String name,
|
||||
required String description,
|
||||
required Rarity rarity,
|
||||
required this.price,
|
||||
}) : super(
|
||||
imageUrl: imageUrl,
|
||||
name: name,
|
||||
description: description,
|
||||
rarity: rarity,
|
||||
);
|
||||
}
|
60
lib/presentation/pages/datailpage.dart
Normal file
60
lib/presentation/pages/datailpage.dart
Normal file
@ -0,0 +1,60 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:pmu_malafeev_pi31/presentation/classes/skin.dart';
|
||||
|
||||
class DetailPage extends StatelessWidget {
|
||||
final FortniteSkin skin;
|
||||
const DetailPage(this.skin, {super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
backgroundColor: Colors.greenAccent,
|
||||
title: const Text('About skin'),
|
||||
),
|
||||
body: Container(
|
||||
color: Colors.greenAccent,
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Center(
|
||||
child: Image.asset(
|
||||
skin.imageUrl,
|
||||
width: 300,
|
||||
height: 300,
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
Center(
|
||||
child: Text(
|
||||
skin.name,
|
||||
style: Theme.of(context).textTheme.headlineLarge,
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(left: 8.0),
|
||||
child: Text(
|
||||
skin.description,
|
||||
style: Theme.of(context).textTheme.bodyLarge,
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(left: 8.0, top: 4.0),
|
||||
child: Text(
|
||||
skin.rarity.toString(),
|
||||
style: Theme.of(context).textTheme.bodyLarge,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
}
|
108
lib/presentation/pages/homepage.dart
Normal file
108
lib/presentation/pages/homepage.dart
Normal file
@ -0,0 +1,108 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:pmu_malafeev_pi31/presentation/pages/datailpage.dart';
|
||||
|
||||
import '../classes/skin.dart';
|
||||
|
||||
part '../widgets/card.dart';
|
||||
|
||||
class MyHomePage extends StatefulWidget {
|
||||
const MyHomePage({super.key, required this.title});
|
||||
final String title;
|
||||
|
||||
@override
|
||||
State<MyHomePage> createState() => _MyHomePageState();
|
||||
}
|
||||
|
||||
class _MyHomePageState extends State<MyHomePage> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
backgroundColor: Colors.greenAccent,
|
||||
title: Text(widget.title),
|
||||
),
|
||||
body: const Body(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class Body extends StatelessWidget{
|
||||
const Body({super.key});
|
||||
void _showSnackBar(BuildContext context, String name, bool isLiked) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
|
||||
content: Text(
|
||||
'Skin $name ${isLiked ? 'liked' : 'disliked'}',
|
||||
style: Theme.of(context).textTheme.bodyLarge,
|
||||
),
|
||||
backgroundColor: Colors.greenAccent,
|
||||
duration: const Duration(seconds: 1),
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Center(
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
for (var skin in skins)
|
||||
_Card(
|
||||
name: skin.name,
|
||||
description: skin.description,
|
||||
imageUrl: skin.imageUrl,
|
||||
rarity: skin.rarity,
|
||||
onLike: (name, isLiked) => _showSnackBar(context, name, isLiked),
|
||||
onTap: () => _navToDetails(context, skin),
|
||||
),
|
||||
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
void _navToDetails(BuildContext context, FortniteSkin skin)
|
||||
{
|
||||
Navigator.push(
|
||||
context,
|
||||
CupertinoPageRoute(builder: (context) => DetailPage(skin)),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
final List<FortniteSkin> skins = [
|
||||
FortniteSkin(
|
||||
imageUrl: 'assets/images/shark.png',
|
||||
name: 'Safety First Steve',
|
||||
description: 'Dont make him blow the whistle.!',
|
||||
rarity: Rarity.Epic,
|
||||
),
|
||||
FortniteSkin(
|
||||
imageUrl: 'assets/images/raven.png',
|
||||
name: 'Raven',
|
||||
description: 'Brooding master of dark skies.',
|
||||
rarity: Rarity.Legendary,
|
||||
),
|
||||
FortniteSkin(
|
||||
imageUrl: 'assets/images/bonejamin.png',
|
||||
name: 'Bonejamin',
|
||||
description: 'Hes ready to party til midnight.',
|
||||
rarity: Rarity.Epic,
|
||||
),
|
||||
FortniteSkin(
|
||||
imageUrl: 'assets/images/delirium.png',
|
||||
name: 'Delirium',
|
||||
description: 'Dont worry, its only a nightmare...',
|
||||
rarity: Rarity.Epic,
|
||||
),
|
||||
];
|
108
lib/presentation/widgets/card.dart
Normal file
108
lib/presentation/widgets/card.dart
Normal file
@ -0,0 +1,108 @@
|
||||
part of '../pages/homepage.dart';
|
||||
|
||||
class _CardState extends State<_Card> {
|
||||
bool isLiked = false;
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return GestureDetector(
|
||||
onTap: widget.onTap,
|
||||
child: Container(
|
||||
margin: const EdgeInsets.all(16),
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.greenAccent,
|
||||
borderRadius: BorderRadius.circular(15),
|
||||
border: Border.all(
|
||||
color: Colors.black,
|
||||
width: 3,
|
||||
)
|
||||
),
|
||||
child: IntrinsicHeight(
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
ClipRRect(
|
||||
borderRadius: const BorderRadius.only(
|
||||
bottomLeft: Radius.circular(20),
|
||||
bottomRight: Radius.circular(20)
|
||||
),
|
||||
child: SizedBox(
|
||||
height: double.infinity,
|
||||
width: 120,
|
||||
child: Image.asset(
|
||||
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.name,
|
||||
style: const TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
|
||||
),
|
||||
Text(
|
||||
widget.description,
|
||||
style: const TextStyle(fontSize: 15),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
//const Spacer(), да не умер он в конце драйва
|
||||
Align(
|
||||
alignment: Alignment.bottomRight,
|
||||
child: (
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(left: 8.0),
|
||||
child: GestureDetector
|
||||
(
|
||||
onTap: () {
|
||||
setState(() {
|
||||
isLiked = !isLiked;
|
||||
});
|
||||
widget.onLike.call(widget.name, isLiked);
|
||||
},
|
||||
child: Icon(
|
||||
isLiked ? Icons.favorite : Icons.favorite_border,
|
||||
color: isLiked ? Colors.red : null,
|
||||
)
|
||||
),
|
||||
)
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
typedef OnLikeCallback = void Function(String name, bool isLiked);
|
||||
class _Card extends StatefulWidget {
|
||||
final String name;
|
||||
final String imageUrl;
|
||||
final String description;
|
||||
final Rarity rarity;
|
||||
final OnLikeCallback onLike;
|
||||
final VoidCallback onTap;
|
||||
|
||||
const _Card({
|
||||
required this.name,
|
||||
required this.description,
|
||||
required this.imageUrl,
|
||||
required this.rarity,
|
||||
required this.onLike,
|
||||
required this.onTap,
|
||||
});
|
||||
|
||||
@override
|
||||
State<_Card> createState() => _CardState();
|
||||
}
|
||||
|
||||
|
@ -56,6 +56,8 @@ flutter:
|
||||
- assets/images/cat_haha.jpg
|
||||
- assets/images/raven.png
|
||||
- assets/images/shark.png
|
||||
- assets/images/bonejamin.png
|
||||
- assets/images/delirium.png
|
||||
# The following line ensures that the Material Icons font is
|
||||
# included with your application, so that you can use the icons in
|
||||
# the material Icons class.
|
||||
|
Loading…
Reference in New Issue
Block a user