├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ ├── custom.md │ └── feature_request.md └── workflows │ └── dart.yml ├── .gitignore ├── .idea ├── .gitignore ├── codeStyles │ └── Project.xml ├── libraries │ ├── Dart_SDK.xml │ ├── Flutter_Plugins.xml │ └── Flutter_for_Android.xml ├── misc.xml ├── modules.xml ├── runConfigurations │ └── example_lib_main_dart.xml ├── vcs.xml └── workspace.xml ├── .metadata ├── CHANGELOG.md ├── LICENSE ├── README.md ├── android ├── .gitignore ├── .idea │ ├── $CACHE_FILE$ │ ├── .name │ ├── caches │ │ └── build_file_checksums.ser │ ├── codeStyles │ │ └── Project.xml │ ├── gradle.xml │ ├── jarRepositories.xml │ ├── misc.xml │ ├── modules.xml │ ├── runConfigurations.xml │ └── vcs.xml ├── build.gradle ├── gradle.properties ├── gradle │ └── wrapper │ │ └── gradle-wrapper.properties ├── settings.gradle └── src │ └── main │ ├── AndroidManifest.xml │ └── kotlin │ └── com │ └── josh │ └── nineold │ └── NineoldPlugin.kt ├── example ├── .gitignore ├── .metadata ├── README.md ├── android │ ├── .gitignore │ ├── app │ │ ├── build.gradle │ │ └── src │ │ │ ├── debug │ │ │ └── AndroidManifest.xml │ │ │ ├── main │ │ │ ├── AndroidManifest.xml │ │ │ ├── kotlin │ │ │ │ └── com │ │ │ │ │ └── josh │ │ │ │ │ └── nineold_example │ │ │ │ │ └── MainActivity.kt │ │ │ └── res │ │ │ │ ├── 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 │ │ │ │ └── styles.xml │ │ │ └── profile │ │ │ └── AndroidManifest.xml │ ├── build.gradle │ ├── gradle.properties │ ├── gradle │ │ └── wrapper │ │ │ └── gradle-wrapper.properties │ └── settings.gradle ├── assets │ └── video.gif ├── ios │ ├── .gitignore │ ├── Flutter │ │ ├── .last_build_id │ │ ├── AppFrameworkInfo.plist │ │ ├── Debug.xcconfig │ │ └── Release.xcconfig │ ├── Podfile │ ├── Podfile.lock │ ├── Runner.xcodeproj │ │ ├── project.pbxproj │ │ ├── project.xcworkspace │ │ │ └── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ └── Runner.xcscheme │ ├── Runner.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ └── 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 ├── lib │ ├── generated │ │ ├── intl │ │ │ ├── messages_all.dart │ │ │ ├── messages_en.dart │ │ │ └── messages_zh.dart │ │ └── l10n.dart │ ├── l10n │ │ ├── intl_en.arb │ │ └── intl_zh.arb │ └── main.dart ├── pubspec.lock ├── pubspec.yaml └── test │ └── widget_test.dart ├── ios ├── .gitignore ├── Assets │ └── .gitkeep ├── Classes │ ├── NineoldPlugin.h │ ├── NineoldPlugin.m │ └── SwiftNineoldPlugin.swift └── nineold.podspec ├── lib ├── loader │ └── image_with_loader.dart ├── nine_old_frame.dart ├── watcher │ └── gallery_watcher.dart └── widget │ └── nine_old_widget.dart ├── nineold.iml ├── pubspec.lock └── pubspec.yaml /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. iOS] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Smartphone (please complete the following information):** 32 | - Device: [e.g. iPhone6] 33 | - OS: [e.g. iOS8.1] 34 | - Browser [e.g. stock browser, safari] 35 | - Version [e.g. 22] 36 | 37 | **Additional context** 38 | Add any other context about the problem here. 39 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/custom.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Custom issue template 3 | about: Describe this issue template's purpose here. 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | 11 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/workflows/dart.yml: -------------------------------------------------------------------------------- 1 | # This workflow uses actions that are not certified by GitHub. 2 | # They are provided by a third-party and are governed by 3 | # separate terms of service, privacy policy, and support 4 | # documentation. 5 | 6 | name: Dart 7 | 8 | on: 9 | push: 10 | branches: [ "master" ] 11 | pull_request: 12 | branches: [ "master" ] 13 | 14 | jobs: 15 | build: 16 | runs-on: ubuntu-latest 17 | 18 | steps: 19 | - uses: actions/checkout@v3 20 | 21 | # Note: This workflow uses the latest stable version of the Dart SDK. 22 | # You can specify other versions if desired, see documentation here: 23 | # https://github.com/dart-lang/setup-dart/blob/main/README.md 24 | # - uses: dart-lang/setup-dart@v1 25 | - uses: dart-lang/setup-dart@9a04e6d73cca37bd455e0608d7e5092f881fd603 26 | 27 | - name: Install dependencies 28 | run: dart pub get 29 | 30 | # Uncomment this step to verify the use of 'dart format' on each commit. 31 | # - name: Verify formatting 32 | # run: dart format --output=none --set-exit-if-changed . 33 | 34 | # Consider passing '--fatal-infos' for slightly stricter analysis. 35 | - name: Analyze project source 36 | run: dart analyze 37 | 38 | # Your project will need to have tests in test/ and a dependency on 39 | # package:test for this step to succeed. Note that Flutter projects will 40 | # want to change this to 'flutter test'. 41 | - name: Run tests 42 | run: dart test 43 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .dart_tool/ 3 | 4 | .packages 5 | .pub/ 6 | 7 | build/ 8 | -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Project exclude paths 2 | /. -------------------------------------------------------------------------------- /.idea/codeStyles/Project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | xmlns:android 14 | 15 | ^$ 16 | 17 | 18 | 19 |
20 |
21 | 22 | 23 | 24 | xmlns:.* 25 | 26 | ^$ 27 | 28 | 29 | BY_NAME 30 | 31 |
32 |
33 | 34 | 35 | 36 | .*:id 37 | 38 | http://schemas.android.com/apk/res/android 39 | 40 | 41 | 42 |
43 |
44 | 45 | 46 | 47 | .*:name 48 | 49 | http://schemas.android.com/apk/res/android 50 | 51 | 52 | 53 |
54 |
55 | 56 | 57 | 58 | name 59 | 60 | ^$ 61 | 62 | 63 | 64 |
65 |
66 | 67 | 68 | 69 | style 70 | 71 | ^$ 72 | 73 | 74 | 75 |
76 |
77 | 78 | 79 | 80 | .* 81 | 82 | ^$ 83 | 84 | 85 | BY_NAME 86 | 87 |
88 |
89 | 90 | 91 | 92 | .* 93 | 94 | http://schemas.android.com/apk/res/android 95 | 96 | 97 | ANDROID_ATTRIBUTE_ORDER 98 | 99 |
100 |
101 | 102 | 103 | 104 | .* 105 | 106 | .* 107 | 108 | 109 | BY_NAME 110 | 111 |
112 |
113 |
114 |
115 |
116 |
-------------------------------------------------------------------------------- /.idea/libraries/Dart_SDK.xml: -------------------------------------------------------------------------------- 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 | -------------------------------------------------------------------------------- /.idea/libraries/Flutter_Plugins.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /.idea/libraries/Flutter_for_Android.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /.idea/runConfigurations/example_lib_main_dart.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /.idea/workspace.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 18 | 19 | 20 | 22 | 23 | 24 | 25 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 1584004746186 55 | 59 | 60 | 61 | 62 | 71 | 73 | -------------------------------------------------------------------------------- /.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: 0b8abb4724aa590dd0f429683339b1e045a1594d 8 | channel: stable 9 | 10 | project_type: plugin 11 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## Version 3.2.2 2 | 1. Update pub dependency and fluent version 2.10.1 3 | 4 | 2. Fix the same picture address hero animation tag problem 5 | 6 | 3. The same address of the picture hero animation cannot be loaded 7 | 8 | 4. Fix the black screen display of hero animation 9 | 10 | 5. Long press the picture to recall the picture position 11 | 12 | 6. Fix the image display dislocation bug 13 | 14 | 7. Add long press event callback for viewing pictures 15 | 16 | 8. Support custom loading box and more picture text styles 17 | 18 | 9. Adapt to screen width and height display 19 | 20 | 10. Support dynamic picture display 21 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Josh Lu 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. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # flutter_nineold 2 | 3 | 九宫格图片列表,支持9+以上数量的显示,支持Hero动画预览图片 4 | 5 | # Demo 6 | 7 | 8 | 9 | 10 | # 开始 11 | 12 | 在flutter的项目文件中增加依赖 13 | 14 | ``` 15 | dependencies: 16 | ... 17 | nineold: ^3.2.2 18 | ``` 19 | 20 | 关于如何运行flutter项目, 参考官方文档[documentation](https://flutter.io/). 21 | 22 | 23 | 24 | # 版本更新 25 | ## 3.2.2 26 | 27 | 1.更新pub依赖以及flutter版本2.10.1 28 | 29 | 2.修复相同图片地址Hero动画tag相同问题 30 | 31 | 3.图片Hero动画相同地址不能加载 32 | 33 | 4.修复Hero动画黑屏显示 34 | 35 | 5.图片长按回调图片位置 36 | 37 | 6.修复图片显示错位bug 38 | 39 | 7.增加查看图片长按事件回调 40 | 41 | 8.支持自定义加载框,以及更多图片文字样式 42 | 43 | 9.适配屏幕宽高显示 44 | 45 | 10.支持动态显示9+以上图片 46 | 47 | # 使用方法 48 | 49 | Import nine_old_widget.dart 50 | 51 | ``` 52 | import 'package:nineold/widget/nine_old_widget.dart'; 53 | ``` 54 | 55 | 简单使用方法 56 | 57 | ``` 58 | class _MyHomePageState extends State { 59 | List> images = []; 60 | 61 | @override 62 | void initState() { 63 | super.initState(); 64 | images.add(getData()); 65 | } 66 | 67 | @override 68 | Widget build(BuildContext context) { 69 | return Scaffold( 70 | appBar: AppBar( 71 | title: Text("Flutter Nine Old"), 72 | ), 73 | body: ListView.separated( 74 | itemBuilder: (context, index) { 75 | return _buildActiveItem(index, getData().sublist(0, index)); 76 | }, 77 | itemCount: 13, 78 | separatorBuilder: (BuildContext context, int index) => 79 | Divider(height: 1.0, color: Colors.lightBlueAccent), 80 | ), 81 | floatingActionButton: FloatingActionButton( 82 | child: Icon(Icons.add), 83 | onPressed: () { 84 | setState(() { 85 | // count++; 86 | // images.add(getData().sublist(0, count % 15)); 87 | }); 88 | }, 89 | ), 90 | ); 91 | } 92 | 93 | Widget _buildActiveItem(int index, List photos) { 94 | return Container( 95 | margin: EdgeInsets.all(10), 96 | child: Column( 97 | mainAxisAlignment: MainAxisAlignment.center, 98 | crossAxisAlignment: CrossAxisAlignment.center, 99 | children: [ 100 | _buildActiveItemHeader(index), 101 | null != photos || photos.isNotEmpty 102 | ? NineOldWidget( 103 | images: photos, 104 | //必填 105 | onLongPressListener: (position) { 106 | //可选 107 | //长按事件回调 108 | print("长按事件回调当前位置 : $position"); 109 | }, 110 | backgroundColor: Colors.white, 111 | //可选 112 | //加载背景颜色 113 | valueColor: Colors.red, 114 | //可选 115 | //加载进度条颜色 116 | strokeWidth: 4, 117 | //可选 118 | //加载进度条宽度 119 | moreStyle: 120 | TextStyle(fontSize: 28, color: Colors.orange), //更多加号样式 121 | //可选 122 | //资源加载失败显示 123 | errorWidget: Icon(Icons.error_outline_rounded), 124 | ) 125 | : SizedBox() 126 | ], 127 | ), 128 | ); 129 | } 130 | 131 | Widget _buildActiveItemHeader(int index) { 132 | return Container( 133 | child: Column( 134 | children: [ 135 | Row( 136 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 137 | crossAxisAlignment: CrossAxisAlignment.center, 138 | children: [ 139 | ClipOval( 140 | child: Image.network( 141 | "http://t7.baidu.com/it/u=3616242789,1098670747&fm=79&app=86&f=JPEG?w=900&h=1350", 142 | width: 30.0, 143 | height: 30.0, 144 | ), 145 | ), 146 | ], 147 | ), 148 | Text("第$index条") 149 | ], 150 | ), 151 | ); 152 | } 153 | 154 | List getData() { 155 | List list = []; 156 | list.add( 157 | "http://t7.baidu.com/it/u=3616242789,1098670747&fm=79&app=86&f=JPEG?w=900&h=1350"); 158 | list.add( 159 | "http://t7.baidu.com/it/u=3616242789,1098670747&fm=79&app=86&f=JPEG?w=900&h=1350"); 160 | list.add( 161 | "http://t7.baidu.com/it/u=3616242789,1098670747&fm=79&app=86&f=JPEG?w=900&h=1350"); 162 | list.add( 163 | "https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=3687862105,320198720&fm=26&gp=0.jpg"); 164 | list.add( 165 | "https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=339659526,3524437886&fm=26&gp=0.jpg"); 166 | list.add( 167 | "https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=1492148550,3573121792&fm=11&gp=0.jpg"); 168 | list.add( 169 | "https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=3059211665,2147448542&fm=26&gp=0.jpg"); 170 | list.add( 171 | "https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=2333676140,2717071870&fm=11&gp=0.jpg"); 172 | list.add( 173 | "https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=2417108265,1198830140&fm=26&gp=0.jpg"); 174 | list.add( 175 | "https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=244450851,2728981198&fm=26&gp=0.jpg"); 176 | list.add( 177 | "https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=2083759825,3454063564&fm=26&gp=0.jpg"); 178 | list.add( 179 | "https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=310077658,2097249993&fm=11&gp=0.jpg"); 180 | list.add( 181 | "https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=415170272,1239551712&fm=26&gp=0.jpg"); 182 | list.add( 183 | "https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=1030558027,1672821388&fm=26&gp=0.jpg"); 184 | list.add( 185 | "https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=3153722339,140981551&fm=26&gp=0.jpg"); 186 | list.add( 187 | "https://t8.baidu.com/it/u=3571592872,3353494284&fm=79&app=86&size=h300&n=0&g=4n&f=jpeg?sec=1584605109&t=4c346851d3f4f4cf76439fe6440ffe9f"); 188 | list.add( 189 | "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1594817167403&di=87226dc3d6b70a7e02722b9f9bd9f33a&imgtype=0&src=http%3A%2F%2Ft9.baidu.com%2Fit%2Fu%3D1307125826%2C3433407105%26fm%3D79%26app%3D86%26f%3DJPEG%3Fw%3D5760%26h%3D3240"); 190 | return list; 191 | } 192 | } 193 | ``` 194 | 195 | 196 | NineOldWidget控件构造方法以及参数设置 197 | 198 | ``` 199 | NineOldWidget( 200 | {@required this.images, 201 | this.moreStyle, 202 | this.backgroundColor = Colors.white, 203 | this.strokeWidth = 3, 204 | this.valueColor = Colors.tealAccent, 205 | this.onLongPressListener, 206 | this.errorWidget}); 207 | ``` 208 | 209 | 210 | 211 | 212 | ### 使用说明 213 | NineOldWidget 是用来封装图片九宫格显示的组件, 方便使用者能更好的使用该插件. 使用者只要需要注入图片集合,集成和Photo_view的Hero动画以及网络图片加载的展位图进度显示,就可以实现图片查看,九宫格列表 214 | 215 | 216 | 217 | 218 | 219 | ### 致谢 220 | 221 | [timy-messenger](https://github.com/janoodleFTW/timy-messenger) 222 | 223 | [photo_view](https://github.com/renancaraujo/photo_view) 224 | 225 | 226 | ## 浏览数 227 | 228 | Loading 229 | 230 | 231 | 232 | -------------------------------------------------------------------------------- /android/.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | -------------------------------------------------------------------------------- /android/.idea/$CACHE_FILE$: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | AccessibilityLintAndroid 12 | 13 | 14 | Android 15 | 16 | 17 | Chrome OSCorrectnessLintAndroid 18 | 19 | 20 | Concurrency annotation issuesJava 21 | 22 | 23 | CorrectnessLintAndroid 24 | 25 | 26 | Data flow issuesJava 27 | 28 | 29 | Groovy 30 | 31 | 32 | IconsUsabilityLintAndroid 33 | 34 | 35 | Initialization issuesJava 36 | 37 | 38 | InternationalizationLintAndroid 39 | 40 | 41 | Java 42 | 43 | 44 | LintAndroid 45 | 46 | 47 | MessagesCorrectnessLintAndroid 48 | 49 | 50 | PerformanceLintAndroid 51 | 52 | 53 | SecurityLintAndroid 54 | 55 | 56 | Serialization issuesJava 57 | 58 | 59 | Threading issuesGroovy 60 | 61 | 62 | Threading issuesJava 63 | 64 | 65 | TypographyUsabilityLintAndroid 66 | 67 | 68 | UsabilityLintAndroid 69 | 70 | 71 | 72 | 73 | Android 74 | 75 | 76 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /android/.idea/.name: -------------------------------------------------------------------------------- 1 | nineold -------------------------------------------------------------------------------- /android/.idea/caches/build_file_checksums.ser: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lanzhu1993/flutter_nineold/4100f6cbb776803a668ee31f7417579721a5321c/android/.idea/caches/build_file_checksums.ser -------------------------------------------------------------------------------- /android/.idea/codeStyles/Project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | xmlns:android 14 | 15 | ^$ 16 | 17 | 18 | 19 |
20 |
21 | 22 | 23 | 24 | xmlns:.* 25 | 26 | ^$ 27 | 28 | 29 | BY_NAME 30 | 31 |
32 |
33 | 34 | 35 | 36 | .*:id 37 | 38 | http://schemas.android.com/apk/res/android 39 | 40 | 41 | 42 |
43 |
44 | 45 | 46 | 47 | .*:name 48 | 49 | http://schemas.android.com/apk/res/android 50 | 51 | 52 | 53 |
54 |
55 | 56 | 57 | 58 | name 59 | 60 | ^$ 61 | 62 | 63 | 64 |
65 |
66 | 67 | 68 | 69 | style 70 | 71 | ^$ 72 | 73 | 74 | 75 |
76 |
77 | 78 | 79 | 80 | .* 81 | 82 | ^$ 83 | 84 | 85 | BY_NAME 86 | 87 |
88 |
89 | 90 | 91 | 92 | .* 93 | 94 | http://schemas.android.com/apk/res/android 95 | 96 | 97 | ANDROID_ATTRIBUTE_ORDER 98 | 99 |
100 |
101 | 102 | 103 | 104 | .* 105 | 106 | .* 107 | 108 | 109 | BY_NAME 110 | 111 |
112 |
113 |
114 |
115 |
116 |
-------------------------------------------------------------------------------- /android/.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 20 | -------------------------------------------------------------------------------- /android/.idea/jarRepositories.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 10 | 14 | 15 | 19 | 20 | 24 | 25 | -------------------------------------------------------------------------------- /android/.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 9 | -------------------------------------------------------------------------------- /android/.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /android/.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /android/.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | group 'com.josh.nineold' 2 | version '1.0-SNAPSHOT' 3 | 4 | buildscript { 5 | ext.kotlin_version = '1.3.50' 6 | repositories { 7 | google() 8 | jcenter() 9 | } 10 | 11 | dependencies { 12 | classpath 'com.android.tools.build:gradle:3.5.0' 13 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 14 | } 15 | } 16 | 17 | rootProject.allprojects { 18 | repositories { 19 | google() 20 | jcenter() 21 | } 22 | } 23 | 24 | apply plugin: 'com.android.library' 25 | apply plugin: 'kotlin-android' 26 | 27 | android { 28 | compileSdkVersion 28 29 | 30 | sourceSets { 31 | main.java.srcDirs += 'src/main/kotlin' 32 | } 33 | defaultConfig { 34 | minSdkVersion 16 35 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 36 | } 37 | lintOptions { 38 | disable 'InvalidPackage' 39 | } 40 | } 41 | 42 | dependencies { 43 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 44 | } 45 | -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | android.enableR8=true 3 | android.useAndroidX=true 4 | android.enableJetifier=true 5 | -------------------------------------------------------------------------------- /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-5.6.2-all.zip 6 | -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'nineold' 2 | -------------------------------------------------------------------------------- /android/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | -------------------------------------------------------------------------------- /android/src/main/kotlin/com/josh/nineold/NineoldPlugin.kt: -------------------------------------------------------------------------------- 1 | package com.josh.nineold 2 | 3 | import androidx.annotation.NonNull; 4 | import io.flutter.embedding.engine.plugins.FlutterPlugin 5 | import io.flutter.plugin.common.MethodCall 6 | import io.flutter.plugin.common.MethodChannel 7 | import io.flutter.plugin.common.MethodChannel.MethodCallHandler 8 | import io.flutter.plugin.common.MethodChannel.Result 9 | import io.flutter.plugin.common.PluginRegistry.Registrar 10 | 11 | /** NineoldPlugin */ 12 | public class NineoldPlugin: FlutterPlugin, MethodCallHandler { 13 | override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) { 14 | val channel = MethodChannel(flutterPluginBinding.getFlutterEngine().getDartExecutor(), "nineold") 15 | channel.setMethodCallHandler(NineoldPlugin()); 16 | } 17 | 18 | // This static function is optional and equivalent to onAttachedToEngine. It supports the old 19 | // pre-Flutter-1.12 Android projects. You are encouraged to continue supporting 20 | // plugin registration via this function while apps migrate to use the new Android APIs 21 | // post-flutter-1.12 via https://flutter.dev/go/android-project-migration. 22 | // 23 | // It is encouraged to share logic between onAttachedToEngine and registerWith to keep 24 | // them functionally equivalent. Only one of onAttachedToEngine or registerWith will be called 25 | // depending on the user's project. onAttachedToEngine or registerWith must both be defined 26 | // in the same class. 27 | companion object { 28 | @JvmStatic 29 | fun registerWith(registrar: Registrar) { 30 | val channel = MethodChannel(registrar.messenger(), "nineold") 31 | channel.setMethodCallHandler(NineoldPlugin()) 32 | } 33 | } 34 | 35 | override fun onMethodCall(@NonNull call: MethodCall, @NonNull result: Result) { 36 | if (call.method == "getPlatformVersion") { 37 | result.success("Android ${android.os.Build.VERSION.RELEASE}") 38 | } else { 39 | result.notImplemented() 40 | } 41 | } 42 | 43 | override fun onDetachedFromEngine(@NonNull binding: FlutterPlugin.FlutterPluginBinding) { 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /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 | .dart_tool/ 26 | .flutter-plugins 27 | .flutter-plugins-dependencies 28 | .packages 29 | .pub-cache/ 30 | .pub/ 31 | /build/ 32 | 33 | # Web related 34 | lib/generated_plugin_registrant.dart 35 | 36 | # Exceptions to above rules. 37 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages 38 | -------------------------------------------------------------------------------- /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: 0b8abb4724aa590dd0f429683339b1e045a1594d 8 | channel: stable 9 | 10 | project_type: app 11 | -------------------------------------------------------------------------------- /example/README.md: -------------------------------------------------------------------------------- 1 | # nineold_example 2 | 3 | Demonstrates how to use the nineold plugin. 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 | -------------------------------------------------------------------------------- /example/android/app/build.gradle: -------------------------------------------------------------------------------- 1 | def localProperties = new Properties() 2 | def localPropertiesFile = rootProject.file('local.properties') 3 | if (localPropertiesFile.exists()) { 4 | localPropertiesFile.withReader('UTF-8') { reader -> 5 | localProperties.load(reader) 6 | } 7 | } 8 | 9 | def flutterRoot = localProperties.getProperty('flutter.sdk') 10 | if (flutterRoot == null) { 11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") 12 | } 13 | 14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode') 15 | if (flutterVersionCode == null) { 16 | flutterVersionCode = '1' 17 | } 18 | 19 | def flutterVersionName = localProperties.getProperty('flutter.versionName') 20 | if (flutterVersionName == null) { 21 | flutterVersionName = '1.0' 22 | } 23 | 24 | apply plugin: 'com.android.application' 25 | apply plugin: 'kotlin-android' 26 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" 27 | 28 | android { 29 | compileSdkVersion 29 30 | 31 | sourceSets { 32 | main.java.srcDirs += 'src/main/kotlin' 33 | } 34 | 35 | lintOptions { 36 | disable 'InvalidPackage' 37 | } 38 | 39 | defaultConfig { 40 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 41 | applicationId "com.josh.nineold_example" 42 | minSdkVersion 16 43 | targetSdkVersion 29 44 | versionCode flutterVersionCode.toInteger() 45 | versionName flutterVersionName 46 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 47 | 48 | ndk { 49 | // Specifies the ABI configurations of your native 50 | // libraries Gradle should build and package with your APK. 51 | abiFilters 'armeabi-v7a', 'arm64-v8a' 52 | } 53 | } 54 | 55 | buildTypes { 56 | release { 57 | // TODO: Add your own signing config for the release build. 58 | // Signing with the debug keys for now, so `flutter run --release` works. 59 | signingConfig signingConfigs.debug 60 | } 61 | } 62 | } 63 | 64 | flutter { 65 | source '../..' 66 | } 67 | 68 | dependencies { 69 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 70 | testImplementation 'junit:junit:4.12' 71 | androidTestImplementation 'androidx.test:runner:1.1.1' 72 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1' 73 | } 74 | -------------------------------------------------------------------------------- /example/android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 8 | 12 | 19 | 20 | 21 | 22 | 23 | 24 | 26 | 27 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /example/android/app/src/main/kotlin/com/josh/nineold_example/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.josh.nineold_example 2 | 3 | import androidx.annotation.NonNull; 4 | import io.flutter.embedding.android.FlutterActivity 5 | import io.flutter.embedding.engine.FlutterEngine 6 | import io.flutter.plugins.GeneratedPluginRegistrant 7 | 8 | class MainActivity: FlutterActivity() { 9 | override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) { 10 | GeneratedPluginRegistrant.registerWith(flutterEngine); 11 | } 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/lanzhu1993/flutter_nineold/4100f6cbb776803a668ee31f7417579721a5321c/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/lanzhu1993/flutter_nineold/4100f6cbb776803a668ee31f7417579721a5321c/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/lanzhu1993/flutter_nineold/4100f6cbb776803a668ee31f7417579721a5321c/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/lanzhu1993/flutter_nineold/4100f6cbb776803a668ee31f7417579721a5321c/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/lanzhu1993/flutter_nineold/4100f6cbb776803a668ee31f7417579721a5321c/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | -------------------------------------------------------------------------------- /example/android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | ext.kotlin_version = '1.5.31' 3 | repositories { 4 | google() 5 | jcenter() 6 | } 7 | 8 | dependencies { 9 | classpath 'com.android.tools.build:gradle:3.5.0' 10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 11 | } 12 | } 13 | 14 | allprojects { 15 | repositories { 16 | google() 17 | jcenter() 18 | } 19 | } 20 | 21 | rootProject.buildDir = '../build' 22 | subprojects { 23 | project.buildDir = "${rootProject.buildDir}/${project.name}" 24 | } 25 | subprojects { 26 | project.evaluationDependsOn(':app') 27 | } 28 | 29 | task clean(type: Delete) { 30 | delete rootProject.buildDir 31 | } 32 | -------------------------------------------------------------------------------- /example/android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | android.enableR8=true 3 | android.useAndroidX=true 4 | android.enableJetifier=true 5 | -------------------------------------------------------------------------------- /example/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Jun 23 08:50:38 CEST 2017 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-bin.zip 7 | -------------------------------------------------------------------------------- /example/android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | 3 | def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() 4 | 5 | def plugins = new Properties() 6 | def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') 7 | if (pluginsFile.exists()) { 8 | pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } 9 | } 10 | 11 | plugins.each { name, path -> 12 | def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() 13 | include ":$name" 14 | project(":$name").projectDir = pluginDirectory 15 | } 16 | -------------------------------------------------------------------------------- /example/assets/video.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lanzhu1993/flutter_nineold/4100f6cbb776803a668ee31f7417579721a5321c/example/assets/video.gif -------------------------------------------------------------------------------- /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/.last_build_id: -------------------------------------------------------------------------------- 1 | bbdb553b87fa2463a6fc2c1277a80444 -------------------------------------------------------------------------------- /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 | 8.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /example/ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /example/ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /example/ios/Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment this line to define a global platform for your project 2 | platform :ios, '9.0' 3 | 4 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency. 5 | ENV['COCOAPODS_DISABLE_STATS'] = 'true' 6 | 7 | project 'Runner', { 8 | 'Debug' => :debug, 9 | 'Profile' => :release, 10 | 'Release' => :release, 11 | } 12 | 13 | def parse_KV_file(file, separator='=') 14 | file_abs_path = File.expand_path(file) 15 | if !File.exists? file_abs_path 16 | return []; 17 | end 18 | generated_key_values = {} 19 | skip_line_start_symbols = ["#", "/"] 20 | File.foreach(file_abs_path) do |line| 21 | next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ } 22 | plugin = line.split(pattern=separator) 23 | if plugin.length == 2 24 | podname = plugin[0].strip() 25 | path = plugin[1].strip() 26 | podpath = File.expand_path("#{path}", file_abs_path) 27 | generated_key_values[podname] = podpath 28 | else 29 | puts "Invalid plugin specification: #{line}" 30 | end 31 | end 32 | generated_key_values 33 | end 34 | 35 | target 'Runner' do 36 | use_frameworks! 37 | use_modular_headers! 38 | 39 | # Flutter Pod 40 | 41 | copied_flutter_dir = File.join(__dir__, 'Flutter') 42 | copied_framework_path = File.join(copied_flutter_dir, 'Flutter.framework') 43 | copied_podspec_path = File.join(copied_flutter_dir, 'Flutter.podspec') 44 | unless File.exist?(copied_framework_path) && File.exist?(copied_podspec_path) 45 | # Copy Flutter.framework and Flutter.podspec to Flutter/ to have something to link against if the xcode backend script has not run yet. 46 | # That script will copy the correct debug/profile/release version of the framework based on the currently selected Xcode configuration. 47 | # CocoaPods will not embed the framework on pod install (before any build phases can generate) if the dylib does not exist. 48 | 49 | generated_xcode_build_settings_path = File.join(copied_flutter_dir, 'Generated.xcconfig') 50 | unless File.exist?(generated_xcode_build_settings_path) 51 | raise "Generated.xcconfig must exist. If you're running pod install manually, make sure flutter pub get is executed first" 52 | end 53 | generated_xcode_build_settings = parse_KV_file(generated_xcode_build_settings_path) 54 | cached_framework_dir = generated_xcode_build_settings['FLUTTER_FRAMEWORK_DIR']; 55 | 56 | unless File.exist?(copied_framework_path) 57 | FileUtils.cp_r(File.join(cached_framework_dir, 'Flutter.framework'), copied_flutter_dir) 58 | end 59 | unless File.exist?(copied_podspec_path) 60 | FileUtils.cp(File.join(cached_framework_dir, 'Flutter.podspec'), copied_flutter_dir) 61 | end 62 | end 63 | 64 | # Keep pod path relative so it can be checked into Podfile.lock. 65 | pod 'Flutter', :path => 'Flutter' 66 | 67 | # Plugin Pods 68 | 69 | # Prepare symlinks folder. We use symlinks to avoid having Podfile.lock 70 | # referring to absolute paths on developers' machines. 71 | system('rm -rf .symlinks') 72 | system('mkdir -p .symlinks/plugins') 73 | plugin_pods = parse_KV_file('../.flutter-plugins') 74 | plugin_pods.each do |name, path| 75 | symlink = File.join('.symlinks', 'plugins', name) 76 | File.symlink(path, symlink) 77 | pod name, :path => File.join(symlink, 'ios') 78 | end 79 | end 80 | 81 | # Prevent Cocoapods from embedding a second Flutter framework and causing an error with the new Xcode build system. 82 | install! 'cocoapods', :disable_input_output_paths => true 83 | 84 | post_install do |installer| 85 | installer.pods_project.targets.each do |target| 86 | target.build_configurations.each do |config| 87 | config.build_settings['ENABLE_BITCODE'] = 'NO' 88 | end 89 | end 90 | end 91 | -------------------------------------------------------------------------------- /example/ios/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - Flutter (1.0.0) 3 | - FMDB (2.7.5): 4 | - FMDB/standard (= 2.7.5) 5 | - FMDB/standard (2.7.5) 6 | - nineold (0.0.1): 7 | - Flutter 8 | - path_provider (0.0.1): 9 | - Flutter 10 | - path_provider_linux (0.0.1): 11 | - Flutter 12 | - path_provider_macos (0.0.1): 13 | - Flutter 14 | - path_provider_windows (0.0.1): 15 | - Flutter 16 | - sqflite (0.0.2): 17 | - Flutter 18 | - FMDB (>= 2.7.5) 19 | 20 | DEPENDENCIES: 21 | - Flutter (from `Flutter`) 22 | - nineold (from `.symlinks/plugins/nineold/ios`) 23 | - path_provider (from `.symlinks/plugins/path_provider/ios`) 24 | - path_provider_linux (from `.symlinks/plugins/path_provider_linux/ios`) 25 | - path_provider_macos (from `.symlinks/plugins/path_provider_macos/ios`) 26 | - path_provider_windows (from `.symlinks/plugins/path_provider_windows/ios`) 27 | - sqflite (from `.symlinks/plugins/sqflite/ios`) 28 | 29 | SPEC REPOS: 30 | trunk: 31 | - FMDB 32 | 33 | EXTERNAL SOURCES: 34 | Flutter: 35 | :path: Flutter 36 | nineold: 37 | :path: ".symlinks/plugins/nineold/ios" 38 | path_provider: 39 | :path: ".symlinks/plugins/path_provider/ios" 40 | path_provider_linux: 41 | :path: ".symlinks/plugins/path_provider_linux/ios" 42 | path_provider_macos: 43 | :path: ".symlinks/plugins/path_provider_macos/ios" 44 | path_provider_windows: 45 | :path: ".symlinks/plugins/path_provider_windows/ios" 46 | sqflite: 47 | :path: ".symlinks/plugins/sqflite/ios" 48 | 49 | SPEC CHECKSUMS: 50 | Flutter: 0e3d915762c693b495b44d77113d4970485de6ec 51 | FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a 52 | nineold: d0d68a3226a2b819ab0c25617ec667fec71797dd 53 | path_provider: abfe2b5c733d04e238b0d8691db0cfd63a27a93c 54 | path_provider_linux: 4d630dc393e1f20364f3e3b4a2ff41d9674a84e4 55 | path_provider_macos: f760a3c5b04357c380e2fddb6f9db6f3015897e0 56 | path_provider_windows: a2b81600c677ac1959367280991971cb9a1edb3b 57 | sqflite: 6d358c025f5b867b29ed92fc697fd34924e11904 58 | 59 | PODFILE CHECKSUM: e45c292f618eeca3034958d33b444b6e1249b55f 60 | 61 | COCOAPODS: 1.9.3 62 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 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 | 7363FEAFFA6959826467ACCF /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 783417CDA9335901639D0F3C /* Pods_Runner.framework */; }; 13 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; 14 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 15 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 16 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; 17 | /* End PBXBuildFile section */ 18 | 19 | /* Begin PBXCopyFilesBuildPhase section */ 20 | 9705A1C41CF9048500538489 /* Embed Frameworks */ = { 21 | isa = PBXCopyFilesBuildPhase; 22 | buildActionMask = 2147483647; 23 | dstPath = ""; 24 | dstSubfolderSpec = 10; 25 | files = ( 26 | ); 27 | name = "Embed Frameworks"; 28 | runOnlyForDeploymentPostprocessing = 0; 29 | }; 30 | /* End PBXCopyFilesBuildPhase section */ 31 | 32 | /* Begin PBXFileReference section */ 33 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 34 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; 35 | 2FAB25410E0F3AEC11151FF2 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; 36 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; 37 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; 38 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 39 | 7558264E26BB3FE01C2565F2 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; 40 | 75D15EC48BA7FE517EA80EBB /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; 41 | 783417CDA9335901639D0F3C /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 42 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; 43 | 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 44 | 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; 45 | 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; 46 | 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 47 | 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 48 | 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 49 | 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 50 | /* End PBXFileReference section */ 51 | 52 | /* Begin PBXFrameworksBuildPhase section */ 53 | 97C146EB1CF9000F007C117D /* Frameworks */ = { 54 | isa = PBXFrameworksBuildPhase; 55 | buildActionMask = 2147483647; 56 | files = ( 57 | 7363FEAFFA6959826467ACCF /* Pods_Runner.framework in Frameworks */, 58 | ); 59 | runOnlyForDeploymentPostprocessing = 0; 60 | }; 61 | /* End PBXFrameworksBuildPhase section */ 62 | 63 | /* Begin PBXGroup section */ 64 | 267E820CCB9E3C74E405D295 /* Pods */ = { 65 | isa = PBXGroup; 66 | children = ( 67 | 7558264E26BB3FE01C2565F2 /* Pods-Runner.debug.xcconfig */, 68 | 2FAB25410E0F3AEC11151FF2 /* Pods-Runner.release.xcconfig */, 69 | 75D15EC48BA7FE517EA80EBB /* Pods-Runner.profile.xcconfig */, 70 | ); 71 | name = Pods; 72 | path = Pods; 73 | sourceTree = ""; 74 | }; 75 | 8C1F42028079F85AE1F9A984 /* Frameworks */ = { 76 | isa = PBXGroup; 77 | children = ( 78 | 783417CDA9335901639D0F3C /* Pods_Runner.framework */, 79 | ); 80 | name = Frameworks; 81 | sourceTree = ""; 82 | }; 83 | 9740EEB11CF90186004384FC /* Flutter */ = { 84 | isa = PBXGroup; 85 | children = ( 86 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, 87 | 9740EEB21CF90195004384FC /* Debug.xcconfig */, 88 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, 89 | 9740EEB31CF90195004384FC /* Generated.xcconfig */, 90 | ); 91 | name = Flutter; 92 | sourceTree = ""; 93 | }; 94 | 97C146E51CF9000F007C117D = { 95 | isa = PBXGroup; 96 | children = ( 97 | 9740EEB11CF90186004384FC /* Flutter */, 98 | 97C146F01CF9000F007C117D /* Runner */, 99 | 97C146EF1CF9000F007C117D /* Products */, 100 | 267E820CCB9E3C74E405D295 /* Pods */, 101 | 8C1F42028079F85AE1F9A984 /* Frameworks */, 102 | ); 103 | sourceTree = ""; 104 | }; 105 | 97C146EF1CF9000F007C117D /* Products */ = { 106 | isa = PBXGroup; 107 | children = ( 108 | 97C146EE1CF9000F007C117D /* Runner.app */, 109 | ); 110 | name = Products; 111 | sourceTree = ""; 112 | }; 113 | 97C146F01CF9000F007C117D /* Runner */ = { 114 | isa = PBXGroup; 115 | children = ( 116 | 97C146FA1CF9000F007C117D /* Main.storyboard */, 117 | 97C146FD1CF9000F007C117D /* Assets.xcassets */, 118 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, 119 | 97C147021CF9000F007C117D /* Info.plist */, 120 | 97C146F11CF9000F007C117D /* Supporting Files */, 121 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, 122 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, 123 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, 124 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, 125 | ); 126 | path = Runner; 127 | sourceTree = ""; 128 | }; 129 | 97C146F11CF9000F007C117D /* Supporting Files */ = { 130 | isa = PBXGroup; 131 | children = ( 132 | ); 133 | name = "Supporting Files"; 134 | sourceTree = ""; 135 | }; 136 | /* End PBXGroup section */ 137 | 138 | /* Begin PBXNativeTarget section */ 139 | 97C146ED1CF9000F007C117D /* Runner */ = { 140 | isa = PBXNativeTarget; 141 | buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; 142 | buildPhases = ( 143 | 09CF054EBA390752DE636146 /* [CP] Check Pods Manifest.lock */, 144 | 9740EEB61CF901F6004384FC /* Run Script */, 145 | 97C146EA1CF9000F007C117D /* Sources */, 146 | 97C146EB1CF9000F007C117D /* Frameworks */, 147 | 97C146EC1CF9000F007C117D /* Resources */, 148 | 9705A1C41CF9048500538489 /* Embed Frameworks */, 149 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */, 150 | A8D397ADE57B47B42CEA3D09 /* [CP] Embed Pods Frameworks */, 151 | ); 152 | buildRules = ( 153 | ); 154 | dependencies = ( 155 | ); 156 | name = Runner; 157 | productName = Runner; 158 | productReference = 97C146EE1CF9000F007C117D /* Runner.app */; 159 | productType = "com.apple.product-type.application"; 160 | }; 161 | /* End PBXNativeTarget section */ 162 | 163 | /* Begin PBXProject section */ 164 | 97C146E61CF9000F007C117D /* Project object */ = { 165 | isa = PBXProject; 166 | attributes = { 167 | LastUpgradeCheck = 1020; 168 | ORGANIZATIONNAME = "The Chromium Authors"; 169 | TargetAttributes = { 170 | 97C146ED1CF9000F007C117D = { 171 | CreatedOnToolsVersion = 7.3.1; 172 | DevelopmentTeam = 6YY9Q528HM; 173 | LastSwiftMigration = 1100; 174 | }; 175 | }; 176 | }; 177 | buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; 178 | compatibilityVersion = "Xcode 3.2"; 179 | developmentRegion = en; 180 | hasScannedForEncodings = 0; 181 | knownRegions = ( 182 | en, 183 | Base, 184 | ); 185 | mainGroup = 97C146E51CF9000F007C117D; 186 | productRefGroup = 97C146EF1CF9000F007C117D /* Products */; 187 | projectDirPath = ""; 188 | projectRoot = ""; 189 | targets = ( 190 | 97C146ED1CF9000F007C117D /* Runner */, 191 | ); 192 | }; 193 | /* End PBXProject section */ 194 | 195 | /* Begin PBXResourcesBuildPhase section */ 196 | 97C146EC1CF9000F007C117D /* Resources */ = { 197 | isa = PBXResourcesBuildPhase; 198 | buildActionMask = 2147483647; 199 | files = ( 200 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, 201 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, 202 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, 203 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, 204 | ); 205 | runOnlyForDeploymentPostprocessing = 0; 206 | }; 207 | /* End PBXResourcesBuildPhase section */ 208 | 209 | /* Begin PBXShellScriptBuildPhase section */ 210 | 09CF054EBA390752DE636146 /* [CP] Check Pods Manifest.lock */ = { 211 | isa = PBXShellScriptBuildPhase; 212 | buildActionMask = 2147483647; 213 | files = ( 214 | ); 215 | inputFileListPaths = ( 216 | ); 217 | inputPaths = ( 218 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 219 | "${PODS_ROOT}/Manifest.lock", 220 | ); 221 | name = "[CP] Check Pods Manifest.lock"; 222 | outputFileListPaths = ( 223 | ); 224 | outputPaths = ( 225 | "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", 226 | ); 227 | runOnlyForDeploymentPostprocessing = 0; 228 | shellPath = /bin/sh; 229 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 230 | showEnvVarsInLog = 0; 231 | }; 232 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { 233 | isa = PBXShellScriptBuildPhase; 234 | buildActionMask = 2147483647; 235 | files = ( 236 | ); 237 | inputPaths = ( 238 | ); 239 | name = "Thin Binary"; 240 | outputPaths = ( 241 | ); 242 | runOnlyForDeploymentPostprocessing = 0; 243 | shellPath = /bin/sh; 244 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; 245 | }; 246 | 9740EEB61CF901F6004384FC /* Run Script */ = { 247 | isa = PBXShellScriptBuildPhase; 248 | buildActionMask = 2147483647; 249 | files = ( 250 | ); 251 | inputPaths = ( 252 | ); 253 | name = "Run Script"; 254 | outputPaths = ( 255 | ); 256 | runOnlyForDeploymentPostprocessing = 0; 257 | shellPath = /bin/sh; 258 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; 259 | }; 260 | A8D397ADE57B47B42CEA3D09 /* [CP] Embed Pods Frameworks */ = { 261 | isa = PBXShellScriptBuildPhase; 262 | buildActionMask = 2147483647; 263 | files = ( 264 | ); 265 | inputPaths = ( 266 | ); 267 | name = "[CP] Embed Pods Frameworks"; 268 | outputPaths = ( 269 | ); 270 | runOnlyForDeploymentPostprocessing = 0; 271 | shellPath = /bin/sh; 272 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; 273 | showEnvVarsInLog = 0; 274 | }; 275 | /* End PBXShellScriptBuildPhase section */ 276 | 277 | /* Begin PBXSourcesBuildPhase section */ 278 | 97C146EA1CF9000F007C117D /* Sources */ = { 279 | isa = PBXSourcesBuildPhase; 280 | buildActionMask = 2147483647; 281 | files = ( 282 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, 283 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, 284 | ); 285 | runOnlyForDeploymentPostprocessing = 0; 286 | }; 287 | /* End PBXSourcesBuildPhase section */ 288 | 289 | /* Begin PBXVariantGroup section */ 290 | 97C146FA1CF9000F007C117D /* Main.storyboard */ = { 291 | isa = PBXVariantGroup; 292 | children = ( 293 | 97C146FB1CF9000F007C117D /* Base */, 294 | ); 295 | name = Main.storyboard; 296 | sourceTree = ""; 297 | }; 298 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { 299 | isa = PBXVariantGroup; 300 | children = ( 301 | 97C147001CF9000F007C117D /* Base */, 302 | ); 303 | name = LaunchScreen.storyboard; 304 | sourceTree = ""; 305 | }; 306 | /* End PBXVariantGroup section */ 307 | 308 | /* Begin XCBuildConfiguration section */ 309 | 249021D3217E4FDB00AE95B9 /* Profile */ = { 310 | isa = XCBuildConfiguration; 311 | buildSettings = { 312 | ALWAYS_SEARCH_USER_PATHS = NO; 313 | CLANG_ANALYZER_NONNULL = YES; 314 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 315 | CLANG_CXX_LIBRARY = "libc++"; 316 | CLANG_ENABLE_MODULES = YES; 317 | CLANG_ENABLE_OBJC_ARC = YES; 318 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 319 | CLANG_WARN_BOOL_CONVERSION = YES; 320 | CLANG_WARN_COMMA = YES; 321 | CLANG_WARN_CONSTANT_CONVERSION = YES; 322 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 323 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 324 | CLANG_WARN_EMPTY_BODY = YES; 325 | CLANG_WARN_ENUM_CONVERSION = YES; 326 | CLANG_WARN_INFINITE_RECURSION = YES; 327 | CLANG_WARN_INT_CONVERSION = YES; 328 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 329 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 330 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 331 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 332 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 333 | CLANG_WARN_STRICT_PROTOTYPES = YES; 334 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 335 | CLANG_WARN_UNREACHABLE_CODE = YES; 336 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 337 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 338 | COPY_PHASE_STRIP = NO; 339 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 340 | ENABLE_NS_ASSERTIONS = NO; 341 | ENABLE_STRICT_OBJC_MSGSEND = YES; 342 | GCC_C_LANGUAGE_STANDARD = gnu99; 343 | GCC_NO_COMMON_BLOCKS = YES; 344 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 345 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 346 | GCC_WARN_UNDECLARED_SELECTOR = YES; 347 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 348 | GCC_WARN_UNUSED_FUNCTION = YES; 349 | GCC_WARN_UNUSED_VARIABLE = YES; 350 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 351 | MTL_ENABLE_DEBUG_INFO = NO; 352 | SDKROOT = iphoneos; 353 | SUPPORTED_PLATFORMS = iphoneos; 354 | TARGETED_DEVICE_FAMILY = "1,2"; 355 | VALIDATE_PRODUCT = YES; 356 | }; 357 | name = Profile; 358 | }; 359 | 249021D4217E4FDB00AE95B9 /* Profile */ = { 360 | isa = XCBuildConfiguration; 361 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 362 | buildSettings = { 363 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 364 | CLANG_ENABLE_MODULES = YES; 365 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 366 | DEVELOPMENT_TEAM = 6YY9Q528HM; 367 | ENABLE_BITCODE = NO; 368 | FRAMEWORK_SEARCH_PATHS = ( 369 | "$(inherited)", 370 | "$(PROJECT_DIR)/Flutter", 371 | ); 372 | INFOPLIST_FILE = Runner/Info.plist; 373 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 374 | LIBRARY_SEARCH_PATHS = ( 375 | "$(inherited)", 376 | "$(PROJECT_DIR)/Flutter", 377 | ); 378 | PRODUCT_BUNDLE_IDENTIFIER = com.josh.nineoldExample; 379 | PRODUCT_NAME = "$(TARGET_NAME)"; 380 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 381 | SWIFT_VERSION = 5.0; 382 | VERSIONING_SYSTEM = "apple-generic"; 383 | }; 384 | name = Profile; 385 | }; 386 | 97C147031CF9000F007C117D /* Debug */ = { 387 | isa = XCBuildConfiguration; 388 | buildSettings = { 389 | ALWAYS_SEARCH_USER_PATHS = NO; 390 | CLANG_ANALYZER_NONNULL = YES; 391 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 392 | CLANG_CXX_LIBRARY = "libc++"; 393 | CLANG_ENABLE_MODULES = YES; 394 | CLANG_ENABLE_OBJC_ARC = YES; 395 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 396 | CLANG_WARN_BOOL_CONVERSION = YES; 397 | CLANG_WARN_COMMA = YES; 398 | CLANG_WARN_CONSTANT_CONVERSION = YES; 399 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 400 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 401 | CLANG_WARN_EMPTY_BODY = YES; 402 | CLANG_WARN_ENUM_CONVERSION = YES; 403 | CLANG_WARN_INFINITE_RECURSION = YES; 404 | CLANG_WARN_INT_CONVERSION = YES; 405 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 406 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 407 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 408 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 409 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 410 | CLANG_WARN_STRICT_PROTOTYPES = YES; 411 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 412 | CLANG_WARN_UNREACHABLE_CODE = YES; 413 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 414 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 415 | COPY_PHASE_STRIP = NO; 416 | DEBUG_INFORMATION_FORMAT = dwarf; 417 | ENABLE_STRICT_OBJC_MSGSEND = YES; 418 | ENABLE_TESTABILITY = YES; 419 | GCC_C_LANGUAGE_STANDARD = gnu99; 420 | GCC_DYNAMIC_NO_PIC = NO; 421 | GCC_NO_COMMON_BLOCKS = YES; 422 | GCC_OPTIMIZATION_LEVEL = 0; 423 | GCC_PREPROCESSOR_DEFINITIONS = ( 424 | "DEBUG=1", 425 | "$(inherited)", 426 | ); 427 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 428 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 429 | GCC_WARN_UNDECLARED_SELECTOR = YES; 430 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 431 | GCC_WARN_UNUSED_FUNCTION = YES; 432 | GCC_WARN_UNUSED_VARIABLE = YES; 433 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 434 | MTL_ENABLE_DEBUG_INFO = YES; 435 | ONLY_ACTIVE_ARCH = YES; 436 | SDKROOT = iphoneos; 437 | TARGETED_DEVICE_FAMILY = "1,2"; 438 | }; 439 | name = Debug; 440 | }; 441 | 97C147041CF9000F007C117D /* Release */ = { 442 | isa = XCBuildConfiguration; 443 | buildSettings = { 444 | ALWAYS_SEARCH_USER_PATHS = NO; 445 | CLANG_ANALYZER_NONNULL = YES; 446 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 447 | CLANG_CXX_LIBRARY = "libc++"; 448 | CLANG_ENABLE_MODULES = YES; 449 | CLANG_ENABLE_OBJC_ARC = YES; 450 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 451 | CLANG_WARN_BOOL_CONVERSION = YES; 452 | CLANG_WARN_COMMA = YES; 453 | CLANG_WARN_CONSTANT_CONVERSION = YES; 454 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 455 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 456 | CLANG_WARN_EMPTY_BODY = YES; 457 | CLANG_WARN_ENUM_CONVERSION = YES; 458 | CLANG_WARN_INFINITE_RECURSION = YES; 459 | CLANG_WARN_INT_CONVERSION = YES; 460 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 461 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 462 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 463 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 464 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 465 | CLANG_WARN_STRICT_PROTOTYPES = YES; 466 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 467 | CLANG_WARN_UNREACHABLE_CODE = YES; 468 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 469 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 470 | COPY_PHASE_STRIP = NO; 471 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 472 | ENABLE_NS_ASSERTIONS = NO; 473 | ENABLE_STRICT_OBJC_MSGSEND = YES; 474 | GCC_C_LANGUAGE_STANDARD = gnu99; 475 | GCC_NO_COMMON_BLOCKS = YES; 476 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 477 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 478 | GCC_WARN_UNDECLARED_SELECTOR = YES; 479 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 480 | GCC_WARN_UNUSED_FUNCTION = YES; 481 | GCC_WARN_UNUSED_VARIABLE = YES; 482 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 483 | MTL_ENABLE_DEBUG_INFO = NO; 484 | SDKROOT = iphoneos; 485 | SUPPORTED_PLATFORMS = iphoneos; 486 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 487 | TARGETED_DEVICE_FAMILY = "1,2"; 488 | VALIDATE_PRODUCT = YES; 489 | }; 490 | name = Release; 491 | }; 492 | 97C147061CF9000F007C117D /* Debug */ = { 493 | isa = XCBuildConfiguration; 494 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; 495 | buildSettings = { 496 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 497 | CLANG_ENABLE_MODULES = YES; 498 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 499 | DEVELOPMENT_TEAM = 6YY9Q528HM; 500 | ENABLE_BITCODE = NO; 501 | FRAMEWORK_SEARCH_PATHS = ( 502 | "$(inherited)", 503 | "$(PROJECT_DIR)/Flutter", 504 | ); 505 | INFOPLIST_FILE = Runner/Info.plist; 506 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 507 | LIBRARY_SEARCH_PATHS = ( 508 | "$(inherited)", 509 | "$(PROJECT_DIR)/Flutter", 510 | ); 511 | PRODUCT_BUNDLE_IDENTIFIER = com.josh.nineoldExample; 512 | PRODUCT_NAME = "$(TARGET_NAME)"; 513 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 514 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 515 | SWIFT_VERSION = 5.0; 516 | VERSIONING_SYSTEM = "apple-generic"; 517 | }; 518 | name = Debug; 519 | }; 520 | 97C147071CF9000F007C117D /* Release */ = { 521 | isa = XCBuildConfiguration; 522 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 523 | buildSettings = { 524 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 525 | CLANG_ENABLE_MODULES = YES; 526 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 527 | DEVELOPMENT_TEAM = 6YY9Q528HM; 528 | ENABLE_BITCODE = NO; 529 | FRAMEWORK_SEARCH_PATHS = ( 530 | "$(inherited)", 531 | "$(PROJECT_DIR)/Flutter", 532 | ); 533 | INFOPLIST_FILE = Runner/Info.plist; 534 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 535 | LIBRARY_SEARCH_PATHS = ( 536 | "$(inherited)", 537 | "$(PROJECT_DIR)/Flutter", 538 | ); 539 | PRODUCT_BUNDLE_IDENTIFIER = com.josh.nineoldExample; 540 | PRODUCT_NAME = "$(TARGET_NAME)"; 541 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 542 | SWIFT_VERSION = 5.0; 543 | VERSIONING_SYSTEM = "apple-generic"; 544 | }; 545 | name = Release; 546 | }; 547 | /* End XCBuildConfiguration section */ 548 | 549 | /* Begin XCConfigurationList section */ 550 | 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { 551 | isa = XCConfigurationList; 552 | buildConfigurations = ( 553 | 97C147031CF9000F007C117D /* Debug */, 554 | 97C147041CF9000F007C117D /* Release */, 555 | 249021D3217E4FDB00AE95B9 /* Profile */, 556 | ); 557 | defaultConfigurationIsVisible = 0; 558 | defaultConfigurationName = Release; 559 | }; 560 | 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { 561 | isa = XCConfigurationList; 562 | buildConfigurations = ( 563 | 97C147061CF9000F007C117D /* Debug */, 564 | 97C147071CF9000F007C117D /* Release */, 565 | 249021D4217E4FDB00AE95B9 /* Profile */, 566 | ); 567 | defaultConfigurationIsVisible = 0; 568 | defaultConfigurationName = Release; 569 | }; 570 | /* End XCConfigurationList section */ 571 | }; 572 | rootObject = 97C146E61CF9000F007C117D /* Project object */; 573 | } 574 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import Flutter 3 | 4 | @UIApplicationMain 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/lanzhu1993/flutter_nineold/4100f6cbb776803a668ee31f7417579721a5321c/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/lanzhu1993/flutter_nineold/4100f6cbb776803a668ee31f7417579721a5321c/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/lanzhu1993/flutter_nineold/4100f6cbb776803a668ee31f7417579721a5321c/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/lanzhu1993/flutter_nineold/4100f6cbb776803a668ee31f7417579721a5321c/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/lanzhu1993/flutter_nineold/4100f6cbb776803a668ee31f7417579721a5321c/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/lanzhu1993/flutter_nineold/4100f6cbb776803a668ee31f7417579721a5321c/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/lanzhu1993/flutter_nineold/4100f6cbb776803a668ee31f7417579721a5321c/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/lanzhu1993/flutter_nineold/4100f6cbb776803a668ee31f7417579721a5321c/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/lanzhu1993/flutter_nineold/4100f6cbb776803a668ee31f7417579721a5321c/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/lanzhu1993/flutter_nineold/4100f6cbb776803a668ee31f7417579721a5321c/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/lanzhu1993/flutter_nineold/4100f6cbb776803a668ee31f7417579721a5321c/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/lanzhu1993/flutter_nineold/4100f6cbb776803a668ee31f7417579721a5321c/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/lanzhu1993/flutter_nineold/4100f6cbb776803a668ee31f7417579721a5321c/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/lanzhu1993/flutter_nineold/4100f6cbb776803a668ee31f7417579721a5321c/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/lanzhu1993/flutter_nineold/4100f6cbb776803a668ee31f7417579721a5321c/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/lanzhu1993/flutter_nineold/4100f6cbb776803a668ee31f7417579721a5321c/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lanzhu1993/flutter_nineold/4100f6cbb776803a668ee31f7417579721a5321c/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lanzhu1993/flutter_nineold/4100f6cbb776803a668ee31f7417579721a5321c/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 | nineold_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 | 45 | 46 | -------------------------------------------------------------------------------- /example/ios/Runner/Runner-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #import "GeneratedPluginRegistrant.h" -------------------------------------------------------------------------------- /example/lib/generated/intl/messages_all.dart: -------------------------------------------------------------------------------- 1 | // DO NOT EDIT. This is code generated via package:intl/generate_localized.dart 2 | // This is a library that looks up messages for specific locales by 3 | // delegating to the appropriate library. 4 | 5 | // Ignore issues from commonly used lints in this file. 6 | // ignore_for_file:implementation_imports, file_names, unnecessary_new 7 | // ignore_for_file:unnecessary_brace_in_string_interps, directives_ordering 8 | // ignore_for_file:argument_type_not_assignable, invalid_assignment 9 | // ignore_for_file:prefer_single_quotes, prefer_generic_function_type_aliases 10 | // ignore_for_file:comment_references 11 | 12 | import 'dart:async'; 13 | 14 | import 'package:intl/intl.dart'; 15 | import 'package:intl/message_lookup_by_library.dart'; 16 | import 'package:intl/src/intl_helpers.dart'; 17 | 18 | import 'messages_en.dart' as messages_en; 19 | import 'messages_zh.dart' as messages_zh; 20 | 21 | typedef Future LibraryLoader(); 22 | Map _deferredLibraries = { 23 | 'en': () => new Future.value(null), 24 | 'zh': () => new Future.value(null), 25 | }; 26 | 27 | MessageLookupByLibrary _findExact(String localeName) { 28 | switch (localeName) { 29 | case 'en': 30 | return messages_en.messages; 31 | case 'zh': 32 | return messages_zh.messages; 33 | default: 34 | return null; 35 | } 36 | } 37 | 38 | /// User programs should call this before using [localeName] for messages. 39 | Future initializeMessages(String localeName) async { 40 | var availableLocale = Intl.verifiedLocale( 41 | localeName, 42 | (locale) => _deferredLibraries[locale] != null, 43 | onFailure: (_) => null); 44 | if (availableLocale == null) { 45 | return new Future.value(false); 46 | } 47 | var lib = _deferredLibraries[availableLocale]; 48 | await (lib == null ? new Future.value(false) : lib()); 49 | initializeInternalMessageLookup(() => new CompositeMessageLookup()); 50 | messageLookup.addLocale(availableLocale, _findGeneratedMessagesFor); 51 | return new Future.value(true); 52 | } 53 | 54 | bool _messagesExistFor(String locale) { 55 | try { 56 | return _findExact(locale) != null; 57 | } catch (e) { 58 | return false; 59 | } 60 | } 61 | 62 | MessageLookupByLibrary _findGeneratedMessagesFor(String locale) { 63 | var actualLocale = Intl.verifiedLocale(locale, _messagesExistFor, 64 | onFailure: (_) => null); 65 | if (actualLocale == null) return null; 66 | return _findExact(actualLocale); 67 | } 68 | -------------------------------------------------------------------------------- /example/lib/generated/intl/messages_en.dart: -------------------------------------------------------------------------------- 1 | // DO NOT EDIT. This is code generated via package:intl/generate_localized.dart 2 | // This is a library that provides messages for a en locale. All the 3 | // messages from the main program should be duplicated here with the same 4 | // function name. 5 | 6 | // Ignore issues from commonly used lints in this file. 7 | // ignore_for_file:unnecessary_brace_in_string_interps, unnecessary_new 8 | // ignore_for_file:prefer_single_quotes,comment_references, directives_ordering 9 | // ignore_for_file:annotate_overrides,prefer_generic_function_type_aliases 10 | // ignore_for_file:unused_import, file_names 11 | 12 | import 'package:intl/intl.dart'; 13 | import 'package:intl/message_lookup_by_library.dart'; 14 | 15 | final messages = new MessageLookup(); 16 | 17 | typedef String MessageIfAbsent(String messageStr, List args); 18 | 19 | class MessageLookup extends MessageLookupByLibrary { 20 | String get localeName => 'en'; 21 | 22 | final messages = _notInlinedMessages(_notInlinedMessages); 23 | static _notInlinedMessages(_) => { 24 | "title" : MessageLookupByLibrary.simpleMessage("Flutter Nine Old"), 25 | "unit_item" : MessageLookupByLibrary.simpleMessage("item"), 26 | "unit_the" : MessageLookupByLibrary.simpleMessage("the") 27 | }; 28 | } 29 | -------------------------------------------------------------------------------- /example/lib/generated/intl/messages_zh.dart: -------------------------------------------------------------------------------- 1 | // DO NOT EDIT. This is code generated via package:intl/generate_localized.dart 2 | // This is a library that provides messages for a zh locale. All the 3 | // messages from the main program should be duplicated here with the same 4 | // function name. 5 | 6 | // Ignore issues from commonly used lints in this file. 7 | // ignore_for_file:unnecessary_brace_in_string_interps, unnecessary_new 8 | // ignore_for_file:prefer_single_quotes,comment_references, directives_ordering 9 | // ignore_for_file:annotate_overrides,prefer_generic_function_type_aliases 10 | // ignore_for_file:unused_import, file_names 11 | 12 | import 'package:intl/intl.dart'; 13 | import 'package:intl/message_lookup_by_library.dart'; 14 | 15 | final messages = new MessageLookup(); 16 | 17 | typedef String MessageIfAbsent(String messageStr, List args); 18 | 19 | class MessageLookup extends MessageLookupByLibrary { 20 | String get localeName => 'zh'; 21 | 22 | final messages = _notInlinedMessages(_notInlinedMessages); 23 | static _notInlinedMessages(_) => { 24 | "title" : MessageLookupByLibrary.simpleMessage("Flutter 九宫格"), 25 | "unit_item" : MessageLookupByLibrary.simpleMessage("条"), 26 | "unit_the" : MessageLookupByLibrary.simpleMessage("第") 27 | }; 28 | } 29 | -------------------------------------------------------------------------------- /example/lib/generated/l10n.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | import 'package:flutter/material.dart'; 3 | import 'package:intl/intl.dart'; 4 | import 'intl/messages_all.dart'; 5 | 6 | // ************************************************************************** 7 | // Generator: Flutter Intl IDE plugin 8 | // Made by Localizely 9 | // ************************************************************************** 10 | 11 | // ignore_for_file: non_constant_identifier_names, lines_longer_than_80_chars 12 | // ignore_for_file: join_return_with_assignment, prefer_final_in_for_each 13 | // ignore_for_file: avoid_redundant_argument_values 14 | 15 | class S { 16 | S(); 17 | 18 | static S current; 19 | 20 | static const AppLocalizationDelegate delegate = 21 | AppLocalizationDelegate(); 22 | 23 | static Future load(Locale locale) { 24 | final name = (locale.countryCode?.isEmpty ?? false) ? locale.languageCode : locale.toString(); 25 | final localeName = Intl.canonicalizedLocale(name); 26 | return initializeMessages(localeName).then((_) { 27 | Intl.defaultLocale = localeName; 28 | S.current = S(); 29 | 30 | return S.current; 31 | }); 32 | } 33 | 34 | static S of(BuildContext context) { 35 | return Localizations.of(context, S); 36 | } 37 | 38 | /// `Flutter Nine Old` 39 | String get title { 40 | return Intl.message( 41 | 'Flutter Nine Old', 42 | name: 'title', 43 | desc: '', 44 | args: [], 45 | ); 46 | } 47 | 48 | /// `the` 49 | String get unit_the { 50 | return Intl.message( 51 | 'the', 52 | name: 'unit_the', 53 | desc: '', 54 | args: [], 55 | ); 56 | } 57 | 58 | /// `item` 59 | String get unit_item { 60 | return Intl.message( 61 | 'item', 62 | name: 'unit_item', 63 | desc: '', 64 | args: [], 65 | ); 66 | } 67 | } 68 | 69 | class AppLocalizationDelegate extends LocalizationsDelegate { 70 | const AppLocalizationDelegate(); 71 | 72 | List get supportedLocales { 73 | return const [ 74 | Locale.fromSubtags(languageCode: 'en'), 75 | Locale.fromSubtags(languageCode: 'zh'), 76 | ]; 77 | } 78 | 79 | @override 80 | bool isSupported(Locale locale) => _isSupported(locale); 81 | @override 82 | Future load(Locale locale) => S.load(locale); 83 | @override 84 | bool shouldReload(AppLocalizationDelegate old) => false; 85 | 86 | bool _isSupported(Locale locale) { 87 | if (locale != null) { 88 | for (var supportedLocale in supportedLocales) { 89 | if (supportedLocale.languageCode == locale.languageCode) { 90 | return true; 91 | } 92 | } 93 | } 94 | return false; 95 | } 96 | } -------------------------------------------------------------------------------- /example/lib/l10n/intl_en.arb: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Flutter Nine Old", 3 | "unit_the": "the", 4 | "unit_item": "item" 5 | } -------------------------------------------------------------------------------- /example/lib/l10n/intl_zh.arb: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Flutter 九宫格", 3 | "unit_the": "第", 4 | "unit_item": "条" 5 | } -------------------------------------------------------------------------------- /example/lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_localizations/flutter_localizations.dart'; 3 | import 'package:nineold/widget/nine_old_widget.dart'; 4 | 5 | import 'generated/l10n.dart'; 6 | 7 | void main() => runApp(MyApp()); 8 | 9 | class MyApp extends StatelessWidget { 10 | @override 11 | Widget build(BuildContext context) { 12 | return MaterialApp( 13 | title: "国际化", 14 | theme: ThemeData( 15 | primarySwatch: Colors.blue, 16 | ), 17 | home: MyHomePage(), 18 | localizationsDelegates: [ 19 | GlobalMaterialLocalizations.delegate, 20 | GlobalWidgetsLocalizations.delegate, 21 | GlobalCupertinoLocalizations.delegate, 22 | S.delegate 23 | ], 24 | supportedLocales: S.delegate.supportedLocales, 25 | ); 26 | } 27 | } 28 | 29 | class MyHomePage extends StatefulWidget { 30 | @override 31 | _MyHomePageState createState() => _MyHomePageState(); 32 | } 33 | 34 | class _MyHomePageState extends State { 35 | List> images = []; 36 | 37 | @override 38 | void initState() { 39 | super.initState(); 40 | images.add(getData()); 41 | } 42 | 43 | @override 44 | Widget build(BuildContext context) { 45 | return Scaffold( 46 | appBar: AppBar( 47 | title: Text(S.of(context).title), 48 | ), 49 | body: ListView.separated( 50 | itemBuilder: (context, index) { 51 | return _buildActiveItem(index, getData().sublist(0, index)); 52 | }, 53 | itemCount: 13, 54 | separatorBuilder: (BuildContext context, int index) => 55 | Divider(height: 1.0, color: Colors.lightBlueAccent), 56 | ), 57 | floatingActionButton: FloatingActionButton( 58 | child: Icon(Icons.add), 59 | onPressed: () { 60 | setState(() { 61 | // count++; 62 | // images.add(getData().sublist(0, count % 15)); 63 | }); 64 | }, 65 | ), 66 | ); 67 | } 68 | 69 | Widget _buildActiveItem(int index, List photos) { 70 | return Container( 71 | margin: EdgeInsets.all(10), 72 | child: Column( 73 | mainAxisAlignment: MainAxisAlignment.center, 74 | crossAxisAlignment: CrossAxisAlignment.center, 75 | children: [ 76 | _buildActiveItemHeader(index), 77 | null != photos || photos.isNotEmpty 78 | ? NineOldWidget( 79 | images: photos, 80 | //必填 81 | onLongPressListener: (position) { 82 | //可选 83 | //长按事件回调 84 | print("长按事件回调当前位置 : $position"); 85 | }, 86 | backgroundColor: Colors.white, 87 | //可选 88 | //加载背景颜色 89 | valueColor: Colors.red, 90 | //可选 91 | //加载进度条颜色 92 | strokeWidth: 4, 93 | //可选 94 | //加载进度条宽度 95 | moreStyle: 96 | TextStyle(fontSize: 28, color: Colors.orange), //更多加号样式 97 | //可选 98 | //资源加载失败显示 99 | errorWidget: Icon(Icons.error_outline_rounded), 100 | ) 101 | : SizedBox() 102 | ], 103 | ), 104 | ); 105 | } 106 | 107 | Widget _buildActiveItemHeader(int index) { 108 | return Container( 109 | child: Column( 110 | children: [ 111 | Row( 112 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 113 | crossAxisAlignment: CrossAxisAlignment.center, 114 | children: [ 115 | ClipOval( 116 | child: Image.network( 117 | "http://t7.baidu.com/it/u=3616242789,1098670747&fm=79&app=86&f=JPEG?w=900&h=1350", 118 | width: 30.0, 119 | height: 30.0, 120 | ), 121 | ), 122 | ], 123 | ), 124 | Text("${S.of(context).unit_the}$index${S.of(context).unit_item}") 125 | ], 126 | ), 127 | ); 128 | } 129 | 130 | List getData() { 131 | List list = []; 132 | list.add( 133 | "http://t7.baidu.com/it/u=3616242789,1098670747&fm=79&app=86&f=JPEG?w=900&h=1350"); 134 | list.add( 135 | "http://t7.baidu.com/it/u=3616242789,1098670747&fm=79&app=86&f=JPEG?w=900&h=1350"); 136 | list.add( 137 | "http://t7.baidu.com/it/u=3616242789,1098670747&fm=79&app=86&f=JPEG?w=900&h=1350"); 138 | list.add( 139 | "https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=3687862105,320198720&fm=26&gp=0.jpg"); 140 | list.add( 141 | "https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=339659526,3524437886&fm=26&gp=0.jpg"); 142 | list.add( 143 | "https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=1492148550,3573121792&fm=11&gp=0.jpg"); 144 | list.add( 145 | "https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=3059211665,2147448542&fm=26&gp=0.jpg"); 146 | list.add( 147 | "https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=2333676140,2717071870&fm=11&gp=0.jpg"); 148 | list.add( 149 | "https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=2417108265,1198830140&fm=26&gp=0.jpg"); 150 | list.add( 151 | "https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=244450851,2728981198&fm=26&gp=0.jpg"); 152 | list.add( 153 | "https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=2083759825,3454063564&fm=26&gp=0.jpg"); 154 | list.add( 155 | "https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=310077658,2097249993&fm=11&gp=0.jpg"); 156 | list.add( 157 | "https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=415170272,1239551712&fm=26&gp=0.jpg"); 158 | list.add( 159 | "https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=1030558027,1672821388&fm=26&gp=0.jpg"); 160 | list.add( 161 | "https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=3153722339,140981551&fm=26&gp=0.jpg"); 162 | list.add( 163 | "https://t8.baidu.com/it/u=3571592872,3353494284&fm=79&app=86&size=h300&n=0&g=4n&f=jpeg?sec=1584605109&t=4c346851d3f4f4cf76439fe6440ffe9f"); 164 | list.add( 165 | "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1594817167403&di=87226dc3d6b70a7e02722b9f9bd9f33a&imgtype=0&src=http%3A%2F%2Ft9.baidu.com%2Fit%2Fu%3D1307125826%2C3433407105%26fm%3D79%26app%3D86%26f%3DJPEG%3Fw%3D5760%26h%3D3240"); 166 | return list; 167 | } 168 | } 169 | -------------------------------------------------------------------------------- /example/pubspec.lock: -------------------------------------------------------------------------------- 1 | # Generated by pub 2 | # See https://dart.dev/tools/pub/glossary#lockfile 3 | packages: 4 | async: 5 | dependency: transitive 6 | description: 7 | name: async 8 | url: "https://pub.flutter-io.cn" 9 | source: hosted 10 | version: "2.8.2" 11 | boolean_selector: 12 | dependency: transitive 13 | description: 14 | name: boolean_selector 15 | url: "https://pub.flutter-io.cn" 16 | source: hosted 17 | version: "2.1.0" 18 | cached_network_image: 19 | dependency: transitive 20 | description: 21 | name: cached_network_image 22 | url: "https://pub.flutter-io.cn" 23 | source: hosted 24 | version: "3.2.0" 25 | cached_network_image_platform_interface: 26 | dependency: transitive 27 | description: 28 | name: cached_network_image_platform_interface 29 | url: "https://pub.flutter-io.cn" 30 | source: hosted 31 | version: "1.0.0" 32 | cached_network_image_web: 33 | dependency: transitive 34 | description: 35 | name: cached_network_image_web 36 | url: "https://pub.flutter-io.cn" 37 | source: hosted 38 | version: "1.0.1" 39 | characters: 40 | dependency: transitive 41 | description: 42 | name: characters 43 | url: "https://pub.flutter-io.cn" 44 | source: hosted 45 | version: "1.2.0" 46 | charcode: 47 | dependency: transitive 48 | description: 49 | name: charcode 50 | url: "https://pub.flutter-io.cn" 51 | source: hosted 52 | version: "1.3.1" 53 | clock: 54 | dependency: transitive 55 | description: 56 | name: clock 57 | url: "https://pub.flutter-io.cn" 58 | source: hosted 59 | version: "1.1.0" 60 | collection: 61 | dependency: transitive 62 | description: 63 | name: collection 64 | url: "https://pub.flutter-io.cn" 65 | source: hosted 66 | version: "1.15.0" 67 | crypto: 68 | dependency: transitive 69 | description: 70 | name: crypto 71 | url: "https://pub.flutter-io.cn" 72 | source: hosted 73 | version: "3.0.0" 74 | cupertino_icons: 75 | dependency: "direct main" 76 | description: 77 | name: cupertino_icons 78 | url: "https://pub.flutter-io.cn" 79 | source: hosted 80 | version: "0.1.3" 81 | fake_async: 82 | dependency: transitive 83 | description: 84 | name: fake_async 85 | url: "https://pub.flutter-io.cn" 86 | source: hosted 87 | version: "1.2.0" 88 | ffi: 89 | dependency: transitive 90 | description: 91 | name: ffi 92 | url: "https://pub.flutter-io.cn" 93 | source: hosted 94 | version: "1.0.0" 95 | file: 96 | dependency: transitive 97 | description: 98 | name: file 99 | url: "https://pub.flutter-io.cn" 100 | source: hosted 101 | version: "6.1.0" 102 | flutter: 103 | dependency: "direct main" 104 | description: flutter 105 | source: sdk 106 | version: "0.0.0" 107 | flutter_blurhash: 108 | dependency: transitive 109 | description: 110 | name: flutter_blurhash 111 | url: "https://pub.flutter-io.cn" 112 | source: hosted 113 | version: "0.6.0" 114 | flutter_cache_manager: 115 | dependency: transitive 116 | description: 117 | name: flutter_cache_manager 118 | url: "https://pub.flutter-io.cn" 119 | source: hosted 120 | version: "3.3.0" 121 | flutter_localizations: 122 | dependency: "direct main" 123 | description: flutter 124 | source: sdk 125 | version: "0.0.0" 126 | flutter_test: 127 | dependency: "direct dev" 128 | description: flutter 129 | source: sdk 130 | version: "0.0.0" 131 | http: 132 | dependency: transitive 133 | description: 134 | name: http 135 | url: "https://pub.flutter-io.cn" 136 | source: hosted 137 | version: "0.13.1" 138 | http_parser: 139 | dependency: transitive 140 | description: 141 | name: http_parser 142 | url: "https://pub.flutter-io.cn" 143 | source: hosted 144 | version: "4.0.0" 145 | intl: 146 | dependency: transitive 147 | description: 148 | name: intl 149 | url: "https://pub.flutter-io.cn" 150 | source: hosted 151 | version: "0.17.0" 152 | matcher: 153 | dependency: transitive 154 | description: 155 | name: matcher 156 | url: "https://pub.flutter-io.cn" 157 | source: hosted 158 | version: "0.12.11" 159 | material_color_utilities: 160 | dependency: transitive 161 | description: 162 | name: material_color_utilities 163 | url: "https://pub.flutter-io.cn" 164 | source: hosted 165 | version: "0.1.3" 166 | meta: 167 | dependency: transitive 168 | description: 169 | name: meta 170 | url: "https://pub.flutter-io.cn" 171 | source: hosted 172 | version: "1.7.0" 173 | nineold: 174 | dependency: "direct dev" 175 | description: 176 | path: ".." 177 | relative: true 178 | source: path 179 | version: "3.2.2" 180 | octo_image: 181 | dependency: transitive 182 | description: 183 | name: octo_image 184 | url: "https://pub.flutter-io.cn" 185 | source: hosted 186 | version: "1.0.0+1" 187 | path: 188 | dependency: transitive 189 | description: 190 | name: path 191 | url: "https://pub.flutter-io.cn" 192 | source: hosted 193 | version: "1.8.0" 194 | path_provider: 195 | dependency: transitive 196 | description: 197 | name: path_provider 198 | url: "https://pub.flutter-io.cn" 199 | source: hosted 200 | version: "2.0.1" 201 | path_provider_linux: 202 | dependency: transitive 203 | description: 204 | name: path_provider_linux 205 | url: "https://pub.flutter-io.cn" 206 | source: hosted 207 | version: "2.0.0" 208 | path_provider_macos: 209 | dependency: transitive 210 | description: 211 | name: path_provider_macos 212 | url: "https://pub.flutter-io.cn" 213 | source: hosted 214 | version: "2.0.0" 215 | path_provider_platform_interface: 216 | dependency: transitive 217 | description: 218 | name: path_provider_platform_interface 219 | url: "https://pub.flutter-io.cn" 220 | source: hosted 221 | version: "2.0.1" 222 | path_provider_windows: 223 | dependency: transitive 224 | description: 225 | name: path_provider_windows 226 | url: "https://pub.flutter-io.cn" 227 | source: hosted 228 | version: "2.0.0" 229 | pedantic: 230 | dependency: transitive 231 | description: 232 | name: pedantic 233 | url: "https://pub.flutter-io.cn" 234 | source: hosted 235 | version: "1.11.0" 236 | photo_view: 237 | dependency: transitive 238 | description: 239 | name: photo_view 240 | url: "https://pub.flutter-io.cn" 241 | source: hosted 242 | version: "0.13.0" 243 | platform: 244 | dependency: transitive 245 | description: 246 | name: platform 247 | url: "https://pub.flutter-io.cn" 248 | source: hosted 249 | version: "3.1.0" 250 | plugin_platform_interface: 251 | dependency: transitive 252 | description: 253 | name: plugin_platform_interface 254 | url: "https://pub.flutter-io.cn" 255 | source: hosted 256 | version: "2.0.0" 257 | process: 258 | dependency: transitive 259 | description: 260 | name: process 261 | url: "https://pub.flutter-io.cn" 262 | source: hosted 263 | version: "4.2.1" 264 | rxdart: 265 | dependency: transitive 266 | description: 267 | name: rxdart 268 | url: "https://pub.flutter-io.cn" 269 | source: hosted 270 | version: "0.26.0" 271 | sky_engine: 272 | dependency: transitive 273 | description: flutter 274 | source: sdk 275 | version: "0.0.99" 276 | source_span: 277 | dependency: transitive 278 | description: 279 | name: source_span 280 | url: "https://pub.flutter-io.cn" 281 | source: hosted 282 | version: "1.8.1" 283 | sqflite: 284 | dependency: transitive 285 | description: 286 | name: sqflite 287 | url: "https://pub.flutter-io.cn" 288 | source: hosted 289 | version: "2.0.0+3" 290 | sqflite_common: 291 | dependency: transitive 292 | description: 293 | name: sqflite_common 294 | url: "https://pub.flutter-io.cn" 295 | source: hosted 296 | version: "2.0.0+2" 297 | stack_trace: 298 | dependency: transitive 299 | description: 300 | name: stack_trace 301 | url: "https://pub.flutter-io.cn" 302 | source: hosted 303 | version: "1.10.0" 304 | stream_channel: 305 | dependency: transitive 306 | description: 307 | name: stream_channel 308 | url: "https://pub.flutter-io.cn" 309 | source: hosted 310 | version: "2.1.0" 311 | string_scanner: 312 | dependency: transitive 313 | description: 314 | name: string_scanner 315 | url: "https://pub.flutter-io.cn" 316 | source: hosted 317 | version: "1.1.0" 318 | synchronized: 319 | dependency: transitive 320 | description: 321 | name: synchronized 322 | url: "https://pub.flutter-io.cn" 323 | source: hosted 324 | version: "3.0.0" 325 | term_glyph: 326 | dependency: transitive 327 | description: 328 | name: term_glyph 329 | url: "https://pub.flutter-io.cn" 330 | source: hosted 331 | version: "1.2.0" 332 | test_api: 333 | dependency: transitive 334 | description: 335 | name: test_api 336 | url: "https://pub.flutter-io.cn" 337 | source: hosted 338 | version: "0.4.8" 339 | typed_data: 340 | dependency: transitive 341 | description: 342 | name: typed_data 343 | url: "https://pub.flutter-io.cn" 344 | source: hosted 345 | version: "1.3.0" 346 | uuid: 347 | dependency: transitive 348 | description: 349 | name: uuid 350 | url: "https://pub.flutter-io.cn" 351 | source: hosted 352 | version: "3.0.6" 353 | vector_math: 354 | dependency: transitive 355 | description: 356 | name: vector_math 357 | url: "https://pub.flutter-io.cn" 358 | source: hosted 359 | version: "2.1.1" 360 | win32: 361 | dependency: transitive 362 | description: 363 | name: win32 364 | url: "https://pub.flutter-io.cn" 365 | source: hosted 366 | version: "2.0.5" 367 | xdg_directories: 368 | dependency: transitive 369 | description: 370 | name: xdg_directories 371 | url: "https://pub.flutter-io.cn" 372 | source: hosted 373 | version: "0.2.0" 374 | sdks: 375 | dart: ">=2.14.0 <3.0.0" 376 | flutter: ">=2.0.4" 377 | -------------------------------------------------------------------------------- /example/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: nineold_example 2 | description: Demonstrates how to use the nineold plugin. 3 | publish_to: 'none' 4 | 5 | environment: 6 | sdk: ">=2.1.0 <3.0.0" 7 | 8 | dependencies: 9 | flutter: 10 | sdk: flutter 11 | flutter_localizations: 12 | sdk: flutter 13 | 14 | # The following adds the Cupertino Icons font to your application. 15 | # Use with the CupertinoIcons class for iOS style icons. 16 | cupertino_icons: ^0.1.2 17 | 18 | dev_dependencies: 19 | flutter_test: 20 | sdk: flutter 21 | flutter_localizations: 22 | sdk: flutter 23 | 24 | nineold: 25 | path: ../ 26 | 27 | # For information on the generic Dart part of this file, see the 28 | # following page: https://dart.dev/tools/pub/pubspec 29 | 30 | # The following section is specific to Flutter. 31 | flutter: 32 | 33 | # The following line ensures that the Material Icons font is 34 | # included with your application, so that you can use the icons in 35 | # the material Icons class. 36 | uses-material-design: true 37 | 38 | # To add assets to your application, add an assets section, like this: 39 | # assets: 40 | # - images/a_dot_burr.jpeg 41 | # - images/a_dot_ham.jpeg 42 | 43 | # An image asset can refer to one or more resolution-specific "variants", see 44 | # https://flutter.dev/assets-and-images/#resolution-aware. 45 | 46 | # For details regarding adding assets from package dependencies, see 47 | # https://flutter.dev/assets-and-images/#from-packages 48 | 49 | # To add custom fonts to your application, add a fonts section here, 50 | # in this "flutter" section. Each entry in this list should have a 51 | # "family" key with the font family name, and a "fonts" key with a 52 | # list giving the asset and other descriptors for the font. For 53 | # example: 54 | # fonts: 55 | # - family: Schyler 56 | # fonts: 57 | # - asset: fonts/Schyler-Regular.ttf 58 | # - asset: fonts/Schyler-Italic.ttf 59 | # style: italic 60 | # - family: Trajan Pro 61 | # fonts: 62 | # - asset: fonts/TrajanPro.ttf 63 | # - asset: fonts/TrajanPro_Bold.ttf 64 | # weight: 700 65 | # 66 | # For details regarding fonts from package dependencies, 67 | # see https://flutter.dev/custom-fonts/#from-packages 68 | flutter_intl: 69 | enabled: true 70 | -------------------------------------------------------------------------------- /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:flutter/material.dart'; 9 | import 'package:flutter_test/flutter_test.dart'; 10 | 11 | import 'package:nineold_example/main.dart'; 12 | 13 | void main() { 14 | testWidgets('Verify Platform version', (WidgetTester tester) async { 15 | // Build our app and trigger a frame. 16 | await tester.pumpWidget(MyApp()); 17 | 18 | // Verify that platform version is retrieved. 19 | expect( 20 | find.byWidgetPredicate( 21 | (Widget widget) => widget is Text && 22 | widget.data.startsWith('Running on:'), 23 | ), 24 | findsOneWidget, 25 | ); 26 | }); 27 | } 28 | -------------------------------------------------------------------------------- /ios/.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | .vagrant/ 3 | .sconsign.dblite 4 | .svn/ 5 | 6 | .DS_Store 7 | *.swp 8 | profile 9 | 10 | DerivedData/ 11 | build/ 12 | GeneratedPluginRegistrant.h 13 | GeneratedPluginRegistrant.m 14 | 15 | .generated/ 16 | 17 | *.pbxuser 18 | *.mode1v3 19 | *.mode2v3 20 | *.perspectivev3 21 | 22 | !default.pbxuser 23 | !default.mode1v3 24 | !default.mode2v3 25 | !default.perspectivev3 26 | 27 | xcuserdata 28 | 29 | *.moved-aside 30 | 31 | *.pyc 32 | *sync/ 33 | Icon? 34 | .tags* 35 | 36 | /Flutter/Generated.xcconfig 37 | /Flutter/flutter_export_environment.sh -------------------------------------------------------------------------------- /ios/Assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lanzhu1993/flutter_nineold/4100f6cbb776803a668ee31f7417579721a5321c/ios/Assets/.gitkeep -------------------------------------------------------------------------------- /ios/Classes/NineoldPlugin.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface NineoldPlugin : NSObject 4 | @end 5 | -------------------------------------------------------------------------------- /ios/Classes/NineoldPlugin.m: -------------------------------------------------------------------------------- 1 | #import "NineoldPlugin.h" 2 | #if __has_include() 3 | #import 4 | #else 5 | // Support project import fallback if the generated compatibility header 6 | // is not copied when this plugin is created as a library. 7 | // https://forums.swift.org/t/swift-static-libraries-dont-copy-generated-objective-c-header/19816 8 | #import "nineold-Swift.h" 9 | #endif 10 | 11 | @implementation NineoldPlugin 12 | + (void)registerWithRegistrar:(NSObject*)registrar { 13 | [SwiftNineoldPlugin registerWithRegistrar:registrar]; 14 | } 15 | @end 16 | -------------------------------------------------------------------------------- /ios/Classes/SwiftNineoldPlugin.swift: -------------------------------------------------------------------------------- 1 | import Flutter 2 | import UIKit 3 | 4 | public class SwiftNineoldPlugin: NSObject, FlutterPlugin { 5 | public static func register(with registrar: FlutterPluginRegistrar) { 6 | let channel = FlutterMethodChannel(name: "nineold", binaryMessenger: registrar.messenger()) 7 | let instance = SwiftNineoldPlugin() 8 | registrar.addMethodCallDelegate(instance, channel: channel) 9 | } 10 | 11 | public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { 12 | result("iOS " + UIDevice.current.systemVersion) 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /ios/nineold.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html. 3 | # Run `pod lib lint nineold.podspec' to validate before publishing. 4 | # 5 | Pod::Spec.new do |s| 6 | s.name = 'nineold' 7 | s.version = '0.0.1' 8 | s.summary = 'A new Flutter plugin.' 9 | s.description = <<-DESC 10 | A new Flutter plugin. 11 | DESC 12 | s.homepage = 'http://example.com' 13 | s.license = { :file => '../LICENSE' } 14 | s.author = { 'Your Company' => 'email@example.com' } 15 | s.source = { :path => '.' } 16 | s.source_files = 'Classes/**/*' 17 | s.dependency 'Flutter' 18 | s.platform = :ios, '8.0' 19 | 20 | # Flutter.framework does not contain a i386 slice. Only x86_64 simulators are supported. 21 | s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'VALID_ARCHS[sdk=iphonesimulator*]' => 'x86_64' } 22 | s.swift_version = '5.0' 23 | end 24 | -------------------------------------------------------------------------------- /lib/loader/image_with_loader.dart: -------------------------------------------------------------------------------- 1 | import 'package:cached_network_image/cached_network_image.dart'; 2 | import "package:flutter/material.dart"; 3 | 4 | class ImageWithLoader extends StatelessWidget { 5 | const ImageWithLoader( 6 | {required this.url, 7 | required this.backgroundColor, 8 | required this.strokeWidth, 9 | required this.valueColor, 10 | required this.errorWidget, 11 | this.fit = BoxFit.cover, 12 | this.loaderSize = 48.0}); 13 | 14 | final String url; 15 | final BoxFit fit; 16 | final double loaderSize; 17 | 18 | final Color backgroundColor; 19 | final double strokeWidth; 20 | final Color valueColor; 21 | final Widget errorWidget; 22 | 23 | @override 24 | Widget build(BuildContext context) { 25 | return Stack( 26 | fit: StackFit.expand, 27 | alignment: Alignment.center, 28 | children: [ 29 | Container( 30 | color: Colors.grey, 31 | ), 32 | CachedNetworkImage( 33 | imageUrl: url, 34 | fit: fit, 35 | placeholder: (context, url) => Center( 36 | child: SizedBox( 37 | width: loaderSize, 38 | height: loaderSize, 39 | child: CircularProgressIndicator( 40 | valueColor: AlwaysStoppedAnimation(valueColor), 41 | backgroundColor: backgroundColor, 42 | strokeWidth: strokeWidth, 43 | ), 44 | ), 45 | ), 46 | errorWidget: (context, url, error) => 47 | null == errorWidget ? Icon(Icons.error) : errorWidget, 48 | ) 49 | ], 50 | ); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /lib/nine_old_frame.dart: -------------------------------------------------------------------------------- 1 | 2 | library nine_old; 3 | 4 | export 'loader/image_with_loader.dart'; 5 | export 'watcher/gallery_watcher.dart'; 6 | export 'widget/nine_old_widget.dart'; 7 | -------------------------------------------------------------------------------- /lib/watcher/gallery_watcher.dart: -------------------------------------------------------------------------------- 1 | import 'package:cached_network_image/cached_network_image.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:photo_view/photo_view.dart'; 4 | import 'package:photo_view/photo_view_gallery.dart'; 5 | 6 | typedef OnLongPressCallback = void Function(int position); 7 | 8 | class GalleryPhotoViewWrapper extends StatefulWidget { 9 | GalleryPhotoViewWrapper({ 10 | required this.backgroundDecoration, 11 | required this.initialIndex, 12 | required this.thumbGalleryItems, 13 | required this.tagItems, 14 | required this.originGalleryItems, 15 | this.scrollDirection = Axis.horizontal, 16 | required this.onLongPressListener, 17 | }) : pageController = PageController(initialPage: initialIndex); 18 | 19 | final Decoration backgroundDecoration; 20 | final int initialIndex; 21 | final PageController pageController; 22 | final List thumbGalleryItems; 23 | final List originGalleryItems; 24 | final List tagItems; 25 | final Axis scrollDirection; 26 | 27 | final OnLongPressCallback onLongPressListener; 28 | 29 | @override 30 | State createState() { 31 | return _GalleryPhotoViewWrapperState(); 32 | } 33 | } 34 | 35 | class _GalleryPhotoViewWrapperState extends State { 36 | late int currentIndex; 37 | 38 | @override 39 | void initState() { 40 | currentIndex = widget.initialIndex; 41 | super.initState(); 42 | } 43 | 44 | void onPageChanged(int index) { 45 | setState(() { 46 | currentIndex = index; 47 | }); 48 | } 49 | 50 | @override 51 | Widget build(BuildContext context) { 52 | return Scaffold( 53 | body: Container( 54 | decoration: widget.backgroundDecoration, 55 | constraints: BoxConstraints.expand( 56 | height: MediaQuery 57 | .of(context) 58 | .size 59 | .height, 60 | ), 61 | child: InkWell( 62 | onLongPress: () { 63 | widget.onLongPressListener(currentIndex); 64 | }, 65 | child: Stack( 66 | alignment: Alignment.bottomRight, 67 | children: [ 68 | PhotoViewGallery.builder( 69 | scrollPhysics: const BouncingScrollPhysics(), 70 | builder: _buildItem, 71 | itemCount: widget.thumbGalleryItems.length, 72 | backgroundDecoration: BoxDecoration( 73 | color: Colors.black, 74 | ), 75 | pageController: widget.pageController, 76 | onPageChanged: onPageChanged, 77 | scrollDirection: widget.scrollDirection, 78 | ), 79 | Positioned( 80 | bottom: 20, 81 | right: 20, 82 | child: Container( 83 | child: Text( 84 | "${currentIndex + 1}" + 85 | "/" + 86 | "${widget.thumbGalleryItems.length}", 87 | style: const TextStyle( 88 | color: Colors.white, 89 | fontSize: 17.0, 90 | decoration: null, 91 | ), 92 | ), 93 | ), 94 | ), 95 | Positioned( 96 | top: 30, 97 | left: 0, 98 | child: IconButton( 99 | iconSize: 20, 100 | icon: Icon( 101 | Icons.arrow_back, 102 | color: Colors.white, 103 | ), 104 | onPressed: () { 105 | Navigator.of(context).pop(); 106 | }, 107 | ), 108 | ) 109 | ], 110 | ), 111 | ), 112 | ), 113 | ); 114 | } 115 | 116 | PhotoViewGalleryPageOptions _buildItem(BuildContext context, int index) { 117 | String item = ""; 118 | if (widget.originGalleryItems.length == 0) { 119 | item = widget.thumbGalleryItems[index]; 120 | } else { 121 | item = widget.originGalleryItems[index]; 122 | } 123 | var tag = item + widget.tagItems[index]; 124 | return PhotoViewGalleryPageOptions( 125 | imageProvider: CachedNetworkImageProvider(item), 126 | initialScale: PhotoViewComputedScale.contained, 127 | minScale: PhotoViewComputedScale.contained * (0.5 + index / 10), 128 | maxScale: PhotoViewComputedScale.covered * 1.1, 129 | heroAttributes: PhotoViewHeroAttributes(tag: tag), 130 | ); 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /lib/widget/nine_old_widget.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:nineold/loader/image_with_loader.dart'; 3 | import 'package:nineold/watcher/gallery_watcher.dart'; 4 | import 'package:uuid/uuid.dart'; 5 | 6 | class NineOldWidget extends StatelessWidget { 7 | final List images; 8 | final TextStyle moreStyle; 9 | 10 | final Color backgroundColor; 11 | final double strokeWidth; 12 | final Color valueColor; 13 | final Widget errorWidget; 14 | 15 | final OnLongPressCallback onLongPressListener; 16 | 17 | final List tagItems = []; 18 | 19 | NineOldWidget( 20 | {required this.images, 21 | this.moreStyle = 22 | const TextStyle(fontSize: 32, fontFamily: "Poppins-Regular"), 23 | this.backgroundColor = Colors.white, 24 | this.strokeWidth = 3, 25 | this.valueColor = Colors.tealAccent, 26 | required this.onLongPressListener, 27 | required this.errorWidget}); 28 | 29 | @override 30 | Widget build(BuildContext context) { 31 | images.forEach((element) { 32 | tagItems.add(Uuid().v1()); 33 | }); 34 | return _buildImagesFrame(context); 35 | } 36 | 37 | Widget _buildImagesFrame(BuildContext context) { 38 | switch (images.length) { 39 | case 0: 40 | return SizedBox.shrink(); 41 | case 1: 42 | return _buildSingleImage(context); 43 | case 2: 44 | return _buildTwoImages(context); 45 | case 3: 46 | return _buildThreeImages(context); 47 | case 4: 48 | return _buildFourImages(context); 49 | case 5: 50 | return _buildFiveImages(context); 51 | case 6: 52 | return _buildSixImages(context); 53 | case 7: 54 | return _buildSevenImages(context); 55 | case 8: 56 | return _buildEightImages(context); 57 | case 9: 58 | return _buildNineImages(context); 59 | default: 60 | return _buildNineImages(context); 61 | } 62 | } 63 | 64 | /// Build a picture and adapt it to the on-screen display 65 | Widget _buildSingleImage(BuildContext context) { 66 | return ConstrainedBox( 67 | constraints: BoxConstraints( 68 | maxHeight: MediaQuery.of(context).size.width, 69 | maxWidth: MediaQuery.of(context).size.width, 70 | ), 71 | child: _aspectRatioImage(context, index: 0, aspectRatio: 1), 72 | ); 73 | } 74 | 75 | /// Build two picture and adapt it to the on-screen display 76 | Widget _buildTwoImages(BuildContext context) { 77 | return ConstrainedBox( 78 | constraints: BoxConstraints( 79 | maxWidth: MediaQuery.of(context).size.width, 80 | maxHeight: MediaQuery.of(context).size.width / 2, 81 | ), 82 | child: Row( 83 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 84 | children: [ 85 | Expanded(child: _aspectRatioImage(context, index: 0)), 86 | _spacer(), 87 | Expanded(child: _aspectRatioImage(context, index: 1)), 88 | ], 89 | ), 90 | ); 91 | } 92 | 93 | /// Build three picture and adapt it to the on-screen display 94 | Widget _buildThreeImages(BuildContext context) { 95 | return ConstrainedBox( 96 | constraints: BoxConstraints( 97 | maxWidth: MediaQuery.of(context).size.width, 98 | maxHeight: (MediaQuery.of(context).size.width * 2 / 3) + 1, 99 | ), 100 | child: Row( 101 | mainAxisSize: MainAxisSize.max, 102 | crossAxisAlignment: CrossAxisAlignment.start, 103 | children: [ 104 | Expanded( 105 | flex: (MediaQuery.of(context).size.width * 2 ~/ 3), 106 | child: _aspectRatioImage(context, index: 0)), 107 | _spacer(), 108 | Expanded( 109 | flex: MediaQuery.of(context).size.width ~/ 3, 110 | child: Column( 111 | children: [ 112 | _aspectRatioImage(context, index: 1), 113 | _spacer(), 114 | _aspectRatioImage(context, index: 2), 115 | ], 116 | ), 117 | ), 118 | ], 119 | ), 120 | ); 121 | } 122 | 123 | /// Build four picture and adapt it to the on-screen display 124 | Widget _buildFourImages(BuildContext context) { 125 | return ConstrainedBox( 126 | constraints: BoxConstraints( 127 | maxWidth: MediaQuery.of(context).size.width, 128 | maxHeight: MediaQuery.of(context).size.width, 129 | ), 130 | child: Column( 131 | children: [ 132 | Row( 133 | children: [ 134 | Expanded(child: _aspectRatioImage(context, index: 0)), 135 | _spacer(), 136 | Expanded(child: _aspectRatioImage(context, index: 1)), 137 | ], 138 | ), 139 | _spacer(), 140 | Row( 141 | children: [ 142 | Expanded(child: _aspectRatioImage(context, index: 2)), 143 | _spacer(), 144 | Expanded(child: _aspectRatioImage(context, index: 3)), 145 | ], 146 | ), 147 | ], 148 | ), 149 | ); 150 | } 151 | 152 | /// Build five picture and adapt it to the on-screen display 153 | Widget _buildFiveImages(BuildContext context) { 154 | return ConstrainedBox( 155 | constraints: BoxConstraints( 156 | maxWidth: MediaQuery.of(context).size.width, 157 | maxHeight: MediaQuery.of(context).size.width * 5 / 6, 158 | ), 159 | child: Column( 160 | children: [ 161 | Row( 162 | children: [ 163 | Expanded(child: _aspectRatioImage(context, index: 0)), 164 | _spacer(), 165 | Expanded(child: _aspectRatioImage(context, index: 1)), 166 | ], 167 | ), 168 | _spacer(), 169 | Row( 170 | children: [ 171 | Expanded(child: _aspectRatioImage(context, index: 2)), 172 | _spacer(), 173 | Expanded(child: _aspectRatioImage(context, index: 3)), 174 | _spacer(), 175 | Expanded(child: _aspectRatioImage(context, index: 4)), 176 | ], 177 | ), 178 | ], 179 | ), 180 | ); 181 | } 182 | 183 | /// Build six picture and adapt it to the on-screen display 184 | Widget _buildSixImages(BuildContext context) { 185 | return ConstrainedBox( 186 | constraints: BoxConstraints( 187 | maxWidth: MediaQuery.of(context).size.width, 188 | maxHeight: MediaQuery.of(context).size.width * 2 / 3, 189 | ), 190 | child: Column( 191 | children: [ 192 | Row( 193 | children: [ 194 | Expanded(child: _aspectRatioImage(context, index: 0)), 195 | _spacer(), 196 | Expanded(child: _aspectRatioImage(context, index: 1)), 197 | _spacer(), 198 | Expanded(child: _aspectRatioImage(context, index: 2)), 199 | ], 200 | ), 201 | _spacer(), 202 | Row( 203 | children: [ 204 | Expanded(child: _aspectRatioImage(context, index: 3)), 205 | _spacer(), 206 | Expanded(child: _aspectRatioImage(context, index: 4)), 207 | _spacer(), 208 | Expanded(child: _aspectRatioImage(context, index: 5)), 209 | ], 210 | ), 211 | ], 212 | ), 213 | ); 214 | } 215 | 216 | /// Build seven picture and adapt it to the on-screen display 217 | Widget _buildSevenImages(BuildContext context) { 218 | return ConstrainedBox( 219 | constraints: BoxConstraints( 220 | maxWidth: MediaQuery.of(context).size.width, 221 | maxHeight: MediaQuery.of(context).size.width, 222 | ), 223 | child: Column( 224 | children: [ 225 | Row( 226 | children: [ 227 | Expanded(child: _aspectRatioImage(context, index: 0)), 228 | _spacer(), 229 | Expanded(child: _aspectRatioImage(context, index: 1)), 230 | _spacer(), 231 | Expanded(child: _aspectRatioImage(context, index: 2)), 232 | ], 233 | ), 234 | _spacer(), 235 | Row( 236 | children: [ 237 | Expanded(child: _aspectRatioImage(context, index: 3)), 238 | _spacer(), 239 | Expanded(child: _aspectRatioImage(context, index: 4)), 240 | _spacer(), 241 | Expanded(child: _aspectRatioImage(context, index: 5)), 242 | ], 243 | ), 244 | _spacer(), 245 | Row( 246 | children: [ 247 | Expanded(child: _aspectRatioImage(context, index: 6)), 248 | _spacer(), 249 | Expanded(child: _aspectRatioEmpty()), 250 | _spacer(), 251 | Expanded(child: _aspectRatioEmpty()), 252 | ], 253 | ) 254 | ], 255 | ), 256 | ); 257 | } 258 | 259 | /// Build eight picture and adapt it to the on-screen display 260 | Widget _buildEightImages(BuildContext context) { 261 | return ConstrainedBox( 262 | constraints: BoxConstraints( 263 | maxWidth: MediaQuery.of(context).size.width, 264 | maxHeight: MediaQuery.of(context).size.width, 265 | ), 266 | child: Column( 267 | children: [ 268 | Row( 269 | children: [ 270 | Expanded(child: _aspectRatioImage(context, index: 0)), 271 | _spacer(), 272 | Expanded(child: _aspectRatioImage(context, index: 1)), 273 | _spacer(), 274 | Expanded(child: _aspectRatioImage(context, index: 2)), 275 | ], 276 | ), 277 | _spacer(), 278 | Row( 279 | children: [ 280 | Expanded(child: _aspectRatioImage(context, index: 3)), 281 | _spacer(), 282 | Expanded(child: _aspectRatioImage(context, index: 4)), 283 | _spacer(), 284 | Expanded(child: _aspectRatioImage(context, index: 5)), 285 | ], 286 | ), 287 | _spacer(), 288 | Row( 289 | children: [ 290 | Expanded(child: _aspectRatioImage(context, index: 6)), 291 | _spacer(), 292 | Expanded(child: _aspectRatioImage(context, index: 7)), 293 | _spacer(), 294 | Expanded(child: _aspectRatioEmpty()), 295 | ], 296 | ) 297 | ], 298 | ), 299 | ); 300 | } 301 | 302 | /// Build nine picture and adapt it to the on-screen display 303 | Widget _buildNineImages(BuildContext context) { 304 | return ConstrainedBox( 305 | constraints: BoxConstraints( 306 | maxWidth: MediaQuery.of(context).size.width, 307 | maxHeight: MediaQuery.of(context).size.width, 308 | ), 309 | child: Column( 310 | children: [ 311 | Row( 312 | children: [ 313 | Expanded(child: _aspectRatioImage(context, index: 0)), 314 | _spacer(), 315 | Expanded(child: _aspectRatioImage(context, index: 1)), 316 | _spacer(), 317 | Expanded(child: _aspectRatioImage(context, index: 2)), 318 | ], 319 | ), 320 | _spacer(), 321 | Row( 322 | children: [ 323 | Expanded(child: _aspectRatioImage(context, index: 3)), 324 | _spacer(), 325 | Expanded(child: _aspectRatioImage(context, index: 4)), 326 | _spacer(), 327 | Expanded(child: _aspectRatioImage(context, index: 5)), 328 | ], 329 | ), 330 | _spacer(), 331 | Row( 332 | children: [ 333 | Expanded(child: _aspectRatioImage(context, index: 6)), 334 | _spacer(), 335 | Expanded(child: _aspectRatioImage(context, index: 7)), 336 | _spacer(), 337 | Expanded( 338 | child: _plusMorePictures( 339 | context, 340 | valueCount: images.length - 9, 341 | child: _aspectRatioImage( 342 | context, 343 | index: 8, 344 | ), 345 | ), 346 | ), 347 | ], 348 | ) 349 | ], 350 | ), 351 | ); 352 | } 353 | 354 | /// Build more than nine picture and adapt it to the on-screen display 355 | Widget _plusMorePictures( 356 | BuildContext context, { 357 | required int valueCount, 358 | required Widget child, 359 | }) { 360 | if (valueCount <= 0) { 361 | return child; 362 | } else { 363 | return Stack( 364 | alignment: Alignment.center, 365 | children: [ 366 | child, 367 | InkWell( 368 | onTap: () { 369 | _openGalleryWatcher(context, 9); 370 | }, 371 | child: AspectRatio( 372 | aspectRatio: 1, 373 | child: Container( 374 | color: Colors.white30, 375 | child: Center( 376 | child: Text( 377 | "+$valueCount", 378 | style: moreStyle, 379 | ), 380 | ), 381 | ), 382 | ), 383 | ) 384 | ], 385 | ); 386 | } 387 | } 388 | 389 | SizedBox _spacer() { 390 | return SizedBox.fromSize( 391 | size: Size(2, 2), 392 | ); 393 | } 394 | 395 | /// Build a picture ration Image to display 396 | Widget _aspectRatioImage( 397 | BuildContext context, { 398 | required int index, 399 | double aspectRatio = 1, 400 | }) { 401 | return InkWell( 402 | child: AspectRatio( 403 | aspectRatio: aspectRatio, 404 | child: Hero( 405 | tag: images[index] + tagItems[index], 406 | child: ImageWithLoader( 407 | url: images[index], 408 | backgroundColor: backgroundColor, 409 | valueColor: valueColor, 410 | strokeWidth: strokeWidth, 411 | errorWidget: errorWidget, 412 | ), 413 | )), 414 | onTap: () { 415 | _openGalleryWatcher(context, index); 416 | }); 417 | } 418 | 419 | _openGalleryWatcher(BuildContext context, int index) { 420 | Navigator.push( 421 | context, 422 | MaterialPageRoute( 423 | builder: (context) => GalleryPhotoViewWrapper( 424 | thumbGalleryItems: images, 425 | tagItems: tagItems, 426 | backgroundDecoration: const BoxDecoration( 427 | color: Colors.black, 428 | ), 429 | initialIndex: index, 430 | scrollDirection: Axis.horizontal, 431 | onLongPressListener: onLongPressListener, 432 | originGalleryItems: images, 433 | ), 434 | ), 435 | ); 436 | } 437 | 438 | Widget _aspectRatioEmpty({ 439 | double aspectRatio = 1, 440 | }) { 441 | return AspectRatio( 442 | aspectRatio: aspectRatio, 443 | child: SizedBox(), 444 | ); 445 | } 446 | } 447 | -------------------------------------------------------------------------------- /nineold.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /pubspec.lock: -------------------------------------------------------------------------------- 1 | # Generated by pub 2 | # See https://dart.dev/tools/pub/glossary#lockfile 3 | packages: 4 | async: 5 | dependency: transitive 6 | description: 7 | name: async 8 | url: "https://pub.flutter-io.cn" 9 | source: hosted 10 | version: "2.8.2" 11 | boolean_selector: 12 | dependency: transitive 13 | description: 14 | name: boolean_selector 15 | url: "https://pub.flutter-io.cn" 16 | source: hosted 17 | version: "2.1.0" 18 | cached_network_image: 19 | dependency: "direct main" 20 | description: 21 | name: cached_network_image 22 | url: "https://pub.flutter-io.cn" 23 | source: hosted 24 | version: "3.2.0" 25 | cached_network_image_platform_interface: 26 | dependency: transitive 27 | description: 28 | name: cached_network_image_platform_interface 29 | url: "https://pub.flutter-io.cn" 30 | source: hosted 31 | version: "1.0.0" 32 | cached_network_image_web: 33 | dependency: transitive 34 | description: 35 | name: cached_network_image_web 36 | url: "https://pub.flutter-io.cn" 37 | source: hosted 38 | version: "1.0.1" 39 | characters: 40 | dependency: transitive 41 | description: 42 | name: characters 43 | url: "https://pub.flutter-io.cn" 44 | source: hosted 45 | version: "1.2.0" 46 | charcode: 47 | dependency: transitive 48 | description: 49 | name: charcode 50 | url: "https://pub.flutter-io.cn" 51 | source: hosted 52 | version: "1.3.1" 53 | clock: 54 | dependency: transitive 55 | description: 56 | name: clock 57 | url: "https://pub.flutter-io.cn" 58 | source: hosted 59 | version: "1.1.0" 60 | collection: 61 | dependency: transitive 62 | description: 63 | name: collection 64 | url: "https://pub.flutter-io.cn" 65 | source: hosted 66 | version: "1.15.0" 67 | crypto: 68 | dependency: transitive 69 | description: 70 | name: crypto 71 | url: "https://pub.flutter-io.cn" 72 | source: hosted 73 | version: "3.0.1" 74 | fake_async: 75 | dependency: transitive 76 | description: 77 | name: fake_async 78 | url: "https://pub.flutter-io.cn" 79 | source: hosted 80 | version: "1.2.0" 81 | ffi: 82 | dependency: transitive 83 | description: 84 | name: ffi 85 | url: "https://pub.flutter-io.cn" 86 | source: hosted 87 | version: "1.1.2" 88 | file: 89 | dependency: transitive 90 | description: 91 | name: file 92 | url: "https://pub.flutter-io.cn" 93 | source: hosted 94 | version: "6.1.2" 95 | flutter: 96 | dependency: "direct main" 97 | description: flutter 98 | source: sdk 99 | version: "0.0.0" 100 | flutter_blurhash: 101 | dependency: transitive 102 | description: 103 | name: flutter_blurhash 104 | url: "https://pub.flutter-io.cn" 105 | source: hosted 106 | version: "0.6.4" 107 | flutter_cache_manager: 108 | dependency: transitive 109 | description: 110 | name: flutter_cache_manager 111 | url: "https://pub.flutter-io.cn" 112 | source: hosted 113 | version: "3.3.0" 114 | flutter_localizations: 115 | dependency: "direct dev" 116 | description: flutter 117 | source: sdk 118 | version: "0.0.0" 119 | flutter_test: 120 | dependency: "direct dev" 121 | description: flutter 122 | source: sdk 123 | version: "0.0.0" 124 | http: 125 | dependency: transitive 126 | description: 127 | name: http 128 | url: "https://pub.flutter-io.cn" 129 | source: hosted 130 | version: "0.13.4" 131 | http_parser: 132 | dependency: transitive 133 | description: 134 | name: http_parser 135 | url: "https://pub.flutter-io.cn" 136 | source: hosted 137 | version: "4.0.0" 138 | intl: 139 | dependency: transitive 140 | description: 141 | name: intl 142 | url: "https://pub.flutter-io.cn" 143 | source: hosted 144 | version: "0.17.0" 145 | matcher: 146 | dependency: transitive 147 | description: 148 | name: matcher 149 | url: "https://pub.flutter-io.cn" 150 | source: hosted 151 | version: "0.12.11" 152 | material_color_utilities: 153 | dependency: transitive 154 | description: 155 | name: material_color_utilities 156 | url: "https://pub.flutter-io.cn" 157 | source: hosted 158 | version: "0.1.3" 159 | meta: 160 | dependency: transitive 161 | description: 162 | name: meta 163 | url: "https://pub.flutter-io.cn" 164 | source: hosted 165 | version: "1.7.0" 166 | octo_image: 167 | dependency: transitive 168 | description: 169 | name: octo_image 170 | url: "https://pub.flutter-io.cn" 171 | source: hosted 172 | version: "1.0.1" 173 | path: 174 | dependency: transitive 175 | description: 176 | name: path 177 | url: "https://pub.flutter-io.cn" 178 | source: hosted 179 | version: "1.8.0" 180 | path_provider: 181 | dependency: transitive 182 | description: 183 | name: path_provider 184 | url: "https://pub.flutter-io.cn" 185 | source: hosted 186 | version: "2.0.9" 187 | path_provider_android: 188 | dependency: transitive 189 | description: 190 | name: path_provider_android 191 | url: "https://pub.flutter-io.cn" 192 | source: hosted 193 | version: "2.0.12" 194 | path_provider_ios: 195 | dependency: transitive 196 | description: 197 | name: path_provider_ios 198 | url: "https://pub.flutter-io.cn" 199 | source: hosted 200 | version: "2.0.8" 201 | path_provider_linux: 202 | dependency: transitive 203 | description: 204 | name: path_provider_linux 205 | url: "https://pub.flutter-io.cn" 206 | source: hosted 207 | version: "2.1.5" 208 | path_provider_macos: 209 | dependency: transitive 210 | description: 211 | name: path_provider_macos 212 | url: "https://pub.flutter-io.cn" 213 | source: hosted 214 | version: "2.0.5" 215 | path_provider_platform_interface: 216 | dependency: transitive 217 | description: 218 | name: path_provider_platform_interface 219 | url: "https://pub.flutter-io.cn" 220 | source: hosted 221 | version: "2.0.3" 222 | path_provider_windows: 223 | dependency: transitive 224 | description: 225 | name: path_provider_windows 226 | url: "https://pub.flutter-io.cn" 227 | source: hosted 228 | version: "2.0.5" 229 | pedantic: 230 | dependency: transitive 231 | description: 232 | name: pedantic 233 | url: "https://pub.flutter-io.cn" 234 | source: hosted 235 | version: "1.11.1" 236 | photo_view: 237 | dependency: "direct main" 238 | description: 239 | name: photo_view 240 | url: "https://pub.flutter-io.cn" 241 | source: hosted 242 | version: "0.13.0" 243 | platform: 244 | dependency: "direct main" 245 | description: 246 | name: platform 247 | url: "https://pub.flutter-io.cn" 248 | source: hosted 249 | version: "3.1.0" 250 | plugin_platform_interface: 251 | dependency: transitive 252 | description: 253 | name: plugin_platform_interface 254 | url: "https://pub.flutter-io.cn" 255 | source: hosted 256 | version: "2.1.2" 257 | process: 258 | dependency: transitive 259 | description: 260 | name: process 261 | url: "https://pub.flutter-io.cn" 262 | source: hosted 263 | version: "4.2.4" 264 | rxdart: 265 | dependency: transitive 266 | description: 267 | name: rxdart 268 | url: "https://pub.flutter-io.cn" 269 | source: hosted 270 | version: "0.27.3" 271 | sky_engine: 272 | dependency: transitive 273 | description: flutter 274 | source: sdk 275 | version: "0.0.99" 276 | source_span: 277 | dependency: transitive 278 | description: 279 | name: source_span 280 | url: "https://pub.flutter-io.cn" 281 | source: hosted 282 | version: "1.8.1" 283 | sqflite: 284 | dependency: transitive 285 | description: 286 | name: sqflite 287 | url: "https://pub.flutter-io.cn" 288 | source: hosted 289 | version: "2.0.2" 290 | sqflite_common: 291 | dependency: transitive 292 | description: 293 | name: sqflite_common 294 | url: "https://pub.flutter-io.cn" 295 | source: hosted 296 | version: "2.2.1" 297 | stack_trace: 298 | dependency: transitive 299 | description: 300 | name: stack_trace 301 | url: "https://pub.flutter-io.cn" 302 | source: hosted 303 | version: "1.10.0" 304 | stream_channel: 305 | dependency: transitive 306 | description: 307 | name: stream_channel 308 | url: "https://pub.flutter-io.cn" 309 | source: hosted 310 | version: "2.1.0" 311 | string_scanner: 312 | dependency: transitive 313 | description: 314 | name: string_scanner 315 | url: "https://pub.flutter-io.cn" 316 | source: hosted 317 | version: "1.1.0" 318 | synchronized: 319 | dependency: transitive 320 | description: 321 | name: synchronized 322 | url: "https://pub.flutter-io.cn" 323 | source: hosted 324 | version: "3.0.0+2" 325 | term_glyph: 326 | dependency: transitive 327 | description: 328 | name: term_glyph 329 | url: "https://pub.flutter-io.cn" 330 | source: hosted 331 | version: "1.2.0" 332 | test_api: 333 | dependency: transitive 334 | description: 335 | name: test_api 336 | url: "https://pub.flutter-io.cn" 337 | source: hosted 338 | version: "0.4.8" 339 | typed_data: 340 | dependency: transitive 341 | description: 342 | name: typed_data 343 | url: "https://pub.flutter-io.cn" 344 | source: hosted 345 | version: "1.3.0" 346 | uuid: 347 | dependency: "direct main" 348 | description: 349 | name: uuid 350 | url: "https://pub.flutter-io.cn" 351 | source: hosted 352 | version: "3.0.6" 353 | vector_math: 354 | dependency: transitive 355 | description: 356 | name: vector_math 357 | url: "https://pub.flutter-io.cn" 358 | source: hosted 359 | version: "2.1.1" 360 | win32: 361 | dependency: transitive 362 | description: 363 | name: win32 364 | url: "https://pub.flutter-io.cn" 365 | source: hosted 366 | version: "2.5.0" 367 | xdg_directories: 368 | dependency: transitive 369 | description: 370 | name: xdg_directories 371 | url: "https://pub.flutter-io.cn" 372 | source: hosted 373 | version: "0.2.0+1" 374 | sdks: 375 | dart: ">=2.16.0 <3.0.0" 376 | flutter: ">=2.8.0" 377 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: nineold 2 | description: Nineoldwidget is a component used to encapsulate the nine palace display of pictures. 3 | version: 3.2.2 4 | homepage: https://github.com/lanzhu1993/flutter_nineold 5 | 6 | environment: 7 | sdk: ">=2.12.0 <3.0.0" 8 | flutter: ">=2.0.4" 9 | 10 | dependencies: 11 | flutter: 12 | sdk: flutter 13 | photo_view: ^0.13.0 14 | cached_network_image: ^3.2.0 15 | uuid: ^3.0.6 16 | platform: ^3.1.0 17 | 18 | 19 | 20 | 21 | dev_dependencies: 22 | flutter_test: 23 | sdk: flutter 24 | 25 | 26 | # For information on the generic Dart part of this file, see the 27 | # following page: https://dart.dev/tools/pub/pubspec 28 | 29 | # The following section is specific to Flutter. 30 | flutter: 31 | # This section identifies this Flutter project as a plugin project. 32 | # The androidPackage and pluginClass identifiers should not ordinarily 33 | # be modified. They are used by the tooling to maintain consistency when 34 | # adding or updating assets for this project. 35 | plugin: 36 | platforms: 37 | android: 38 | package: com.josh.nineold 39 | pluginClass: NineoldPlugin 40 | ios: 41 | pluginClass: NineoldPlugin 42 | 43 | 44 | # To add assets to your plugin package, add an assets section, like this: 45 | # assets: 46 | # - images/a_dot_burr.jpeg 47 | # - images/a_dot_ham.jpeg 48 | # 49 | # For details regarding assets in packages, see 50 | # https://flutter.dev/assets-and-images/#from-packages 51 | # 52 | # An image asset can refer to one or more resolution-specific "variants", see 53 | # https://flutter.dev/assets-and-images/#resolution-aware. 54 | 55 | # To add custom fonts to your plugin package, add a fonts section here, 56 | # in this "flutter" section. Each entry in this list should have a 57 | # "family" key with the font family name, and a "fonts" key with a 58 | # list giving the asset and other descriptors for the font. For 59 | # example: 60 | # fonts: 61 | # - family: Schyler 62 | # fonts: 63 | # - asset: fonts/Schyler-Regular.ttf 64 | # - asset: fonts/Schyler-Italic.ttf 65 | # style: italic 66 | # - family: Trajan Pro 67 | # fonts: 68 | # - asset: fonts/TrajanPro.ttf 69 | # - asset: fonts/TrajanPro_Bold.ttf 70 | # weight: 700 71 | # 72 | # For details regarding fonts in packages, see 73 | # https://flutter.dev/custom-fonts/#from-packages 74 | --------------------------------------------------------------------------------