https://github.com/khlebobul/dynamic_island_pet
Example of interaction with Dynamic Island in a Flutter application
https://github.com/khlebobul/dynamic_island_pet
dart dynamic-island flutter ios-flutter
Last synced: 8 months ago
JSON representation
Example of interaction with Dynamic Island in a Flutter application
- Host: GitHub
- URL: https://github.com/khlebobul/dynamic_island_pet
- Owner: khlebobul
- License: mit
- Created: 2024-11-02T14:25:43.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2024-12-15T10:20:26.000Z (over 1 year ago)
- Last Synced: 2025-04-10T09:48:27.684Z (about 1 year ago)
- Topics: dart, dynamic-island, flutter, ios-flutter
- Language: Dart
- Homepage: https://medium.com/@khlebobul/how-to-work-with-dynamic-island-in-the-flutter-application-89851b0d9887
- Size: 128 KB
- Stars: 6
- Watchers: 1
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Dynamic Island Pet Flutter app
[](https://app.codacy.com/gh/khlebobul/dynamic_island_pet/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade) [](https://opensource.org/licenses/MIT)
Example of interaction with Dynamic Island in a Flutter application
https://github.com/user-attachments/assets/0fb54a02-eb9d-4d79-ae22-0b6495d8e6df
I really like it when developers and designers add little details to an app. It shows that they really care about their user. In this article, I will discuss how to make your app a little cuter for the user with Dynamic Island and a little pet.
> It has long been an axiom of mine that the little things are infinitely the most important.
> — *Sir Arthur Conan Doyle, The Memoirs of Sherlock Holmes*
About this project: [How to work with Dynamic Island in the Flutter application](https://medium.com/@khlebobul/how-to-work-with-dynamic-island-in-the-flutter-application-89851b0d9887)
## To see the work in action, download Knight's Graph ♞:
- [App Store](https://apps.apple.com/us/app/knights-graph/id6737812039)
- [Google Play](https://play.google.com/store/apps/details?id=com.khlebobul.knights_graph)
- [Website](https://knightsgraph.vercel.app)
## Usage
```dart
Scaffold(
backgroundColor: Colors.white,
body: Stack(
children: [
if (_hasDynamicIsland && _isInForeground)
DynamicIsland(
animationDuration: const Duration(milliseconds: 2000),
startOffset: -1.0,
endOffset: 1.0,
reverse: false,
child: Image.asset(
'assets/dash.png',
height: 15,
width: 15,
),
),
],
),
);
```
### Define the model
```dart
final dynamicIslandModels = [
'iPhone15,2', // iPhone 14 Pro
'iPhone15,3', // iPhone 14 Pro Max
'iPhone15,4', // iPhone 15
'iPhone15,5', // iPhone 15 Plus
'iPhone16,1', // iPhone 15 Pro
'iPhone16,2', // iPhone 15 Pro Max
'iPhone17,1', // iPhone 16 Pro
'iPhone17,2', // iPhone 16 Pro Max
'iPhone17,3', // iPhone 16
'iPhone17,4', // iPhone 16 Plus
'iPhone18,1', // iPhone 17 Pro
'iPhone18,2', // iPhone 17 Pro Max
'iPhone18,3', // iPhone 17
'iPhone18,4', // iPhone Air
];
```
### It is better to use a separate padding for each model
```dart
final deviceModel = await DeviceInfo.getDeviceModel();
return switch (deviceModel) {
// iPhone 14 ❌
// iPhone 14 Plus ❌
'iPhone15,2' => 13.0, // iPhone 14 Pro ✅
'iPhone15,3' => 13.0, // iPhone 14 Pro Max ✅
'iPhone15,4' => 13.0, // iPhone 15 ✅
'iPhone15,5' => 13.0, // iPhone 15 Plus ✅
'iPhone16,1' => 13.0, // iPhone 15 Pro ✅
'iPhone16,2' => 13.0, // iPhone 15 Pro Max ✅
'iPhone17,1' => 16.5, // iPhone 16 Pro ✅
'iPhone17,2' => 16.0, // iPhone 16 Pro Max ✅
'iPhone17,3' => 13.0, // iPhone 16 ✅
'iPhone17,4' => 13.0, // iPhone 16 Plus ✅
'iPhone18,1' => 13.0, // iPhone 17 Pro ✅
'iPhone18,2' => 13.0, // iPhone 17 Pro Max ✅
'iPhone18,3' => 13.0, // iPhone 17 ✅
'iPhone18,4' => 16.5, // iPhone Air ✅
_ => 13.0,
};
```
### Display conditions
```dart
bool _hasDynamicIsland = false; // check if the device has a dynamic island
bool _isInForeground = true; // check if the app is in the foreground
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this); // add the observer
_checkForDynamicIsland(); // check if the device has a dynamic island
}
@override
void dispose() {
WidgetsBinding.instance.removeObserver(this); // remove the observer
super.dispose();
}
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
setState(() {
// check if the app is in the foreground
_isInForeground = state == AppLifecycleState.resumed;
});
}
Future _checkForDynamicIsland() async {
final hasDynamicIsland = await DeviceInfo.hasDynamicIsland();
setState(() {
_hasDynamicIsland = hasDynamicIsland;
});
}
```