We are currently in the process of evaluating whether Flutter is a good platform to build a new app on. So we wanted to make sure that our app looks good on devices with dif
Flutter supports loading of assets by automatically choosing DPI dependent resources, see https://flutter.io/assets-and-images/#declaring-resolution-aware-image-assets for how the mechanism works.
Flutter should scale text according to devicePixelRatio value. Here is an example app showing you how that works:
import 'package:flutter/material.dart';
void main() {
runApp(new MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Demo',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
home: new MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
MediaQueryData queryData;
void _incrementCounter() {
setState(() {
_counter++;
});
}
@override
Widget build(BuildContext context) {
queryData = MediaQuery.of(context);
double devicePixelRatio = queryData.devicePixelRatio;
TextStyle style38 = new TextStyle(
inherit: true,
fontSize: 38.0,
);
TextStyle style20 = new TextStyle(
inherit: true,
fontSize: 20.0,
);
return new Scaffold(
appBar: new AppBar(
title: new Text(widget.title),
),
body: new Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
new Text(
'Button tapped $_counter time${ _counter == 1 ? '' : 's' }.',
style: style38,
),
new Text(
'size (pixels): w=${queryData.size.width * devicePixelRatio}, h=${queryData.size.height * devicePixelRatio}',
style: style20,
),
new Text(
'devicePixelRatio: $devicePixelRatio',
style: style20,
),
new Text(
'size: w=${queryData.size.width}, h=${queryData.size.height}',
style: style20,
),
new Text(
'textScaleFactor: w=${queryData.textScaleFactor}',
style: style20,
),
],
),
floatingActionButton: new FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: new Icon(Icons.add),
),
);
}
}
It's a modified version of the default Flutter app showing the device viewport size in pixels, the devicePixelRatio value, the size in absolute pixels. See the screenshot of the app running on Android in 3 different resolutions, and then iOS emulator with iPhone 7 Plus screen resolution. The screen resolutions are:
The text on all devices is scaled according to the actual screen size and logical viewport.
For smaller devices, I created an optional scaler.
We test on many different devices including the iPhone SE 4" and Android devices with extremely high DPI as default. Works well.
double scaleSmallDevice(BuildContext context) {
final size = MediaQuery.of(context).size;
// For tiny devices.
if (size.height < 600) {
return 0.7;
}
// For normal devices.
return 1.0;
}