Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
MarcinusX
committed
Jan 21, 2020
1 parent
1f7b11d
commit bd077be
Showing
4 changed files
with
334 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,267 @@ | ||
import 'dart:math'; | ||
import 'dart:ui'; | ||
|
||
import 'package:flutter/material.dart'; | ||
|
||
///Notice that by default this class is not used | ||
///Go to [home_page.dart] and replace [ExhibitionBottomSheet] with [ScrollableExhibitionSheet] to use it | ||
class ScrollableExhibitionSheet extends StatefulWidget { | ||
@override | ||
_ScrollableExhibitionSheetState createState() => | ||
_ScrollableExhibitionSheetState(); | ||
} | ||
|
||
class _ScrollableExhibitionSheetState extends State<ScrollableExhibitionSheet> { | ||
double initialPercentage = 0.15; | ||
|
||
@override | ||
Widget build(BuildContext context) { | ||
return Positioned.fill( | ||
child: DraggableScrollableSheet( | ||
minChildSize: initialPercentage, | ||
initialChildSize: initialPercentage, | ||
builder: (context, scrollController) { | ||
return AnimatedBuilder( | ||
animation: scrollController, | ||
builder: (context, child) { | ||
double percentage = initialPercentage; | ||
if (scrollController.hasClients) { | ||
percentage = (scrollController.position.viewportDimension) / | ||
(MediaQuery.of(context).size.height); | ||
} | ||
double scaledPercentage = | ||
(percentage - initialPercentage) / (1 - initialPercentage); | ||
return Container( | ||
padding: const EdgeInsets.only(left: 32), | ||
decoration: const BoxDecoration( | ||
color: Color(0xFF162A49), | ||
borderRadius: BorderRadius.vertical(top: Radius.circular(32)), | ||
), | ||
child: Stack( | ||
children: <Widget>[ | ||
Opacity( | ||
opacity: percentage == 1 ? 1 : 0, | ||
child: ListView.builder( | ||
padding: EdgeInsets.only(right: 32, top: 128), | ||
controller: scrollController, | ||
itemCount: 20, | ||
itemBuilder: (context, index) { | ||
Event event = events[index % 3]; | ||
return MyEventItem( | ||
event: event, | ||
percentageCompleted: percentage, | ||
); | ||
}, | ||
), | ||
), | ||
...events.map((event) { | ||
int index = events.indexOf(event); | ||
int heightPerElement = 120 + 8 + 8; | ||
double widthPerElement = | ||
40 + percentage * 80 + 8 * (1 - percentage); | ||
double leftOffset = widthPerElement * | ||
(index > 4 ? index + 2 : index) * | ||
(1 - scaledPercentage); | ||
return Positioned( | ||
top: 44.0 + | ||
scaledPercentage * (128 - 44) + | ||
index * heightPerElement * scaledPercentage, | ||
left: leftOffset, | ||
right: 32 - leftOffset, | ||
child: IgnorePointer( | ||
ignoring: true, | ||
child: Opacity( | ||
opacity: percentage == 1 ? 0 : 1, | ||
child: MyEventItem( | ||
event: event, | ||
percentageCompleted: percentage, | ||
), | ||
), | ||
), | ||
); | ||
}), | ||
SheetHeader( | ||
fontSize: 14 + percentage * 8, | ||
topMargin: | ||
16 + percentage * MediaQuery.of(context).padding.top, | ||
), | ||
MenuButton(), | ||
], | ||
), | ||
); | ||
}, | ||
); | ||
}, | ||
), | ||
); | ||
} | ||
} | ||
|
||
class MyEventItem extends StatelessWidget { | ||
final Event event; | ||
final double percentageCompleted; | ||
|
||
const MyEventItem({Key key, this.event, this.percentageCompleted}) | ||
: super(key: key); | ||
|
||
@override | ||
Widget build(BuildContext context) { | ||
return Padding( | ||
padding: EdgeInsets.symmetric(vertical: 8), | ||
child: Transform.scale( | ||
alignment: Alignment.topLeft, | ||
scale: 1 / 3 + 2 / 3 * percentageCompleted, | ||
child: SizedBox( | ||
height: 120, | ||
child: Row( | ||
children: <Widget>[ | ||
ClipRRect( | ||
borderRadius: BorderRadius.horizontal( | ||
left: Radius.circular(16), | ||
right: Radius.circular(16 * (1 - percentageCompleted)), | ||
), | ||
child: Image.asset( | ||
'assets/${event.assetName}', | ||
width: 120, | ||
height: 120, | ||
fit: BoxFit.cover, | ||
), | ||
), | ||
Expanded( | ||
child: Opacity( | ||
opacity: max(0, percentageCompleted * 2 - 1), | ||
child: Container( | ||
decoration: BoxDecoration( | ||
borderRadius: | ||
BorderRadius.horizontal(right: Radius.circular(16)), | ||
color: Colors.white, | ||
), | ||
padding: EdgeInsets.all(8), | ||
child: _buildContent(), | ||
), | ||
), | ||
) | ||
], | ||
), | ||
), | ||
), | ||
); | ||
} | ||
|
||
Widget _buildContent() { | ||
return Column( | ||
children: <Widget>[ | ||
Text(event.title, style: TextStyle(fontSize: 16)), | ||
SizedBox(height: 8), | ||
Row( | ||
children: <Widget>[ | ||
Text( | ||
'1 ticket', | ||
style: TextStyle( | ||
fontWeight: FontWeight.w500, | ||
fontSize: 12, | ||
color: Colors.grey.shade600, | ||
), | ||
), | ||
SizedBox(width: 8), | ||
Text( | ||
event.date, | ||
style: TextStyle( | ||
fontWeight: FontWeight.w300, | ||
fontSize: 12, | ||
color: Colors.grey, | ||
), | ||
), | ||
], | ||
), | ||
Spacer(), | ||
Row( | ||
children: <Widget>[ | ||
Icon(Icons.place, color: Colors.grey.shade400, size: 16), | ||
Text( | ||
'Science Park 10 25A', | ||
style: TextStyle(color: Colors.grey.shade400, fontSize: 13), | ||
) | ||
], | ||
) | ||
], | ||
); | ||
} | ||
} | ||
|
||
final List<Event> events = [ | ||
Event('steve-johnson.jpeg', 'Shenzhen GLOBAL DESIGN AWARD 2018', '4.20-30'), | ||
Event('efe-kurnaz.jpg', 'Shenzhen GLOBAL DESIGN AWARD 2018', '4.20-30'), | ||
Event('rodion-kutsaev.jpeg', 'Dawan District Guangdong Hong Kong', '4.28-31'), | ||
Event('steve-johnson.jpeg', 'Shenzhen GLOBAL DESIGN AWARD 2018', '4.20-30'), | ||
Event('efe-kurnaz.jpg', 'Shenzhen GLOBAL DESIGN AWARD 2018', '4.20-30'), | ||
Event('rodion-kutsaev.jpeg', 'Dawan District Guangdong Hong Kong', '4.28-31'), | ||
Event('steve-johnson.jpeg', 'Shenzhen GLOBAL DESIGN AWARD 2018', '4.20-30'), | ||
Event('efe-kurnaz.jpg', 'Shenzhen GLOBAL DESIGN AWARD 2018', '4.20-30'), | ||
Event('rodion-kutsaev.jpeg', 'Dawan District Guangdong Hong Kong', '4.28-31'), | ||
Event('steve-johnson.jpeg', 'Shenzhen GLOBAL DESIGN AWARD 2018', '4.20-30'), | ||
Event('efe-kurnaz.jpg', 'Shenzhen GLOBAL DESIGN AWARD 2018', '4.20-30'), | ||
Event('rodion-kutsaev.jpeg', 'Dawan District Guangdong Hong Kong', '4.28-31'), | ||
Event('steve-johnson.jpeg', 'Shenzhen GLOBAL DESIGN AWARD 2018', '4.20-30'), | ||
Event('efe-kurnaz.jpg', 'Shenzhen GLOBAL DESIGN AWARD 2018', '4.20-30'), | ||
Event('rodion-kutsaev.jpeg', 'Dawan District Guangdong Hong Kong', '4.28-31'), | ||
Event('steve-johnson.jpeg', 'Shenzhen GLOBAL DESIGN AWARD 2018', '4.20-30'), | ||
Event('efe-kurnaz.jpg', 'Shenzhen GLOBAL DESIGN AWARD 2018', '4.20-30'), | ||
Event('rodion-kutsaev.jpeg', 'Dawan District Guangdong Hong Kong', '4.28-31'), | ||
]; | ||
|
||
class Event { | ||
final String assetName; | ||
final String title; | ||
final String date; | ||
|
||
Event(this.assetName, this.title, this.date); | ||
} | ||
|
||
class SheetHeader extends StatelessWidget { | ||
final double fontSize; | ||
final double topMargin; | ||
|
||
const SheetHeader( | ||
{Key key, @required this.fontSize, @required this.topMargin}) | ||
: super(key: key); | ||
|
||
@override | ||
Widget build(BuildContext context) { | ||
return Positioned( | ||
left: 0, | ||
right: 32, | ||
child: IgnorePointer( | ||
child: Container( | ||
padding: EdgeInsets.only(top: topMargin, bottom: 12), | ||
decoration: const BoxDecoration( | ||
color: Color(0xFF162A49), | ||
), | ||
child: Text( | ||
'Booked Exhibition', | ||
style: TextStyle( | ||
color: Colors.white, | ||
fontSize: fontSize, | ||
fontWeight: FontWeight.w500, | ||
), | ||
), | ||
), | ||
), | ||
); | ||
} | ||
} | ||
|
||
class MenuButton extends StatelessWidget { | ||
@override | ||
Widget build(BuildContext context) { | ||
return Positioned( | ||
right: 12, | ||
bottom: 24, | ||
child: Icon( | ||
Icons.menu, | ||
color: Colors.white, | ||
size: 28, | ||
), | ||
); | ||
} | ||
} |
Oops, something went wrong.