What's the best way to make a adaptive flutter app?
on the flutter web page you can find a nice article about how to build an adaptive flutter application (see here).
Another option, which is simular to the screen-based breakpoint approach is the abstract factory pattern.
In order to implement the abstract factory pattern you need at first an abstract factory and a class, which determines the available screen size (AdaptivityWidget) :
abstract class IWidgetsFactory {
// returns the factory regarding to the screen size
static IWidgetsFactory getFactory(BuildContext context) {
if (AdaptivityWidget.isTinyScreen(context)) {
return TinyScreenFactory();
} else if (AdaptivityWidget.isSmallScreen(context)) {
return SmallScreenFactory();
} else if (AdaptivityWidget.isMediumScreen(context)) {
return MediumScreenFactory();
} else {
return LargeScreenFactory();
}
}
// implement the abstract methods, which the concrete factories shall implement
double getBurgerMenuIconSize();
// and so on ...
}
/// [AdaptivityWidget] determines, which type of screen is available.
class AdaptivityWidget {
/// Returns the current width depending on the current context.
static double _getWidth(BuildContext context) {
return MediaQuery.of(context).size.width;
}
/// Large screen is any screen whose width is more than 1200 pixels.
static bool isLargeScreen(BuildContext context) {
return _getWidth(context) >= 1200;
}
/// Medium screen is any screen whose width is less than 1200 pixels,
/// and more than 799 pixels.
static bool isMediumScreen(BuildContext context) {
return _getWidth(context) >= 800 && _getWidth(context) < 1200;
}
/// Small screen is any screen whose width is less than 800 pixels,
/// and more than 399.
static bool isSmallScreen(BuildContext context) {
return _getWidth(context) >= 400 && _getWidth(context) < 800;
}
/// Tiny Screen is any screen whose width is less than 400 pixels.
static bool isTinyScreen(BuildContext context) {
return _getWidth(context) < 400;
}
}
Afterwards you have to implement the concrete factories (I will show that on one example):
/// Concrete factory for large screens.
class LargeScreenFactory extends IWidgetsFactory {
/// Returns 48.0px.
@override
double getBurgerMenuIconSize() {
return SizeT24S32M40L48().large;
}
}
Than you require an abstract class for your styles. This could look like this:
abstract class IStyle {
/// Parameter for [TinyScreenFactory]
dynamic get tiny;
/// Parameter for [SmallScreenFactory]
dynamic get small;
/// Parameter for [MediumScreenFactory]
dynamic get medium;
/// Parameter for [LargeScreenFactory]
dynamic get large;
}
And a concrete implementation of that looks like this:
class SizeT24S32M40L48 implements IStyle {
@override
double get large => 48.0;
@override
double get medium => 40.0;
@override
double get small => 32.0;
@override
double get tiny => 24.0;
}
To use it in a view would look like this:
class View extends StatelessWidget implements IMyFactory, IMySize{
@override
Widget build(BuildContext context){
return Icon(
Icons.menu,
size: getSize(getFactory(context)),
);
}
/// Returns a widget factory.
@override
IWidgetsFactory getFactory(BuildContext context) {
return IWidgetsFactory.getFactory(context);
}
/// Returns a single icon size.
@override
double getSize(IWidgetsFactory factory) {
return factory.getBurgerMenuIconSize();
}
}
Where IMySize and IMyFactory can look like this:
abstract class IMySize {
double getSize(IWidgetsFactory factory);
}
abstract class IMyFactory {
IWidgetsFactory getFactory(BuildContext context);
}
You can use the abstract factory pattern also in order to differ between Android and iOS in order to generate platform specific behaviour.
sammhung
Updated on January 01, 2023Comments
-
sammhung over 1 year
I've made quite a few flutter apps, but I'm not too sure what's the best way to make a responsive app. What I am currently doing is I'm making all my widgets relative to the screeensize.
For example, to render a container, instead of putting a fixed size:
width: MediaQuery.of(context).size.width * 0.2;
So instead of having different breakpoints all my widgets will be relative to whatever phone they are using. Is that the right way of doing it?
If I should be using breakpoints, what should the mobile breakpoints be? I know that for a website I would do breakpoints for a phone, Ipad, Laptop, Desktop etc, but what are the breakpoints for a small phone, medium phone and large phone? Thanks!