Skip to content

Commit ed1193f

Browse files
author
Tim Sneath
authored
Update building-adaptive-apps.md (#5929)
The general tone of this advice is good, but it unnecessarily complicates things, since it adds a dependency on a third-party package that doesn't have a stable null-safe version, when all that is needed is to flip the order so that Dart can short-circuit execution. I've also removed the macOS example, because the use of RTL to reorder buttons seems dangerous. I've not tested this, but I suspect this may have other side-effects. For example, this code assumes that the default platform is LTR, so may have opposite results on an Arabic or Hebrew workstation.
1 parent bd509d0 commit ed1193f

File tree

1 file changed

+10
-83
lines changed

1 file changed

+10
-83
lines changed

src/docs/development/ui/layout/building-adaptive-apps.md

Lines changed: 10 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -332,91 +332,18 @@ you can use the [`Platform`][] API along with the `kIsWeb` value:
332332

333333
<!--skip-->
334334
```dart
335-
bool get isMobileDevice => (Platform.isIOS || Platform.isAndroid);
336-
bool get isMobileDeviceOrWeb => isMobileDevice || kIsWeb;
335+
bool get isMobileDevice => !kIsWeb && (Platform.isIOS || Platform.isAndroid);
336+
bool get isDesktopDevice =>
337+
!kIsWeb && (Platform.isMacOS || Platform.isWindows || Platform.isLinux);
338+
bool get isMobileDeviceOrWeb => kIsWeb || isMobileDevice;
339+
bool get isDesktopDeviceOrWeb => kIsWeb || isDesktopDevice;
337340
```
338341

339-
One issue with this check is that the `Platform` API
340-
can’t be accessed from web builds without throwing an exception.
341-
This is because the API imports the `dart.io` package,
342-
which isn’t fully supported on the web target.
343-
To workaround this issue, you can use the
344-
[`UniversalPlatform`][] package:
345-
346-
[`UniversalPlatform`]: {{site.pub}}/packages/universal_platform
347-
348-
<!--skip-->
349-
```dart
350-
bool get isMobileDevice => (UniversalPlatform.isIOS || UniversalPlatform.isAndroid);
351-
```
352-
353-
This device check is now safe to run on any platform,
354-
but it suffers from another issue, which is its verbosity
355-
and repetitiveness. For example, consider the following code
356-
for a view that you want to show on any of the desktop
357-
platforms and the web:
358-
359-
<!--skip-->
360-
```dart
361-
return (UniversalPlatform.isWindows || UniversalPlatform.isLinux || UniversalPlatform.isMacOS || kIsWeb)? DesktopView() : MobileView();
362-
```
363-
364-
The code is easier to read and less prone to typos if you
365-
write it like this:
366-
367-
<!--skip-->
368-
```dart
369-
return DeviceType.isDesktopOrWeb? DesktopView() : MobileView();
370-
```
371-
372-
As such, you may want to create a small utility class
373-
of shortcut methods:
374-
375-
<!--skip-->
376-
```dart
377-
class DeviceType {
378-
// Syntax sugar, proxy the UniversalPlatform methods so our views can reference a single API
379-
static bool isIOS = UniversalPlatform.isIOS;
380-
static bool isAndroid = UniversalPlatform.isAndroid;
381-
static bool isMacOS = UniversalPlatform.isMacOS;
382-
static bool isLinux = UniversalPlatform.isLinux;
383-
static bool isWindows = UniversalPlatform.isWindows;
384-
385-
// Higher level device class abstractions (more syntax sugar for the views)
386-
static bool isWeb = UniversalPlatform.isWeb;
387-
static bool get isDesktop => isWindows || isMacOS || isLinux;
388-
static bool get isMobile => isAndroid || isIOS;
389-
static bool get isDesktopOrWeb => isDesktop || isWeb;
390-
static bool get isMobileOrWeb => isMobile || isWeb;
391-
}
392-
```
393-
394-
While this is really just syntactic sugar,
395-
the helper methods can help keep your UI code clean and readable.
396-
397-
You can now write the preceding example similar to this:
398-
399-
<!--skip-->
400-
```dart
401-
class TitleBar extends StatelessWidget {
402-
@override
403-
Widget build(BuildContext context) {
404-
Row(
405-
// Our button should be right-aligned on macOS to avoid the native buttons
406-
textDirection: DeviceType.isMacOS ? TextDirection.rtl : TextDirection.ltr,
407-
children: [
408-
IconButton( ... ),
409-
Spacer(),
410-
],
411-
),
412-
}
413-
}
414-
```
415-
416-
This view now aligns its controls on the right hand side
417-
on macOS, while leaving them on the left side for all other platforms.
418-
With this small amount of logic,
419-
you have a single universal widget that is easy to test and maintain.
342+
The `Platform` API can’t be accessed from web builds without
343+
throwing an exception, because the `dart.io` package is not
344+
supported on the web target. As a result, this code checks
345+
for web first, and becuase of short-circuiting, Dart will
346+
never call `Platform` on web targets.
420347

421348
### Single source of truth for styling
422349

0 commit comments

Comments
 (0)