├── .gitignore ├── .metadata ├── CHANGELOG.md ├── LICENSE ├── README.md ├── example ├── .gitignore ├── .metadata ├── README.md ├── android │ ├── .gitignore │ ├── app │ │ ├── build.gradle │ │ └── src │ │ │ ├── debug │ │ │ └── AndroidManifest.xml │ │ │ ├── main │ │ │ ├── AndroidManifest.xml │ │ │ ├── kotlin │ │ │ │ └── com │ │ │ │ │ └── letsar │ │ │ │ │ └── vlb │ │ │ │ │ └── example │ │ │ │ │ └── MainActivity.kt │ │ │ └── res │ │ │ │ ├── drawable-v21 │ │ │ │ └── launch_background.xml │ │ │ │ ├── drawable │ │ │ │ └── launch_background.xml │ │ │ │ ├── mipmap-hdpi │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-mdpi │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xhdpi │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ └── ic_launcher.png │ │ │ │ ├── values-night │ │ │ │ └── styles.xml │ │ │ │ └── values │ │ │ │ └── styles.xml │ │ │ └── profile │ │ │ └── AndroidManifest.xml │ ├── build.gradle │ ├── gradle.properties │ ├── gradle │ │ └── wrapper │ │ │ └── gradle-wrapper.properties │ └── settings.gradle ├── ios │ ├── .gitignore │ ├── Flutter │ │ ├── AppFrameworkInfo.plist │ │ ├── Debug.xcconfig │ │ ├── Release.xcconfig │ │ └── ephemeral │ │ │ ├── flutter_lldb_helper.py │ │ │ └── flutter_lldbinit │ ├── Runner.xcodeproj │ │ ├── project.pbxproj │ │ ├── project.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata │ │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ │ └── WorkspaceSettings.xcsettings │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ └── Runner.xcscheme │ ├── Runner.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ └── WorkspaceSettings.xcsettings │ ├── Runner │ │ ├── AppDelegate.swift │ │ ├── Assets.xcassets │ │ │ ├── AppIcon.appiconset │ │ │ │ ├── Contents.json │ │ │ │ ├── Icon-App-1024x1024@1x.png │ │ │ │ ├── Icon-App-20x20@1x.png │ │ │ │ ├── Icon-App-20x20@2x.png │ │ │ │ ├── Icon-App-20x20@3x.png │ │ │ │ ├── Icon-App-29x29@1x.png │ │ │ │ ├── Icon-App-29x29@2x.png │ │ │ │ ├── Icon-App-29x29@3x.png │ │ │ │ ├── Icon-App-40x40@1x.png │ │ │ │ ├── Icon-App-40x40@2x.png │ │ │ │ ├── Icon-App-40x40@3x.png │ │ │ │ ├── Icon-App-60x60@2x.png │ │ │ │ ├── Icon-App-60x60@3x.png │ │ │ │ ├── Icon-App-76x76@1x.png │ │ │ │ ├── Icon-App-76x76@2x.png │ │ │ │ └── Icon-App-83.5x83.5@2x.png │ │ │ └── LaunchImage.imageset │ │ │ │ ├── Contents.json │ │ │ │ ├── LaunchImage.png │ │ │ │ ├── LaunchImage@2x.png │ │ │ │ ├── LaunchImage@3x.png │ │ │ │ └── README.md │ │ ├── Base.lproj │ │ │ ├── LaunchScreen.storyboard │ │ │ └── Main.storyboard │ │ ├── Info.plist │ │ └── Runner-Bridging-Header.h │ └── RunnerTests │ │ └── RunnerTests.swift ├── lib │ └── main.dart ├── pubspec.yaml └── test │ └── widget_test.dart ├── lib ├── src │ ├── sliver_value_layout_builder.dart │ └── value_layout_builder.dart └── value_layout_builder.dart ├── pubspec.yaml └── test ├── sliver_value_layout_builder_test.dart └── value_layout_builder_test.dart /.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | 12 | # IntelliJ related 13 | *.iml 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # The .vscode folder contains launch configuration and tasks you configure in 19 | # VS Code which you may wish to be included in version control, so this line 20 | # is commented out by default. 21 | #.vscode/ 22 | 23 | # Flutter/Dart/Pub related 24 | **/doc/api/ 25 | .dart_tool/ 26 | .flutter-plugins 27 | .flutter-plugins-dependencies 28 | .packages 29 | .pub-cache/ 30 | .pub/ 31 | build/ 32 | pubspec.lock 33 | 34 | # Android related 35 | **/android/**/gradle-wrapper.jar 36 | **/android/.gradle 37 | **/android/captures/ 38 | **/android/gradlew 39 | **/android/gradlew.bat 40 | **/android/local.properties 41 | **/android/**/GeneratedPluginRegistrant.java 42 | 43 | # iOS/XCode related 44 | **/ios/**/*.mode1v3 45 | **/ios/**/*.mode2v3 46 | **/ios/**/*.moved-aside 47 | **/ios/**/*.pbxuser 48 | **/ios/**/*.perspectivev3 49 | **/ios/**/*sync/ 50 | **/ios/**/.sconsign.dblite 51 | **/ios/**/.tags* 52 | **/ios/**/.vagrant/ 53 | **/ios/**/DerivedData/ 54 | **/ios/**/Icon? 55 | **/ios/**/Pods/ 56 | **/ios/**/.symlinks/ 57 | **/ios/**/profile 58 | **/ios/**/xcuserdata 59 | **/ios/.generated/ 60 | **/ios/Flutter/App.framework 61 | **/ios/Flutter/Flutter.framework 62 | **/ios/Flutter/Flutter.podspec 63 | **/ios/Flutter/Generated.xcconfig 64 | **/ios/Flutter/app.flx 65 | **/ios/Flutter/app.zip 66 | **/ios/Flutter/flutter_assets/ 67 | **/ios/Flutter/flutter_export_environment.sh 68 | **/ios/ServiceDefinitions.json 69 | **/ios/Runner/GeneratedPluginRegistrant.* 70 | 71 | # Exceptions to above rules. 72 | !**/ios/**/default.mode1v3 73 | !**/ios/**/default.mode2v3 74 | !**/ios/**/default.pbxuser 75 | !**/ios/**/default.perspectivev3 76 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages 77 | -------------------------------------------------------------------------------- /.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: bbfbf1770cca2da7c82e887e4e4af910034800b6 8 | channel: stable 9 | 10 | project_type: package 11 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 0.5.0 2 | ### Changed 3 | * Flutter constraints 4 | 5 | ### Fixed 6 | * Fixes [Flutter 3.32 breaking changes](https://github.com/letsar/value_layout_builder/issues/6) 7 | 8 | ## 0.4.0 9 | ### Changed 10 | * Flutter & Dart SDK constraints 11 | * Removed usage of hashValues (https://github.com/letsar/value_layout_builder/pull/5) 12 | 13 | ## 0.3.1 14 | ### Changed 15 | * Small formatting issues. 16 | 17 | ## 0.3.0 18 | ### Changed 19 | * Add support for null-safety. 20 | * Increase the minimum version of Flutter. 21 | * Increase the minimum version of dart sdk. 22 | 23 | ## 0.2.0 24 | ### Changed 25 | * The minimum version of Flutter. 26 | 27 | ## 0.1.0 28 | * Initial Open Source release. -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Romain Rastel 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # value_layout_builder 2 | 3 | [![Pub](https://img.shields.io/pub/v/value_layout_builder.svg)][pub] 4 | 5 | A `LayoutBuilder` with an extra value. It's useful when you want to build a widget with a value computed during layout. 6 | 7 | ## Features 8 | * ValueLayoutBuilder - The RenderBox version. 9 | * SliverValueLayoutBuilder - The RenderSliver version. 10 | 11 | ## Getting started 12 | 13 | In the `pubspec.yaml` of your flutter project, add the following dependency: 14 | 15 | ```yaml 16 | dependencies: 17 | ... 18 | value_layout_builder: 19 | ``` 20 | 21 | In your library add the following import: 22 | 23 | ```dart 24 | import 'package:value_layout_builder/value_layout_builder.dart'; 25 | ``` 26 | 27 | For help getting started with Flutter, view the online [documentation](https://flutter.io/). 28 | 29 | ## Usage 30 | 31 | `ValueLayoutBuilder` and `SliverValueLayoutBuilder` will pair with a custom `RenderObject` which accepts a one of them as a child. 32 | 33 | For example it is used in [flutter_sticky_header][flutter_sticky_header] in order to know how much the header is hidden. 34 | 35 | 36 | The typical usage is to expose a builder in the parameter of your widget's constructor which takes a `BuildContext` and the value you want to get from layout, and to pass it from your custom `RenderObject`. 37 | 38 | The following code is a dumb example to show you how to use it: 39 | ```dart 40 | class _Tester extends SingleChildRenderObjectWidget { 41 | const _Tester({ 42 | Key? key, 43 | required this.value, 44 | required Widget child, 45 | }) : super(key: key, child: child); 46 | 47 | final T value; 48 | 49 | @override 50 | _RenderTester createRenderObject(BuildContext context) { 51 | return _RenderTester(value: value); 52 | } 53 | 54 | @override 55 | void updateRenderObject( 56 | BuildContext context, 57 | _RenderTester renderObject, 58 | ) { 59 | renderObject.value = value; 60 | } 61 | } 62 | 63 | class _RenderTester extends RenderBox 64 | with RenderObjectWithChildMixin { 65 | _RenderTester({ 66 | required T value, 67 | }) : _value = value; 68 | 69 | T get value => _value; 70 | T _value; 71 | set value(T value) { 72 | if (_value != value) { 73 | _value = value; 74 | markNeedsLayout(); 75 | } 76 | } 77 | 78 | @override 79 | void performLayout() { 80 | // We create a specific constraints with the value we want to pass to the builder. 81 | BoxValueConstraints constraints = BoxValueConstraints( 82 | constraints: this.constraints, 83 | value: value, 84 | ); 85 | child.layout(constraints); 86 | size = constraints.biggest; 87 | } 88 | 89 | @override 90 | void paint(PaintingContext context, Offset offset) { 91 | context.paintChild(child, offset); 92 | } 93 | } 94 | ``` 95 | 96 | We can then use `_Tester ` like this: 97 | ```dart 98 | _Tester( 99 | value: 'test', 100 | child: ValueLayoutBuilder( 101 | builder: (context, constraints) { 102 | // The constraints holds the String value. 103 | final String value = constraints.value; 104 | return Text(value); 105 | }, 106 | ), 107 | ) 108 | ``` 109 | 110 | ## Sponsoring 111 | 112 | I'm working on my packages on my free-time, but I don't have as much time as I would. If this package or any other package I created is helping you, please consider to sponsor me. By doing so, I will prioritize your issues or your pull-requests before the others. 113 | 114 | ## Changelog 115 | 116 | Please see the [Changelog][changelog] page to know what's recently changed. 117 | 118 | ## Contributions 119 | 120 | Feel free to contribute to this project. 121 | 122 | If you find a bug or want a feature, but don't know how to fix/implement it, please fill an [issue][issue]. 123 | If you fixed a bug or implemented a feature, please send a [pull request][pr]. 124 | 125 | 126 | [pub]: https://pub.dartlang.org/packages/value_layout_builder 127 | [changelog]: https://github.com/letsar/value_layout_builder/blob/master/CHANGELOG.md 128 | [issue]: https://github.com/letsar/value_layout_builder/issues 129 | [pr]: https://github.com/letsar/value_layout_builder/pulls 130 | [flutter_sticky_header]: https://github.com/letsar/flutter_sticky_header/ 131 | 132 | -------------------------------------------------------------------------------- /example/.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | 12 | # IntelliJ related 13 | *.iml 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # The .vscode folder contains launch configuration and tasks you configure in 19 | # VS Code which you may wish to be included in version control, so this line 20 | # is commented out by default. 21 | #.vscode/ 22 | 23 | # Flutter/Dart/Pub related 24 | **/doc/api/ 25 | **/ios/Flutter/.last_build_id 26 | .dart_tool/ 27 | .flutter-plugins 28 | .flutter-plugins-dependencies 29 | .packages 30 | .pub-cache/ 31 | .pub/ 32 | /build/ 33 | 34 | # Web related 35 | lib/generated_plugin_registrant.dart 36 | 37 | # Symbolication related 38 | app.*.symbols 39 | 40 | # Obfuscation related 41 | app.*.map.json 42 | 43 | # Exceptions to above rules. 44 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages 45 | -------------------------------------------------------------------------------- /example/.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: "2663184aa79047d0a33a14a3b607954f8fdd8730" 8 | channel: "stable" 9 | 10 | project_type: app 11 | 12 | # Tracks metadata for the flutter migrate command 13 | migration: 14 | platforms: 15 | - platform: root 16 | create_revision: 2663184aa79047d0a33a14a3b607954f8fdd8730 17 | base_revision: 2663184aa79047d0a33a14a3b607954f8fdd8730 18 | - platform: android 19 | create_revision: 2663184aa79047d0a33a14a3b607954f8fdd8730 20 | base_revision: 2663184aa79047d0a33a14a3b607954f8fdd8730 21 | - platform: ios 22 | create_revision: 2663184aa79047d0a33a14a3b607954f8fdd8730 23 | base_revision: 2663184aa79047d0a33a14a3b607954f8fdd8730 24 | - platform: linux 25 | create_revision: 2663184aa79047d0a33a14a3b607954f8fdd8730 26 | base_revision: 2663184aa79047d0a33a14a3b607954f8fdd8730 27 | - platform: macos 28 | create_revision: 2663184aa79047d0a33a14a3b607954f8fdd8730 29 | base_revision: 2663184aa79047d0a33a14a3b607954f8fdd8730 30 | - platform: web 31 | create_revision: 2663184aa79047d0a33a14a3b607954f8fdd8730 32 | base_revision: 2663184aa79047d0a33a14a3b607954f8fdd8730 33 | - platform: windows 34 | create_revision: 2663184aa79047d0a33a14a3b607954f8fdd8730 35 | base_revision: 2663184aa79047d0a33a14a3b607954f8fdd8730 36 | 37 | # User provided section 38 | 39 | # List of Local paths (relative to this file) that should be 40 | # ignored by the migrate tool. 41 | # 42 | # Files that are not part of the templates will be ignored by default. 43 | unmanaged_files: 44 | - 'lib/main.dart' 45 | - 'ios/Runner.xcodeproj/project.pbxproj' 46 | -------------------------------------------------------------------------------- /example/README.md: -------------------------------------------------------------------------------- 1 | # example 2 | 3 | A new Flutter project. 4 | 5 | ## Getting Started 6 | 7 | This project is a starting point for a Flutter application. 8 | 9 | A few resources to get you started if this is your first Flutter project: 10 | 11 | - [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) 12 | - [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) 13 | 14 | For help getting started with Flutter, view our 15 | [online documentation](https://flutter.dev/docs), which offers tutorials, 16 | samples, guidance on mobile development, and a full API reference. 17 | -------------------------------------------------------------------------------- /example/android/.gitignore: -------------------------------------------------------------------------------- 1 | gradle-wrapper.jar 2 | /.gradle 3 | /captures/ 4 | /gradlew 5 | /gradlew.bat 6 | /local.properties 7 | GeneratedPluginRegistrant.java 8 | 9 | # Remember to never publicly share your keystore. 10 | # See https://flutter.dev/to/reference-keystore 11 | key.properties 12 | **/*.keystore 13 | **/*.jks 14 | -------------------------------------------------------------------------------- /example/android/app/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "com.android.application" 3 | id "kotlin-android" 4 | // The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins. 5 | id "dev.flutter.flutter-gradle-plugin" 6 | } 7 | 8 | android { 9 | namespace = "com.letsar.vlb.example" 10 | compileSdk = flutter.compileSdkVersion 11 | ndkVersion = flutter.ndkVersion 12 | 13 | compileOptions { 14 | sourceCompatibility = JavaVersion.VERSION_1_8 15 | targetCompatibility = JavaVersion.VERSION_1_8 16 | } 17 | 18 | kotlinOptions { 19 | jvmTarget = JavaVersion.VERSION_1_8 20 | } 21 | 22 | defaultConfig { 23 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 24 | applicationId = "com.letsar.vlb.example" 25 | // You can update the following values to match your application needs. 26 | // For more information, see: https://flutter.dev/to/review-gradle-config. 27 | minSdk = flutter.minSdkVersion 28 | targetSdk = flutter.targetSdkVersion 29 | versionCode = flutter.versionCode 30 | versionName = flutter.versionName 31 | } 32 | 33 | buildTypes { 34 | release { 35 | // TODO: Add your own signing config for the release build. 36 | // Signing with the debug keys for now, so `flutter run --release` works. 37 | signingConfig = signingConfigs.debug 38 | } 39 | } 40 | } 41 | 42 | flutter { 43 | source = "../.." 44 | } 45 | -------------------------------------------------------------------------------- /example/android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 15 | 19 | 23 | 24 | 25 | 26 | 27 | 28 | 30 | 33 | 34 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /example/android/app/src/main/kotlin/com/letsar/vlb/example/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.letsar.vlb.example 2 | 3 | import io.flutter.embedding.android.FlutterActivity 4 | 5 | class MainActivity: FlutterActivity() 6 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/drawable-v21/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/letsar/value_layout_builder/61237e2043d0c4a5ae6f493e77b566614a2f659f/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/letsar/value_layout_builder/61237e2043d0c4a5ae6f493e77b566614a2f659f/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/letsar/value_layout_builder/61237e2043d0c4a5ae6f493e77b566614a2f659f/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/letsar/value_layout_builder/61237e2043d0c4a5ae6f493e77b566614a2f659f/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/letsar/value_layout_builder/61237e2043d0c4a5ae6f493e77b566614a2f659f/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/values-night/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /example/android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/android/build.gradle: -------------------------------------------------------------------------------- 1 | allprojects { 2 | repositories { 3 | google() 4 | mavenCentral() 5 | } 6 | } 7 | 8 | rootProject.buildDir = "../build" 9 | subprojects { 10 | project.buildDir = "${rootProject.buildDir}/${project.name}" 11 | } 12 | subprojects { 13 | project.evaluationDependsOn(":app") 14 | } 15 | 16 | tasks.register("clean", Delete) { 17 | delete rootProject.buildDir 18 | } 19 | -------------------------------------------------------------------------------- /example/android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx4G -XX:MaxMetaspaceSize=2G -XX:+HeapDumpOnOutOfMemoryError 2 | android.useAndroidX=true 3 | android.enableJetifier=true 4 | -------------------------------------------------------------------------------- /example/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | zipStoreBase=GRADLE_USER_HOME 4 | zipStorePath=wrapper/dists 5 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-all.zip 6 | -------------------------------------------------------------------------------- /example/android/settings.gradle: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | def flutterSdkPath = { 3 | def properties = new Properties() 4 | file("local.properties").withInputStream { properties.load(it) } 5 | def flutterSdkPath = properties.getProperty("flutter.sdk") 6 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties" 7 | return flutterSdkPath 8 | }() 9 | 10 | includeBuild("$flutterSdkPath/packages/flutter_tools/gradle") 11 | 12 | repositories { 13 | google() 14 | mavenCentral() 15 | gradlePluginPortal() 16 | } 17 | } 18 | 19 | plugins { 20 | id "dev.flutter.flutter-plugin-loader" version "1.0.0" 21 | id "com.android.application" version "8.1.0" apply false 22 | id "org.jetbrains.kotlin.android" version "1.8.22" apply false 23 | } 24 | 25 | include ":app" 26 | -------------------------------------------------------------------------------- /example/ios/.gitignore: -------------------------------------------------------------------------------- 1 | *.mode1v3 2 | *.mode2v3 3 | *.moved-aside 4 | *.pbxuser 5 | *.perspectivev3 6 | **/*sync/ 7 | .sconsign.dblite 8 | .tags* 9 | **/.vagrant/ 10 | **/DerivedData/ 11 | Icon? 12 | **/Pods/ 13 | **/.symlinks/ 14 | profile 15 | xcuserdata 16 | **/.generated/ 17 | Flutter/App.framework 18 | Flutter/Flutter.framework 19 | Flutter/Flutter.podspec 20 | Flutter/Generated.xcconfig 21 | Flutter/app.flx 22 | Flutter/app.zip 23 | Flutter/flutter_assets/ 24 | Flutter/flutter_export_environment.sh 25 | ServiceDefinitions.json 26 | Runner/GeneratedPluginRegistrant.* 27 | 28 | # Exceptions to above rules. 29 | !default.mode1v3 30 | !default.mode2v3 31 | !default.pbxuser 32 | !default.perspectivev3 33 | -------------------------------------------------------------------------------- /example/ios/Flutter/AppFrameworkInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | App 9 | CFBundleIdentifier 10 | io.flutter.flutter.app 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | App 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.0 23 | MinimumOSVersion 24 | 12.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /example/ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Generated.xcconfig" 2 | -------------------------------------------------------------------------------- /example/ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Generated.xcconfig" 2 | -------------------------------------------------------------------------------- /example/ios/Flutter/ephemeral/flutter_lldb_helper.py: -------------------------------------------------------------------------------- 1 | # 2 | # Generated file, do not edit. 3 | # 4 | 5 | import lldb 6 | 7 | def handle_new_rx_page(frame: lldb.SBFrame, bp_loc, extra_args, intern_dict): 8 | """Intercept NOTIFY_DEBUGGER_ABOUT_RX_PAGES and touch the pages.""" 9 | base = frame.register["x0"].GetValueAsAddress() 10 | page_len = frame.register["x1"].GetValueAsUnsigned() 11 | 12 | # Note: NOTIFY_DEBUGGER_ABOUT_RX_PAGES will check contents of the 13 | # first page to see if handled it correctly. This makes diagnosing 14 | # misconfiguration (e.g. missing breakpoint) easier. 15 | data = bytearray(page_len) 16 | data[0:8] = b'IHELPED!' 17 | 18 | error = lldb.SBError() 19 | frame.GetThread().GetProcess().WriteMemory(base, data, error) 20 | if not error.Success(): 21 | print(f'Failed to write into {base}[+{page_len}]', error) 22 | return 23 | 24 | def __lldb_init_module(debugger: lldb.SBDebugger, _): 25 | target = debugger.GetDummyTarget() 26 | # Caveat: must use BreakpointCreateByRegEx here and not 27 | # BreakpointCreateByName. For some reasons callback function does not 28 | # get carried over from dummy target for the later. 29 | bp = target.BreakpointCreateByRegex("^NOTIFY_DEBUGGER_ABOUT_RX_PAGES$") 30 | bp.SetScriptCallbackFunction('{}.handle_new_rx_page'.format(__name__)) 31 | bp.SetAutoContinue(True) 32 | print("-- LLDB integration loaded --") 33 | -------------------------------------------------------------------------------- /example/ios/Flutter/ephemeral/flutter_lldbinit: -------------------------------------------------------------------------------- 1 | # 2 | # Generated file, do not edit. 3 | # 4 | 5 | command script import --relative-to-command-file flutter_lldb_helper.py 6 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 54; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 11 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 12 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; 13 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 14 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 15 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; 16 | /* End PBXBuildFile section */ 17 | 18 | /* Begin PBXCopyFilesBuildPhase section */ 19 | 9705A1C41CF9048500538489 /* Embed Frameworks */ = { 20 | isa = PBXCopyFilesBuildPhase; 21 | buildActionMask = 2147483647; 22 | dstPath = ""; 23 | dstSubfolderSpec = 10; 24 | files = ( 25 | ); 26 | name = "Embed Frameworks"; 27 | runOnlyForDeploymentPostprocessing = 0; 28 | }; 29 | /* End PBXCopyFilesBuildPhase section */ 30 | 31 | /* Begin PBXFileReference section */ 32 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 33 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; 34 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; 35 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; 36 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 37 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; 38 | 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 39 | 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; 40 | 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; 41 | 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 42 | 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 43 | 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 44 | 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 45 | /* End PBXFileReference section */ 46 | 47 | /* Begin PBXFrameworksBuildPhase section */ 48 | 97C146EB1CF9000F007C117D /* Frameworks */ = { 49 | isa = PBXFrameworksBuildPhase; 50 | buildActionMask = 2147483647; 51 | files = ( 52 | ); 53 | runOnlyForDeploymentPostprocessing = 0; 54 | }; 55 | /* End PBXFrameworksBuildPhase section */ 56 | 57 | /* Begin PBXGroup section */ 58 | 9740EEB11CF90186004384FC /* Flutter */ = { 59 | isa = PBXGroup; 60 | children = ( 61 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, 62 | 9740EEB21CF90195004384FC /* Debug.xcconfig */, 63 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, 64 | 9740EEB31CF90195004384FC /* Generated.xcconfig */, 65 | ); 66 | name = Flutter; 67 | sourceTree = ""; 68 | }; 69 | 97C146E51CF9000F007C117D = { 70 | isa = PBXGroup; 71 | children = ( 72 | 9740EEB11CF90186004384FC /* Flutter */, 73 | 97C146F01CF9000F007C117D /* Runner */, 74 | 97C146EF1CF9000F007C117D /* Products */, 75 | ); 76 | sourceTree = ""; 77 | }; 78 | 97C146EF1CF9000F007C117D /* Products */ = { 79 | isa = PBXGroup; 80 | children = ( 81 | 97C146EE1CF9000F007C117D /* Runner.app */, 82 | ); 83 | name = Products; 84 | sourceTree = ""; 85 | }; 86 | 97C146F01CF9000F007C117D /* Runner */ = { 87 | isa = PBXGroup; 88 | children = ( 89 | 97C146FA1CF9000F007C117D /* Main.storyboard */, 90 | 97C146FD1CF9000F007C117D /* Assets.xcassets */, 91 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, 92 | 97C147021CF9000F007C117D /* Info.plist */, 93 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, 94 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, 95 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, 96 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, 97 | ); 98 | path = Runner; 99 | sourceTree = ""; 100 | }; 101 | /* End PBXGroup section */ 102 | 103 | /* Begin PBXNativeTarget section */ 104 | 97C146ED1CF9000F007C117D /* Runner */ = { 105 | isa = PBXNativeTarget; 106 | buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; 107 | buildPhases = ( 108 | 9740EEB61CF901F6004384FC /* Run Script */, 109 | 97C146EA1CF9000F007C117D /* Sources */, 110 | 97C146EB1CF9000F007C117D /* Frameworks */, 111 | 97C146EC1CF9000F007C117D /* Resources */, 112 | 9705A1C41CF9048500538489 /* Embed Frameworks */, 113 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */, 114 | ); 115 | buildRules = ( 116 | ); 117 | dependencies = ( 118 | ); 119 | name = Runner; 120 | productName = Runner; 121 | productReference = 97C146EE1CF9000F007C117D /* Runner.app */; 122 | productType = "com.apple.product-type.application"; 123 | }; 124 | /* End PBXNativeTarget section */ 125 | 126 | /* Begin PBXProject section */ 127 | 97C146E61CF9000F007C117D /* Project object */ = { 128 | isa = PBXProject; 129 | attributes = { 130 | LastUpgradeCheck = 1510; 131 | ORGANIZATIONNAME = ""; 132 | TargetAttributes = { 133 | 97C146ED1CF9000F007C117D = { 134 | CreatedOnToolsVersion = 7.3.1; 135 | LastSwiftMigration = 1100; 136 | }; 137 | }; 138 | }; 139 | buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; 140 | compatibilityVersion = "Xcode 9.3"; 141 | developmentRegion = en; 142 | hasScannedForEncodings = 0; 143 | knownRegions = ( 144 | en, 145 | Base, 146 | ); 147 | mainGroup = 97C146E51CF9000F007C117D; 148 | productRefGroup = 97C146EF1CF9000F007C117D /* Products */; 149 | projectDirPath = ""; 150 | projectRoot = ""; 151 | targets = ( 152 | 97C146ED1CF9000F007C117D /* Runner */, 153 | ); 154 | }; 155 | /* End PBXProject section */ 156 | 157 | /* Begin PBXResourcesBuildPhase section */ 158 | 97C146EC1CF9000F007C117D /* Resources */ = { 159 | isa = PBXResourcesBuildPhase; 160 | buildActionMask = 2147483647; 161 | files = ( 162 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, 163 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, 164 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, 165 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, 166 | ); 167 | runOnlyForDeploymentPostprocessing = 0; 168 | }; 169 | /* End PBXResourcesBuildPhase section */ 170 | 171 | /* Begin PBXShellScriptBuildPhase section */ 172 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { 173 | isa = PBXShellScriptBuildPhase; 174 | alwaysOutOfDate = 1; 175 | buildActionMask = 2147483647; 176 | files = ( 177 | ); 178 | inputPaths = ( 179 | "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}", 180 | ); 181 | name = "Thin Binary"; 182 | outputPaths = ( 183 | ); 184 | runOnlyForDeploymentPostprocessing = 0; 185 | shellPath = /bin/sh; 186 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; 187 | }; 188 | 9740EEB61CF901F6004384FC /* Run Script */ = { 189 | isa = PBXShellScriptBuildPhase; 190 | alwaysOutOfDate = 1; 191 | buildActionMask = 2147483647; 192 | files = ( 193 | ); 194 | inputPaths = ( 195 | ); 196 | name = "Run Script"; 197 | outputPaths = ( 198 | ); 199 | runOnlyForDeploymentPostprocessing = 0; 200 | shellPath = /bin/sh; 201 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; 202 | }; 203 | /* End PBXShellScriptBuildPhase section */ 204 | 205 | /* Begin PBXSourcesBuildPhase section */ 206 | 97C146EA1CF9000F007C117D /* Sources */ = { 207 | isa = PBXSourcesBuildPhase; 208 | buildActionMask = 2147483647; 209 | files = ( 210 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, 211 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, 212 | ); 213 | runOnlyForDeploymentPostprocessing = 0; 214 | }; 215 | /* End PBXSourcesBuildPhase section */ 216 | 217 | /* Begin PBXVariantGroup section */ 218 | 97C146FA1CF9000F007C117D /* Main.storyboard */ = { 219 | isa = PBXVariantGroup; 220 | children = ( 221 | 97C146FB1CF9000F007C117D /* Base */, 222 | ); 223 | name = Main.storyboard; 224 | sourceTree = ""; 225 | }; 226 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { 227 | isa = PBXVariantGroup; 228 | children = ( 229 | 97C147001CF9000F007C117D /* Base */, 230 | ); 231 | name = LaunchScreen.storyboard; 232 | sourceTree = ""; 233 | }; 234 | /* End PBXVariantGroup section */ 235 | 236 | /* Begin XCBuildConfiguration section */ 237 | 249021D3217E4FDB00AE95B9 /* Profile */ = { 238 | isa = XCBuildConfiguration; 239 | buildSettings = { 240 | ALWAYS_SEARCH_USER_PATHS = NO; 241 | CLANG_ANALYZER_NONNULL = YES; 242 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 243 | CLANG_CXX_LIBRARY = "libc++"; 244 | CLANG_ENABLE_MODULES = YES; 245 | CLANG_ENABLE_OBJC_ARC = YES; 246 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 247 | CLANG_WARN_BOOL_CONVERSION = YES; 248 | CLANG_WARN_COMMA = YES; 249 | CLANG_WARN_CONSTANT_CONVERSION = YES; 250 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 251 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 252 | CLANG_WARN_EMPTY_BODY = YES; 253 | CLANG_WARN_ENUM_CONVERSION = YES; 254 | CLANG_WARN_INFINITE_RECURSION = YES; 255 | CLANG_WARN_INT_CONVERSION = YES; 256 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 257 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 258 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 259 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 260 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 261 | CLANG_WARN_STRICT_PROTOTYPES = YES; 262 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 263 | CLANG_WARN_UNREACHABLE_CODE = YES; 264 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 265 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 266 | COPY_PHASE_STRIP = NO; 267 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 268 | ENABLE_NS_ASSERTIONS = NO; 269 | ENABLE_STRICT_OBJC_MSGSEND = YES; 270 | GCC_C_LANGUAGE_STANDARD = gnu99; 271 | GCC_NO_COMMON_BLOCKS = YES; 272 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 273 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 274 | GCC_WARN_UNDECLARED_SELECTOR = YES; 275 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 276 | GCC_WARN_UNUSED_FUNCTION = YES; 277 | GCC_WARN_UNUSED_VARIABLE = YES; 278 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 279 | MTL_ENABLE_DEBUG_INFO = NO; 280 | SDKROOT = iphoneos; 281 | SUPPORTED_PLATFORMS = iphoneos; 282 | TARGETED_DEVICE_FAMILY = "1,2"; 283 | VALIDATE_PRODUCT = YES; 284 | }; 285 | name = Profile; 286 | }; 287 | 249021D4217E4FDB00AE95B9 /* Profile */ = { 288 | isa = XCBuildConfiguration; 289 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 290 | buildSettings = { 291 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 292 | CLANG_ENABLE_MODULES = YES; 293 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 294 | ENABLE_BITCODE = NO; 295 | FRAMEWORK_SEARCH_PATHS = ( 296 | "$(inherited)", 297 | "$(PROJECT_DIR)/Flutter", 298 | ); 299 | INFOPLIST_FILE = Runner/Info.plist; 300 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 301 | LIBRARY_SEARCH_PATHS = ( 302 | "$(inherited)", 303 | "$(PROJECT_DIR)/Flutter", 304 | ); 305 | PRODUCT_BUNDLE_IDENTIFIER = com.letsar.vlb.example; 306 | PRODUCT_NAME = "$(TARGET_NAME)"; 307 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 308 | SWIFT_VERSION = 5.0; 309 | VERSIONING_SYSTEM = "apple-generic"; 310 | }; 311 | name = Profile; 312 | }; 313 | 97C147031CF9000F007C117D /* Debug */ = { 314 | isa = XCBuildConfiguration; 315 | buildSettings = { 316 | ALWAYS_SEARCH_USER_PATHS = NO; 317 | CLANG_ANALYZER_NONNULL = YES; 318 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 319 | CLANG_CXX_LIBRARY = "libc++"; 320 | CLANG_ENABLE_MODULES = YES; 321 | CLANG_ENABLE_OBJC_ARC = YES; 322 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 323 | CLANG_WARN_BOOL_CONVERSION = YES; 324 | CLANG_WARN_COMMA = YES; 325 | CLANG_WARN_CONSTANT_CONVERSION = YES; 326 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 327 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 328 | CLANG_WARN_EMPTY_BODY = YES; 329 | CLANG_WARN_ENUM_CONVERSION = YES; 330 | CLANG_WARN_INFINITE_RECURSION = YES; 331 | CLANG_WARN_INT_CONVERSION = YES; 332 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 333 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 334 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 335 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 336 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 337 | CLANG_WARN_STRICT_PROTOTYPES = YES; 338 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 339 | CLANG_WARN_UNREACHABLE_CODE = YES; 340 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 341 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 342 | COPY_PHASE_STRIP = NO; 343 | DEBUG_INFORMATION_FORMAT = dwarf; 344 | ENABLE_STRICT_OBJC_MSGSEND = YES; 345 | ENABLE_TESTABILITY = YES; 346 | GCC_C_LANGUAGE_STANDARD = gnu99; 347 | GCC_DYNAMIC_NO_PIC = NO; 348 | GCC_NO_COMMON_BLOCKS = YES; 349 | GCC_OPTIMIZATION_LEVEL = 0; 350 | GCC_PREPROCESSOR_DEFINITIONS = ( 351 | "DEBUG=1", 352 | "$(inherited)", 353 | ); 354 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 355 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 356 | GCC_WARN_UNDECLARED_SELECTOR = YES; 357 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 358 | GCC_WARN_UNUSED_FUNCTION = YES; 359 | GCC_WARN_UNUSED_VARIABLE = YES; 360 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 361 | MTL_ENABLE_DEBUG_INFO = YES; 362 | ONLY_ACTIVE_ARCH = YES; 363 | SDKROOT = iphoneos; 364 | TARGETED_DEVICE_FAMILY = "1,2"; 365 | }; 366 | name = Debug; 367 | }; 368 | 97C147041CF9000F007C117D /* Release */ = { 369 | isa = XCBuildConfiguration; 370 | buildSettings = { 371 | ALWAYS_SEARCH_USER_PATHS = NO; 372 | CLANG_ANALYZER_NONNULL = YES; 373 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 374 | CLANG_CXX_LIBRARY = "libc++"; 375 | CLANG_ENABLE_MODULES = YES; 376 | CLANG_ENABLE_OBJC_ARC = YES; 377 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 378 | CLANG_WARN_BOOL_CONVERSION = YES; 379 | CLANG_WARN_COMMA = YES; 380 | CLANG_WARN_CONSTANT_CONVERSION = YES; 381 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 382 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 383 | CLANG_WARN_EMPTY_BODY = YES; 384 | CLANG_WARN_ENUM_CONVERSION = YES; 385 | CLANG_WARN_INFINITE_RECURSION = YES; 386 | CLANG_WARN_INT_CONVERSION = YES; 387 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 388 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 389 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 390 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 391 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 392 | CLANG_WARN_STRICT_PROTOTYPES = YES; 393 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 394 | CLANG_WARN_UNREACHABLE_CODE = YES; 395 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 396 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 397 | COPY_PHASE_STRIP = NO; 398 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 399 | ENABLE_NS_ASSERTIONS = NO; 400 | ENABLE_STRICT_OBJC_MSGSEND = YES; 401 | GCC_C_LANGUAGE_STANDARD = gnu99; 402 | GCC_NO_COMMON_BLOCKS = YES; 403 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 404 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 405 | GCC_WARN_UNDECLARED_SELECTOR = YES; 406 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 407 | GCC_WARN_UNUSED_FUNCTION = YES; 408 | GCC_WARN_UNUSED_VARIABLE = YES; 409 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 410 | MTL_ENABLE_DEBUG_INFO = NO; 411 | SDKROOT = iphoneos; 412 | SUPPORTED_PLATFORMS = iphoneos; 413 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 414 | TARGETED_DEVICE_FAMILY = "1,2"; 415 | VALIDATE_PRODUCT = YES; 416 | }; 417 | name = Release; 418 | }; 419 | 97C147061CF9000F007C117D /* Debug */ = { 420 | isa = XCBuildConfiguration; 421 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; 422 | buildSettings = { 423 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 424 | CLANG_ENABLE_MODULES = YES; 425 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 426 | ENABLE_BITCODE = NO; 427 | FRAMEWORK_SEARCH_PATHS = ( 428 | "$(inherited)", 429 | "$(PROJECT_DIR)/Flutter", 430 | ); 431 | INFOPLIST_FILE = Runner/Info.plist; 432 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 433 | LIBRARY_SEARCH_PATHS = ( 434 | "$(inherited)", 435 | "$(PROJECT_DIR)/Flutter", 436 | ); 437 | PRODUCT_BUNDLE_IDENTIFIER = com.letsar.vlb.example; 438 | PRODUCT_NAME = "$(TARGET_NAME)"; 439 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 440 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 441 | SWIFT_VERSION = 5.0; 442 | VERSIONING_SYSTEM = "apple-generic"; 443 | }; 444 | name = Debug; 445 | }; 446 | 97C147071CF9000F007C117D /* Release */ = { 447 | isa = XCBuildConfiguration; 448 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 449 | buildSettings = { 450 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 451 | CLANG_ENABLE_MODULES = YES; 452 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 453 | ENABLE_BITCODE = NO; 454 | FRAMEWORK_SEARCH_PATHS = ( 455 | "$(inherited)", 456 | "$(PROJECT_DIR)/Flutter", 457 | ); 458 | INFOPLIST_FILE = Runner/Info.plist; 459 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 460 | LIBRARY_SEARCH_PATHS = ( 461 | "$(inherited)", 462 | "$(PROJECT_DIR)/Flutter", 463 | ); 464 | PRODUCT_BUNDLE_IDENTIFIER = com.letsar.vlb.example; 465 | PRODUCT_NAME = "$(TARGET_NAME)"; 466 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 467 | SWIFT_VERSION = 5.0; 468 | VERSIONING_SYSTEM = "apple-generic"; 469 | }; 470 | name = Release; 471 | }; 472 | /* End XCBuildConfiguration section */ 473 | 474 | /* Begin XCConfigurationList section */ 475 | 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { 476 | isa = XCConfigurationList; 477 | buildConfigurations = ( 478 | 97C147031CF9000F007C117D /* Debug */, 479 | 97C147041CF9000F007C117D /* Release */, 480 | 249021D3217E4FDB00AE95B9 /* Profile */, 481 | ); 482 | defaultConfigurationIsVisible = 0; 483 | defaultConfigurationName = Release; 484 | }; 485 | 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { 486 | isa = XCConfigurationList; 487 | buildConfigurations = ( 488 | 97C147061CF9000F007C117D /* Debug */, 489 | 97C147071CF9000F007C117D /* Release */, 490 | 249021D4217E4FDB00AE95B9 /* Profile */, 491 | ); 492 | defaultConfigurationIsVisible = 0; 493 | defaultConfigurationName = Release; 494 | }; 495 | /* End XCConfigurationList section */ 496 | }; 497 | rootObject = 97C146E61CF9000F007C117D /* Project object */; 498 | } 499 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 31 | 32 | 33 | 34 | 40 | 41 | 42 | 43 | 44 | 45 | 57 | 59 | 65 | 66 | 67 | 68 | 69 | 70 | 76 | 78 | 84 | 85 | 86 | 87 | 89 | 90 | 93 | 94 | 95 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import Flutter 3 | 4 | @main 5 | @objc class AppDelegate: FlutterAppDelegate { 6 | override func application( 7 | _ application: UIApplication, 8 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? 9 | ) -> Bool { 10 | GeneratedPluginRegistrant.register(with: self) 11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "Icon-App-20x20@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "Icon-App-20x20@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "Icon-App-29x29@1x.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "Icon-App-29x29@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "29x29", 29 | "idiom" : "iphone", 30 | "filename" : "Icon-App-29x29@3x.png", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "Icon-App-40x40@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "40x40", 41 | "idiom" : "iphone", 42 | "filename" : "Icon-App-40x40@3x.png", 43 | "scale" : "3x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "Icon-App-60x60@2x.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "60x60", 53 | "idiom" : "iphone", 54 | "filename" : "Icon-App-60x60@3x.png", 55 | "scale" : "3x" 56 | }, 57 | { 58 | "size" : "20x20", 59 | "idiom" : "ipad", 60 | "filename" : "Icon-App-20x20@1x.png", 61 | "scale" : "1x" 62 | }, 63 | { 64 | "size" : "20x20", 65 | "idiom" : "ipad", 66 | "filename" : "Icon-App-20x20@2x.png", 67 | "scale" : "2x" 68 | }, 69 | { 70 | "size" : "29x29", 71 | "idiom" : "ipad", 72 | "filename" : "Icon-App-29x29@1x.png", 73 | "scale" : "1x" 74 | }, 75 | { 76 | "size" : "29x29", 77 | "idiom" : "ipad", 78 | "filename" : "Icon-App-29x29@2x.png", 79 | "scale" : "2x" 80 | }, 81 | { 82 | "size" : "40x40", 83 | "idiom" : "ipad", 84 | "filename" : "Icon-App-40x40@1x.png", 85 | "scale" : "1x" 86 | }, 87 | { 88 | "size" : "40x40", 89 | "idiom" : "ipad", 90 | "filename" : "Icon-App-40x40@2x.png", 91 | "scale" : "2x" 92 | }, 93 | { 94 | "size" : "76x76", 95 | "idiom" : "ipad", 96 | "filename" : "Icon-App-76x76@1x.png", 97 | "scale" : "1x" 98 | }, 99 | { 100 | "size" : "76x76", 101 | "idiom" : "ipad", 102 | "filename" : "Icon-App-76x76@2x.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "83.5x83.5", 107 | "idiom" : "ipad", 108 | "filename" : "Icon-App-83.5x83.5@2x.png", 109 | "scale" : "2x" 110 | }, 111 | { 112 | "size" : "1024x1024", 113 | "idiom" : "ios-marketing", 114 | "filename" : "Icon-App-1024x1024@1x.png", 115 | "scale" : "1x" 116 | } 117 | ], 118 | "info" : { 119 | "version" : 1, 120 | "author" : "xcode" 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/letsar/value_layout_builder/61237e2043d0c4a5ae6f493e77b566614a2f659f/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/letsar/value_layout_builder/61237e2043d0c4a5ae6f493e77b566614a2f659f/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/letsar/value_layout_builder/61237e2043d0c4a5ae6f493e77b566614a2f659f/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/letsar/value_layout_builder/61237e2043d0c4a5ae6f493e77b566614a2f659f/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/letsar/value_layout_builder/61237e2043d0c4a5ae6f493e77b566614a2f659f/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/letsar/value_layout_builder/61237e2043d0c4a5ae6f493e77b566614a2f659f/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/letsar/value_layout_builder/61237e2043d0c4a5ae6f493e77b566614a2f659f/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/letsar/value_layout_builder/61237e2043d0c4a5ae6f493e77b566614a2f659f/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/letsar/value_layout_builder/61237e2043d0c4a5ae6f493e77b566614a2f659f/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/letsar/value_layout_builder/61237e2043d0c4a5ae6f493e77b566614a2f659f/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/letsar/value_layout_builder/61237e2043d0c4a5ae6f493e77b566614a2f659f/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/letsar/value_layout_builder/61237e2043d0c4a5ae6f493e77b566614a2f659f/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/letsar/value_layout_builder/61237e2043d0c4a5ae6f493e77b566614a2f659f/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/letsar/value_layout_builder/61237e2043d0c4a5ae6f493e77b566614a2f659f/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/letsar/value_layout_builder/61237e2043d0c4a5ae6f493e77b566614a2f659f/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "LaunchImage.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "LaunchImage@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "LaunchImage@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/letsar/value_layout_builder/61237e2043d0c4a5ae6f493e77b566614a2f659f/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/letsar/value_layout_builder/61237e2043d0c4a5ae6f493e77b566614a2f659f/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/letsar/value_layout_builder/61237e2043d0c4a5ae6f493e77b566614a2f659f/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md: -------------------------------------------------------------------------------- 1 | # Launch Screen Assets 2 | 3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory. 4 | 5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. -------------------------------------------------------------------------------- /example/ios/Runner/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /example/ios/Runner/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /example/ios/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | example 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | $(FLUTTER_BUILD_NAME) 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(FLUTTER_BUILD_NUMBER) 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UISupportedInterfaceOrientations 30 | 31 | UIInterfaceOrientationPortrait 32 | UIInterfaceOrientationLandscapeLeft 33 | UIInterfaceOrientationLandscapeRight 34 | 35 | UISupportedInterfaceOrientations~ipad 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationPortraitUpsideDown 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | UIViewControllerBasedStatusBarAppearance 43 | 44 | CADisableMinimumFrameDurationOnPhone 45 | 46 | UIApplicationSupportsIndirectInputEvents 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /example/ios/Runner/Runner-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #import "GeneratedPluginRegistrant.h" 2 | -------------------------------------------------------------------------------- /example/ios/RunnerTests/RunnerTests.swift: -------------------------------------------------------------------------------- 1 | import Flutter 2 | import UIKit 3 | import XCTest 4 | 5 | class RunnerTests: XCTestCase { 6 | 7 | func testExample() { 8 | // If you add code to the Runner application, consider adding tests here. 9 | // See https://developer.apple.com/documentation/xctest for more information about using XCTest. 10 | } 11 | 12 | } 13 | -------------------------------------------------------------------------------- /example/lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter/rendering.dart'; 3 | import 'package:value_layout_builder/value_layout_builder.dart'; 4 | 5 | void main() { 6 | runApp(MyApp()); 7 | } 8 | 9 | class MyApp extends StatelessWidget { 10 | @override 11 | Widget build(BuildContext context) { 12 | return MaterialApp( 13 | title: 'Flutter Demo', 14 | home: Scaffold( 15 | body: SafeArea( 16 | child: _Tester( 17 | value: 'test', 18 | child: ValueLayoutBuilder( 19 | builder: (context, constraints) { 20 | // The constraints holds the String value. 21 | final String value = constraints.value; 22 | return Text(value); 23 | }, 24 | ), 25 | ), 26 | ), 27 | ), 28 | ); 29 | } 30 | } 31 | 32 | class _Tester extends SingleChildRenderObjectWidget { 33 | const _Tester({ 34 | Key? key, 35 | required this.value, 36 | required Widget child, 37 | }) : super(key: key, child: child); 38 | 39 | final T value; 40 | 41 | @override 42 | _RenderTester createRenderObject(BuildContext context) { 43 | return _RenderTester(value: value); 44 | } 45 | 46 | @override 47 | void updateRenderObject( 48 | BuildContext context, 49 | _RenderTester renderObject, 50 | ) { 51 | renderObject.value = value; 52 | } 53 | } 54 | 55 | class _RenderTester extends RenderBox 56 | with RenderObjectWithChildMixin { 57 | _RenderTester({ 58 | required T value, 59 | }) : _value = value; 60 | 61 | T get value => _value; 62 | T _value; 63 | set value(T value) { 64 | if (_value != value) { 65 | _value = value; 66 | markNeedsLayout(); 67 | } 68 | } 69 | 70 | @override 71 | void performLayout() { 72 | // We create a specific constraints with the value we want to pass to the builder. 73 | BoxValueConstraints constraints = BoxValueConstraints( 74 | constraints: this.constraints, 75 | value: value, 76 | ); 77 | child!.layout(constraints); 78 | size = constraints.biggest; 79 | } 80 | 81 | @override 82 | void paint(PaintingContext context, Offset offset) { 83 | context.paintChild(child!, offset); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /example/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: example 2 | description: A new Flutter project. 3 | 4 | # The following line prevents the package from being accidentally published to 5 | # pub.dev using `pub publish`. This is preferred for private packages. 6 | publish_to: 'none' # Remove this line if you wish to publish to pub.dev 7 | 8 | # The following defines the version and build number for your application. 9 | # A version number is three numbers separated by dots, like 1.2.43 10 | # followed by an optional build number separated by a +. 11 | # Both the version and the builder number may be overridden in flutter 12 | # build by specifying --build-name and --build-number, respectively. 13 | # In Android, build-name is used as versionName while build-number used as versionCode. 14 | # Read more about Android versioning at https://developer.android.com/studio/publish/versioning 15 | # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. 16 | # Read more about iOS versioning at 17 | # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html 18 | version: 1.0.0+1 19 | 20 | environment: 21 | sdk: '>=2.12.0 <4.0.0' 22 | 23 | dependencies: 24 | flutter: 25 | sdk: flutter 26 | value_layout_builder: 27 | path: ../ 28 | 29 | 30 | # The following adds the Cupertino Icons font to your application. 31 | # Use with the CupertinoIcons class for iOS style icons. 32 | cupertino_icons: ^1.0.2 33 | 34 | dev_dependencies: 35 | flutter_test: 36 | sdk: flutter 37 | 38 | # For information on the generic Dart part of this file, see the 39 | # following page: https://dart.dev/tools/pub/pubspec 40 | 41 | # The following section is specific to Flutter. 42 | flutter: 43 | 44 | # The following line ensures that the Material Icons font is 45 | # included with your application, so that you can use the icons in 46 | # the material Icons class. 47 | uses-material-design: true 48 | 49 | # To add assets to your application, add an assets section, like this: 50 | # assets: 51 | # - images/a_dot_burr.jpeg 52 | # - images/a_dot_ham.jpeg 53 | 54 | # An image asset can refer to one or more resolution-specific "variants", see 55 | # https://flutter.dev/assets-and-images/#resolution-aware. 56 | 57 | # For details regarding adding assets from package dependencies, see 58 | # https://flutter.dev/assets-and-images/#from-packages 59 | 60 | # To add custom fonts to your application, add a fonts section here, 61 | # in this "flutter" section. Each entry in this list should have a 62 | # "family" key with the font family name, and a "fonts" key with a 63 | # list giving the asset and other descriptors for the font. For 64 | # example: 65 | # fonts: 66 | # - family: Schyler 67 | # fonts: 68 | # - asset: fonts/Schyler-Regular.ttf 69 | # - asset: fonts/Schyler-Italic.ttf 70 | # style: italic 71 | # - family: Trajan Pro 72 | # fonts: 73 | # - asset: fonts/TrajanPro.ttf 74 | # - asset: fonts/TrajanPro_Bold.ttf 75 | # weight: 700 76 | # 77 | # For details regarding fonts from package dependencies, 78 | # see https://flutter.dev/custom-fonts/#from-packages 79 | -------------------------------------------------------------------------------- /example/test/widget_test.dart: -------------------------------------------------------------------------------- 1 | // This is a basic Flutter widget test. 2 | // 3 | // To perform an interaction with a widget in your test, use the WidgetTester 4 | // utility that Flutter provides. For example, you can send tap and scroll 5 | // gestures. You can also use WidgetTester to find child widgets in the widget 6 | // tree, read text, and verify that the values of widget properties are correct. 7 | 8 | import 'package:example/main.dart'; 9 | import 'package:flutter_test/flutter_test.dart'; 10 | 11 | void main() { 12 | testWidgets('Counter increments smoke test', (WidgetTester tester) async { 13 | // Build our app and trigger a frame. 14 | await tester.pumpWidget(MyApp()); 15 | 16 | expect(find.text('test'), findsOneWidget); 17 | }); 18 | } 19 | -------------------------------------------------------------------------------- /lib/src/sliver_value_layout_builder.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/rendering.dart'; 2 | import 'package:flutter/widgets.dart'; 3 | 4 | /// The signature of the [SliverValueLayoutBuilder] builder function. 5 | typedef SliverValueLayoutWidgetBuilder = Widget Function( 6 | BuildContext context, 7 | SliverValueConstraints constraints, 8 | ); 9 | 10 | class SliverValueConstraints extends SliverConstraints { 11 | SliverValueConstraints({ 12 | required this.value, 13 | required SliverConstraints constraints, 14 | }) : super( 15 | axisDirection: constraints.axisDirection, 16 | growthDirection: constraints.growthDirection, 17 | userScrollDirection: constraints.userScrollDirection, 18 | scrollOffset: constraints.scrollOffset, 19 | precedingScrollExtent: constraints.precedingScrollExtent, 20 | overlap: constraints.overlap, 21 | remainingPaintExtent: constraints.remainingPaintExtent, 22 | crossAxisExtent: constraints.crossAxisExtent, 23 | crossAxisDirection: constraints.crossAxisDirection, 24 | viewportMainAxisExtent: constraints.viewportMainAxisExtent, 25 | remainingCacheExtent: constraints.remainingCacheExtent, 26 | cacheOrigin: constraints.cacheOrigin, 27 | ); 28 | 29 | final T value; 30 | 31 | @override 32 | bool operator ==(Object other) { 33 | if (identical(this, other)) return true; 34 | if (other is! SliverValueConstraints) return false; 35 | assert(other.debugAssertIsValid()); 36 | return other.value == value && 37 | other.axisDirection == axisDirection && 38 | other.growthDirection == growthDirection && 39 | other.scrollOffset == scrollOffset && 40 | other.overlap == overlap && 41 | other.remainingPaintExtent == remainingPaintExtent && 42 | other.crossAxisExtent == crossAxisExtent && 43 | other.crossAxisDirection == crossAxisDirection && 44 | other.viewportMainAxisExtent == viewportMainAxisExtent && 45 | other.remainingCacheExtent == remainingCacheExtent && 46 | other.cacheOrigin == cacheOrigin; 47 | } 48 | 49 | @override 50 | int get hashCode { 51 | return Object.hash( 52 | axisDirection, 53 | growthDirection, 54 | scrollOffset, 55 | overlap, 56 | remainingPaintExtent, 57 | crossAxisExtent, 58 | crossAxisDirection, 59 | viewportMainAxisExtent, 60 | remainingCacheExtent, 61 | cacheOrigin, 62 | value, 63 | ); 64 | } 65 | } 66 | 67 | /// Builds a sliver widget tree that can depend on its own 68 | /// [SliverValueConstraints]. 69 | /// 70 | /// Similar to the [ValueLayoutBuilder] widget except its builder should return 71 | /// a sliver widget, and [SliverValueLayoutBuilder] is itself a sliver. 72 | /// The framework calls the [builder] function at layout time and provides the 73 | /// current [SliverValueConstraints]. 74 | /// The [SliverValueLayoutBuilder]'s final [SliverGeometry] will match the 75 | /// [SliverGeometry] of its child. 76 | /// 77 | /// See also: 78 | /// 79 | /// * [ValueLayoutBuilder], the non-sliver version of this widget. 80 | class SliverValueLayoutBuilder 81 | extends ConstrainedLayoutBuilder> { 82 | /// Creates a sliver widget that defers its building until layout. 83 | const SliverValueLayoutBuilder({ 84 | Key? key, 85 | required SliverValueLayoutWidgetBuilder builder, 86 | }) : super(key: key, builder: builder); 87 | 88 | /// Called at layout time to construct the widget tree. 89 | /// 90 | /// The builder must return a non-null sliver widget. 91 | @override 92 | SliverValueLayoutWidgetBuilder get builder => super.builder; 93 | 94 | @override 95 | _RenderSliverValueLayoutBuilder createRenderObject(BuildContext context) => 96 | _RenderSliverValueLayoutBuilder(); 97 | } 98 | 99 | class _RenderSliverValueLayoutBuilder extends RenderSliver 100 | with 101 | RenderObjectWithChildMixin, 102 | RenderObjectWithLayoutCallbackMixin, 103 | RenderConstrainedLayoutBuilder, 104 | RenderSliver> { 105 | @override 106 | double childMainAxisPosition(RenderObject child) { 107 | assert(child == this.child); 108 | return 0; 109 | } 110 | 111 | @override 112 | void performLayout() { 113 | runLayoutCallback(); 114 | child?.layout(constraints, parentUsesSize: true); 115 | geometry = child?.geometry ?? SliverGeometry.zero; 116 | } 117 | 118 | @override 119 | void applyPaintTransform(RenderObject child, Matrix4 transform) { 120 | assert(child == this.child); 121 | // child's offset is always (0, 0), transform.translate(0, 0) does not mutate the transform. 122 | } 123 | 124 | @override 125 | void paint(PaintingContext context, Offset offset) { 126 | // This renderObject does not introduce additional offset to child's position. 127 | if (child?.geometry?.visible == true) context.paintChild(child!, offset); 128 | } 129 | 130 | @override 131 | bool hitTestChildren( 132 | SliverHitTestResult result, { 133 | required double mainAxisPosition, 134 | required double crossAxisPosition, 135 | }) { 136 | return child != null && 137 | child!.geometry!.hitTestExtent > 0 && 138 | child!.hitTest( 139 | result, 140 | mainAxisPosition: mainAxisPosition, 141 | crossAxisPosition: crossAxisPosition, 142 | ); 143 | } 144 | } 145 | -------------------------------------------------------------------------------- /lib/src/value_layout_builder.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/rendering.dart'; 2 | import 'package:flutter/widgets.dart'; 3 | 4 | /// The signature of the [ValueLayoutBuilder] builder function. 5 | typedef ValueLayoutWidgetBuilder = Widget Function( 6 | BuildContext context, 7 | BoxValueConstraints constraints, 8 | ); 9 | 10 | class BoxValueConstraints extends BoxConstraints { 11 | BoxValueConstraints({ 12 | required this.value, 13 | required BoxConstraints constraints, 14 | }) : super( 15 | minWidth: constraints.minWidth, 16 | maxWidth: constraints.maxWidth, 17 | minHeight: constraints.minHeight, 18 | maxHeight: constraints.maxHeight, 19 | ); 20 | 21 | final T value; 22 | 23 | @override 24 | bool operator ==(Object other) { 25 | assert(debugAssertIsValid()); 26 | if (identical(this, other)) return true; 27 | if (other is! BoxValueConstraints) return false; 28 | final BoxValueConstraints typedOther = other; 29 | assert(typedOther.debugAssertIsValid()); 30 | return value == typedOther.value && 31 | minWidth == typedOther.minWidth && 32 | maxWidth == typedOther.maxWidth && 33 | minHeight == typedOther.minHeight && 34 | maxHeight == typedOther.maxHeight; 35 | } 36 | 37 | @override 38 | int get hashCode { 39 | assert(debugAssertIsValid()); 40 | return Object.hash(minWidth, maxWidth, minHeight, maxHeight, value); 41 | } 42 | } 43 | 44 | /// Builds a widget tree that can depend on the parent widget's size and a extra 45 | /// value. 46 | /// 47 | /// Similar to the [LayoutBuilder] widget except that the constraints contains 48 | /// an extra value. 49 | /// 50 | /// See also: 51 | /// 52 | /// * [LayoutBuilder]. 53 | /// * [SliverValueLayoutBuilder], the sliver version of this widget. 54 | class ValueLayoutBuilder 55 | extends ConstrainedLayoutBuilder> { 56 | /// Creates a widget that defers its building until layout. 57 | const ValueLayoutBuilder({ 58 | Key? key, 59 | required ValueLayoutWidgetBuilder builder, 60 | }) : super(key: key, builder: builder); 61 | 62 | @override 63 | ValueLayoutWidgetBuilder get builder => super.builder; 64 | 65 | @override 66 | _RenderValueLayoutBuilder createRenderObject(BuildContext context) => 67 | _RenderValueLayoutBuilder(); 68 | } 69 | 70 | class _RenderValueLayoutBuilder extends RenderBox 71 | with 72 | RenderObjectWithChildMixin, 73 | RenderObjectWithLayoutCallbackMixin, 74 | RenderAbstractLayoutBuilderMixin, RenderBox> { 75 | @override 76 | double computeMinIntrinsicWidth(double height) { 77 | assert(_debugThrowIfNotCheckingIntrinsics()); 78 | return 0.0; 79 | } 80 | 81 | @override 82 | double computeMaxIntrinsicWidth(double height) { 83 | assert(_debugThrowIfNotCheckingIntrinsics()); 84 | return 0.0; 85 | } 86 | 87 | @override 88 | double computeMinIntrinsicHeight(double width) { 89 | assert(_debugThrowIfNotCheckingIntrinsics()); 90 | return 0.0; 91 | } 92 | 93 | @override 94 | double computeMaxIntrinsicHeight(double width) { 95 | assert(_debugThrowIfNotCheckingIntrinsics()); 96 | return 0.0; 97 | } 98 | 99 | @override 100 | Size computeDryLayout(BoxConstraints constraints) { 101 | assert( 102 | debugCannotComputeDryLayout( 103 | reason: 104 | 'Calculating the dry layout would require running the layout callback ' 105 | 'speculatively, which might mutate the live render object tree.', 106 | ), 107 | ); 108 | return Size.zero; 109 | } 110 | 111 | @override 112 | double? computeDryBaseline( 113 | BoxConstraints constraints, 114 | TextBaseline baseline, 115 | ) { 116 | assert( 117 | debugCannotComputeDryLayout( 118 | reason: 119 | 'Calculating the dry baseline would require running the layout callback ' 120 | 'speculatively, which might mutate the live render object tree.', 121 | ), 122 | ); 123 | return null; 124 | } 125 | 126 | @override 127 | void performLayout() { 128 | final BoxConstraints constraints = this.constraints; 129 | runLayoutCallback(); 130 | if (child != null) { 131 | child!.layout(constraints, parentUsesSize: true); 132 | size = constraints.constrain(child!.size); 133 | } else { 134 | size = constraints.biggest; 135 | } 136 | } 137 | 138 | @override 139 | double? computeDistanceToActualBaseline(TextBaseline baseline) { 140 | return child?.getDistanceToActualBaseline(baseline) ?? 141 | super.computeDistanceToActualBaseline(baseline); 142 | } 143 | 144 | @override 145 | bool hitTestChildren(BoxHitTestResult result, {required Offset position}) { 146 | return child?.hitTest(result, position: position) ?? false; 147 | } 148 | 149 | @override 150 | void paint(PaintingContext context, Offset offset) { 151 | if (child != null) context.paintChild(child!, offset); 152 | } 153 | 154 | bool _debugThrowIfNotCheckingIntrinsics() { 155 | assert(() { 156 | if (!RenderObject.debugCheckingIntrinsics) { 157 | throw FlutterError( 158 | 'ValueLayoutBuilder does not support returning intrinsic dimensions.\n' 159 | 'Calculating the intrinsic dimensions would require running the layout ' 160 | 'callback speculatively, which might mutate the live render object tree.'); 161 | } 162 | return true; 163 | }()); 164 | 165 | return true; 166 | } 167 | } 168 | -------------------------------------------------------------------------------- /lib/value_layout_builder.dart: -------------------------------------------------------------------------------- 1 | library value_layout_builder; 2 | 3 | export 'src/sliver_value_layout_builder.dart'; 4 | export 'src/value_layout_builder.dart'; 5 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: value_layout_builder 2 | description: A LayoutBuilder with an extra value. It's useful when you want to build a widget with a value computed during layout. 3 | version: 0.5.0 4 | homepage: https://github.com/letsar/value_layout_builder 5 | 6 | environment: 7 | sdk: '>=2.17.0 <4.0.0' 8 | flutter: '>=3.32.0' 9 | 10 | dependencies: 11 | flutter: 12 | sdk: flutter 13 | 14 | dev_dependencies: 15 | flutter_test: 16 | sdk: flutter 17 | -------------------------------------------------------------------------------- /test/sliver_value_layout_builder_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter/rendering.dart'; 3 | import 'package:flutter_test/flutter_test.dart'; 4 | 5 | import 'package:value_layout_builder/value_layout_builder.dart'; 6 | 7 | class _Tester extends SingleChildRenderObjectWidget { 8 | const _Tester({ 9 | Key? key, 10 | required this.value, 11 | required Widget child, 12 | }) : super(key: key, child: child); 13 | 14 | final T value; 15 | 16 | @override 17 | _SliverRenderTester createRenderObject(BuildContext context) { 18 | return _SliverRenderTester(value: value); 19 | } 20 | 21 | @override 22 | void updateRenderObject( 23 | BuildContext context, _SliverRenderTester renderObject) { 24 | renderObject.value = value; 25 | } 26 | } 27 | 28 | class _SliverRenderTester extends RenderSliver 29 | with RenderObjectWithChildMixin { 30 | _SliverRenderTester({ 31 | required T value, 32 | }) : _value = value; 33 | 34 | T get value => _value; 35 | T _value; 36 | set value(T value) { 37 | if (_value != value) { 38 | _value = value; 39 | markNeedsLayout(); 40 | } 41 | } 42 | 43 | @override 44 | void performLayout() { 45 | SliverValueConstraints constraints = SliverValueConstraints( 46 | constraints: this.constraints, 47 | value: value, 48 | ); 49 | child?.layout(constraints); 50 | geometry = SliverGeometry.zero; 51 | } 52 | } 53 | 54 | void main() { 55 | testWidgets('the constraints have the specified value', (tester) async { 56 | List logs = []; 57 | 58 | await tester.pumpWidget( 59 | Directionality( 60 | textDirection: TextDirection.ltr, 61 | child: CustomScrollView( 62 | slivers: [ 63 | _Tester( 64 | value: 'test', 65 | child: SliverValueLayoutBuilder( 66 | builder: (context, constraints) { 67 | logs.add(constraints.value); 68 | return SliverToBoxAdapter( 69 | child: SizedBox.shrink(), 70 | ); 71 | }, 72 | ), 73 | ), 74 | ], 75 | ), 76 | ), 77 | ); 78 | 79 | expect(logs, ['test']); 80 | 81 | await tester.pumpWidget( 82 | Directionality( 83 | textDirection: TextDirection.ltr, 84 | child: CustomScrollView( 85 | slivers: [ 86 | _Tester( 87 | value: '42', 88 | child: SliverValueLayoutBuilder( 89 | builder: (context, constraints) { 90 | logs.add(constraints.value); 91 | return SliverToBoxAdapter( 92 | child: SizedBox.shrink(), 93 | ); 94 | }, 95 | ), 96 | ), 97 | ], 98 | ), 99 | ), 100 | ); 101 | 102 | expect(logs, ['test', '42']); 103 | }); 104 | } 105 | -------------------------------------------------------------------------------- /test/value_layout_builder_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter/rendering.dart'; 3 | import 'package:flutter_test/flutter_test.dart'; 4 | 5 | import 'package:value_layout_builder/value_layout_builder.dart'; 6 | 7 | class _Tester extends SingleChildRenderObjectWidget { 8 | const _Tester({ 9 | Key? key, 10 | required this.value, 11 | required Widget child, 12 | }) : super(key: key, child: child); 13 | 14 | final T value; 15 | 16 | @override 17 | _RenderTester createRenderObject(BuildContext context) { 18 | return _RenderTester(value: value); 19 | } 20 | 21 | @override 22 | void updateRenderObject(BuildContext context, _RenderTester renderObject) { 23 | renderObject.value = value; 24 | } 25 | } 26 | 27 | class _RenderTester extends RenderBox 28 | with RenderObjectWithChildMixin { 29 | _RenderTester({ 30 | required T value, 31 | }) : _value = value; 32 | 33 | T get value => _value; 34 | T _value; 35 | set value(T value) { 36 | if (_value != value) { 37 | _value = value; 38 | markNeedsLayout(); 39 | } 40 | } 41 | 42 | @override 43 | void performLayout() { 44 | BoxValueConstraints constraints = BoxValueConstraints( 45 | constraints: this.constraints, 46 | value: value, 47 | ); 48 | child?.layout(constraints); 49 | size = constraints.biggest; 50 | } 51 | } 52 | 53 | void main() { 54 | testWidgets('the constraints have the specified value', (tester) async { 55 | List logs = []; 56 | 57 | await tester.pumpWidget( 58 | _Tester( 59 | value: 'test', 60 | child: ValueLayoutBuilder( 61 | builder: (context, constraints) { 62 | logs.add(constraints.value); 63 | return SizedBox.shrink(); 64 | }, 65 | ), 66 | ), 67 | ); 68 | 69 | expect(logs, ['test']); 70 | 71 | await tester.pumpWidget( 72 | _Tester( 73 | value: '42', 74 | child: ValueLayoutBuilder( 75 | builder: (context, constraints) { 76 | logs.add(constraints.value); 77 | return SizedBox.shrink(); 78 | }, 79 | ), 80 | ), 81 | ); 82 | 83 | expect(logs, ['test', '42']); 84 | }); 85 | } 86 | --------------------------------------------------------------------------------