Skip to content

Commit

Permalink
Add google_fonts dependency and register PathProviderPlugin
Browse files Browse the repository at this point in the history
  • Loading branch information
PlugFox committed Dec 19, 2023
1 parent 6dbb9c8 commit 6cd3415
Show file tree
Hide file tree
Showing 4 changed files with 202 additions and 48 deletions.
206 changes: 158 additions & 48 deletions example/lib/src/feature/shop/widget/favorite_button.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,63 +8,173 @@ import 'package:flutter/services.dart';
/// {@endtemplate}
class FavoriteButton extends StatelessWidget {
/// {@macro favorite_button}
const FavoriteButton({required this.productId, super.key});
const FavoriteButton({
required this.productId,
super.key,
});

final ProductID productId;

@override
Widget build(BuildContext context) {
final status = ShopScope.isFavorite(context, productId, listen: true);
return FloatingActionButton(
onPressed: () {
if (status) {
ShopScope.removeFavorite(context, productId);
HapticFeedback.lightImpact().ignore();
} else {
ShopScope.addFavorite(context, productId);
HapticFeedback.mediumImpact().ignore();
}
},
backgroundColor: status
? Theme.of(context).buttonTheme.colorScheme?.background
: Theme.of(context).primaryColor,
shape: status
? RoundedRectangleBorder(
borderRadius: BorderRadius.circular(18),
side: BorderSide(
color: Theme.of(context).buttonTheme.colorScheme?.primary ??
Colors.transparent,
),
)
: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
child: AnimatedSwitcher(
duration: const Duration(milliseconds: 350),
transitionBuilder: (child, animation) => ScaleTransition(
scale: CurvedAnimation(
parent: animation,
curve: Curves.bounceInOut,
),
child: FadeTransition(
opacity: Tween<double>(begin: 0.5, end: 1).animate(animation),
child: child,
),
),
child: status
? const Icon(
Icons.favorite,
key: ValueKey('favorite'),
color: Colors.red,
size: 36,
return RepaintBoundary(
child: FloatingActionButton(
onPressed: () {
if (status) {
ShopScope.removeFavorite(context, productId);
HapticFeedback.lightImpact().ignore();
} else {
ShopScope.addFavorite(context, productId);
HapticFeedback.mediumImpact().ignore();
}
},
backgroundColor: status
? Theme.of(context).buttonTheme.colorScheme?.background
: Theme.of(context).primaryColor,
shape: status
? RoundedRectangleBorder(
borderRadius: BorderRadius.circular(18),
side: BorderSide(
color: Theme.of(context).buttonTheme.colorScheme?.primary ??
Colors.transparent,
),
)
: const Icon(
Icons.favorite_border,
key: ValueKey('favorite_border'),
color: Colors.grey,
size: 24,
: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
child: _FavoriteHeartBeatIcon(
favorite: status,
),
),
);
}
}

class _FavoriteHeartBeatIcon extends StatefulWidget {
const _FavoriteHeartBeatIcon({
this.favorite = true,
this.duration = const Duration(milliseconds: 650), // ignore: unused_element
super.key, // ignore: unused_element
});

/// Is the icon currently filled in?
final bool favorite;

/// The duration of the animation.
final Duration duration;

@override
State<_FavoriteHeartBeatIcon> createState() => _FavoriteHeartBeatIconState();
}

/// State for widget _FavoriteHeartBeatIcon.
class _FavoriteHeartBeatIconState extends State<_FavoriteHeartBeatIcon>
with SingleTickerProviderStateMixin {
late final AnimationController _controller;
late final Animation<double> _heartbeat1, _heartbeat2;

@override
void initState() {
super.initState();
_controller =
AnimationController(vsync: this, duration: widget.duration, value: 0);
_heartbeat1 = CurvedAnimation(
parent: _controller,
curve: const Interval(0, .75, curve: Curves.easeInOut));
_heartbeat2 = CurvedAnimation(
parent: _controller,
curve: const Interval(.5, 1, curve: Curves.easeInOut));
if (!widget.favorite) {
_controller.repeat();
}
}

@override
void didUpdateWidget(covariant _FavoriteHeartBeatIcon oldWidget) {
super.didUpdateWidget(oldWidget);
if (widget.duration != _controller.duration) {
_controller.duration = widget.duration;
}
if (widget.favorite != oldWidget.favorite) {
if (widget.favorite) {
_controller.stop();
} else {
_controller.repeat();
}
}
}

@override
void dispose() {
_controller.dispose();
super.dispose();
}

@override
Widget build(BuildContext context) => Stack(
alignment: Alignment.center,
children: <Widget>[
if (!widget.favorite)
Positioned.fill(
child: FadeTransition(
opacity: ReverseAnimation(_heartbeat1),
child: ScaleTransition(
scale:
Tween<double>(begin: 1, end: 1.75).animate(_heartbeat1),
child: Icon(
Icons.favorite_border,
color: Colors.redAccent.withAlpha(127),
size: 32,
),
),
),
),
if (!widget.favorite)
Positioned.fill(
child: FadeTransition(
opacity: Tween<double>(begin: 0, end: .75)
.animate(ReverseAnimation(_heartbeat2)),
child: ScaleTransition(
scale:
Tween<double>(begin: 0.8, end: 1.5).animate(_heartbeat2),
child: Icon(
Icons.favorite_border,
color: Colors.red.withAlpha(200),
size: 28,
),
),
),
),
Positioned.fill(
key: const ValueKey<String>('_FavoriteHeartBeatIconState#icon'),
child: AnimatedSwitcher(
duration: const Duration(milliseconds: 350),
transitionBuilder: (child, animation) => ScaleTransition(
scale: CurvedAnimation(
parent: animation,
curve: Curves.bounceInOut,
),
child: FadeTransition(
opacity: Tween<double>(begin: 0.5, end: 1).animate(animation),
child: child,
),
),
child: widget.favorite
? const Icon(
Icons.favorite,
key: ValueKey('favorite'),
color: Colors.red,
size: 36,
)
: Icon(
Icons.favorite_border,
key: const ValueKey('favorite_border'),
color: Colors.grey.withAlpha(200),
size: 24,
),
),
),
],
);
}
2 changes: 2 additions & 0 deletions example/macos/Flutter/GeneratedPluginRegistrant.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@
import FlutterMacOS
import Foundation

import path_provider_foundation
import shared_preferences_foundation

func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
}
40 changes: 40 additions & 0 deletions example/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.1.2"
google_fonts:
dependency: "direct main"
description:
name: google_fonts
sha256: f0b8d115a13ecf827013ec9fc883390ccc0e87a96ed5347a3114cac177ef18e8
url: "https://pub.dev"
source: hosted
version: "6.1.0"
graphs:
dependency: transitive
description:
Expand All @@ -359,6 +367,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.15.4"
http:
dependency: transitive
description:
name: http
sha256: d4872660c46d929f6b8a9ef4e7a7eff7e49bbf0c4ec3f385ee32df5119175139
url: "https://pub.dev"
source: hosted
version: "1.1.2"
http_multi_server:
dependency: transitive
description:
Expand Down Expand Up @@ -499,6 +515,30 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.8.3"
path_provider:
dependency: transitive
description:
name: path_provider
sha256: a1aa8aaa2542a6bc57e381f132af822420216c80d4781f7aa085ca3229208aaa
url: "https://pub.dev"
source: hosted
version: "2.1.1"
path_provider_android:
dependency: transitive
description:
name: path_provider_android
sha256: e595b98692943b4881b219f0a9e3945118d3c16bd7e2813f98ec6e532d905f72
url: "https://pub.dev"
source: hosted
version: "2.2.1"
path_provider_foundation:
dependency: transitive
description:
name: path_provider_foundation
sha256: "19314d595120f82aca0ba62787d58dde2cc6b5df7d2f0daf72489e38d1b57f2d"
url: "https://pub.dev"
source: hosted
version: "2.3.1"
path_provider_linux:
dependency: transitive
description:
Expand Down
2 changes: 2 additions & 0 deletions example/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ dependencies:
# UI and Widgets
cupertino_icons: ^1.0.5
photo_view: ^0.14.0
google_fonts: ^6.1.0
#font_awesome_flutter: ^10.6.0

dev_dependencies:
# Unit & Widget tests for Flutter
Expand Down

0 comments on commit 6cd3415

Please sign in to comment.