Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Product Page section expanding animation #267

Merged
merged 4 commits into from
Mar 16, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,11 @@ class AttributeListExpandable extends StatelessWidget {
);
if (!collapsible) {
return SmoothCard(
collapsed: null,
content: content,
background: background,
);
}

final Widget header =
Text(title, style: Theme.of(context).textTheme.headline3);
return SmoothExpandableCard(
Expand Down
1 change: 0 additions & 1 deletion packages/smooth_app/lib/pages/list_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,6 @@ class _ListPageState extends State<ListPage> {
Colors.blue,
ColorDestination.SURFACE_BACKGROUND,
),
collapsed: null,
content: ListTile(
leading: Icon(Icons.add, size: iconSize),
onTap: () async => await _add(daoProductList),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,6 @@ class _PantryListPageState extends State<PantryListPage> {
Colors.blue,
ColorDestination.SURFACE_BACKGROUND,
),
collapsed: null,
content: ListTile(
leading: Icon(Icons.add, size: iconSize),
onTap: () async => await _add(userPreferences),
Expand Down
7 changes: 6 additions & 1 deletion packages/smooth_app/lib/pages/product/product_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,7 @@ class _ProductPageState extends State<ProductPage> {

listItems.add(_buildProductImagesCarousel(context));

// Brands, quantity
listItems.add(
Padding(
padding: const EdgeInsets.all(16.0),
Expand All @@ -413,11 +414,14 @@ class _ProductPageState extends State<ProductPage> {
),
),
);

final Map<String, Attribute> matchingAttributes =
Match.getMatchingAttributes(_product, mainAttributes);
final double opacity = themeData.brightness == Brightness.light
? 1
: SmoothTheme.ADDITIONAL_OPACITY_FOR_DARK;

//Nutri, Nova
for (final String attributeId in mainAttributes) {
if (matchingAttributes[attributeId] != null) {
listItems.add(
Expand All @@ -432,11 +436,13 @@ class _ProductPageState extends State<ProductPage> {
);
}
}

for (final AttributeGroup attributeGroup
in _getOrderedAttributeGroups(userPreferencesModel)) {
listItems.add(_getAttributeGroupWidget(attributeGroup, iconWidth));
}

//Similar foods
if (_product.categoriesTags != null && _product.categoriesTags.isNotEmpty) {
for (int i = _product.categoriesTags.length - 1;
i < _product.categoriesTags.length;
Expand All @@ -450,7 +456,6 @@ class _ProductPageState extends State<ProductPage> {
materialColor,
ColorDestination.SURFACE_BACKGROUND,
),
collapsed: null,
content: ListTile(
leading: Icon(
Icons.search,
Expand Down
18 changes: 2 additions & 16 deletions packages/smooth_ui_library/lib/widgets/smooth_card.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,11 @@ import 'package:flutter/material.dart';

class SmoothCard extends StatelessWidget {
const SmoothCard({
@required this.collapsed,
@required this.content,
this.background,
this.header,
});

final bool collapsed;
final Widget content;
final Color background;
final Widget header;
Expand All @@ -27,20 +25,8 @@ class SmoothCard extends StatelessWidget {
padding: const EdgeInsets.all(12.0),
child: Column(
children: <Widget>[
if (collapsed != null)
Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(child: header),
if (collapsed != null)
Icon(collapsed
? Icons.keyboard_arrow_down
: Icons.keyboard_arrow_up),
],
),
if (collapsed != true) content,
header,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@M123-dev : I think this is causing #270 . header should be required, or we should test if it is null. The AttributeListExpandable does not set it.

content,
],
),
),
Expand Down
115 changes: 79 additions & 36 deletions packages/smooth_ui_library/lib/widgets/smooth_expandable_card.dart
Original file line number Diff line number Diff line change
@@ -1,59 +1,102 @@
import 'dart:math';

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:smooth_ui_library/widgets/models/single_boolean_model.dart';
import 'package:smooth_ui_library/widgets/smooth_card.dart';

class SmoothExpandableCard extends StatelessWidget {
class SmoothExpandableCard extends StatefulWidget {
const SmoothExpandableCard({
@required this.collapsedHeader,
this.expandedHeader,
@required this.content,
this.expandedHeader,
this.background,
});

final Widget collapsedHeader;
final Widget expandedHeader;
final Color background;
final Widget content;
@override
_SmoothExpandableCardState createState() => _SmoothExpandableCardState();
}

class _SmoothExpandableCardState extends State<SmoothExpandableCard>
with SingleTickerProviderStateMixin {
bool collapsed = true;
AnimationController _controller;
Animation<double> animation;
static const Duration _ANIMATION_DURATION = Duration(milliseconds: 160);

@override
void initState() {
super.initState();
_controller =
AnimationController(vsync: this, duration: _ANIMATION_DURATION);
animation = Tween<double>(begin: 0, end: pi).animate(_controller);
}

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

@override
Widget build(BuildContext context) {
return ChangeNotifierProvider<SingleBooleanModel>(
create: (BuildContext context) => SingleBooleanModel(),
child: Consumer<SingleBooleanModel>(
builder: (BuildContext context, SingleBooleanModel singleBooleanModel,
Widget child) {
return AnimatedCrossFade(
duration: const Duration(milliseconds: 160),
firstCurve: Curves.easeInOutBack,
secondCurve: Curves.easeInOutBack,
firstChild: _buildExpandedWidget(
singleBooleanModel, Theme.of(context), true),
secondChild: _buildExpandedWidget(
singleBooleanModel, Theme.of(context), false),
crossFadeState: singleBooleanModel.isActive
? CrossFadeState.showSecond
: CrossFadeState.showFirst,
);
},
),
return AnimatedCrossFade(
duration: _ANIMATION_DURATION,
crossFadeState: CrossFadeState.showFirst,
firstChild: _buildCard(),
secondChild: _buildCard(),
);
}

Widget _buildExpandedWidget(
final SingleBooleanModel singleBooleanModel,
final ThemeData themeData,
final bool collapsed,
) {
Widget _buildCard() {
return GestureDetector(
onTap: () => collapsed
? singleBooleanModel.setActive()
: singleBooleanModel.setInactive(),
child: SmoothCard(
collapsed: collapsed,
content: content,
header: collapsed == true ? collapsedHeader : expandedHeader,
onTap: () {
setState(() {
collapsed = !collapsed;
animation.value == 0 ? _controller.forward() : _controller.reverse();
});
},
child: Padding(
padding: const EdgeInsets.only(
right: 8.0, left: 8.0, top: 4.0, bottom: 20.0),
child: Material(
elevation: 8.0,
shadowColor: Colors.black45,
borderRadius: const BorderRadius.all(Radius.circular(10.0)),
color: widget.background ?? Theme.of(context).colorScheme.surface,
child: Container(
padding: const EdgeInsets.all(12.0),
child: Column(
children: <Widget>[
Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
child: collapsed
? widget.collapsedHeader
: widget.expandedHeader ?? widget.collapsedHeader,
),
AnimatedBuilder(
animation: animation,
child: const Icon(Icons.keyboard_arrow_down),
builder: (BuildContext context, Widget child) {
return Transform.rotate(
angle: animation.value,
child: child,
);
},
),
],
),
if (collapsed != true) widget.content,
],
),
),
),
),
);
}
Expand Down