Is it possible to add to or override specific methods or properties of a widget, while still having access to the default properties. I can imagine this would come in useful when still wanting the full widget functionality but maybe adding a method or to provide defaults.
For example:
Lets say I want to style a container to have rounded corners:
Instead of doing this everywhere I want this style:
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(15)),
)
I create a CustomRoundedDecoration class and default the borderRadius property:
class CustomRoundedDecoration extends BoxDecoration {
RoundedDecoration( /* somehow keep all BoxDecoration properties */ )
#override
BorderRadiusGeometry get borderRadius => BorderRadius.all(Radius.circular(15)); // my default
}
Then I can just use my new CustomRoundedDecoration, but most importantly still have access to the default BoxDecoration properties, and potentially still override the borderRadius.
decoration: CustomRoundedDecoration(/* access other BoxDecoration properties but now I've got borderRadius defaulted */),
Obviously in practice you would add or override many properties, not just the one.
I know it is possible to copy the source code into your own widget and change whats needed there, but this seems a bit overkill to just provide defaults
Related
I'm not sure how I should structure my pages when using a BottomNavBar.
Right now, I use a MainScreen which contains a Scaffold and BottomNavBar
The MainScreen widget contains a list with the different pages. Is this the recommended way to use the bottomNavBar? I know I could also use the Navigator to navigate between the screens, but then it launches a different window for each page, which isn't what you expect when using a bottomNavBar. The way I implemented it now works fine, but how could I use a FloatingActionButton in the one of the screens? Do you always need a Scaffold for that?
List<Widget> screens = [
Screen1(),
Screen2(),
Screen3()
];
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(Constants.APP_NAME),
),
body: screens[_currentIndex],
bottomNavigationBar: CustomBottomNav(onBottomNavPressed: onBottomNavPressed,),
);
}
According to the official BottomNavigationBar class documentation, providing widgets as a <Widget>[ ]is the recommended way to provide widgets. And for the second part of your question, yes. a FloatingActionButton can only be included inside a Scaffold, so you should add one in the widget where you need to use the FloatingActionButton.
I am using the Dismissible widget for swiping within my application. However, I wish to reuse the swiping activity, without the ability for the user to swipe. The whole class is wrapped in the dismissible.
So the overall code looks something like this:
Dimissible(
Row(
Column(
// random code
),
),
);
Whereas I want to be able to either have everything wrapped inside the dismissble, or not, without having to copy paste the entire code into a new class. Any suggestions?
How can I return either a specific container widget, or nothing at all
How would I go about that. Either return the dismissible or instead null? Wouldn't that leave me with an exception?
You can return a blank Container() or a SizedBox() widget (when you condition meets to return null).
Flutter will not throw an error then.
I have a list of ListTile and whenever I tapped them, a new page will appear. Currently, the new page will slide up (when appearing) and slide down (when removed). I wanted to change the transition animation to Fade.
I've read the solution of that in here then I edited the code from the link and here is the result.
class MyCustomRoute<T> extends MaterialPageRoute<T> {
MyCustomRoute({ WidgetBuilder builder})
: super(builder: builder);
#override
Widget buildTransitions(BuildContext context,
Animation<double> animation,
Animation<double> secondaryAnimation,
Widget child) {
if (settings.isInitialRoute)
return child;
return new FadeTransition(opacity: animation, child: child);
}
}
The only difference from the link's solution to mine was that I never supplied the "settings" variable to the MaterialPageRoute class.
And here is the part of the code where I've used the Navigator.push:
new ListTile(
onTap: (){
Navigator.push(context, new MyCustomRoute(builder: (context) => new SecondPage("someTitle", "someDescription") ));
},
//The rest of the code goes here
I've tried to run this code and I've never expected that this will run smoothly since I never provided the settings variable to the MaterialPageRoute widget but it ran perfectly.
My question is, is this the right way to do it? or
Should I provide settings for the MaterialPageRoute class?
And also since I didn't provide a settings variable for the MaterialPageRoute class, where did it get its settings? In this part of the code:
if (settings.isInitialRoute)
return child;
I would appreciate any enlightment. Thanks in advance.
The settings are only meant for two things - specifying the name, and letting the route know whether it's the first page to be opened.
The isInitialRoute simply tells the route whether it's the first page to be opened; this is important because you don't want a slide up animation on the very first page.
Since it seems your Custom Route is really only used after the first page, you don't need to worry about this. So you're probably fine ignoring the settings, unless you start to use the page as your first page (and even then, fading in might not be the worst thing).
I want animate widgets like the below gif
But whats happening is like the below gif
I just added a color to the container to get a sense of the frame of parent container
How can we make the inner widgets to clip when moving out of parent widget?
I am using Transform to animate like projects.
Please let me know if any more info is required.
If you want your red container to clip overflow, you have to wrap it into a ClipRect.
new ClipRect(
child: new Container(color: Colors.red, child: myAnimationThing),
),
Is there any way to get an open keyboard's height in Flutter? I'm trying to pad a bottomSheet widget by the height of the keyboard while it's open.
Usually viewInsets provides data about any system ui that obscures the flutter ui. To know about the keyboard height, you can just check for the bottom property of viewInsets, when the keyboard is onscreen, this will hold the height of keyboard else zero.
You can check for the viewInsets with MediaQuery like:
MediaQuery.of(context).viewInsets.bottom
Note: The bottom property may have value even if some other system ui obscures the flutter ui from bottom.
Hope that helps!
The MediaQuery.of(context).viewInsets solution does not work for me. It always says zero even if keyboard is open. Moreover, looking at the highest-upvoted comment in this answer, it is a bad idea to use it as keyboard indicator.
Thus, here is a one-line solution:
final viewInsets = EdgeInsets.fromWindowPadding(WidgetsBinding.instance.window.viewInsets,WidgetsBinding.instance.window.devicePixelRatio);
Then do whatever you want (e.g. viewInsets.bottom is keyboard height) :)
EDIT: https://api.flutter.dev/flutter/dart-ui/FlutterView-class.html is a good source to see how keyboard affects various kinds of padding.
This one work for me:
https://pub.dev/packages/keyboard_utils
Sample code from package:
In case of complicated widget tree MediaQuery.of(context).viewInsets.bottom gives null even if the keyboard is open. So, we have to mutate values down the tree.
I made the package that provides all needed info down the tree https://pub.dev/packages/flutter_keyboard_size
Welcome to use and in case you find bugs or want to extend functionality please add the issue https://github.com/awaik/flutter_keyboard_size/issues
If MediaQuery.of(context).viewInsets.bottom shows 0.0, this should work:
First, go into your Scaffold and set this:
resizeToAvoidBottomInset: false,
THEN you can check the height of the keyboard in this way:
MediaQuery.of(context).viewInsets.bottom,
In case you need to get the keyboard height even when the keyboard is not open, you can use the flutter_persistent_keyboard_height package (note: it was created by me).
First thing you need to do is wrap a widget from children of which you want to get the keyboard height with PersistentKeyboardHeightProvider. Wrap your app widget (perhaps MaterialApp) if you want to get keyboard height from all widgets.
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Persistent Keyboard Height Example',
home: const FlutterPersistentKeyboardHeightExample(),
builder: (context, child) => PersistentKeyboardHeightProvider(
child: child!,
),
);
}
}
And after that you can use the PersistentKeyboardHeight.of(context).keyboardHeight to get the height.
In my case nothing worked, but I needed screen height without keyboard height and LayoutBuilder work perfect.
LayoutBuilder(
builder: (context, constraints) => Container(
//maxHeight will change depending on your keyboard visible or not
height:constraints.maxHeight,
),
);
In theory you can do this
LayoutBuilder(
builder: (context, constraints) {
double keyboardHeight = MediaQuery.of(context).size.height - constrains.maxHeight;
}
);