showGeneralDialog not working as expected - dart

Code:
void showNow() {
showGeneralDialog(
context: context,
pageBuilder: (BuildContext buildContext, Animation<double> animation, Animation<double> secondaryAnimation) {
return Container(
width: 200.0,
height: 200.0,
color: Colors.orange,
);
},
barrierDismissible: true,
barrierLabel: MaterialLocalizations.of(context).modalBarrierDismissLabel,
barrierColor: Colors.black,
transitionDuration: const Duration(milliseconds: 200),
);
}
But this dialog takes up the entire space instead of 200.0 width and height that I used. I tried wrapping Container in Scaffold, but then barrierDismissible and barrierColor doesn't seem to work. I changed their values too but no luck.

Wrap your Container in Wrap Widget :
void showNow() {
showGeneralDialog(
context: context,
pageBuilder: (BuildContext buildContext, Animation<double> animation,
Animation<double> secondaryAnimation) {
return Wrap(
children: <Widget>[
Container(
width: 200.0,
height: 200.0,
color: Colors.orange,
),
],
);
},
barrierDismissible: true,
barrierLabel: MaterialLocalizations.of(context).modalBarrierDismissLabel,
barrierColor: Colors.black,
transitionDuration: const Duration(milliseconds: 200),
);
}

Related

Matrix4 parameter acting differently when passed to Transform indirectly

I've run into a really weird issue. This is like some type confusion?
If I write my animation like this, it works as expected:
Widget _animatedButtonsBuilder(BuildContext context, LoginState state) {
final animTarget = state.isPhoneNumberFocused
? _controller.lowerBound
: _controller.upperBound;
_controller.animateTo(animTarget);
final double width = MediaQuery.of(context).size.width;
//final transform = Matrix4.translationValues(_animation.value * width, 0.0, 0.0)..scale(1.0, 1.0-_animation.value, 1.0);
return AnimatedBuilder(
animation: _controller,
builder: (BuildContext context, Widget child) {
return Transform(
transform: Matrix4.translationValues(_animation.value * width, 0.0, 0.0)..scale(1.0, 1.0-_animation.value, 1.0),
child: new RaisedButton(
child: const Text('Login'),
color: Color(0xff938065),
elevation: 4.0,
splashColor: Colors.blueGrey,
textColor: Color(0xffffffff),
onPressed: () {},
));
});
}
but if I uncomment
//final transform = Matrix4.transla...
and passed that to the transform: parameter, it doesn't seem to work right.
What's happening?
I think to get equivalent result you'd need to move the line into the builder,
because there it is executed every time the animation progresses, not only at the start of the animation.
Widget _animatedButtonsBuilder(BuildContext context, LoginState state) {
final animTarget = state.isPhoneNumberFocused
? _controller.lowerBound
: _controller.upperBound;
_controller.animateTo(animTarget);
final double width = MediaQuery.of(context).size.width;
return AnimatedBuilder(
animation: _controller,
builder: (BuildContext context, Widget child) {
//final transform = Matrix4.translationValues(_animation.value * width, 0.0, 0.0)..scale(1.0, 1.0-_animation.value, 1.0);
return Transform(
transform: Matrix4.translationValues(_animation.value * width, 0.0, 0.0)..scale(1.0, 1.0-_animation.value, 1.0),
child: new RaisedButton(
child: const Text('Login'),
color: Color(0xff938065),
elevation: 4.0,
splashColor: Colors.blueGrey,
textColor: Color(0xffffffff),
onPressed: () {},
));
});
}

Disable drag down to close showModalBottomSheet

How do I disable / escape drag down gesture within the Bottom Sheet Modal so the user can interact within the modal without accidentally closing the modal?
Updated below with the actual modal bottom sheet.
return showModalBottomSheet(
context: context,
builder: (BuildContext context) {
...
}
}
Set enableDrag to false
bool enableDrag
If true, the bottom sheet can dragged up and down and dismissed by swiping downwards.
https://docs.flutter.io/flutter/material/BottomSheet/enableDrag.html
you can try to wrap builder's result with GestureDetector with onVerticalDragStart = (_) {}
showModalBottomSheet(
context: context,
builder: (context) => GestureDetector(
child: **any_widget_here**,
onVerticalDragStart: (_) {},
),
isDismissible: false,
isScrollControlled: true,
);
If you still want to have the scroll inside the modal without the user drag and close it, you can use this:
showModalBottomSheet(
context: context,
enableDrag: false,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(
top: Radius.circular(20),
),
),
clipBehavior: Clip.antiAliasWithSaveLayer,
builder: (context) => DraggableScrollableSheet(
expand: false,
initialChildSize: 0.9,
minChildSize: 0.5,
maxChildSize: 0.9,
builder: (context, scrollController) {
return SingleChildScrollView(
child: new Container(
color: Colors.white,
child: buildTitleWidget(),
),
);
},
),
isDismissible: false,
isScrollControlled: true,
);
The trick is not to add scrollController to the SingleChildScrollView
builder: (context, scrollController) {
return SingleChildScrollView(
controller: scrollController <-- HERE
child: new Container(
color: Colors.white,
child: buildTitleWidget(),
),
);
},
I wanted a bottomsheet that is draggable up and down, but does not close on dragging down. My thought was what if as soon as it closes, I call it again? Here, recursion comes to rescue. So, first of all I created a function for my modalBottomSheet.
Future modalBottomSheetShow(BuildContext context) {
return showModalBottomSheet(
backgroundColor: Colors.transparent,
context: context,
builder: (context) => buildSheet(),
isDismissible: false,
elevation: 0,
);
}
Next, I used .whenComplete() method of showModalBottomSheet() to recursively call the modalBottomSheetShow() function.
Future modalBottomSheetShow(BuildContext context) {
return showModalBottomSheet(
backgroundColor: Colors.transparent,
context: context,
builder: (context) => buildSheet(),
isDismissible: false,
elevation: 0,
).whenComplete(() => modalBottomSheetShow(context));
}
Next, I simply call the modalBottomSheetShow() whenever I wanted a bottomsheet. It cannot be closed, until the recursion ends. Here is the entire code for reference:
import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
static const idScreen = "HomePage";
#override
State<HomePage> createState() => _HomePageState();
}
#override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) async {
modalBottomSheetShow(context);
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
toolbarHeight: 0,
elevation: 0,
backgroundColor: Colors.black,
),
);
}
Widget buildSheet() {
return DraggableScrollableSheet(
initialChildSize: 0.6,
builder: (BuildContext context, ScrollController scrollController) {
return Container(
decoration: BoxDecoration(color: Colors.white, boxShadow: [
BoxShadow(
color: Color(0x6C000000),
spreadRadius: 5,
blurRadius: 20,
offset: Offset(0, 0),
)
]),
padding: EdgeInsets.all(16),
);
},
);
}
Future modalBottomSheetShow(BuildContext context) {
return showModalBottomSheet(
backgroundColor: Colors.transparent,
context: context,
builder: (context) => buildSheet(),
isDismissible: false,
elevation: 0,
).whenComplete(() => modalBottomSheetShow(context));
}
}

how to set showModalBottomSheet to full height?

I use showRoundedModalBottomSheet, how can I adjust this modal height till the appbar?
[Update]
In showModalBottomSheet(...) set the property isScrollControlled:true.
It will make bottomSheet to full height.
[Original answer]
You can Implement the FullScreenDialog instead.
Flutter Gallery app has an example of FullScreenDialog
You can open your Dialog using below code:
Navigator.of(context).push(new MaterialPageRoute<Null>(
builder: (BuildContext context) {
return Dialog();
},
fullscreenDialog: true
));
Check this blog post too for more:
Hope it will help you.
You can control the height by using FractionallySizedBox and setting the isScrollControlled to true.
showModalBottomSheet(
context: context,
isScrollControlled: true,
builder: (context) {
return FractionallySizedBox(
heightFactor: 0.9,
child: Container(),
);
});
If you call showModalBottomSheet() with isScrollControlled: true, then the dialog will be allowed to occupy the whole height.
To adjust the height to the content, you can proceed as usually, for example, using Container and Wrap widgets.
Example:
final items = <Widget>[
ListTile(
leading: Icon(Icons.photo_camera),
title: Text('Camera'),
onTap: () {},
),
ListTile(
leading: Icon(Icons.photo_library),
title: Text('Select'),
onTap: () {},
),
ListTile(
leading: Icon(Icons.delete),
title: Text('Delete'),
onTap: () {},
),
Divider(),
if (true)
ListTile(
title: Text('Cancel'),
onTap: () {},
),
];
showModalBottomSheet(
context: context,
builder: (BuildContext _) {
return Container(
child: Wrap(
children: items,
),
);
},
isScrollControlled: true,
);
What worked for me was returning the modal's content wrapped in a DraggableScrollableSheet:
showModalBottomSheet(
backgroundColor: Colors.transparent,
context: context,
isScrollControlled: true,
isDismissible: true,
builder: (BuildContext context) {
return DraggableScrollableSheet(
initialChildSize: 0.75, //set this as you want
maxChildSize: 0.75, //set this as you want
minChildSize: 0.75, //set this as you want
expand: true,
builder: (context, scrollController) {
return Container(...); //whatever you're returning, does not have to be a Container
}
);
}
)
I guess the easiest way is:
showModalBottomSheet(
isScrollControlled: true,
context: context,
builder: (context) => Wrap(children: [YourSheetWidget()]),
);
You open class BottomSheet in library of flutter and change maxHeight
from
BoxConstraints getConstraintsForChild(BoxConstraints constraints) {
return BoxConstraints(
minWidth: constraints.maxWidth,
maxWidth: constraints.maxWidth,
minHeight: 0.0,
maxHeight: constraints.maxHeight * 9.0 / 16.0
);}
to
BoxConstraints getConstraintsForChild(BoxConstraints constraints) {
return BoxConstraints(
minWidth: constraints.maxWidth,
maxWidth: constraints.maxWidth,
minHeight: 0.0,
maxHeight: constraints.maxHeight
);}
You can create a new class with other name and copy source code from class BottomSheet and change maxHeight
You can wrap the contents in a Container and provide height to full height
await showModalBottomSheet(
context: context,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(30), topRight: Radius.circular(30))),
backgroundColor: Colors.white,
builder: (BuildContext context) {
return Container(
height: MediaQuery.of(context).size.height,
child: ListView(
)
)
}
}
You can modify this method in the definition of the bottom sheet. Normally, it is 9.0, but as you can see here I changed it to 13.0. 16.0 is full screen.
#override
BoxConstraints getConstraintsForChild(BoxConstraints constraints) {
return BoxConstraints(
minWidth: constraints.maxWidth,
maxWidth: constraints.maxWidth,
minHeight: 0.0,
maxHeight: isScrollControlled
? constraints.maxHeight
: constraints.maxHeight * 13.0 / 16.0,
);
}

How to create a transparent full screen dialog on top of activity - Flutter

I am trying to create a transparent full screen dialog on top of activity. I have tried following this thread but solution doesn't work.
In short , what I need is:
full screen dialog.
transparent background except for the widget I use for the dialog
here's my code:
To open dialog
void onNextBtnClick(){
var route = new MaterialPageRoute(
builder: (BuildContext context) =>
new GenreDialogUI(),fullscreenDialog: true
);
Navigator.of(context).push(route);
}
For Dialog view
import 'package:flutter/widgets.dart';
class HolePuncherPainter extends CustomPainter {
static final clearPaint = new Paint()
..color = Colors.transparent,
..blendMode = BlendMode.clear;
const HolePuncherPainter();
#override
void paint(Canvas canvas, Size size) {
canvas.drawRect(
new Rect.fromLTWH(0.0, 0.0, size.width, size.height), clearPaint);
}
#override
bool shouldRepaint(CustomPainter oldDelegate) {
return true;
}
}
class GenreDialogUI extends StatefulWidget {
#override
_GenreDialogUI createState() => new _GenreDialogUI();
}
class _GenreDialogUI extends State<GenreDialogUI> {
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: addAppbar(),
body: new CustomPaint(
painter: HolePuncherPainter(),
child: new Container(
color: Colors.transparent,
alignment: Alignment.center,
child: UtilCommonWidget.addText('Transparent Dialog', Colors.red, 22.0, 1),
),
),
);
}
}
Navigator.of(context).push(PageRouteBuilder(
opaque: false,
pageBuilder: (BuildContext context, _, __) {
return YourFullScreenAlertDialog()
}
));
YourFullScreenAlertDialog could be a widget that has a background color, Colors.transparent, like #creativecreatorormaybenot mentioned earlier.
For me the following worked:
showDialog(
context: context,
builder: (_) => Material(
type: MaterialType.transparency,
child: Center(
// Aligns the container to center
child: Container(
// A simplified version of dialog.
width: 100.0,
height: 56.0,
color: Colors.green,
child: Text('jojo'),
),
),
),
);
Screenshot (showGeneralDialog):
Code:
#override
Widget build(BuildContext context) {
return Scaffold(
body: SizedBox.expand(child: FlutterLogo()),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.open_in_new),
onPressed: () {
showGeneralDialog(
context: context,
barrierColor: Colors.black38,
barrierLabel: 'Label',
barrierDismissible: true,
pageBuilder: (_, __, ___) => Center(
child: Container(
color: Colors.white,
child: Material(
color: Colors.transparent,
child: Text('Dialog', style: TextStyle(color: Colors.black, fontSize: 40),),
),
),
),
);
},
),
);
}
This is my implementation.
From first screen call this.
Navigator.push(
context,
PageRouteBuilder(
pageBuilder: (_, __, ___) => const NoInternetScreen(),
opaque: false, ---->> opacity should be false
fullscreenDialog: true));
And in next screen set background color with opacity.
return Scaffold(
backgroundColor: white.withOpacity(0.85),
......
result

Fading Edge ListView - Flutter

has anyone come across something like fadingEdgeLength in Android for Flutter so that when you scroll up items start fading into the top of the screen?
Below is my interface built up of the Widgets.
If it helps these are the properties I'm referring to:
android:fadingEdgeLength="10dp"
android:requiresFadingEdge="horizontal">
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('CMS Users'),
),
body: ListView.builder(
padding: EdgeInsets.only(top: 20.0, left: 4.0),
itemExtent: 70.0,
itemCount: data == null ? 0 : data.length,
itemBuilder: (BuildContext context, int index) {
return Card(
elevation: 10.0,
child: InkWell(
onTap: () {
Navigator.push(
context,
new MaterialPageRoute(
builder: (BuildContext context) =>
new PeopleDetails("Profile Page", profiles[index]),
));
},
child: ListTile(
leading: CircleAvatar(
child: Text(profiles[index].getInitials()),
backgroundColor: Colors.deepPurple,
radius: 30.0,
),
title: Text(
data[index]["firstname"] + "." + data[index]["lastname"]),
subtitle: Text(
data[index]["email"] + "\n" + data[index]["phonenumber"]),
),
),
);
}),
);
}
}
As others have mentioned, you can put the ListView under a ShaderMask, but with minor extra parameterizations you can get much better results - at least if you want to achieve what I wanted.
Optionally you can set the [stops] list for the LinearGradient:
The [stops] list, if specified, must have the same length as [colors]. It specifies fractions of the vector from start to end, between 0.0 and 1.0, for each color.
Plus: There are blend modes, where the color channels of the source are ignored, only the opacity has an effect. BlendMode.dstOut is also such in the example below. As you can see in the screenshot, the purple color is not used concretely, only for the fractions of the vector.
You can play with the different [blendMode] settings, there are quite a few of them.
void main() {
runApp(
MaterialApp(
home: Scaffold(
body: FadingListViewWidget(),
),
),
);
}
class FadingListViewWidget extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Center(
child: Container(
height: 320,
child: ShaderMask(
shaderCallback: (Rect rect) {
return LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [Colors.purple, Colors.transparent, Colors.transparent, Colors.purple],
stops: [0.0, 0.1, 0.9, 1.0], // 10% purple, 80% transparent, 10% purple
).createShader(rect);
},
blendMode: BlendMode.dstOut,
child: ListView.builder(
itemCount: 100,
itemBuilder: (BuildContext context, int index) {
return Card(
color: Colors.orangeAccent,
child: ListTile(
title: Text('test test test test test test'),
),
);
},
),
),
),
);
}
}
You could apply a ShaderMask on top of ListView and use BlendMode to get what you want.
Widget animationsList() {
return Expanded(
child: ShaderMask(
shaderCallback: (Rect bounds) {
return LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: <Color>[Colors.transparent,Colors.red],
).createShader(bounds);
},
child: Container(height: 200.0, width: 200.0, color: Colors.blue,),
blendMode: BlendMode.dstATop,
),
);
I had similar request so I created a library for this task.
You can find it here: fading_edge_scrollview
To use it you need to add a ScrollController to your ListView and then pass this ListView as child to FadingEdgeScrollView.fromScrollView constructor
Wrap the Listview with Stack, add the Listview as the first child, the second is Positioned Container with LinearGradient.
Sample from my code:
Stack:
return Stack(
children: <Widget>[
ListView(
scrollDirection: Axis.horizontal,
children: _myListOrderByDate,
),
FadeEndListview(),
],
);
The overlay class:
class FadeEndListview extends StatelessWidget {
const FadeEndListview({
Key key,
}) : super(key: key);
#override
Widget build(BuildContext context) {
return Positioned(
right: 0,
width: 8.0,
height: kYoutubeThumbnailsHeight,
child: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.centerRight,
end: Alignment.centerLeft,
stops: [0.0, 1.0],
colors: [
Theme.of(context).scaffoldBackgroundColor,
Theme.of(context).scaffoldBackgroundColor.withOpacity(0.0),
],
),
),
),
);
}
}
And it will look something like this:
Try to use
Text(
'This is big text, I am using Flutter and trying to fade text',
overflow: TextOverflow.fade,
maxLines: 1,
),

Resources