flutter bottomsheet with notch (similar to bottomNavigationBar: BottomAppBar's shape property) - dart

question 1:
how to add a notch to flutter bottom sheet around the floatingactionbutton, so that it looks like a bottomappbar (with shape of CircularNotchedRectangle()) but behave like bottomsheet (can drag to dismiss)
question 2:
how to make a bottomsheet non-dismissible yet still draggable. (similiar to android's bottomsheet)
question 3:
bottomsheet peek height, bottom sheet that dismissible, but also expandable (again, just like android bottomsheet)
is it possible to achieve what I've listed above? or i'm out of luck and have to use a 3rd party library? (if there's one?)

hope its help :)
Scaffold(
floatingActionButtonLocation: FloatingActionButtonLocation.startDocked, //specify the location of the FAB
floatingActionButton: FloatingActionButton(
backgroundColor: Colors.blue,
onPressed: () {
print('OK');
},
tooltip: "start FAB",
child: Container(
margin: EdgeInsets.all(15.0),
child: Icon(Icons.add),
),
elevation: 4.0,
),
bottomNavigationBar: BottomAppBar(
child: Container(
color: mycolor,
height: 35,
),
)
);

You can use this technique too
Scaffold(
backgroundColor: myBackgroundColor,
floatingActionButtonLocation: FloatingActionButtonLocation.startDocked, //specify the location of the FAB
floatingActionButton: CircleAvatar(
radius: 32,
backgroundColor: myBackgroundColor,
child: Padding(
padding: EdgeInsets.all(1),
child: FloatingActionButton(
backgroundColor: MyColor.textColor,
onPressed: () {
print('OK');
},
child: Container(
margin: EdgeInsets.all(15.0),
child: Icon(Icons.add),
),
elevation: 4.0,
),
),
),
bottomNavigationBar: BottomAppBar(
child: Container(
color: MyColor.textColor,
height: 35,
),
)
);

Related

How to change the icon position in FloatingActionButton extended

The icon on FloatingActionButton extended is on left, how can i put the icon on right? after the text
floatingActionButton: FloatingActionButton.extended(
onPressed: (){},
label: Text("Next",),
icon: Icon(Icons.arrow_forward,
),
),
floatingActionButtonLocation: FloatingActionButtonLocation.endFloat
There isn't any direct way to do that.
But as a workaround, you could just pass a Row widget (Which contains a Text and Icon widgets) to label parameter.
floatingActionButton: FloatingActionButton.extended(
onPressed: () {},
label: Row(
children: <Widget>[Text("Proceed"), Icon(Icons.arrow_forward)],
),
icon: Container(),
),
Hope it helps.
I don't think you can do that with FloatingActionButton, but instead you can configure a RaisedButton to look very similar.
Just use it same as you would do it with FloatingActionButton.
floatingActionButton: RaisedButton(
child: Container(
height: 50.0,
child: Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
const SizedBox(width: 16.0),
Text('Next', style: TextStyle(color: Colors.white, fontSize: 25),),
const SizedBox(width: 8.0),
Icon(Icons.arrow_forward, size: 30.0, color: Colors.white,),
const SizedBox(width: 20.0),
]),
),
color: Colors.blue,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30.0),
),
onPressed: () {
print('Do somenthing');
},
)
Hope this help.

Horizontal ListView.builder overflow width bound when scroll

I am trying to use ListView.builder to display a horizontal list in a Stack but am encountering this weird bug when scrolling ListView if I set itemCount: 10. If I set itemCount: 20 the ListView scrolls like normal.
I have tested in the emulator (Galaxy Nexus 720x1280 android 5.0) and on a real device (Nokia 7 plus, android 9.0). How can I fix this?
class BugPage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Stack(
children: <Widget>[
Positioned(
left: 20.0,
right: 20.0,
height: 60.0,
bottom: 70.0,
child: Row(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Expanded(
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: 10, // Overflow when scroll.
itemBuilder: (BuildContext context, int index) {
return Padding(
padding: const EdgeInsets.symmetric(
horizontal: 3.0,
),
child: Container(
width: 40.0,
height: 40.0,
color: Colors.red,
child: Center(child: Text("$index")),
),
);
},
),
),
SizedBox(width: 10.0),
FloatingActionButton(
backgroundColor: Colors.blue,
onPressed: () {},
child: new Icon(
Icons.add,
color: Colors.black,
),
),
],
),
),
],
),
),
);
}
}
Expected output:
Actual output:
And a video of the problem
I tried your code and run with bigger intemcount too without problems, but i have an advice, change the
SizedBox(width: 10.0)
for a padding around the button
Padding(
padding: const EdgeInsets.only(left: 10),
child: FloatingActionButton(
backgroundColor: Colors.blue,
onPressed: () {},
child: new Icon(
Icons.add,
color: Colors.black,
),
)
)
It seems like this bug appears in old flutter version after I updated to newest version everything is ok.

How to give elevation to an image in Flutter?

I have to implement elevation (like a shadow) on an image widget, but I couldn't find a solution to this. Is there a way to implement elevation to an image?
An image example of what I want to remove:
I used the Material widget, but it renders empty space!! The original image has no spaces, how can I remove them?
You can simply use the Material or the Card widget:
Center(
child: Material( // with Material
child: Image.network('https://placeimg.com/640/480/any'),
elevation: 18.0,
shape: const CircleBorder(),
clipBehavior: Clip.antiAlias,
),
),
Center(
child: Card( // with Card
child: Image.network('https://placeimg.com/640/480/any'),
elevation: 18.0,
shape: const CircleBorder(),
clipBehavior: Clip.antiAlias,
),
),
If you want more control on the Radius of the Image. Then you can use CircleAvatar:
Center(
child: Card(
child: CircleAvatar(
maxRadius: 54.0,
backgroundImage:
NetworkImage('https://placeimg.com/640/480/any'),
),
elevation: 18.0,
shape: const CircleBorder(),
clipBehavior: Clip.antiAlias,
),
),

Flutter How to set Title to Show Modal Bottom Sheet?

Is there a possibility to set title and perhaps navigation back button on this showModalBottomSheet?
I expect something like this...
Yes it's possible to do something like that in Flutter. You can use Column Widget and make its first child as a title bar or something like that with title and back arrow icon.
Here's the code for that:
import 'dart:async';
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
canvasColor: Colors.transparent,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget{
#override
HomePageS createState()=> HomePageS();
}
class HomePageS extends State<MyHomePage>{
#override
Widget build(BuildContext context){
return Scaffold(
body: Container(
color: Colors.white,
child: Center(
child: FlatButton(
child: Text("Show BottomSheet"),
onPressed: () async{
showModalBottomSheet(
context: context,
builder: (BuildContext context){
return ClipRRect(
borderRadius: BorderRadius.only(topLeft: Radius.circular(20.0), topRight: Radius.circular(20.0)),
child: Container(
color: Colors.white,
child: Column(
children: [
ListTile(
leading: Material(
color: Colors.transparent,
child: InkWell(
onTap: (){
Navigator.of(context).pop();
},
child: Icon(Icons.arrow_back) // the arrow back icon
),
),
title: Center(
child: Text("My Title") // Your desired title
)
),
]
)
)
);
}
);
}
)
)
)
);
}
}
Here is the output:
If you don't wanna use the InkWell widget, you can use the IconButton widget like this:
...
ListTile(
leading: IconButton(
icon: Icon(Icons.arrow_back),
onPressed: (){
Navigator.of(context).pop();
}
),
title: Center(
child: Text("My Title")
)
),
...
But if you noticed, the title text is not really centered. In this case, we can replace the ListTile widget to a Stack widget and do something like this:
child: Column(
children: [
Stack(
children: [
Container(
width: double.infinity,
height: 56.0,
child: Center(
child: Text("My Title") // Your desired title
),
),
Positioned(
left: 0.0,
top: 0.0,
child: IconButton(
icon: Icon(Icons.arrow_back), // Your desired icon
onPressed: (){
Navigator.of(context).pop();
}
)
)
]
),
]
)
...
This is the output:
But what would happen if we have a very long text for our title? It would definitely look like this:
Ugly, right? We can see that our Text widget overlaps with our IconButton widget. To avoid this, we can replace our Stack widget with a Row widget.
Here's the code for that:
...
child: Column(
children: [
Row( // A Row widget
mainAxisAlignment: MainAxisAlignment.spaceBetween, // Free space will be equally divided and will be placed between the children.
children: [
IconButton( // A normal IconButton
icon: Icon(Icons.arrow_back),
onPressed: (){
Navigator.of(context).pop();
}
),
Flexible( // A Flexible widget that will make its child flexible
child: Text(
"My Title is very very very very very very very long", // A very long text
overflow: TextOverflow.ellipsis, // handles overflowing of text
),
),
Opacity( // A Opacity widget
opacity: 0.0, // setting opacity to zero will make its child invisible
child: IconButton(
icon: Icon(Icons.clear), // some random icon
onPressed: null, // making the IconButton disabled
)
),
]
),
]
)
Output would be like this:
And this (if the title is not long):
I guess I have naive solution but this works perfectly for me. You might as well try it.
showModalBottomSheet(
barrierColor: Colors.transparent,
enableDrag: true,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(top: Radius.circular(20))),
context: context,
builder:(context){
return Padding(
padding: const EdgeInsets.only(left: 8.0, right: 8.0, bottom: 8.0),
child: Stack(children: [
Padding(
padding: const EdgeInsets.only(top: 65),
child: SingleChildScrollView(
child:<<Scrollable Wdgets>>,
),
),
Card(
elevation: 3,
color: Colors.grey[850],
child: ListTile(
leading: Text("YOUR TITLE",
style: TextStyle(
color: Colors.white,
fontSize: 20,
fontWeight: FontWeight.w500)),
trailing: GestureDetector(
onTap: () {
Navigator.pop(context);
},
child: Icon(
Icons.close,
color: Colors.white,
size: 20,
),
),
),
),
]),
);}

IconButton throws an exception

I'm trying to make a simple AppBar widget with some icons in Flutter, but I keep getting this assertion:
The following assertion was thrown building IconButton(Icon(IconData(U+0E5D2)); disabled; tooltip:
I pretty much just mimiced the documentation, but here is my code:
import 'package:flutter/material.dart';
void main() {
runApp(new MaterialApp(
title: "Stateless Widget Example",
home: new AppBar(title: new Text("App Bar"))
));
}
class AppBar extends StatelessWidget {
AppBar({this.title});
final Widget title;
#override
Widget build(BuildContext context) {
return new Container(
height: 56.0,
padding: const EdgeInsets.symmetric(horizontal: 8.0),
decoration: new BoxDecoration(
color: Colors.cyan,
border: new Border(
bottom: new BorderSide(
width: 1.0,
color: Colors.black
)
)
),
child: new Row (
children: <Widget> [
new IconButton(
icon: new Icon(Icons.menu),
tooltip: 'Navigation menu',
onPressed: null, // null disables the button
),
new Expanded(child: title)
]
)
);
}
}
I feel like I'm missing an import or something. But I'm not completely sure. Perhaps my computer was just acting up, because Flutter run has been buggy for me. I'm new to Dart and Flutter, so perhaps I'm just not seeing an obvious error.
IconButton is a Material Widget, so you need to use it inside a Material parent, for example something like this:
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(title: new Text(widget.title), actions: <Widget>[
new IconButton(
icon: new Icon(Icons.favorite),
tooltip: 'Favorite',
onPressed: () {},
),
new IconButton(
icon: new Icon(Icons.more_vert),
tooltip: 'Navigation menu',
onPressed: () {},
),
]),
body: new Center(
child: new Text('This is the body of the page.'),
),
);
}
Check to ensure that your pubspec.yaml contains the following:
flutter:
uses-material-design: true
That will ensure that the Material Icons font is included with your application, so that you can use the icons in the Icons class.
addButton() {
return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Padding(
padding: const EdgeInsets.symmetric(vertical: 10.0),
child: SizedBox(
height: 45,
width: 200,
child: ElevatedButton.icon(
onPressed: () async {},
style: ButtonStyle(
shape: MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30.0),
)),
elevation: MaterialStateProperty.all(1),
backgroundColor: MaterialStateProperty.all(Colors.blue),
),
icon: Icon(Icons.add, size: 18),
label: Text("Add question"),
),
),
),
],
);
}
you lost meterial widget
IconButton needs Material
return new Material(
child: new Container(
height: 56.0,
padding: const EdgeInsets.symmetric(horizontal: 8.0),
decoration: new BoxDecoration(
color: Colors.cyan,
border: new Border(
bottom: new BorderSide(
width: 1.0,
color: Colors.black
)
)
),
child: new Row (
children: <Widget> [
new IconButton(
icon: new Icon(Icons.menu),
tooltip: 'Navigation menu',
onPressed: null, // null disables the button
),
new Expanded(child: title)
]
)
);

Resources