0 purchases
adaptix
adaptix #
A powerful and lightweight package for building beautiful responsive and adaptive applications.
Usage #
Initializing #
Wrap your widget subtree (usually, the starting point of your app) with AdaptixInitializer and pass an instance of AdaptixConfigs to configs parameter.
AdaptixInitializer(
configs: const AdaptixConfigs.canonical(),
builder: (context) {
return MaterialApp(
home: ...
);
});
copied to clipboard
And access data through a BuildContext. You can access AdaptixConstraints with Adaptix.of(context) or use the extension methods designed for pretty semantics.
AdaptixInitializer(
configs: const AdaptixConfigs.canonical(),
builder: (context) {
// Accessing adaptix
print(Adaptix.of(context));
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
color: Colors.red,
width: 50.adaptedPx(context),
height: 50.adaptedPx(context),
child: Text('${50.adaptedPx(context).round()} px'),
)
],
),
),
),
);
});
copied to clipboard
ResponsiveBreakpoint #
Instances of ResponsiveBreakpoint represent a start point of a layout pattern that is used by Adaptix to switch onto when a layout of a device changes. Those breakpoints are distinguished by their templateDeviceWidth field. In a context of this package, templateDeviceWidth of ResponsiveBreakpoint is a device width that is used for Adaptix to decide whether to use the breakpoint if a layout of a device changes the metrics.
A width of a device will be used in comparison with all the declared breakpoints' values if DeviceBreakpointDecisionStrategy.useOriginalWidth was set in the configurations, else if DeviceBreakpointDecisionStrategy.useShortestSide was applied, the shortest side of a device will be selected in comparison with the templateDeviceWidth of the breakpoints. The strategy variations were added as options because there are devices with ultra wide displays.
How Adaptix decides which breakpoint to use? #
So, basically, the device side is selected, as described above, for comparing to the breakpoints and performs following logic:
The breakpoint is selected if the device side is more or equal than n breakpoint's templateDeviceWidth and less than n+1 breakpoint's templateDeviceWidth.
If the device side is less than templateDeviceWidth of the first breakpoint - then the first breakpoint will be selected.
If the device side is more than templateDeviceWidth of the last breakpoint - then the last breakpoint will be selected.
Customization #
You can define your own configurations using default constructor of AdaptixConfigs.
AdaptixConfigs(
/// Here you define the breakpoints
/// Use width of a template device as a templateDeviceWidth of a breakpoint
breakpoints: const [
ResponsiveBreakpoint(templateDeviceWidth: 375, key: 'iphone7'),
ResponsiveBreakpoint(templateDeviceWidth: 414, key: 'iphone11'),
ResponsiveBreakpoint(templateDeviceWidth: 768, key: 'ipadMini'),
],
/// Define pixel scale rule per breakpoint
pixelScaleRules: const {
'iphone7': 1,
'iphone11': 1.1,
'ipadMini': 1.2,
},
)
copied to clipboard
Extension methods #
.adaptedPx on double #
Get a logical pixel scaled according to a current breakpoint of Adaptix.
print(1.adaptedPx(context));
copied to clipboard
.widthFraction on double #
Gives a percent fraction of the device width
// means 50 percent of the device width
print(50.widthFraction(context));
copied to clipboard
.heightFraction on double #
Gives a percent fraction of the device height
// means 50 percent of the device height
print(50.heightFraction(context));
copied to clipboard
.shortestSideFraction on double #
Gives a percent fraction of the device's shortest side
// means 50 percent of the shortest side of the device
print(50.shortestSideFraction(context));
copied to clipboard
.longestSideFraction on double #
Gives a percent fraction of the device's longest side
// means 50 percent of the longest side of the device
print(50.longestSideFraction(context));
copied to clipboard
.orientationSwitch on context #
Returns the text according to the current orientation
print(
context.orientationSwitch<String>(
onLandscape: 'Landscape text',
onPortrait: 'Portrait text'
)
);
copied to clipboard
.responsiveSwitch on context #
Do you want to display some widget according to a current breakpoint or maybe to display some text instead? This extension method allows to return a generic value of type T according to a current breakpoint of Adaptix.
AdaptixInitializer(
configs: AdaptixConfigs(
/// Here you define the breakpoints
/// Use width of a template device as a value of a breakpoint
breakpoints: const [
ResponsiveBreakpoint(templateDeviceWidth: 375, key: 'iphone7'),
ResponsiveBreakpoint(templateDeviceWidth: 414, key: 'iphone11'),
ResponsiveBreakpoint(templateDeviceWidth: 768, key: 'ipadMini'),
],
/// Define pixel scale rule per breakpoint.
pixelScaleRules: const {
'iphone7': 1,
'iphone11': 1.1,
'ipadMini': 1.2,
},
),
builder: (context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
color: Colors.red,
width: 50.adaptedPx(context),
height: 50.adaptedPx(context),
child: Text(
context.responsiveSwitch(
const GenericResponsiveSwitchArgs<String>(
defaultValue: 'This is a default text',
rules: const {
'iphone7': 'Hello, I am a pattern based on width of iphone7',
'iphone11':
'Hello, I am a pattern based on dimensions of iphone11',
'ipadMini':
'Hello, I am a pattern based on dimensions of ipadMini',
},
),
),
),
);
],
),
),
),
);
});
copied to clipboard
Note: #
If you use AdaptixConfigs.canonical, then pass CanonicalResponsiveBreakpoint.createCanonicalSwitchArguments as an argument to .responsiveSwitch
context.responsiveSwitch(CanonicalResponsiveBreakpoint
.createCanonicalSwitchArguments<String>(
defaultValue: 'Some default text',
xSmall: 'Text of xSmall devices',
small: 'Text of small devices',
medium: 'Text of medium devices',
tablet: 'Text of tablets',
desktop: 'Text of desktop apps'));
copied to clipboard
Best practice #
It's recommended to implement the value object pattern using this package for an elegant semantics and maintainable architecture. For that purpose you can use enhanced enums that come out of the box with Dart 2.17. Example:
enum MyResposivenessPattern implements ResponsiveBreakpoint {
iphone11(templateDeviceWidth: 414, pixelScale: 1.1),
iphone7(templateDeviceWidth: 375, pixelScale: 1),
ipadMini(templateDeviceWidth: 768, pixelScale: 1.12),
someDesktopDevice(templateDeviceWidth: 1024, pixelScale: 1.2);
static final myPixelScaleRules = {
for (var value in values) value.key: value.pixelScale,
};
@override
final double templateDeviceWidth;
final double pixelScale;
const MyResposivenessPattern(
{required this.templateDeviceWidth, required this.pixelScale});
@override
String get debugLabel => key;
@override
bool hasSameValueAs(ResponsiveBreakpoint other) =>
other.templateDeviceWidth == templateDeviceWidth;
@override
bool isSameAs(ArgsComparisonMixin other) {
return ResponsiveBreakpoint.breakpointEquality(
this,
other,
);
}
/// key as a name of an element of this enum
@override
String get key => name;
static GenericResponsiveSwitchArgs<T> myResponsiveSwitchArguments<T>(
{required T defaultValue,
T? iphone7Value,
T? iphone11Value,
T? ipadMiniValue,
T? someDesktopDeviceValue}) {
return GenericResponsiveSwitchArgs(
defaultValue: defaultValue,
rules: {
iphone7.key: iphone7Value ?? defaultValue,
iphone11.key: iphone11Value ?? defaultValue,
ipadMini.key: ipadMiniValue ?? defaultValue,
someDesktopDevice.key: someDesktopDeviceValue ?? defaultValue,
},
);
}
static AdaptixConfigs configs() => AdaptixConfigs(
breakpoints: MyResposivenessPattern.values,
pixelScaleRules: MyResposivenessPattern.myPixelScaleRules);
}
copied to clipboard
And use it as:
AdaptixInitializer(
configs: MyResposivenessPattern.configs(),
builder: (context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
color: Colors.red,
width: 50.adaptedPx(context),
height: 50.adaptedPx(context),
child: Text(context.responsiveSwitch(
MyResposivenessPattern.myResponsiveSwitchArguments(
defaultValue: 'Unrecognized device pattern',
iphone7Value: 'iphone7 device pattern',
iphone11Value: 'iphone11 device pattern',
ipadMiniValue: 'ipadMini device pattern'))),
)
],
),
),
),
);
});
copied to clipboard
For personal and professional use. You cannot resell or redistribute these repositories in their original state.
There are no reviews.