🔥🚀 Creates page that is dismissed by swipe gestures, with Hero style animations, Inspired by FB, IG stories.
First thing first give it a star ⭐
Discord Channel
- Fork it
- Create your feature branch (git checkout -b my-new-feature)
- Commit your changes (git commit -am 'Add some feature')
- Push to the branch (git push origin my-new-feature)
- Create new Pull Request
Creates page that is dismissed by swipe gestures, with Hero style animations, Inspired by FB, IG stories.
Add this to your package's pubspec.yaml
file:
dependencies:
dismissible_page: ^0.5.5
You can install packages from the command line:
with pub
:
$ pub get
with Flutter
:
$ flutter packages get
Now in your Dart
code, you can use:
import 'package:dismissible_page/dismissible_page.dart';
DismissiblePage({
@required this.child,
this.isFullScreen = true,
this.disabled = false,
this.backgroundColor = Colors.black,
this.direction = DismissDirection.vertical,
this.dismissThresholds = const <DismissDirection, double>{},
this.dragStartBehavior = DragStartBehavior.start,
this.crossAxisEndOffset = 0.0,
this.minRadius = 7,
this.minScale = .85,
this.maxRadius = 30,
this.maxTransformValue = .4,
this.onDismiss,
this.onDragStart,
this.onDragEnd,
Key key,
}) : assert(dragStartBehavior != null),
super(key: key);
Import the package:
import 'package:dismissible_page/dismissible_page.dart';
import 'package:example/_models.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
void main() => runApp(AppView());
class AppView extends StatelessWidget {
@override
Widget build(BuildContext context) => MaterialApp(home: AppHome());
}
class AppHome extends StatefulWidget {
@override
_AppHomeState createState() => _AppHomeState();
}
class _AppHomeState extends State<AppHome> {
final stories = [
StoryModel(title: 'STORY'),
StoryModel(title: 'STORY'),
StoryModel(title: 'STORY'),
StoryModel(title: 'STORY'),
StoryModel(title: 'STORY'),
StoryModel(title: 'STORY'),
];
@override
Widget build(BuildContext context) {
final padding = MediaQuery.of(context).padding;
return Scaffold(
body: SingleChildScrollView(
padding: padding,
child: Column(
children: [
Padding(
padding: const EdgeInsets.all(20),
child: Text('Dismissible', style: TextStyle(fontSize: 24)),
),
SizedBox(
height: 120,
child: ListView.separated(
padding: EdgeInsets.symmetric(horizontal: 20),
scrollDirection: Axis.horizontal,
itemBuilder: (_, int i) => StoryWidget(story: stories[i]),
separatorBuilder: (_, int i) => SizedBox(width: 10),
itemCount: stories.length,
),
),
],
),
),
);
}
}
class StoryWidget extends StatelessWidget {
final StoryModel story;
const StoryWidget({this.story});
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
context.pushTransparentRoute(StoryPage(story: story));
},
child: Hero(
tag: story.storyId,
child: Container(
height: 120,
width: 88,
padding: const EdgeInsets.all(8),
child: Text(
story.title,
style: Theme.of(context)
.textTheme
.button
.copyWith(color: Colors.white),
),
clipBehavior: Clip.antiAlias,
alignment: Alignment.bottomLeft,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(12),
image: DecorationImage(
fit: BoxFit.cover,
image: NetworkImage(story.imageUrl),
),
),
),
),
);
}
}
class StoryPage extends StatelessWidget {
final StoryModel story;
const StoryPage({this.story});
@override
Widget build(BuildContext context) {
return DismissiblePage(
onDismiss: () => Navigator.of(context).pop(),
isFullScreen: false,
child: Material(
color: Colors.transparent,
child: Hero(
tag: story.storyId,
child: Container(
padding: const EdgeInsets.all(20),
child: Text(
story.title,
style: Theme.of(context)
.textTheme
.button
.copyWith(color: Colors.white),
),
clipBehavior: Clip.antiAlias,
alignment: Alignment.bottomLeft,
decoration: BoxDecoration(
image: DecorationImage(
fit: BoxFit.cover,
image: NetworkImage(story.imageUrl),
),
),
),
),
),
);
}
}
class StoryModel {
final storyId = UniqueKey();
final String title;
String imageUrl;
String get nextVehicleUrl =>
'https://source.unsplash.com/collection/1989985/${Random().nextInt(20) + 400}x${Random().nextInt(20) + 800}';
StoryModel({this.title, this.imageUrl}) {
imageUrl = nextVehicleUrl;
}
}