├── .gitignore
├── .metadata
├── CHANGELOG.md
├── LICENSE
├── README-ZH.md
├── README.md
├── example
├── .gitignore
├── .metadata
├── README.md
├── android
│ ├── .gitignore
│ ├── app
│ │ ├── build.gradle
│ │ └── src
│ │ │ ├── debug
│ │ │ └── AndroidManifest.xml
│ │ │ ├── main
│ │ │ ├── AndroidManifest.xml
│ │ │ ├── java
│ │ │ │ └── club
│ │ │ │ │ └── flutterchina
│ │ │ │ │ └── azlistview_example
│ │ │ │ │ └── MainActivity.java
│ │ │ └── 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
│ ├── data
│ │ ├── car_models.json
│ │ ├── china.json
│ │ └── contacts.json
│ └── images
│ │ ├── ali_connors.png
│ │ ├── avatar.png
│ │ ├── ic_car_models_header1.png
│ │ ├── ic_car_models_header2.png
│ │ ├── ic_favorite.png
│ │ ├── ic_index_bar_bubble_gray.png
│ │ └── ic_index_bar_bubble_white.png
├── ios
│ ├── .gitignore
│ ├── Flutter
│ │ ├── AppFrameworkInfo.plist
│ │ ├── Debug.xcconfig
│ │ └── Release.xcconfig
│ ├── Podfile
│ ├── Podfile.lock
│ ├── Runner.xcodeproj
│ │ ├── project.pbxproj
│ │ ├── project.xcworkspace
│ │ │ ├── contents.xcworkspacedata
│ │ │ └── xcshareddata
│ │ │ │ ├── IDEWorkspaceChecks.plist
│ │ │ │ └── WorkspaceSettings.xcsettings
│ │ └── xcshareddata
│ │ │ └── xcschemes
│ │ │ └── Runner.xcscheme
│ ├── Runner.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ ├── IDEWorkspaceChecks.plist
│ │ │ └── WorkspaceSettings.xcsettings
│ └── Runner
│ │ ├── AppDelegate.swift
│ │ ├── Assets.xcassets
│ │ ├── AppIcon.appiconset
│ │ │ ├── Contents.json
│ │ │ ├── Icon-App-1024x1024@1x.png
│ │ │ ├── Icon-App-20x20@1x.png
│ │ │ ├── Icon-App-20x20@2x.png
│ │ │ ├── Icon-App-20x20@3x.png
│ │ │ ├── Icon-App-29x29@1x.png
│ │ │ ├── Icon-App-29x29@2x.png
│ │ │ ├── Icon-App-29x29@3x.png
│ │ │ ├── Icon-App-40x40@1x.png
│ │ │ ├── Icon-App-40x40@2x.png
│ │ │ ├── Icon-App-40x40@3x.png
│ │ │ ├── Icon-App-60x60@2x.png
│ │ │ ├── Icon-App-60x60@3x.png
│ │ │ ├── Icon-App-76x76@1x.png
│ │ │ ├── Icon-App-76x76@2x.png
│ │ │ └── Icon-App-83.5x83.5@2x.png
│ │ └── LaunchImage.imageset
│ │ │ ├── Contents.json
│ │ │ ├── LaunchImage.png
│ │ │ ├── LaunchImage@2x.png
│ │ │ ├── LaunchImage@3x.png
│ │ │ └── README.md
│ │ ├── Base.lproj
│ │ ├── LaunchScreen.storyboard
│ │ └── Main.storyboard
│ │ ├── Info.plist
│ │ └── Runner-Bridging-Header.h
├── lib
│ ├── common
│ │ ├── index.dart
│ │ ├── models.dart
│ │ ├── res.dart
│ │ └── utils.dart
│ ├── main.dart
│ └── ui
│ │ ├── car_models_page.dart
│ │ ├── citylist_custom_header_page.dart
│ │ ├── citylist_page.dart
│ │ ├── contacts_list_page.dart
│ │ ├── contacts_page.dart
│ │ ├── github_language_page.dart
│ │ ├── index.dart
│ │ ├── large_data_page.dart
│ │ └── page_scaffold.dart
├── pkgget
├── pubspec.lock
├── pubspec.yaml
└── test
│ └── widget_test.dart
├── lib
├── azlistview.dart
└── src
│ ├── az_common.dart
│ ├── az_listview.dart
│ ├── index_bar.dart
│ └── suspension_view.dart
├── pkgget
├── pubspec.lock
├── pubspec.yaml
├── screenshots
├── azlistview1.jpg
├── azlistview2.jpg
├── azlistview3.jpg
├── azlistview4.jpg
├── azlistview5.jpg
└── azlistview6.jpg
└── uploadMaster
/.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 | # Android related
34 | **/android/**/gradle-wrapper.jar
35 | **/android/.gradle
36 | **/android/captures/
37 | **/android/gradlew
38 | **/android/gradlew.bat
39 | **/android/local.properties
40 | **/android/**/GeneratedPluginRegistrant.java
41 |
42 | # iOS/XCode related
43 | **/ios/**/*.mode1v3
44 | **/ios/**/*.mode2v3
45 | **/ios/**/*.moved-aside
46 | **/ios/**/*.pbxuser
47 | **/ios/**/*.perspectivev3
48 | **/ios/**/*sync/
49 | **/ios/**/.sconsign.dblite
50 | **/ios/**/.tags*
51 | **/ios/**/.vagrant/
52 | **/ios/**/DerivedData/
53 | **/ios/**/Icon?
54 | **/ios/**/Pods/
55 | **/ios/**/.symlinks/
56 | **/ios/**/profile
57 | **/ios/**/xcuserdata
58 | **/ios/.generated/
59 | **/ios/Flutter/App.framework
60 | **/ios/Flutter/Flutter.framework
61 | **/ios/Flutter/Flutter.podspec
62 | **/ios/Flutter/Generated.xcconfig
63 | **/ios/Flutter/app.flx
64 | **/ios/Flutter/app.zip
65 | **/ios/Flutter/flutter_assets/
66 | **/ios/Flutter/flutter_export_environment.sh
67 | **/ios/ServiceDefinitions.json
68 | **/ios/Runner/GeneratedPluginRegistrant.*
69 |
70 | # Exceptions to above rules.
71 | !**/ios/**/default.mode1v3
72 | !**/ios/**/default.mode2v3
73 | !**/ios/**/default.pbxuser
74 | !**/ios/**/default.perspectivev3
75 |
--------------------------------------------------------------------------------
/.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: 81a45ec2e5f80fa71d5135f1702ce540558b416d
8 | channel: beta
9 |
10 | project_type: package
11 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | ## 2.0.0 release
2 | * TODO: scrollable_positioned_list: ^0.2.3, Indexbar add haptic feedback.
3 |
4 | ## 2.0.0
5 | * TODO: Migrate to null-safety.
6 |
7 | ## 1.1.1
8 | * TODO: fix analysis.
9 |
10 | ## 1.1.0
11 | * TODO: itemBuilder do not include the header, because it is automatically merged internally. fix [#38](https://github.com/flutterchina/azlistview/issues/38).
12 |
13 | ## 1.0.2
14 | * TODO: fix bugs and add search classification example.
15 |
16 | ## 1.0.1
17 | * TODO: fix analysis.
18 |
19 | ## 1.0.0
20 |
21 | * TODO: A Flutter sticky headers & index ListView. Based on [scrollable_positioned_list](https://pub.flutter-io.cn/packages/scrollable_positioned_list).
22 |
23 | ## 0.1.2
24 |
25 | * TODO: Open ScrollController, ScrollPhysics...
26 |
27 | ## 0.1.1
28 |
29 | * TODO: fix IndexBar onTapUp.
30 |
31 | ## 0.1.0
32 |
33 | * TODO: AzListView, SuspensionView, IndexBar.
34 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | BSD 3-Clause License
2 |
3 | Copyright (c) 2020, Flutter中文网
4 | All rights reserved.
5 |
6 | Redistribution and use in source and binary forms, with or without
7 | modification, are permitted provided that the following conditions are met:
8 |
9 | 1. Redistributions of source code must retain the above copyright notice, this
10 | list of conditions and the following disclaimer.
11 |
12 | 2. Redistributions in binary form must reproduce the above copyright notice,
13 | this list of conditions and the following disclaimer in the documentation
14 | and/or other materials provided with the distribution.
15 |
16 | 3. Neither the name of the copyright holder nor the names of its
17 | contributors may be used to endorse or promote products derived from
18 | this software without specific prior written permission.
19 |
20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 |
--------------------------------------------------------------------------------
/README-ZH.md:
--------------------------------------------------------------------------------
1 | Language: [English](https://github.com/flutterchina/azlistview) | 中文简体
2 |
3 | # azlistview
4 |
5 | Flutter 城市列表、联系人列表,索引&悬停。基于[scrollable_positioned_list](https://pub.flutter-io.cn/packages/scrollable_positioned_list).
6 | AzListView, SuspensionView, IndexBar.
7 |
8 | ## Features
9 |
10 | * 轻松创建城市列表或联系人列表界面。
11 | * 列表项按A-Z分组。
12 | * 带有悬停效果Header。
13 | * 支持自定义Header。
14 | * 支持索引联动。
15 | * IndexBar支持自定义样式。
16 | * IndexBar支持本地图片。
17 | * 允许滚动到列表中的特定项目。
18 |
19 | ## Pub
20 | ```yaml
21 | dependencies:
22 | azlistview: #latest version
23 | ```
24 |
25 | ## Screenshots
26 |
27 | ||||
28 | |:---:|:---:|:---:|
29 | ||||
30 |
31 |
32 | ## Changelog
33 |
34 | Please see the [Changelog](https://github.com/flutterchina/azlistview/blob/master/CHANGELOG.md) page to know what's recently changed.
35 | v1.1.0
36 | itemBuilder不要包含Header,因为它是在内部自动合并的。fix [#38](https://github.com/flutterchina/azlistview/issues/38).
37 |
38 | ## App
39 | [Moss App](https://github.com/Sky24n/Moss)
40 |
41 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Language: English | [中文简体](README-ZH.md)
2 |
3 | # azlistview
4 | A Flutter sticky headers & index ListView. Based on [scrollable_positioned_list](https://pub.flutter-io.cn/packages/scrollable_positioned_list).
5 | AzListView, SuspensionView, IndexBar.
6 |
7 | ## Features
8 | * Easy creation of city list or contact list interfaces.
9 | * List items can be grouped A-Z.
10 | * Sticky headers with floating option.
11 | * Support custom header.
12 | * Support index linkage.
13 | * IndexBar supports custom styles.
14 | * IndexBar supports local images.
15 | * Allows scrolling to a specific item in the list.
16 |
17 | ## Pub
18 | ```yaml
19 | dependencies:
20 | azlistview: ^2.0.0
21 | ```
22 |
23 | ## Screenshots
24 | ||||
25 | |:---:|:---:|:---:|
26 | ||||
27 |
28 |
29 | ## Changelog
30 | Please see the [Changelog](https://github.com/flutterchina/azlistview/blob/master/CHANGELOG.md) page to know what's recently changed.
31 | v1.1.0
32 | itemBuilder do not include the header, because it is automatically merged internally. fix [#38](https://github.com/flutterchina/azlistview/issues/38).
33 |
34 | ## App
35 | [Moss](https://github.com/Sky24n/Moss).
36 | A GitHub client app developed with Flutter, which supports Android iOS Web.
37 | Web :[Flutter Web](https://sky24n.github.io/Sky24n/moss).
38 |
39 | ||||
40 | |:---:|:---:|:---:|
41 |
42 |
--------------------------------------------------------------------------------
/example/.gitignore:
--------------------------------------------------------------------------------
1 | # Miscellaneous
2 | *.class
3 | *.log
4 | *.pyc
5 | *.swp
6 | .DS_Store
7 | .atom/
8 | .buildlog/
9 | .history
10 | .svn/
11 |
12 | # IntelliJ related
13 | *.iml
14 | *.ipr
15 | *.iws
16 | .idea/
17 |
18 | # The .vscode folder contains launch configuration and tasks you configure in
19 | # VS Code which you may wish to be included in version control, so this line
20 | # is commented out by default.
21 | #.vscode/
22 |
23 | # Flutter/Dart/Pub related
24 | **/doc/api/
25 | **/ios/Flutter/.last_build_id
26 | .dart_tool/
27 | .flutter-plugins
28 | .flutter-plugins-dependencies
29 | .packages
30 | .pub-cache/
31 | .pub/
32 | /build/
33 |
34 | # Web related
35 | lib/generated_plugin_registrant.dart
36 |
37 | # Symbolication related
38 | app.*.symbols
39 |
40 | # Obfuscation related
41 | app.*.map.json
42 |
43 | # Exceptions to above rules.
44 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
45 |
--------------------------------------------------------------------------------
/example/.metadata:
--------------------------------------------------------------------------------
1 | # This file tracks properties of this Flutter project.
2 | # Used by Flutter tool to assess capabilities and perform upgrades etc.
3 | #
4 | # This file should be version controlled and should not be manually edited.
5 |
6 | version:
7 | revision: bbfbf1770cca2da7c82e887e4e4af910034800b6
8 | channel: beta
9 |
10 | project_type: app
11 |
--------------------------------------------------------------------------------
/example/README.md:
--------------------------------------------------------------------------------
1 | # azlistview_example
2 |
3 | A new Flutter application.
4 |
5 | ## Getting Started
6 |
7 | This project is a starting point for a Flutter application.
8 |
9 | A few resources to get you started if this is your first Flutter project:
10 |
11 | - [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab)
12 | - [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook)
13 |
14 | For help getting started with Flutter, view our
15 | [online documentation](https://flutter.dev/docs), which offers tutorials,
16 | samples, guidance on mobile development, and a full API reference.
17 |
--------------------------------------------------------------------------------
/example/android/.gitignore:
--------------------------------------------------------------------------------
1 | gradle-wrapper.jar
2 | /.gradle
3 | /captures/
4 | /gradlew
5 | /gradlew.bat
6 | /local.properties
7 | GeneratedPluginRegistrant.java
8 |
9 | # Remember to never publicly share your keystore.
10 | # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app
11 | key.properties
12 |
--------------------------------------------------------------------------------
/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 from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
26 |
27 | android {
28 | compileSdkVersion 28
29 |
30 | lintOptions {
31 | disable 'InvalidPackage'
32 | }
33 |
34 | defaultConfig {
35 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
36 | applicationId "club.flutterchina.azlistview_example"
37 | minSdkVersion 16
38 | targetSdkVersion 28
39 | versionCode flutterVersionCode.toInteger()
40 | versionName flutterVersionName
41 | }
42 |
43 | buildTypes {
44 | release {
45 | // TODO: Add your own signing config for the release build.
46 | // Signing with the debug keys for now, so `flutter run --release` works.
47 | signingConfig signingConfigs.debug
48 | }
49 | }
50 | }
51 |
52 | flutter {
53 | source '../..'
54 | }
55 |
--------------------------------------------------------------------------------
/example/android/app/src/debug/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/example/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
8 |
9 |
12 |
19 |
23 |
26 |
31 |
34 |
35 |
36 |
37 |
38 |
39 |
41 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/example/android/app/src/main/java/club/flutterchina/azlistview_example/MainActivity.java:
--------------------------------------------------------------------------------
1 | package club.flutterchina.azlistview_example;
2 |
3 | import io.flutter.embedding.android.FlutterActivity;
4 |
5 | public class MainActivity extends FlutterActivity {
6 | }
7 |
--------------------------------------------------------------------------------
/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/flutterchina/azlistview/ea7e11660223c3b6b1f3491ab0e5e04a333cca5d/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/flutterchina/azlistview/ea7e11660223c3b6b1f3491ab0e5e04a333cca5d/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/flutterchina/azlistview/ea7e11660223c3b6b1f3491ab0e5e04a333cca5d/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/flutterchina/azlistview/ea7e11660223c3b6b1f3491ab0e5e04a333cca5d/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/flutterchina/azlistview/ea7e11660223c3b6b1f3491ab0e5e04a333cca5d/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
15 |
18 |
19 |
--------------------------------------------------------------------------------
/example/android/app/src/profile/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/example/android/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | repositories {
3 | google()
4 | jcenter()
5 | }
6 |
7 | dependencies {
8 | classpath 'com.android.tools.build:gradle:3.5.0'
9 | }
10 | }
11 |
12 | allprojects {
13 | repositories {
14 | google()
15 | jcenter()
16 | }
17 | }
18 |
19 | rootProject.buildDir = '../build'
20 | subprojects {
21 | project.buildDir = "${rootProject.buildDir}/${project.name}"
22 | }
23 | subprojects {
24 | project.evaluationDependsOn(':app')
25 | }
26 |
27 | task clean(type: Delete) {
28 | delete rootProject.buildDir
29 | }
30 |
--------------------------------------------------------------------------------
/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-5.6.2-all.zip
7 |
--------------------------------------------------------------------------------
/example/android/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
3 | def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
4 | def properties = new Properties()
5 |
6 | assert localPropertiesFile.exists()
7 | localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
8 |
9 | def flutterSdkPath = properties.getProperty("flutter.sdk")
10 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
11 | apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
12 |
--------------------------------------------------------------------------------
/example/assets/data/car_models.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "name": "奥迪"
4 | },
5 | {
6 | "name": "阿斯顿・马丁"
7 | },
8 | {
9 | "name": "阿尔法・罗密欧"
10 | },
11 | {
12 | "name": "ARCFOX"
13 | },
14 | {
15 | "name": "AUXUN傲旋"
16 | },
17 | {
18 | "name": "爱驰"
19 | },
20 | {
21 | "name": "ALPINA"
22 | },
23 | {
24 | "name": "AC Schnitzer"
25 | },
26 | {
27 | "name": "安凯客车"
28 | },
29 | {
30 | "name": "铂驰"
31 | },
32 | {
33 | "name": "比德文汽车"
34 | },
35 | {
36 | "name": "博郡汽车"
37 | },
38 | {
39 | "name": "宝骐汽车"
40 | },
41 | {
42 | "name": "北京清行"
43 | },
44 | {
45 | "name": "北汽昌河"
46 | },
47 | {
48 | "name": "布加迪"
49 | },
50 | {
51 | "name": "宾利"
52 | },
53 | {
54 | "name": "别克"
55 | },
56 | {
57 | "name": "标致"
58 | },
59 | {
60 | "name": "比亚迪"
61 | },
62 | {
63 | "name": "比速汽车"
64 | },
65 | {
66 | "name": "本田"
67 | },
68 | {
69 | "name": "奔腾"
70 | },
71 | {
72 | "name": "奔驰"
73 | },
74 | {
75 | "name": "北汽制造"
76 | },
77 | {
78 | "name": "北汽新能源"
79 | },
80 | {
81 | "name": "北汽威旺"
82 | },
83 | {
84 | "name": "北汽绅宝"
85 | },
86 | {
87 | "name": "北汽幻速"
88 | },
89 | {
90 | "name": "北汽道达"
91 | },
92 | {
93 | "name": "北京"
94 | },
95 | {
96 | "name": "保时捷"
97 | },
98 | {
99 | "name": "宝沃"
100 | },
101 | {
102 | "name": "宝马"
103 | },
104 | {
105 | "name": "宝骏"
106 | },
107 | {
108 | "name": "巴博斯"
109 | },
110 | {
111 | "name": "车驰汽车"
112 | },
113 | {
114 | "name": "成功汽车"
115 | },
116 | {
117 | "name": "长城"
118 | },
119 | {
120 | "name": "长安轻型车"
121 | },
122 | {
123 | "name": "长安欧尚"
124 | },
125 | {
126 | "name": "长安跨越"
127 | },
128 | {
129 | "name": "长安"
130 | },
131 | {
132 | "name": "大乘汽车"
133 | },
134 | {
135 | "name": "东风・瑞泰特"
136 | },
137 | {
138 | "name": "东南"
139 | },
140 | {
141 | "name": "东风小康"
142 | },
143 | {
144 | "name": "东风风行"
145 | },
146 | {
147 | "name": "东风风神"
148 | },
149 | {
150 | "name": "东风风光"
151 | },
152 | {
153 | "name": "东风风度"
154 | },
155 | {
156 | "name": "东风"
157 | },
158 | {
159 | "name": "电咖"
160 | },
161 | {
162 | "name": "道奇"
163 | },
164 | {
165 | "name": "大众"
166 | },
167 | {
168 | "name": "大发"
169 | },
170 | {
171 | "name": "DS"
172 | },
173 | {
174 | "name": "福田乘用车"
175 | },
176 | {
177 | "name": "福田"
178 | },
179 | {
180 | "name": "福特"
181 | },
182 | {
183 | "name": "福汽启腾"
184 | },
185 | {
186 | "name": "福迪"
187 | },
188 | {
189 | "name": "丰田"
190 | },
191 | {
192 | "name": "菲亚特"
193 | },
194 | {
195 | "name": "法拉利"
196 | },
197 | {
198 | "name": "国机智骏"
199 | },
200 | {
201 | "name": "Genesis现代"
202 | },
203 | {
204 | "name": "广汽集团"
205 | },
206 | {
207 | "name": "广汽新能源"
208 | },
209 | {
210 | "name": "国金汽车"
211 | },
212 | {
213 | "name": "广汽吉奥"
214 | },
215 | {
216 | "name": "广汽传祺"
217 | },
218 | {
219 | "name": "光冈"
220 | },
221 | {
222 | "name": "观致"
223 | },
224 | {
225 | "name": "GMC"
226 | },
227 | {
228 | "name": "HYCAN合创"
229 | },
230 | {
231 | "name": "汉龙汽车"
232 | },
233 | {
234 | "name": "合众汽车"
235 | },
236 | {
237 | "name": "红星汽车"
238 | },
239 | {
240 | "name": "黄海"
241 | },
242 | {
243 | "name": "华泰新能源"
244 | },
245 | {
246 | "name": "华泰"
247 | },
248 | {
249 | "name": "华颂"
250 | },
251 | {
252 | "name": "华骐"
253 | },
254 | {
255 | "name": "华普"
256 | },
257 | {
258 | "name": "华利"
259 | },
260 | {
261 | "name": "华凯"
262 | },
263 | {
264 | "name": "红旗"
265 | },
266 | {
267 | "name": "恒天"
268 | },
269 | {
270 | "name": "悍马"
271 | },
272 | {
273 | "name": "汉腾汽车"
274 | },
275 | {
276 | "name": "海马"
277 | },
278 | {
279 | "name": "海格"
280 | },
281 | {
282 | "name": "哈弗"
283 | },
284 | {
285 | "name": "哈飞"
286 | },
287 | {
288 | "name": "Icona"
289 | },
290 | {
291 | "name": "捷达"
292 | },
293 | {
294 | "name": "几何汽车"
295 | },
296 | {
297 | "name": "钧天"
298 | },
299 | {
300 | "name": "捷途"
301 | },
302 | {
303 | "name": "君马汽车"
304 | },
305 | {
306 | "name": "九龙"
307 | },
308 | {
309 | "name": "金旅"
310 | },
311 | {
312 | "name": "金龙"
313 | },
314 | {
315 | "name": "金杯"
316 | },
317 | {
318 | "name": "捷豹"
319 | },
320 | {
321 | "name": "江铃集团新能源"
322 | },
323 | {
324 | "name": "江铃集团轻汽"
325 | },
326 | {
327 | "name": "江铃"
328 | },
329 | {
330 | "name": "江淮"
331 | },
332 | {
333 | "name": "吉利汽车"
334 | },
335 | {
336 | "name": "Jeep"
337 | },
338 | {
339 | "name": "Karma"
340 | },
341 | {
342 | "name": "克莱斯勒"
343 | },
344 | {
345 | "name": "科尼赛克"
346 | },
347 | {
348 | "name": "凯翼"
349 | },
350 | {
351 | "name": "凯迪拉克"
352 | },
353 | {
354 | "name": "开瑞"
355 | },
356 | {
357 | "name": "卡威"
358 | },
359 | {
360 | "name": "卡升"
361 | },
362 | {
363 | "name": "卡尔森"
364 | },
365 | {
366 | "name": "KTM"
367 | },
368 | {
369 | "name": "雷丁"
370 | },
371 | {
372 | "name": "罗夫哈特"
373 | },
374 | {
375 | "name": "理想智造"
376 | },
377 | {
378 | "name": "领途汽车"
379 | },
380 | {
381 | "name": "零跑汽车"
382 | },
383 | {
384 | "name": "LITE"
385 | },
386 | {
387 | "name": "路特斯"
388 | },
389 | {
390 | "name": "路虎"
391 | },
392 | {
393 | "name": "陆风"
394 | },
395 | {
396 | "name": "陆地方舟"
397 | },
398 | {
399 | "name": "领克"
400 | },
401 | {
402 | "name": "铃木"
403 | },
404 | {
405 | "name": "林肯"
406 | },
407 | {
408 | "name": "猎豹汽车"
409 | },
410 | {
411 | "name": "莲花汽车"
412 | },
413 | {
414 | "name": "力帆汽车"
415 | },
416 | {
417 | "name": "理念"
418 | },
419 | {
420 | "name": "雷诺"
421 | },
422 | {
423 | "name": "雷克萨斯"
424 | },
425 | {
426 | "name": "劳斯莱斯"
427 | },
428 | {
429 | "name": "兰博基尼"
430 | },
431 | {
432 | "name": "Lorinser"
433 | },
434 | {
435 | "name": "LOCAL MOTORS"
436 | },
437 | {
438 | "name": "迈迈"
439 | },
440 | {
441 | "name": "迈莎锐"
442 | },
443 | {
444 | "name": "摩根"
445 | },
446 | {
447 | "name": "名爵"
448 | },
449 | {
450 | "name": "迈凯伦"
451 | },
452 | {
453 | "name": "迈巴赫"
454 | },
455 | {
456 | "name": "玛莎拉蒂"
457 | },
458 | {
459 | "name": "马自达"
460 | },
461 | {
462 | "name": "MINI"
463 | },
464 | {
465 | "name": "哪吒汽车"
466 | },
467 | {
468 | "name": "NEVS国能汽车"
469 | },
470 | {
471 | "name": "南京金龙"
472 | },
473 | {
474 | "name": "纳智捷"
475 | },
476 | {
477 | "name": "欧拉"
478 | },
479 | {
480 | "name": "欧尚汽车"
481 | },
482 | {
483 | "name": "欧朗"
484 | },
485 | {
486 | "name": "欧宝"
487 | },
488 | {
489 | "name": "讴歌"
490 | },
491 | {
492 | "name": "Polestar"
493 | },
494 | {
495 | "name": "帕加尼"
496 | },
497 | {
498 | "name": "乔治・巴顿"
499 | },
500 | {
501 | "name": "庆铃汽车"
502 | },
503 | {
504 | "name": "前途"
505 | },
506 | {
507 | "name": "起亚"
508 | },
509 | {
510 | "name": "启辰"
511 | },
512 | {
513 | "name": "祺智"
514 | },
515 | {
516 | "name": "奇瑞"
517 | },
518 | {
519 | "name": "全球鹰"
520 | },
521 | {
522 | "name": "容大智造"
523 | },
524 | {
525 | "name": "瑞麒"
526 | },
527 | {
528 | "name": "瑞驰新能源"
529 | },
530 | {
531 | "name": "如虎"
532 | },
533 | {
534 | "name": "荣威"
535 | },
536 | {
537 | "name": "日产"
538 | },
539 | {
540 | "name": "思皓"
541 | },
542 | {
543 | "name": "SHELBY"
544 | },
545 | {
546 | "name": "SERES赛力斯"
547 | },
548 | {
549 | "name": "斯柯达"
550 | },
551 | {
552 | "name": "斯达泰克"
553 | },
554 | {
555 | "name": "斯巴鲁"
556 | },
557 | {
558 | "name": "思铭"
559 | },
560 | {
561 | "name": "双龙"
562 | },
563 | {
564 | "name": "双环"
565 | },
566 | {
567 | "name": "世爵"
568 | },
569 | {
570 | "name": "上汽大通"
571 | },
572 | {
573 | "name": "陕汽通家"
574 | },
575 | {
576 | "name": "三菱"
577 | },
578 | {
579 | "name": "赛麟"
580 | },
581 | {
582 | "name": "萨博"
583 | },
584 | {
585 | "name": "SWM斯威汽车"
586 | },
587 | {
588 | "name": "smart"
589 | },
590 | {
591 | "name": "天际汽车"
592 | },
593 | {
594 | "name": "腾势"
595 | },
596 | {
597 | "name": "特斯拉"
598 | },
599 | {
600 | "name": "泰卡特"
601 | },
602 | {
603 | "name": "潍柴汽车"
604 | },
605 | {
606 | "name": "威马汽车"
607 | },
608 | {
609 | "name": "五十铃"
610 | },
611 | {
612 | "name": "五菱汽车"
613 | },
614 | {
615 | "name": "沃尔沃"
616 | },
617 | {
618 | "name": "蔚来"
619 | },
620 | {
621 | "name": "潍柴英致"
622 | },
623 | {
624 | "name": "威兹曼"
625 | },
626 | {
627 | "name": "威麟"
628 | },
629 | {
630 | "name": "WEY"
631 | },
632 | {
633 | "name": "新宝骏"
634 | },
635 | {
636 | "name": "星途"
637 | },
638 | {
639 | "name": "小鹏汽车"
640 | },
641 | {
642 | "name": "新特汽车"
643 | },
644 | {
645 | "name": "雪铁龙"
646 | },
647 | {
648 | "name": "雪佛兰"
649 | },
650 | {
651 | "name": "鑫源"
652 | },
653 | {
654 | "name": "新凯"
655 | },
656 | {
657 | "name": "现代"
658 | },
659 | {
660 | "name": "西雅特"
661 | },
662 | {
663 | "name": "一汽凌河"
664 | },
665 | {
666 | "name": "远程汽车"
667 | },
668 | {
669 | "name": "银隆新能源"
670 | },
671 | {
672 | "name": "云雀汽车"
673 | },
674 | {
675 | "name": "云度"
676 | },
677 | {
678 | "name": "裕路"
679 | },
680 | {
681 | "name": "御捷"
682 | },
683 | {
684 | "name": "驭胜"
685 | },
686 | {
687 | "name": "宇通客车"
688 | },
689 | {
690 | "name": "永源"
691 | },
692 | {
693 | "name": "英菲尼迪"
694 | },
695 | {
696 | "name": "依维柯"
697 | },
698 | {
699 | "name": "一汽"
700 | },
701 | {
702 | "name": "野马汽车"
703 | },
704 | {
705 | "name": "众泰"
706 | },
707 | {
708 | "name": "中兴"
709 | },
710 | {
711 | "name": "中华"
712 | },
713 | {
714 | "name": "知豆"
715 | },
716 | {
717 | "name": "之诺"
718 | }
719 | ]
--------------------------------------------------------------------------------
/example/assets/data/china.json:
--------------------------------------------------------------------------------
1 | {
2 | "china": [
3 | {
4 | "name": "北京市"
5 | },
6 | {
7 | "name": "天津市"
8 | },
9 | {
10 | "name": "石家庄市"
11 | },
12 | {
13 | "name": "唐山市"
14 | },
15 | {
16 | "name": "秦皇岛市"
17 | },
18 | {
19 | "name": "邯郸市"
20 | },
21 | {
22 | "name": "邢台市"
23 | },
24 | {
25 | "name": "保定市"
26 | },
27 | {
28 | "name": "张家口市"
29 | },
30 | {
31 | "name": "承德市"
32 | },
33 | {
34 | "name": "沧州市"
35 | },
36 | {
37 | "name": "廊坊市"
38 | },
39 | {
40 | "name": "衡水市"
41 | },
42 | {
43 | "name": "太原市"
44 | },
45 | {
46 | "name": "大同市"
47 | },
48 | {
49 | "name": "阳泉市"
50 | },
51 | {
52 | "name": "长治市"
53 | },
54 | {
55 | "name": "晋城市"
56 | },
57 | {
58 | "name": "朔州市"
59 | },
60 | {
61 | "name": "晋中市"
62 | },
63 | {
64 | "name": "运城市"
65 | },
66 | {
67 | "name": "忻州市"
68 | },
69 | {
70 | "name": "临汾市"
71 | },
72 | {
73 | "name": "吕梁市"
74 | },
75 | {
76 | "name": "呼和浩特市"
77 | },
78 | {
79 | "name": "包头市"
80 | },
81 | {
82 | "name": "乌海市"
83 | },
84 | {
85 | "name": "赤峰市"
86 | },
87 | {
88 | "name": "通辽市"
89 | },
90 | {
91 | "name": "鄂尔多斯市"
92 | },
93 | {
94 | "name": "呼伦贝尔市"
95 | },
96 | {
97 | "name": "巴彦淖尔市"
98 | },
99 | {
100 | "name": "乌兰察布市"
101 | },
102 | {
103 | "name": "兴安盟"
104 | },
105 | {
106 | "name": "锡林郭勒盟"
107 | },
108 | {
109 | "name": "阿拉善盟"
110 | },
111 | {
112 | "name": "沈阳市"
113 | },
114 | {
115 | "name": "大连市"
116 | },
117 | {
118 | "name": "鞍山市"
119 | },
120 | {
121 | "name": "抚顺市"
122 | },
123 | {
124 | "name": "本溪市"
125 | },
126 | {
127 | "name": "丹东市"
128 | },
129 | {
130 | "name": "锦州市"
131 | },
132 | {
133 | "name": "营口市"
134 | },
135 | {
136 | "name": "阜新市"
137 | },
138 | {
139 | "name": "辽阳市"
140 | },
141 | {
142 | "name": "盘锦市"
143 | },
144 | {
145 | "name": "铁岭市"
146 | },
147 | {
148 | "name": "朝阳市"
149 | },
150 | {
151 | "name": "葫芦岛市"
152 | },
153 | {
154 | "name": "长春市"
155 | },
156 | {
157 | "name": "吉林市"
158 | },
159 | {
160 | "name": "四平市"
161 | },
162 | {
163 | "name": "辽源市"
164 | },
165 | {
166 | "name": "通化市"
167 | },
168 | {
169 | "name": "白山市"
170 | },
171 | {
172 | "name": "松原市"
173 | },
174 | {
175 | "name": "白城市"
176 | },
177 | {
178 | "name": "延边朝鲜族自治州"
179 | },
180 | {
181 | "name": "哈尔滨市"
182 | },
183 | {
184 | "name": "齐齐哈尔市"
185 | },
186 | {
187 | "name": "鸡西市"
188 | },
189 | {
190 | "name": "鹤岗市"
191 | },
192 | {
193 | "name": "双鸭山市"
194 | },
195 | {
196 | "name": "大庆市"
197 | },
198 | {
199 | "name": "伊春市"
200 | },
201 | {
202 | "name": "佳木斯市"
203 | },
204 | {
205 | "name": "七台河市"
206 | },
207 | {
208 | "name": "牡丹江市"
209 | },
210 | {
211 | "name": "黑河市"
212 | },
213 | {
214 | "name": "绥化市"
215 | },
216 | {
217 | "name": "大兴安岭地区"
218 | },
219 | {
220 | "name": "上海市"
221 | },
222 | {
223 | "name": "南京市"
224 | },
225 | {
226 | "name": "无锡市"
227 | },
228 | {
229 | "name": "徐州市"
230 | },
231 | {
232 | "name": "常州市"
233 | },
234 | {
235 | "name": "苏州市"
236 | },
237 | {
238 | "name": "南通市"
239 | },
240 | {
241 | "name": "连云港市"
242 | },
243 | {
244 | "name": "淮安市"
245 | },
246 | {
247 | "name": "盐城市"
248 | },
249 | {
250 | "name": "扬州市"
251 | },
252 | {
253 | "name": "镇江市"
254 | },
255 | {
256 | "name": "泰州市"
257 | },
258 | {
259 | "name": "宿迁市"
260 | },
261 | {
262 | "name": "杭州市"
263 | },
264 | {
265 | "name": "宁波市"
266 | },
267 | {
268 | "name": "温州市"
269 | },
270 | {
271 | "name": "嘉兴市"
272 | },
273 | {
274 | "name": "湖州市"
275 | },
276 | {
277 | "name": "绍兴市"
278 | },
279 | {
280 | "name": "金华市"
281 | },
282 | {
283 | "name": "衢州市"
284 | },
285 | {
286 | "name": "舟山市"
287 | },
288 | {
289 | "name": "台州市"
290 | },
291 | {
292 | "name": "丽水市"
293 | },
294 | {
295 | "name": "合肥市"
296 | },
297 | {
298 | "name": "芜湖市"
299 | },
300 | {
301 | "name": "蚌埠市"
302 | },
303 | {
304 | "name": "淮南市"
305 | },
306 | {
307 | "name": "马鞍山市"
308 | },
309 | {
310 | "name": "淮北市"
311 | },
312 | {
313 | "name": "铜陵市"
314 | },
315 | {
316 | "name": "安庆市"
317 | },
318 | {
319 | "name": "黄山市"
320 | },
321 | {
322 | "name": "滁州市"
323 | },
324 | {
325 | "name": "阜阳市"
326 | },
327 | {
328 | "name": "宿州市"
329 | },
330 | {
331 | "name": "巢湖市"
332 | },
333 | {
334 | "name": "六安市"
335 | },
336 | {
337 | "name": "亳州市"
338 | },
339 | {
340 | "name": "池州市"
341 | },
342 | {
343 | "name": "宣城市"
344 | },
345 | {
346 | "name": "福州市"
347 | },
348 | {
349 | "name": "厦门市"
350 | },
351 | {
352 | "name": "莆田市"
353 | },
354 | {
355 | "name": "三明市"
356 | },
357 | {
358 | "name": "泉州市"
359 | },
360 | {
361 | "name": "漳州市"
362 | },
363 | {
364 | "name": "南平市"
365 | },
366 | {
367 | "name": "龙岩市"
368 | },
369 | {
370 | "name": "宁德市"
371 | },
372 | {
373 | "name": "南昌市"
374 | },
375 | {
376 | "name": "景德镇市"
377 | },
378 | {
379 | "name": "萍乡市"
380 | },
381 | {
382 | "name": "九江市"
383 | },
384 | {
385 | "name": "新余市"
386 | },
387 | {
388 | "name": "鹰潭市"
389 | },
390 | {
391 | "name": "赣州市"
392 | },
393 | {
394 | "name": "吉安市"
395 | },
396 | {
397 | "name": "宜春市"
398 | },
399 | {
400 | "name": "抚州市"
401 | },
402 | {
403 | "name": "上饶市"
404 | },
405 | {
406 | "name": "济南市"
407 | },
408 | {
409 | "name": "青岛市"
410 | },
411 | {
412 | "name": "淄博市"
413 | },
414 | {
415 | "name": "枣庄市"
416 | },
417 | {
418 | "name": "东营市"
419 | },
420 | {
421 | "name": "烟台市"
422 | },
423 | {
424 | "name": "潍坊市"
425 | },
426 | {
427 | "name": "济宁市"
428 | },
429 | {
430 | "name": "泰安市"
431 | },
432 | {
433 | "name": "威海市"
434 | },
435 | {
436 | "name": "日照市"
437 | },
438 | {
439 | "name": "莱芜市"
440 | },
441 | {
442 | "name": "临沂市"
443 | },
444 | {
445 | "name": "德州市"
446 | },
447 | {
448 | "name": "聊城市"
449 | },
450 | {
451 | "name": "滨州市"
452 | },
453 | {
454 | "name": "菏泽市"
455 | },
456 | {
457 | "name": "郑州市"
458 | },
459 | {
460 | "name": "开封市"
461 | },
462 | {
463 | "name": "洛阳市"
464 | },
465 | {
466 | "name": "平顶山市"
467 | },
468 | {
469 | "name": "安阳市"
470 | },
471 | {
472 | "name": "鹤壁市"
473 | },
474 | {
475 | "name": "新乡市"
476 | },
477 | {
478 | "name": "焦作市"
479 | },
480 | {
481 | "name": "濮阳市"
482 | },
483 | {
484 | "name": "许昌市"
485 | },
486 | {
487 | "name": "漯河市"
488 | },
489 | {
490 | "name": "三门峡市"
491 | },
492 | {
493 | "name": "南阳市"
494 | },
495 | {
496 | "name": "商丘市"
497 | },
498 | {
499 | "name": "信阳市"
500 | },
501 | {
502 | "name": "周口市"
503 | },
504 | {
505 | "name": "驻马店市"
506 | },
507 | {
508 | "name": "武汉市"
509 | },
510 | {
511 | "name": "黄石市"
512 | },
513 | {
514 | "name": "十堰市"
515 | },
516 | {
517 | "name": "宜昌市"
518 | },
519 | {
520 | "name": "襄樊市"
521 | },
522 | {
523 | "name": "鄂州市"
524 | },
525 | {
526 | "name": "荆门市"
527 | },
528 | {
529 | "name": "孝感市"
530 | },
531 | {
532 | "name": "荆州市"
533 | },
534 | {
535 | "name": "黄冈市"
536 | },
537 | {
538 | "name": "咸宁市"
539 | },
540 | {
541 | "name": "随州市"
542 | },
543 | {
544 | "name": "恩施土家族苗族自治州"
545 | },
546 | {
547 | "name": "仙桃市"
548 | },
549 | {
550 | "name": "潜江市"
551 | },
552 | {
553 | "name": "天门市"
554 | },
555 | {
556 | "name": "神农架林区"
557 | },
558 | {
559 | "name": "长沙市"
560 | },
561 | {
562 | "name": "株洲市"
563 | },
564 | {
565 | "name": "湘潭市"
566 | },
567 | {
568 | "name": "衡阳市"
569 | },
570 | {
571 | "name": "邵阳市"
572 | },
573 | {
574 | "name": "岳阳市"
575 | },
576 | {
577 | "name": "常德市"
578 | },
579 | {
580 | "name": "张家界市"
581 | },
582 | {
583 | "name": "益阳市"
584 | },
585 | {
586 | "name": "郴州市"
587 | },
588 | {
589 | "name": "永州市"
590 | },
591 | {
592 | "name": "怀化市"
593 | },
594 | {
595 | "name": "娄底市"
596 | },
597 | {
598 | "name": "湘西土家族苗族自治州"
599 | },
600 | {
601 | "name": "广州市"
602 | },
603 | {
604 | "name": "韶关市"
605 | },
606 | {
607 | "name": "深圳市"
608 | },
609 | {
610 | "name": "珠海市"
611 | },
612 | {
613 | "name": "汕头市"
614 | },
615 | {
616 | "name": "佛山市"
617 | },
618 | {
619 | "name": "江门市"
620 | },
621 | {
622 | "name": "湛江市"
623 | },
624 | {
625 | "name": "茂名市"
626 | },
627 | {
628 | "name": "肇庆市"
629 | },
630 | {
631 | "name": "惠州市"
632 | },
633 | {
634 | "name": "梅州市"
635 | },
636 | {
637 | "name": "汕尾市"
638 | },
639 | {
640 | "name": "河源市"
641 | },
642 | {
643 | "name": "阳江市"
644 | },
645 | {
646 | "name": "清远市"
647 | },
648 | {
649 | "name": "东莞市"
650 | },
651 | {
652 | "name": "中山市"
653 | },
654 | {
655 | "name": "潮州市"
656 | },
657 | {
658 | "name": "揭阳市"
659 | },
660 | {
661 | "name": "云浮市"
662 | },
663 | {
664 | "name": "南宁市"
665 | },
666 | {
667 | "name": "柳州市"
668 | },
669 | {
670 | "name": "桂林市"
671 | },
672 | {
673 | "name": "梧州市"
674 | },
675 | {
676 | "name": "北海市"
677 | },
678 | {
679 | "name": "防城港市"
680 | },
681 | {
682 | "name": "钦州市"
683 | },
684 | {
685 | "name": "贵港市"
686 | },
687 | {
688 | "name": "玉林市"
689 | },
690 | {
691 | "name": "百色市"
692 | },
693 | {
694 | "name": "贺州市"
695 | },
696 | {
697 | "name": "河池市"
698 | },
699 | {
700 | "name": "来宾市"
701 | },
702 | {
703 | "name": "崇左市"
704 | },
705 | {
706 | "name": "海口市"
707 | },
708 | {
709 | "name": "三亚市"
710 | },
711 | {
712 | "name": "重庆市"
713 | },
714 | {
715 | "name": "成都市"
716 | },
717 | {
718 | "name": "自贡市"
719 | },
720 | {
721 | "name": "攀枝花市"
722 | },
723 | {
724 | "name": "泸州市"
725 | },
726 | {
727 | "name": "德阳市"
728 | },
729 | {
730 | "name": "绵阳市"
731 | },
732 | {
733 | "name": "广元市"
734 | },
735 | {
736 | "name": "遂宁市"
737 | },
738 | {
739 | "name": "内江市"
740 | },
741 | {
742 | "name": "乐山市"
743 | },
744 | {
745 | "name": "南充市"
746 | },
747 | {
748 | "name": "眉山市"
749 | },
750 | {
751 | "name": "宜宾市"
752 | },
753 | {
754 | "name": "广安市"
755 | },
756 | {
757 | "name": "达州市"
758 | },
759 | {
760 | "name": "雅安市"
761 | },
762 | {
763 | "name": "巴中市"
764 | },
765 | {
766 | "name": "资阳市"
767 | },
768 | {
769 | "name": "阿坝藏族羌族自治州"
770 | },
771 | {
772 | "name": "甘孜藏族自治州"
773 | },
774 | {
775 | "name": "凉山彝族自治州"
776 | },
777 | {
778 | "name": "贵阳市"
779 | },
780 | {
781 | "name": "六盘水市"
782 | },
783 | {
784 | "name": "遵义市"
785 | },
786 | {
787 | "name": "安顺市"
788 | },
789 | {
790 | "name": "铜仁市"
791 | },
792 | {
793 | "name": "黔西南布依族苗族自治州"
794 | },
795 | {
796 | "name": "毕节市"
797 | },
798 | {
799 | "name": "黔东南苗族侗族自治州"
800 | },
801 | {
802 | "name": "黔南布依族苗族自治州"
803 | },
804 | {
805 | "name": "昆明市"
806 | },
807 | {
808 | "name": "曲靖市"
809 | },
810 | {
811 | "name": "玉溪市"
812 | },
813 | {
814 | "name": "保山市"
815 | },
816 | {
817 | "name": "昭通市"
818 | },
819 | {
820 | "name": "丽江市"
821 | },
822 | {
823 | "name": "思茅市"
824 | },
825 | {
826 | "name": "临沧市"
827 | },
828 | {
829 | "name": "楚雄彝族自治州"
830 | },
831 | {
832 | "name": "红河哈尼族彝族自治州"
833 | },
834 | {
835 | "name": "文山壮族苗族自治州"
836 | },
837 | {
838 | "name": "西双版纳傣族自治州"
839 | },
840 | {
841 | "name": "大理白族自治州"
842 | },
843 | {
844 | "name": "德宏傣族景颇族自治州"
845 | },
846 | {
847 | "name": "怒江傈僳族自治州"
848 | },
849 | {
850 | "name": "迪庆藏族自治州"
851 | },
852 | {
853 | "name": "拉萨市"
854 | },
855 | {
856 | "name": "昌都地区"
857 | },
858 | {
859 | "name": "山南地区"
860 | },
861 | {
862 | "name": "日喀则地区"
863 | },
864 | {
865 | "name": "那曲地区"
866 | },
867 | {
868 | "name": "阿里地区"
869 | },
870 | {
871 | "name": "林芝地区"
872 | },
873 | {
874 | "name": "西安市"
875 | },
876 | {
877 | "name": "铜川市"
878 | },
879 | {
880 | "name": "宝鸡市"
881 | },
882 | {
883 | "name": "咸阳市"
884 | },
885 | {
886 | "name": "渭南市"
887 | },
888 | {
889 | "name": "延安市"
890 | },
891 | {
892 | "name": "汉中市"
893 | },
894 | {
895 | "name": "榆林市"
896 | },
897 | {
898 | "name": "安康市"
899 | },
900 | {
901 | "name": "商洛市"
902 | },
903 | {
904 | "name": "兰州市"
905 | },
906 | {
907 | "name": "嘉峪关市"
908 | },
909 | {
910 | "name": "金昌市"
911 | },
912 | {
913 | "name": "白银市"
914 | },
915 | {
916 | "name": "天水市"
917 | },
918 | {
919 | "name": "武威市"
920 | },
921 | {
922 | "name": "张掖市"
923 | },
924 | {
925 | "name": "平凉市"
926 | },
927 | {
928 | "name": "酒泉市"
929 | },
930 | {
931 | "name": "庆阳市"
932 | },
933 | {
934 | "name": "定西市"
935 | },
936 | {
937 | "name": "陇南市"
938 | },
939 | {
940 | "name": "临夏回族自治州"
941 | },
942 | {
943 | "name": "甘南藏族自治州"
944 | },
945 | {
946 | "name": "西宁市"
947 | },
948 | {
949 | "name": "海东地区"
950 | },
951 | {
952 | "name": "海北藏族自治州"
953 | },
954 | {
955 | "name": "黄南藏族自治州"
956 | },
957 | {
958 | "name": "海南藏族自治州"
959 | },
960 | {
961 | "name": "果洛藏族自治州"
962 | },
963 | {
964 | "name": "玉树藏族自治州"
965 | },
966 | {
967 | "name": "海西蒙古族藏族自治州"
968 | },
969 | {
970 | "name": "银川市"
971 | },
972 | {
973 | "name": "石嘴山市"
974 | },
975 | {
976 | "name": "吴忠市"
977 | },
978 | {
979 | "name": "固原市"
980 | },
981 | {
982 | "name": "中卫市"
983 | },
984 | {
985 | "name": "乌鲁木齐市"
986 | },
987 | {
988 | "name": "克拉玛依市"
989 | },
990 | {
991 | "name": "吐鲁番地区"
992 | },
993 | {
994 | "name": "哈密地区"
995 | },
996 | {
997 | "name": "昌吉回族自治州"
998 | },
999 | {
1000 | "name": "博尔塔拉蒙古自治州"
1001 | },
1002 | {
1003 | "name": "巴音郭楞蒙古自治州"
1004 | },
1005 | {
1006 | "name": "阿克苏地区"
1007 | },
1008 | {
1009 | "name": "克孜勒苏柯尔克孜自治州"
1010 | },
1011 | {
1012 | "name": "喀什地区"
1013 | },
1014 | {
1015 | "name": "和田地区"
1016 | },
1017 | {
1018 | "name": "伊犁哈萨克"
1019 | },
1020 | {
1021 | "name": "塔城地区"
1022 | },
1023 | {
1024 | "name": "阿勒泰地区"
1025 | },
1026 | {
1027 | "name": "石河子市"
1028 | },
1029 | {
1030 | "name": "阿拉尔市"
1031 | },
1032 | {
1033 | "name": "图木舒克市"
1034 | },
1035 | {
1036 | "name": "五家渠市"
1037 | },
1038 | {
1039 | "name": "台北"
1040 | },
1041 | {
1042 | "name": "高雄"
1043 | },
1044 | {
1045 | "name": "基隆"
1046 | },
1047 | {
1048 | "name": "台中"
1049 | },
1050 | {
1051 | "name": "台南"
1052 | },
1053 | {
1054 | "name": "新竹"
1055 | },
1056 | {
1057 | "name": "嘉义"
1058 | },
1059 | {
1060 | "name": "宜兰"
1061 | },
1062 | {
1063 | "name": "桃园"
1064 | },
1065 | {
1066 | "name": "苗栗"
1067 | },
1068 | {
1069 | "name": "彰化"
1070 | },
1071 | {
1072 | "name": "南投"
1073 | },
1074 | {
1075 | "name": "云林"
1076 | },
1077 | {
1078 | "name": "屏东"
1079 | },
1080 | {
1081 | "name": "台东"
1082 | },
1083 | {
1084 | "name": "花莲"
1085 | },
1086 | {
1087 | "name": "澎湖"
1088 | },
1089 | {
1090 | "name": "香港岛"
1091 | },
1092 | {
1093 | "name": "九龙"
1094 | },
1095 | {
1096 | "name": "新界"
1097 | },
1098 | {
1099 | "name": "澳门半岛"
1100 | },
1101 | {
1102 | "name": "氹仔岛"
1103 | },
1104 | {
1105 | "name": "路环岛"
1106 | },
1107 | {
1108 | "name": "路氹城"
1109 | }
1110 | ]
1111 | }
1112 |
--------------------------------------------------------------------------------
/example/assets/data/contacts.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "name":"Alice",
4 | "phone":[
5 | "18221338086"
6 | ]
7 | },
8 | {
9 | "name":"阿发",
10 | "phone":[
11 | "18221338086"
12 | ]
13 | },
14 | {
15 | "name":"Bob",
16 | "phone":[
17 | "18221338086"
18 | ]
19 | },
20 | {
21 | "name":"David",
22 | "phone":[
23 | "18221338086"
24 | ]
25 | },
26 | {
27 | "name":"Doris",
28 | "phone":[
29 | "18221338086"
30 | ]
31 | },
32 | {
33 | "name":"杜娟",
34 | "phone":[
35 | "18221338086"
36 | ]
37 | },
38 | {
39 | "name":"Jack",
40 | "phone":[
41 | "18221338086"
42 | ]
43 | },
44 | {
45 | "name":"Rose",
46 | "phone":[
47 | "18221338086"
48 | ]
49 | },
50 | {
51 | "name":"任盈盈",
52 | "phone":[
53 | "18221338086"
54 | ]
55 | },
56 | {
57 | "name":"孙正义",
58 | "phone":[
59 | "18221338086"
60 | ]
61 | },
62 | {
63 | "name":"Sally",
64 | "phone":[
65 | "18221338086"
66 | ]
67 | }
68 | ]
--------------------------------------------------------------------------------
/example/assets/images/ali_connors.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flutterchina/azlistview/ea7e11660223c3b6b1f3491ab0e5e04a333cca5d/example/assets/images/ali_connors.png
--------------------------------------------------------------------------------
/example/assets/images/avatar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flutterchina/azlistview/ea7e11660223c3b6b1f3491ab0e5e04a333cca5d/example/assets/images/avatar.png
--------------------------------------------------------------------------------
/example/assets/images/ic_car_models_header1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flutterchina/azlistview/ea7e11660223c3b6b1f3491ab0e5e04a333cca5d/example/assets/images/ic_car_models_header1.png
--------------------------------------------------------------------------------
/example/assets/images/ic_car_models_header2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flutterchina/azlistview/ea7e11660223c3b6b1f3491ab0e5e04a333cca5d/example/assets/images/ic_car_models_header2.png
--------------------------------------------------------------------------------
/example/assets/images/ic_favorite.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flutterchina/azlistview/ea7e11660223c3b6b1f3491ab0e5e04a333cca5d/example/assets/images/ic_favorite.png
--------------------------------------------------------------------------------
/example/assets/images/ic_index_bar_bubble_gray.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flutterchina/azlistview/ea7e11660223c3b6b1f3491ab0e5e04a333cca5d/example/assets/images/ic_index_bar_bubble_gray.png
--------------------------------------------------------------------------------
/example/assets/images/ic_index_bar_bubble_white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flutterchina/azlistview/ea7e11660223c3b6b1f3491ab0e5e04a333cca5d/example/assets/images/ic_index_bar_bubble_white.png
--------------------------------------------------------------------------------
/example/ios/.gitignore:
--------------------------------------------------------------------------------
1 | *.mode1v3
2 | *.mode2v3
3 | *.moved-aside
4 | *.pbxuser
5 | *.perspectivev3
6 | **/*sync/
7 | .sconsign.dblite
8 | .tags*
9 | **/.vagrant/
10 | **/DerivedData/
11 | Icon?
12 | **/Pods/
13 | **/.symlinks/
14 | profile
15 | xcuserdata
16 | **/.generated/
17 | Flutter/App.framework
18 | Flutter/Flutter.framework
19 | Flutter/Flutter.podspec
20 | Flutter/Generated.xcconfig
21 | Flutter/app.flx
22 | Flutter/app.zip
23 | Flutter/flutter_assets/
24 | Flutter/flutter_export_environment.sh
25 | ServiceDefinitions.json
26 | Runner/GeneratedPluginRegistrant.*
27 |
28 | # Exceptions to above rules.
29 | !default.mode1v3
30 | !default.mode2v3
31 | !default.pbxuser
32 | !default.perspectivev3
33 |
--------------------------------------------------------------------------------
/example/ios/Flutter/AppFrameworkInfo.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | App
9 | CFBundleIdentifier
10 | io.flutter.flutter.app
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | App
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1.0
23 | MinimumOSVersion
24 | 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 | post_install do |installer|
82 | installer.pods_project.targets.each do |target|
83 | target.build_configurations.each do |config|
84 | config.build_settings['ENABLE_BITCODE'] = 'NO'
85 | end
86 | end
87 | end
88 |
--------------------------------------------------------------------------------
/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 | - path_provider (0.0.1):
7 | - Flutter
8 | - path_provider_linux (0.0.1):
9 | - Flutter
10 | - path_provider_macos (0.0.1):
11 | - Flutter
12 | - sqflite (0.0.1):
13 | - Flutter
14 | - FMDB (~> 2.7.2)
15 |
16 | DEPENDENCIES:
17 | - Flutter (from `Flutter`)
18 | - path_provider (from `.symlinks/plugins/path_provider/ios`)
19 | - path_provider_linux (from `.symlinks/plugins/path_provider_linux/ios`)
20 | - path_provider_macos (from `.symlinks/plugins/path_provider_macos/ios`)
21 | - sqflite (from `.symlinks/plugins/sqflite/ios`)
22 |
23 | SPEC REPOS:
24 | trunk:
25 | - FMDB
26 |
27 | EXTERNAL SOURCES:
28 | Flutter:
29 | :path: Flutter
30 | path_provider:
31 | :path: ".symlinks/plugins/path_provider/ios"
32 | path_provider_linux:
33 | :path: ".symlinks/plugins/path_provider_linux/ios"
34 | path_provider_macos:
35 | :path: ".symlinks/plugins/path_provider_macos/ios"
36 | sqflite:
37 | :path: ".symlinks/plugins/sqflite/ios"
38 |
39 | SPEC CHECKSUMS:
40 | Flutter: 0e3d915762c693b495b44d77113d4970485de6ec
41 | FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a
42 | path_provider: abfe2b5c733d04e238b0d8691db0cfd63a27a93c
43 | path_provider_linux: 4d630dc393e1f20364f3e3b4a2ff41d9674a84e4
44 | path_provider_macos: f760a3c5b04357c380e2fddb6f9db6f3015897e0
45 | sqflite: 4001a31ff81d210346b500c55b17f4d6c7589dd0
46 |
47 | PODFILE CHECKSUM: c34e2287a9ccaa606aeceab922830efb9a6ff69a
48 |
49 | COCOAPODS: 1.8.4
50 |
--------------------------------------------------------------------------------
/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 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
13 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
14 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
15 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
16 | CE6203087DBD7A8E841D7774 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D10AD785B4A6315ECC23DCDE /* Pods_Runner.framework */; };
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 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; };
36 | 4583996D90605FE936F7A1D6 /* 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 = ""; };
37 | 499A43082F7CE4882CEE5205 /* 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 = ""; };
38 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; };
39 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
40 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; };
41 | 8F0F95455ADF3AD6DC275CD4 /* 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 = ""; };
42 | 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; };
43 | 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; };
44 | 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
45 | 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
46 | 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
47 | 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
48 | 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
49 | D10AD785B4A6315ECC23DCDE /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
50 | /* End PBXFileReference section */
51 |
52 | /* Begin PBXFrameworksBuildPhase section */
53 | 97C146EB1CF9000F007C117D /* Frameworks */ = {
54 | isa = PBXFrameworksBuildPhase;
55 | buildActionMask = 2147483647;
56 | files = (
57 | CE6203087DBD7A8E841D7774 /* Pods_Runner.framework in Frameworks */,
58 | );
59 | runOnlyForDeploymentPostprocessing = 0;
60 | };
61 | /* End PBXFrameworksBuildPhase section */
62 |
63 | /* Begin PBXGroup section */
64 | 9740EEB11CF90186004384FC /* Flutter */ = {
65 | isa = PBXGroup;
66 | children = (
67 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
68 | 9740EEB21CF90195004384FC /* Debug.xcconfig */,
69 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
70 | 9740EEB31CF90195004384FC /* Generated.xcconfig */,
71 | );
72 | name = Flutter;
73 | sourceTree = "";
74 | };
75 | 97C146E51CF9000F007C117D = {
76 | isa = PBXGroup;
77 | children = (
78 | 9740EEB11CF90186004384FC /* Flutter */,
79 | 97C146F01CF9000F007C117D /* Runner */,
80 | 97C146EF1CF9000F007C117D /* Products */,
81 | EB53942A12133464C56B5EC9 /* Pods */,
82 | E84AB69AC495D2940C1E5035 /* Frameworks */,
83 | );
84 | sourceTree = "";
85 | };
86 | 97C146EF1CF9000F007C117D /* Products */ = {
87 | isa = PBXGroup;
88 | children = (
89 | 97C146EE1CF9000F007C117D /* Runner.app */,
90 | );
91 | name = Products;
92 | sourceTree = "";
93 | };
94 | 97C146F01CF9000F007C117D /* Runner */ = {
95 | isa = PBXGroup;
96 | children = (
97 | 97C146FA1CF9000F007C117D /* Main.storyboard */,
98 | 97C146FD1CF9000F007C117D /* Assets.xcassets */,
99 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
100 | 97C147021CF9000F007C117D /* Info.plist */,
101 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,
102 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
103 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */,
104 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */,
105 | );
106 | path = Runner;
107 | sourceTree = "";
108 | };
109 | E84AB69AC495D2940C1E5035 /* Frameworks */ = {
110 | isa = PBXGroup;
111 | children = (
112 | D10AD785B4A6315ECC23DCDE /* Pods_Runner.framework */,
113 | );
114 | name = Frameworks;
115 | sourceTree = "";
116 | };
117 | EB53942A12133464C56B5EC9 /* Pods */ = {
118 | isa = PBXGroup;
119 | children = (
120 | 8F0F95455ADF3AD6DC275CD4 /* Pods-Runner.debug.xcconfig */,
121 | 499A43082F7CE4882CEE5205 /* Pods-Runner.release.xcconfig */,
122 | 4583996D90605FE936F7A1D6 /* Pods-Runner.profile.xcconfig */,
123 | );
124 | name = Pods;
125 | path = Pods;
126 | sourceTree = "";
127 | };
128 | /* End PBXGroup section */
129 |
130 | /* Begin PBXNativeTarget section */
131 | 97C146ED1CF9000F007C117D /* Runner */ = {
132 | isa = PBXNativeTarget;
133 | buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
134 | buildPhases = (
135 | 6A3DD026FB050040666983D1 /* [CP] Check Pods Manifest.lock */,
136 | 9740EEB61CF901F6004384FC /* Run Script */,
137 | 97C146EA1CF9000F007C117D /* Sources */,
138 | 97C146EB1CF9000F007C117D /* Frameworks */,
139 | 97C146EC1CF9000F007C117D /* Resources */,
140 | 9705A1C41CF9048500538489 /* Embed Frameworks */,
141 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */,
142 | 58A7F13BF9B17BEA80A6D729 /* [CP] Embed Pods Frameworks */,
143 | );
144 | buildRules = (
145 | );
146 | dependencies = (
147 | );
148 | name = Runner;
149 | productName = Runner;
150 | productReference = 97C146EE1CF9000F007C117D /* Runner.app */;
151 | productType = "com.apple.product-type.application";
152 | };
153 | /* End PBXNativeTarget section */
154 |
155 | /* Begin PBXProject section */
156 | 97C146E61CF9000F007C117D /* Project object */ = {
157 | isa = PBXProject;
158 | attributes = {
159 | LastUpgradeCheck = 1020;
160 | ORGANIZATIONNAME = "";
161 | TargetAttributes = {
162 | 97C146ED1CF9000F007C117D = {
163 | CreatedOnToolsVersion = 7.3.1;
164 | LastSwiftMigration = 1100;
165 | };
166 | };
167 | };
168 | buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
169 | compatibilityVersion = "Xcode 9.3";
170 | developmentRegion = en;
171 | hasScannedForEncodings = 0;
172 | knownRegions = (
173 | en,
174 | Base,
175 | );
176 | mainGroup = 97C146E51CF9000F007C117D;
177 | productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
178 | projectDirPath = "";
179 | projectRoot = "";
180 | targets = (
181 | 97C146ED1CF9000F007C117D /* Runner */,
182 | );
183 | };
184 | /* End PBXProject section */
185 |
186 | /* Begin PBXResourcesBuildPhase section */
187 | 97C146EC1CF9000F007C117D /* Resources */ = {
188 | isa = PBXResourcesBuildPhase;
189 | buildActionMask = 2147483647;
190 | files = (
191 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
192 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
193 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
194 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
195 | );
196 | runOnlyForDeploymentPostprocessing = 0;
197 | };
198 | /* End PBXResourcesBuildPhase section */
199 |
200 | /* Begin PBXShellScriptBuildPhase section */
201 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
202 | isa = PBXShellScriptBuildPhase;
203 | buildActionMask = 2147483647;
204 | files = (
205 | );
206 | inputPaths = (
207 | );
208 | name = "Thin Binary";
209 | outputPaths = (
210 | );
211 | runOnlyForDeploymentPostprocessing = 0;
212 | shellPath = /bin/sh;
213 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
214 | };
215 | 58A7F13BF9B17BEA80A6D729 /* [CP] Embed Pods Frameworks */ = {
216 | isa = PBXShellScriptBuildPhase;
217 | buildActionMask = 2147483647;
218 | files = (
219 | );
220 | inputPaths = (
221 | "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh",
222 | "${BUILT_PRODUCTS_DIR}/FMDB/FMDB.framework",
223 | "${PODS_ROOT}/../Flutter/Flutter.framework",
224 | "${BUILT_PRODUCTS_DIR}/path_provider/path_provider.framework",
225 | "${BUILT_PRODUCTS_DIR}/sqflite/sqflite.framework",
226 | );
227 | name = "[CP] Embed Pods Frameworks";
228 | outputPaths = (
229 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FMDB.framework",
230 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Flutter.framework",
231 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/path_provider.framework",
232 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/sqflite.framework",
233 | );
234 | runOnlyForDeploymentPostprocessing = 0;
235 | shellPath = /bin/sh;
236 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
237 | showEnvVarsInLog = 0;
238 | };
239 | 6A3DD026FB050040666983D1 /* [CP] Check Pods Manifest.lock */ = {
240 | isa = PBXShellScriptBuildPhase;
241 | buildActionMask = 2147483647;
242 | files = (
243 | );
244 | inputFileListPaths = (
245 | );
246 | inputPaths = (
247 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
248 | "${PODS_ROOT}/Manifest.lock",
249 | );
250 | name = "[CP] Check Pods Manifest.lock";
251 | outputFileListPaths = (
252 | );
253 | outputPaths = (
254 | "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
255 | );
256 | runOnlyForDeploymentPostprocessing = 0;
257 | shellPath = /bin/sh;
258 | 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";
259 | showEnvVarsInLog = 0;
260 | };
261 | 9740EEB61CF901F6004384FC /* Run Script */ = {
262 | isa = PBXShellScriptBuildPhase;
263 | buildActionMask = 2147483647;
264 | files = (
265 | );
266 | inputPaths = (
267 | );
268 | name = "Run Script";
269 | outputPaths = (
270 | );
271 | runOnlyForDeploymentPostprocessing = 0;
272 | shellPath = /bin/sh;
273 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
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 | ENABLE_BITCODE = NO;
367 | FRAMEWORK_SEARCH_PATHS = (
368 | "$(inherited)",
369 | "$(PROJECT_DIR)/Flutter",
370 | );
371 | INFOPLIST_FILE = Runner/Info.plist;
372 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
373 | LIBRARY_SEARCH_PATHS = (
374 | "$(inherited)",
375 | "$(PROJECT_DIR)/Flutter",
376 | );
377 | PRODUCT_BUNDLE_IDENTIFIER = club.flutterchina.azlistviewExample;
378 | PRODUCT_NAME = "$(TARGET_NAME)";
379 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
380 | SWIFT_VERSION = 5.0;
381 | VERSIONING_SYSTEM = "apple-generic";
382 | };
383 | name = Profile;
384 | };
385 | 97C147031CF9000F007C117D /* Debug */ = {
386 | isa = XCBuildConfiguration;
387 | buildSettings = {
388 | ALWAYS_SEARCH_USER_PATHS = NO;
389 | CLANG_ANALYZER_NONNULL = YES;
390 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
391 | CLANG_CXX_LIBRARY = "libc++";
392 | CLANG_ENABLE_MODULES = YES;
393 | CLANG_ENABLE_OBJC_ARC = YES;
394 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
395 | CLANG_WARN_BOOL_CONVERSION = YES;
396 | CLANG_WARN_COMMA = YES;
397 | CLANG_WARN_CONSTANT_CONVERSION = YES;
398 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
399 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
400 | CLANG_WARN_EMPTY_BODY = YES;
401 | CLANG_WARN_ENUM_CONVERSION = YES;
402 | CLANG_WARN_INFINITE_RECURSION = YES;
403 | CLANG_WARN_INT_CONVERSION = YES;
404 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
405 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
406 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
407 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
408 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
409 | CLANG_WARN_STRICT_PROTOTYPES = YES;
410 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
411 | CLANG_WARN_UNREACHABLE_CODE = YES;
412 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
413 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
414 | COPY_PHASE_STRIP = NO;
415 | DEBUG_INFORMATION_FORMAT = dwarf;
416 | ENABLE_STRICT_OBJC_MSGSEND = YES;
417 | ENABLE_TESTABILITY = YES;
418 | GCC_C_LANGUAGE_STANDARD = gnu99;
419 | GCC_DYNAMIC_NO_PIC = NO;
420 | GCC_NO_COMMON_BLOCKS = YES;
421 | GCC_OPTIMIZATION_LEVEL = 0;
422 | GCC_PREPROCESSOR_DEFINITIONS = (
423 | "DEBUG=1",
424 | "$(inherited)",
425 | );
426 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
427 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
428 | GCC_WARN_UNDECLARED_SELECTOR = YES;
429 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
430 | GCC_WARN_UNUSED_FUNCTION = YES;
431 | GCC_WARN_UNUSED_VARIABLE = YES;
432 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
433 | MTL_ENABLE_DEBUG_INFO = YES;
434 | ONLY_ACTIVE_ARCH = YES;
435 | SDKROOT = iphoneos;
436 | TARGETED_DEVICE_FAMILY = "1,2";
437 | };
438 | name = Debug;
439 | };
440 | 97C147041CF9000F007C117D /* Release */ = {
441 | isa = XCBuildConfiguration;
442 | buildSettings = {
443 | ALWAYS_SEARCH_USER_PATHS = NO;
444 | CLANG_ANALYZER_NONNULL = YES;
445 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
446 | CLANG_CXX_LIBRARY = "libc++";
447 | CLANG_ENABLE_MODULES = YES;
448 | CLANG_ENABLE_OBJC_ARC = YES;
449 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
450 | CLANG_WARN_BOOL_CONVERSION = YES;
451 | CLANG_WARN_COMMA = YES;
452 | CLANG_WARN_CONSTANT_CONVERSION = YES;
453 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
454 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
455 | CLANG_WARN_EMPTY_BODY = YES;
456 | CLANG_WARN_ENUM_CONVERSION = YES;
457 | CLANG_WARN_INFINITE_RECURSION = YES;
458 | CLANG_WARN_INT_CONVERSION = YES;
459 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
460 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
461 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
462 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
463 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
464 | CLANG_WARN_STRICT_PROTOTYPES = YES;
465 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
466 | CLANG_WARN_UNREACHABLE_CODE = YES;
467 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
468 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
469 | COPY_PHASE_STRIP = NO;
470 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
471 | ENABLE_NS_ASSERTIONS = NO;
472 | ENABLE_STRICT_OBJC_MSGSEND = YES;
473 | GCC_C_LANGUAGE_STANDARD = gnu99;
474 | GCC_NO_COMMON_BLOCKS = YES;
475 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
476 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
477 | GCC_WARN_UNDECLARED_SELECTOR = YES;
478 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
479 | GCC_WARN_UNUSED_FUNCTION = YES;
480 | GCC_WARN_UNUSED_VARIABLE = YES;
481 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
482 | MTL_ENABLE_DEBUG_INFO = NO;
483 | SDKROOT = iphoneos;
484 | SUPPORTED_PLATFORMS = iphoneos;
485 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
486 | TARGETED_DEVICE_FAMILY = "1,2";
487 | VALIDATE_PRODUCT = YES;
488 | };
489 | name = Release;
490 | };
491 | 97C147061CF9000F007C117D /* Debug */ = {
492 | isa = XCBuildConfiguration;
493 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
494 | buildSettings = {
495 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
496 | CLANG_ENABLE_MODULES = YES;
497 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
498 | ENABLE_BITCODE = NO;
499 | FRAMEWORK_SEARCH_PATHS = (
500 | "$(inherited)",
501 | "$(PROJECT_DIR)/Flutter",
502 | );
503 | INFOPLIST_FILE = Runner/Info.plist;
504 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
505 | LIBRARY_SEARCH_PATHS = (
506 | "$(inherited)",
507 | "$(PROJECT_DIR)/Flutter",
508 | );
509 | PRODUCT_BUNDLE_IDENTIFIER = club.flutterchina.azlistviewExample;
510 | PRODUCT_NAME = "$(TARGET_NAME)";
511 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
512 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
513 | SWIFT_VERSION = 5.0;
514 | VERSIONING_SYSTEM = "apple-generic";
515 | };
516 | name = Debug;
517 | };
518 | 97C147071CF9000F007C117D /* Release */ = {
519 | isa = XCBuildConfiguration;
520 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
521 | buildSettings = {
522 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
523 | CLANG_ENABLE_MODULES = YES;
524 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
525 | ENABLE_BITCODE = NO;
526 | FRAMEWORK_SEARCH_PATHS = (
527 | "$(inherited)",
528 | "$(PROJECT_DIR)/Flutter",
529 | );
530 | INFOPLIST_FILE = Runner/Info.plist;
531 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
532 | LIBRARY_SEARCH_PATHS = (
533 | "$(inherited)",
534 | "$(PROJECT_DIR)/Flutter",
535 | );
536 | PRODUCT_BUNDLE_IDENTIFIER = club.flutterchina.azlistviewExample;
537 | PRODUCT_NAME = "$(TARGET_NAME)";
538 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
539 | SWIFT_VERSION = 5.0;
540 | VERSIONING_SYSTEM = "apple-generic";
541 | };
542 | name = Release;
543 | };
544 | /* End XCBuildConfiguration section */
545 |
546 | /* Begin XCConfigurationList section */
547 | 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = {
548 | isa = XCConfigurationList;
549 | buildConfigurations = (
550 | 97C147031CF9000F007C117D /* Debug */,
551 | 97C147041CF9000F007C117D /* Release */,
552 | 249021D3217E4FDB00AE95B9 /* Profile */,
553 | );
554 | defaultConfigurationIsVisible = 0;
555 | defaultConfigurationName = Release;
556 | };
557 | 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = {
558 | isa = XCConfigurationList;
559 | buildConfigurations = (
560 | 97C147061CF9000F007C117D /* Debug */,
561 | 97C147071CF9000F007C117D /* Release */,
562 | 249021D4217E4FDB00AE95B9 /* Profile */,
563 | );
564 | defaultConfigurationIsVisible = 0;
565 | defaultConfigurationName = Release;
566 | };
567 | /* End XCConfigurationList section */
568 | };
569 | rootObject = 97C146E61CF9000F007C117D /* Project object */;
570 | }
571 |
--------------------------------------------------------------------------------
/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreviewsEnabled
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
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.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreviewsEnabled
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/example/ios/Runner/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | import UIKit
2 | import Flutter
3 |
4 | @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/flutterchina/azlistview/ea7e11660223c3b6b1f3491ab0e5e04a333cca5d/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/flutterchina/azlistview/ea7e11660223c3b6b1f3491ab0e5e04a333cca5d/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/flutterchina/azlistview/ea7e11660223c3b6b1f3491ab0e5e04a333cca5d/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/flutterchina/azlistview/ea7e11660223c3b6b1f3491ab0e5e04a333cca5d/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/flutterchina/azlistview/ea7e11660223c3b6b1f3491ab0e5e04a333cca5d/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/flutterchina/azlistview/ea7e11660223c3b6b1f3491ab0e5e04a333cca5d/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/flutterchina/azlistview/ea7e11660223c3b6b1f3491ab0e5e04a333cca5d/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/flutterchina/azlistview/ea7e11660223c3b6b1f3491ab0e5e04a333cca5d/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/flutterchina/azlistview/ea7e11660223c3b6b1f3491ab0e5e04a333cca5d/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/flutterchina/azlistview/ea7e11660223c3b6b1f3491ab0e5e04a333cca5d/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/flutterchina/azlistview/ea7e11660223c3b6b1f3491ab0e5e04a333cca5d/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/flutterchina/azlistview/ea7e11660223c3b6b1f3491ab0e5e04a333cca5d/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/flutterchina/azlistview/ea7e11660223c3b6b1f3491ab0e5e04a333cca5d/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/flutterchina/azlistview/ea7e11660223c3b6b1f3491ab0e5e04a333cca5d/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/flutterchina/azlistview/ea7e11660223c3b6b1f3491ab0e5e04a333cca5d/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/flutterchina/azlistview/ea7e11660223c3b6b1f3491ab0e5e04a333cca5d/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flutterchina/azlistview/ea7e11660223c3b6b1f3491ab0e5e04a333cca5d/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flutterchina/azlistview/ea7e11660223c3b6b1f3491ab0e5e04a333cca5d/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 | azlistview_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"
2 |
--------------------------------------------------------------------------------
/example/lib/common/index.dart:
--------------------------------------------------------------------------------
1 | export 'models.dart';
2 | export 'utils.dart';
3 | export 'res.dart';
4 |
5 | export 'dart:convert';
6 |
7 | export 'package:common_utils/common_utils.dart';
8 |
9 | export 'package:lpinyin/lpinyin.dart';
10 |
--------------------------------------------------------------------------------
/example/lib/common/models.dart:
--------------------------------------------------------------------------------
1 | import 'dart:convert';
2 |
3 | import 'package:azlistview/azlistview.dart';
4 | import 'package:flutter/material.dart';
5 |
6 | import 'package:github_language_colors/github_language_colors.dart';
7 |
8 | class CityModel extends ISuspensionBean {
9 | String name;
10 | String? tagIndex;
11 | String? namePinyin;
12 |
13 | CityModel({
14 | required this.name,
15 | this.tagIndex,
16 | this.namePinyin,
17 | });
18 |
19 | CityModel.fromJson(Map json) : name = json['name'];
20 |
21 | Map toJson() => {
22 | 'name': name,
23 | // 'tagIndex': tagIndex,
24 | // 'namePinyin': namePinyin,
25 | // 'isShowSuspension': isShowSuspension
26 | };
27 |
28 | @override
29 | String getSuspensionTag() => tagIndex!;
30 |
31 | @override
32 | String toString() => json.encode(this);
33 | }
34 |
35 | class ContactInfo extends ISuspensionBean {
36 | String name;
37 | String? tagIndex;
38 | String? namePinyin;
39 |
40 | Color? bgColor;
41 | IconData? iconData;
42 |
43 | String? img;
44 | String? id;
45 | String? firstletter;
46 |
47 | ContactInfo({
48 | required this.name,
49 | this.tagIndex,
50 | this.namePinyin,
51 | this.bgColor,
52 | this.iconData,
53 | this.img,
54 | this.id,
55 | this.firstletter,
56 | });
57 |
58 | ContactInfo.fromJson(Map json)
59 | : name = json['name'],
60 | img = json['img'],
61 | id = json['id']?.toString(),
62 | firstletter = json['firstletter'];
63 |
64 | Map toJson() => {
65 | // 'id': id,
66 | 'name': name,
67 | 'img': img,
68 | // 'firstletter': firstletter,
69 | // 'tagIndex': tagIndex,
70 | // 'namePinyin': namePinyin,
71 | // 'isShowSuspension': isShowSuspension
72 | };
73 |
74 | @override
75 | String getSuspensionTag() => tagIndex!;
76 |
77 | @override
78 | String toString() => json.encode(this);
79 | }
80 |
81 | class Languages extends GithubLanguage with ISuspensionBean {
82 | String? tagIndex;
83 | String? pinyin;
84 | String? shortPinyin;
85 |
86 | Languages.fromJson(Map json) : super.fromJson(json);
87 |
88 | @override
89 | Map toJson() {
90 | final Map map = super.toJson();
91 | void addIfNonNull(String fieldName, dynamic value) {
92 | if (value != null) {
93 | map[fieldName] = value;
94 | }
95 | }
96 |
97 | // addIfNonNull('tagIndex', tagIndex);
98 | return map;
99 | }
100 |
101 | @override
102 | String getSuspensionTag() {
103 | return tagIndex!;
104 | }
105 |
106 | @override
107 | String toString() {
108 | return json.encode(this);
109 | }
110 | }
111 |
--------------------------------------------------------------------------------
/example/lib/common/res.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class Colours {
4 | static const Color gray_33 = Color(0xFF333333);
5 | static const Color gray_66 = Color(0xFF666666);
6 | static const Color gray_99 = Color(0xFF999999);
7 | }
8 |
--------------------------------------------------------------------------------
/example/lib/common/utils.dart:
--------------------------------------------------------------------------------
1 | import 'package:azlistview_example/common/index.dart';
2 | import 'package:flutter/material.dart';
3 |
4 | class Utils {
5 | static String getImgPath(String name, {String format: 'png'}) {
6 | return 'assets/images/$name.$format';
7 | }
8 |
9 | static void showSnackBar(BuildContext context, String msg) {
10 | ScaffoldMessenger.of(context).showSnackBar(
11 | SnackBar(
12 | content: Text(msg),
13 | duration: Duration(seconds: 2),
14 | ),
15 | );
16 | }
17 |
18 | static Widget getSusItem(BuildContext context, String tag,
19 | {double susHeight = 40}) {
20 | if (tag == '★') {
21 | tag = '★ 热门城市';
22 | }
23 | return Container(
24 | height: susHeight,
25 | width: MediaQuery.of(context).size.width,
26 | padding: EdgeInsets.only(left: 16.0),
27 | color: Color(0xFFF3F4F5),
28 | alignment: Alignment.centerLeft,
29 | child: Text(
30 | '$tag',
31 | softWrap: false,
32 | style: TextStyle(
33 | fontSize: 14.0,
34 | color: Color(0xFF666666),
35 | ),
36 | ),
37 | );
38 | }
39 |
40 | static Widget getListItem(BuildContext context, CityModel model,
41 | {double susHeight = 40}) {
42 | return ListTile(
43 | title: Text(model.name),
44 | onTap: () {
45 | LogUtil.e("onItemClick : $model");
46 | Utils.showSnackBar(context, 'onItemClick : ${model.name}');
47 | },
48 | );
49 | // return Column(
50 | // mainAxisSize: MainAxisSize.min,
51 | // children: [
52 | // Offstage(
53 | // offstage: !(model.isShowSuspension == true),
54 | // child: getSusItem(context, model.getSuspensionTag(),
55 | // susHeight: susHeight),
56 | // ),
57 | // ListTile(
58 | // title: Text(model.name),
59 | // onTap: () {
60 | // LogUtil.e("onItemClick : $model");
61 | // Utils.showSnackBar(context, 'onItemClick : ${model.name}');
62 | // },
63 | // )
64 | // ],
65 | // );
66 | }
67 |
68 | static Widget getWeChatListItem(
69 | BuildContext context,
70 | ContactInfo model, {
71 | double susHeight = 40,
72 | Color? defHeaderBgColor,
73 | }) {
74 | return getWeChatItem(context, model, defHeaderBgColor: defHeaderBgColor);
75 | // return Column(
76 | // mainAxisSize: MainAxisSize.min,
77 | // children: [
78 | // Offstage(
79 | // offstage: !(model.isShowSuspension == true),
80 | // child: getSusItem(context, model.getSuspensionTag(),
81 | // susHeight: susHeight),
82 | // ),
83 | // getWeChatItem(context, model, defHeaderBgColor: defHeaderBgColor),
84 | // ],
85 | // );
86 | }
87 |
88 | static Widget getWeChatItem(
89 | BuildContext context,
90 | ContactInfo model, {
91 | Color? defHeaderBgColor,
92 | }) {
93 | DecorationImage? image;
94 | // if (model.img != null && model.img.isNotEmpty) {
95 | // image = DecorationImage(
96 | // image: CachedNetworkImageProvider(model.img),
97 | // fit: BoxFit.contain,
98 | // );
99 | // }
100 | return ListTile(
101 | leading: Container(
102 | width: 36,
103 | height: 36,
104 | decoration: BoxDecoration(
105 | shape: BoxShape.rectangle,
106 | borderRadius: BorderRadius.circular(4.0),
107 | color: model.bgColor ?? defHeaderBgColor,
108 | image: image,
109 | ),
110 | child: model.iconData == null
111 | ? null
112 | : Icon(
113 | model.iconData,
114 | color: Colors.white,
115 | size: 20,
116 | ),
117 | ),
118 | title: Text(model.name),
119 | onTap: () {
120 | LogUtil.e("onItemClick : $model");
121 | Utils.showSnackBar(context, 'onItemClick : ${model.name}');
122 | },
123 | );
124 | }
125 | }
126 |
--------------------------------------------------------------------------------
/example/lib/main.dart:
--------------------------------------------------------------------------------
1 | import 'dart:io';
2 |
3 | import 'package:flutter/material.dart';
4 | import 'package:flutter/services.dart';
5 |
6 | import 'ui/index.dart';
7 |
8 | void main() {
9 | runApp(MyApp());
10 | if (Platform.isAndroid) {
11 | SystemChrome.setSystemUIOverlayStyle(
12 | SystemUiOverlayStyle(statusBarColor: Colors.transparent));
13 | }
14 | }
15 |
16 | class MyApp extends StatelessWidget {
17 | @override
18 | Widget build(BuildContext context) {
19 | return MaterialApp(
20 | title: 'AzListView Demo',
21 | theme: ThemeData(
22 | primaryColor: Colors.white,
23 | accentColor: Colors.grey,
24 | //primarySwatch: Colors.white,
25 | visualDensity: VisualDensity.adaptivePlatformDensity,
26 | ),
27 | home: Scaffold(
28 | appBar: AppBar(
29 | title: const Text(
30 | 'AzListView',
31 | ),
32 | ),
33 | body: ListPage([
34 | PageInfo("GitHub Languages", (ctx) => GitHubLanguagePage(), false),
35 | PageInfo("Contacts", (ctx) => ContactsPage(), false),
36 | PageInfo("Contacts List", (ctx) => ContactListPage()),
37 | PageInfo("City List", (ctx) => CityListPage(), false),
38 | PageInfo(
39 | "City List(Custom header)", (ctx) => CityListCustomHeaderPage()),
40 | PageInfo("Car models", (ctx) => CarModelsPage(), false),
41 | PageInfo("10000 data", (ctx) => LargeDataPage(), false),
42 | ]),
43 | ),
44 | );
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/example/lib/ui/car_models_page.dart:
--------------------------------------------------------------------------------
1 | import 'dart:developer';
2 |
3 | import 'package:azlistview/azlistview.dart';
4 | import 'package:azlistview_example/common/index.dart';
5 | import 'package:flutter/material.dart';
6 | import 'package:flutter/services.dart';
7 |
8 | class CarModelsPage extends StatefulWidget {
9 | @override
10 | _CarModelsPageState createState() => _CarModelsPageState();
11 | }
12 |
13 | class _CarModelsPageState extends State {
14 | List contactList = [];
15 |
16 | double susItemHeight = 24;
17 |
18 | @override
19 | void initState() {
20 | super.initState();
21 | loadData();
22 | }
23 |
24 | void loadData() async {
25 | rootBundle.loadString('assets/data/car_models.json').then((value) {
26 | List list = json.decode(value);
27 | list.forEach((v) {
28 | contactList.add(ContactInfo.fromJson(v));
29 | });
30 | // contactList = contactList.reversed.toList();
31 | // log('$contactList');
32 | _handleList(contactList);
33 | });
34 | }
35 |
36 | void _handleList(List list) {
37 | if (list.isEmpty) return;
38 | for (int i = 0, length = list.length; i < length; i++) {
39 | String pinyin = PinyinHelper.getPinyinE(list[i].name);
40 | String tag = pinyin.substring(0, 1).toUpperCase();
41 | list[i].namePinyin = pinyin;
42 | if (RegExp("[A-Z]").hasMatch(tag)) {
43 | list[i].tagIndex = tag;
44 | } else {
45 | list[i].tagIndex = "#";
46 | }
47 | }
48 | // A-Z sort.
49 | SuspensionUtil.sortListBySuspensionTag(contactList);
50 |
51 | // show sus tag.
52 | SuspensionUtil.setShowSuspensionStatus(contactList);
53 |
54 | // add header.
55 | contactList.insert(0, ContactInfo(name: 'header', tagIndex: '选'));
56 |
57 | setState(() {});
58 | }
59 |
60 | Widget customHeader() {
61 | return Column(
62 | children: [
63 | Container(
64 | color: Colors.white,
65 | padding: EdgeInsets.only(left: 32, top: 20, right: 32, bottom: 16),
66 | child: Image.asset(
67 | Utils.getImgPath('ic_car_models_header1'),
68 | fit: BoxFit.contain,
69 | ),
70 | ),
71 | Container(
72 | color: Colors.white,
73 | padding: EdgeInsets.only(left: 32, top: 0, right: 32, bottom: 16),
74 | child: Image.asset(
75 | Utils.getImgPath('ic_car_models_header2'),
76 | fit: BoxFit.contain,
77 | ),
78 | ),
79 | ],
80 | );
81 | }
82 |
83 | @override
84 | Widget build(BuildContext context) {
85 | return Scaffold(
86 | appBar: AppBar(
87 | automaticallyImplyLeading: false,
88 | title: Text(
89 | 'Car models',
90 | style: TextStyle(color: Color(0xFF171717)),
91 | ),
92 | ),
93 | body: AzListView(
94 | data: contactList,
95 | itemCount: contactList.length,
96 | itemBuilder: (BuildContext context, int index) {
97 | if (index == 0) return customHeader();
98 | ContactInfo model = contactList[index];
99 | return Utils.getWeChatListItem(context, model,
100 | susHeight: susItemHeight);
101 | },
102 | susItemHeight: susItemHeight,
103 | susItemBuilder: (BuildContext context, int index) {
104 | ContactInfo model = contactList[index];
105 | if ('选' == model.getSuspensionTag()) {
106 | return Container();
107 | }
108 | return Utils.getSusItem(context, model.getSuspensionTag(),
109 | susHeight: susItemHeight);
110 | },
111 | indexBarData: ['选', ...kIndexBarData],
112 | indexBarOptions: IndexBarOptions(
113 | needRebuild: true,
114 | selectTextStyle: TextStyle(
115 | fontSize: 12, color: Colors.white, fontWeight: FontWeight.w500),
116 | selectItemDecoration:
117 | BoxDecoration(shape: BoxShape.circle, color: Color(0xFF333333)),
118 | indexHintWidth: 96,
119 | indexHintHeight: 97,
120 | indexHintDecoration: BoxDecoration(
121 | image: DecorationImage(
122 | image: AssetImage(Utils.getImgPath('ic_index_bar_bubble_white')),
123 | fit: BoxFit.contain,
124 | ),
125 | ),
126 | indexHintAlignment: Alignment.centerRight,
127 | indexHintTextStyle: TextStyle(fontSize: 24.0, color: Colors.black87),
128 | indexHintOffset: Offset(-30, 0),
129 | ),
130 | ),
131 | );
132 | }
133 | }
134 |
--------------------------------------------------------------------------------
/example/lib/ui/citylist_custom_header_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:azlistview/azlistview.dart';
2 | import 'package:azlistview_example/common/index.dart';
3 | import 'package:flutter/material.dart';
4 | import 'package:flutter/services.dart';
5 |
6 | class CityListCustomHeaderPage extends StatefulWidget {
7 | @override
8 | _CityListCustomHeaderPageState createState() =>
9 | _CityListCustomHeaderPageState();
10 | }
11 |
12 | class _CityListCustomHeaderPageState extends State {
13 | List cityList = [];
14 | double susItemHeight = 36;
15 | String imgFavorite = Utils.getImgPath('ic_favorite');
16 |
17 | @override
18 | void initState() {
19 | super.initState();
20 | Future.delayed(Duration(milliseconds: 500), () {
21 | loadData();
22 | });
23 | }
24 |
25 | void loadData() async {
26 | //加载城市列表
27 | rootBundle.loadString('assets/data/china.json').then((value) {
28 | cityList.clear();
29 | Map countyMap = json.decode(value);
30 | List list = countyMap['china'];
31 | list.forEach((v) {
32 | cityList.add(CityModel.fromJson(v));
33 | });
34 | _handleList(cityList);
35 | });
36 | }
37 |
38 | void _handleList(List list) {
39 | if (list.isEmpty) return;
40 | for (int i = 0, length = list.length; i < length; i++) {
41 | String pinyin = PinyinHelper.getPinyinE(list[i].name);
42 | String tag = pinyin.substring(0, 1).toUpperCase();
43 | list[i].namePinyin = pinyin;
44 | if (RegExp('[A-Z]').hasMatch(tag)) {
45 | list[i].tagIndex = tag;
46 | } else {
47 | list[i].tagIndex = '#';
48 | }
49 | }
50 | // A-Z sort.
51 | SuspensionUtil.sortListBySuspensionTag(list);
52 |
53 | // show sus tag.
54 | SuspensionUtil.setShowSuspensionStatus(cityList);
55 |
56 | // add header.
57 | cityList.insert(
58 | 0,
59 | CityModel(
60 | name: 'header',
61 | tagIndex: imgFavorite)); //index bar support local images.
62 |
63 | setState(() {});
64 | }
65 |
66 | Widget _buildHeader() {
67 | List hotCityList = [];
68 | hotCityList.addAll([
69 | CityModel(name: "北京市"),
70 | CityModel(name: "广州市"),
71 | CityModel(name: "成都市"),
72 | CityModel(name: "深圳市"),
73 | CityModel(name: "杭州市"),
74 | CityModel(name: "武汉市"),
75 | ]);
76 | return Padding(
77 | padding: const EdgeInsets.all(20),
78 | child: Wrap(
79 | alignment: WrapAlignment.center,
80 | runAlignment: WrapAlignment.center,
81 | spacing: 10.0,
82 | children: hotCityList.map((e) {
83 | return OutlinedButton(
84 | style: ButtonStyle(
85 | //side: BorderSide(color: Colors.grey[300], width: .5),
86 | ),
87 | child: Padding(
88 | padding: EdgeInsets.only(left: 10, right: 10),
89 | child: Text(e.name),
90 | ),
91 | onPressed: () {
92 | print("OnItemClick: $e");
93 | Navigator.pop(context, e);
94 | },
95 | );
96 | }).toList(),
97 | ),
98 | );
99 | }
100 |
101 | @override
102 | Widget build(BuildContext context) {
103 | return Column(
104 | children: [
105 | ListTile(
106 | title: Text("当前城市"),
107 | trailing: Row(
108 | mainAxisSize: MainAxisSize.min,
109 | children: [
110 | Icon(
111 | Icons.place,
112 | size: 20.0,
113 | ),
114 | Text(" 成都市"),
115 | ],
116 | )),
117 | Divider(
118 | height: .0,
119 | ),
120 | Expanded(
121 | child: AzListView(
122 | data: cityList,
123 | itemCount: cityList.length,
124 | itemBuilder: (BuildContext context, int index) {
125 | if (index == 0) return _buildHeader();
126 | CityModel model = cityList[index];
127 | return Utils.getListItem(context, model,
128 | susHeight: susItemHeight);
129 | },
130 | susItemHeight: susItemHeight,
131 | susItemBuilder: (BuildContext context, int index) {
132 | CityModel model = cityList[index];
133 | String tag = model.getSuspensionTag();
134 | if (imgFavorite == tag) {
135 | return Container();
136 | }
137 | return Utils.getSusItem(context, tag, susHeight: susItemHeight);
138 | },
139 | indexBarData: SuspensionUtil.getTagIndexList(cityList),
140 | indexBarOptions: IndexBarOptions(
141 | needRebuild: true,
142 | color: Colors.transparent,
143 | downColor: Color(0xFFEEEEEE),
144 | localImages: [imgFavorite], //local images.
145 | ),
146 | ),
147 | ),
148 | ],
149 | );
150 | }
151 | }
152 |
--------------------------------------------------------------------------------
/example/lib/ui/citylist_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:azlistview/azlistview.dart';
2 | import 'package:azlistview_example/common/index.dart';
3 | import 'package:flutter/material.dart';
4 | import 'package:flutter/services.dart';
5 |
6 | class CityListPage extends StatefulWidget {
7 | @override
8 | _CityListPageState createState() => _CityListPageState();
9 | }
10 |
11 | class _CityListPageState extends State {
12 | List cityList = [];
13 | List _hotCityList = [];
14 |
15 | @override
16 | void initState() {
17 | super.initState();
18 | _hotCityList.add(CityModel(name: '北京市', tagIndex: '★'));
19 | _hotCityList.add(CityModel(name: '广州市', tagIndex: '★'));
20 | _hotCityList.add(CityModel(name: '成都市', tagIndex: '★'));
21 | _hotCityList.add(CityModel(name: '深圳市', tagIndex: '★'));
22 | _hotCityList.add(CityModel(name: '杭州市', tagIndex: '★'));
23 | _hotCityList.add(CityModel(name: '武汉市', tagIndex: '★'));
24 | cityList.addAll(_hotCityList);
25 | SuspensionUtil.setShowSuspensionStatus(cityList);
26 |
27 | Future.delayed(Duration(milliseconds: 500), () {
28 | loadData();
29 | });
30 | }
31 |
32 | void loadData() async {
33 | //加载城市列表
34 | rootBundle.loadString('assets/data/china.json').then((value) {
35 | cityList.clear();
36 | Map countyMap = json.decode(value);
37 | List list = countyMap['china'];
38 | list.forEach((v) {
39 | cityList.add(CityModel.fromJson(v));
40 | });
41 | _handleList(cityList);
42 | });
43 | }
44 |
45 | void _handleList(List list) {
46 | if (list.isEmpty) return;
47 | for (int i = 0, length = list.length; i < length; i++) {
48 | String pinyin = PinyinHelper.getPinyinE(list[i].name);
49 | String tag = pinyin.substring(0, 1).toUpperCase();
50 | list[i].namePinyin = pinyin;
51 | if (RegExp('[A-Z]').hasMatch(tag)) {
52 | list[i].tagIndex = tag;
53 | } else {
54 | list[i].tagIndex = '#';
55 | }
56 | }
57 | // A-Z sort.
58 | SuspensionUtil.sortListBySuspensionTag(list);
59 |
60 | // add hotCityList.
61 | cityList.insertAll(0, _hotCityList);
62 |
63 | // show sus tag.
64 | SuspensionUtil.setShowSuspensionStatus(cityList);
65 |
66 | setState(() {});
67 | }
68 |
69 | Widget header() {
70 | return Container(
71 | color: Colors.white,
72 | height: 44.0,
73 | child: Row(
74 | children: [
75 | Expanded(
76 | child: TextField(
77 | autofocus: false,
78 | decoration: InputDecoration(
79 | contentPadding: EdgeInsets.only(left: 10, right: 10),
80 | border: InputBorder.none,
81 | labelStyle: TextStyle(fontSize: 14, color: Color(0xFF333333)),
82 | hintText: '城市中文名或拼音',
83 | hintStyle: TextStyle(fontSize: 14, color: Color(0xFFCCCCCC))),
84 | )),
85 | Container(
86 | width: 0.33,
87 | height: 14.0,
88 | color: Color(0xFFEFEFEF),
89 | ),
90 | InkWell(
91 | onTap: () {
92 | Navigator.pop(context);
93 | },
94 | child: Padding(
95 | padding: const EdgeInsets.all(10.0),
96 | child: Text(
97 | "取消",
98 | style: TextStyle(color: Color(0xFF999999), fontSize: 14),
99 | ),
100 | ),
101 | )
102 | ],
103 | ),
104 | );
105 | }
106 |
107 | @override
108 | Widget build(BuildContext context) {
109 | return Scaffold(
110 | resizeToAvoidBottomInset: false,
111 | body: SafeArea(
112 | child: Column(
113 | children: [
114 | header(),
115 | Expanded(
116 | child: Material(
117 | color: Color(0x80000000),
118 | child: Card(
119 | clipBehavior: Clip.hardEdge,
120 | margin: const EdgeInsets.only(left: 8, top: 8, right: 8),
121 | shape: const RoundedRectangleBorder(
122 | borderRadius: const BorderRadius.only(
123 | topLeft: Radius.circular(4.0),
124 | topRight: Radius.circular(4.0)),
125 | ),
126 | child: Column(
127 | children: [
128 | Container(
129 | alignment: Alignment.centerLeft,
130 | padding: const EdgeInsets.only(left: 15.0),
131 | height: 50.0,
132 | child: Text("当前城市: 成都市"),
133 | ),
134 | Expanded(
135 | child: AzListView(
136 | data: cityList,
137 | itemCount: cityList.length,
138 | itemBuilder: (BuildContext context, int index) {
139 | CityModel model = cityList[index];
140 | return Utils.getListItem(context, model);
141 | },
142 | padding: EdgeInsets.zero,
143 | susItemBuilder: (BuildContext context, int index) {
144 | CityModel model = cityList[index];
145 | String tag = model.getSuspensionTag();
146 | return Utils.getSusItem(context, tag);
147 | },
148 | indexBarData: ['★', ...kIndexBarData],
149 | ),
150 | )
151 | ],
152 | ),
153 | ),
154 | ),
155 | ),
156 | ],
157 | )),
158 | );
159 | }
160 | }
161 |
--------------------------------------------------------------------------------
/example/lib/ui/contacts_list_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:azlistview/azlistview.dart';
2 | import 'package:azlistview_example/common/index.dart';
3 | import 'package:flutter/material.dart';
4 | import 'package:flutter/services.dart';
5 |
6 | class ContactListPage extends StatefulWidget {
7 | @override
8 | State createState() {
9 | return new _ContactListPageState();
10 | }
11 | }
12 |
13 | class _ContactListPageState extends State {
14 | List _contacts = [];
15 | double susItemHeight = 40;
16 |
17 | @override
18 | void initState() {
19 | super.initState();
20 | loadData();
21 | }
22 |
23 | void loadData() async {
24 | //加载联系人列表
25 | rootBundle.loadString('assets/data/contacts.json').then((value) {
26 | List list = json.decode(value);
27 | list.forEach((v) {
28 | _contacts.add(ContactInfo.fromJson(v));
29 | });
30 | _handleList(_contacts);
31 | });
32 | }
33 |
34 | void _handleList(List list) {
35 | if (list.isEmpty) return;
36 | for (int i = 0, length = list.length; i < length; i++) {
37 | String pinyin = PinyinHelper.getPinyinE(list[i].name);
38 | String tag = pinyin.substring(0, 1).toUpperCase();
39 | list[i].namePinyin = pinyin;
40 | if (RegExp("[A-Z]").hasMatch(tag)) {
41 | list[i].tagIndex = tag;
42 | } else {
43 | list[i].tagIndex = "#";
44 | }
45 | }
46 | // A-Z sort.
47 | SuspensionUtil.sortListBySuspensionTag(_contacts);
48 |
49 | // show sus tag.
50 | SuspensionUtil.setShowSuspensionStatus(_contacts);
51 |
52 | // add header.
53 | _contacts.insert(0, ContactInfo(name: 'header', tagIndex: '↑'));
54 |
55 | setState(() {});
56 | }
57 |
58 | Widget _buildHeader() {
59 | return Container(
60 | padding: EdgeInsets.all(20),
61 | alignment: Alignment.center,
62 | child: Column(
63 | mainAxisAlignment: MainAxisAlignment.center,
64 | children: [
65 | ClipOval(
66 | child: Image.asset(
67 | "./assets/images/avatar.png",
68 | width: 80.0,
69 | )),
70 | Padding(
71 | padding: const EdgeInsets.all(8.0),
72 | child: Text(
73 | "远行",
74 | textScaleFactor: 1.2,
75 | ),
76 | ),
77 | Text("+86 182-286-44678"),
78 | ],
79 | ),
80 | );
81 | }
82 |
83 | Widget _buildSusWidget(String susTag) {
84 | return Container(
85 | padding: EdgeInsets.symmetric(horizontal: 15.0),
86 | height: susItemHeight,
87 | width: double.infinity,
88 | alignment: Alignment.centerLeft,
89 | child: Row(
90 | children: [
91 | Text(
92 | '$susTag',
93 | textScaleFactor: 1.2,
94 | ),
95 | Expanded(
96 | child: Divider(
97 | height: .0,
98 | indent: 10.0,
99 | ))
100 | ],
101 | ),
102 | );
103 | }
104 |
105 | Widget _buildListItem(ContactInfo model) {
106 | String susTag = model.getSuspensionTag();
107 | return Column(
108 | children: [
109 | Offstage(
110 | offstage: model.isShowSuspension != true,
111 | child: _buildSusWidget(susTag),
112 | ),
113 | ListTile(
114 | leading: CircleAvatar(
115 | backgroundColor: Colors.blue[700],
116 | child: Text(
117 | model.name[0],
118 | style: TextStyle(color: Colors.white),
119 | ),
120 | ),
121 | title: Text(model.name),
122 | onTap: () {
123 | print("OnItemClick: $model");
124 | Navigator.pop(context, model);
125 | },
126 | )
127 | ],
128 | );
129 | }
130 |
131 | Decoration getIndexBarDecoration(Color color) {
132 | return BoxDecoration(
133 | color: color,
134 | borderRadius: BorderRadius.circular(20.0),
135 | border: Border.all(color: Colors.grey[300]!, width: .5));
136 | }
137 |
138 | @override
139 | Widget build(BuildContext context) {
140 | return AzListView(
141 | data: _contacts,
142 | itemCount: _contacts.length,
143 | itemBuilder: (BuildContext context, int index) {
144 | if (index == 0) return _buildHeader();
145 | ContactInfo model = _contacts[index];
146 | return _buildListItem(model);
147 | },
148 | physics: BouncingScrollPhysics(),
149 | indexBarData: SuspensionUtil.getTagIndexList(_contacts),
150 | indexHintBuilder: (context, hint) {
151 | return Container(
152 | alignment: Alignment.center,
153 | width: 60.0,
154 | height: 60.0,
155 | decoration: BoxDecoration(
156 | color: Colors.blue[700]!.withAlpha(200),
157 | shape: BoxShape.circle,
158 | ),
159 | child:
160 | Text(hint, style: TextStyle(color: Colors.white, fontSize: 30.0)),
161 | );
162 | },
163 | indexBarMargin: EdgeInsets.all(10),
164 | indexBarOptions: IndexBarOptions(
165 | needRebuild: true,
166 | decoration: getIndexBarDecoration(Colors.grey[50]!),
167 | downDecoration: getIndexBarDecoration(Colors.grey[200]!),
168 | ),
169 | );
170 | }
171 | }
172 |
--------------------------------------------------------------------------------
/example/lib/ui/contacts_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:azlistview/azlistview.dart';
2 | import 'package:azlistview_example/common/index.dart';
3 | import 'package:flutter/material.dart';
4 | import 'package:flutter/services.dart';
5 |
6 | class ContactsPage extends StatefulWidget {
7 | @override
8 | _ContactsPageState createState() => _ContactsPageState();
9 | }
10 |
11 | class _ContactsPageState extends State {
12 | List contactList = [];
13 | List topList = [];
14 |
15 | @override
16 | void initState() {
17 | super.initState();
18 | topList.add(ContactInfo(
19 | name: '新的朋友',
20 | tagIndex: '↑',
21 | bgColor: Colors.orange,
22 | iconData: Icons.person_add));
23 | topList.add(ContactInfo(
24 | name: '群聊',
25 | tagIndex: '↑',
26 | bgColor: Colors.green,
27 | iconData: Icons.people));
28 | topList.add(ContactInfo(
29 | name: '标签',
30 | tagIndex: '↑',
31 | bgColor: Colors.blue,
32 | iconData: Icons.local_offer));
33 | topList.add(ContactInfo(
34 | name: '公众号',
35 | tagIndex: '↑',
36 | bgColor: Colors.blueAccent,
37 | iconData: Icons.person));
38 | loadData();
39 | }
40 |
41 | void loadData() async {
42 | //加载联系人列表
43 | rootBundle.loadString('assets/data/car_models.json').then((value) {
44 | List list = json.decode(value);
45 | list.forEach((v) {
46 | contactList.add(ContactInfo.fromJson(v));
47 | });
48 | _handleList(contactList);
49 | });
50 | }
51 |
52 | void _handleList(List list) {
53 | if (list.isEmpty) return;
54 | for (int i = 0, length = list.length; i < length; i++) {
55 | String pinyin = PinyinHelper.getPinyinE(list[i].name);
56 | String tag = pinyin.substring(0, 1).toUpperCase();
57 | list[i].namePinyin = pinyin;
58 | if (RegExp("[A-Z]").hasMatch(tag)) {
59 | list[i].tagIndex = tag;
60 | } else {
61 | list[i].tagIndex = "#";
62 | }
63 | }
64 | // A-Z sort.
65 | SuspensionUtil.sortListBySuspensionTag(contactList);
66 |
67 | // show sus tag.
68 | SuspensionUtil.setShowSuspensionStatus(contactList);
69 |
70 | // add topList.
71 | contactList.insertAll(0, topList);
72 |
73 | setState(() {});
74 | }
75 |
76 | @override
77 | Widget build(BuildContext context) {
78 | return Scaffold(
79 | appBar: AppBar(
80 | automaticallyImplyLeading: false,
81 | backgroundColor: Color(0xFFEDEDED),
82 | title: Text(
83 | 'Contants',
84 | style: TextStyle(color: Color(0xFF171717)),
85 | ),
86 | ),
87 | body: AzListView(
88 | data: contactList,
89 | itemCount: contactList.length,
90 | itemBuilder: (BuildContext context, int index) {
91 | ContactInfo model = contactList[index];
92 | return Utils.getWeChatListItem(
93 | context,
94 | model,
95 | defHeaderBgColor: Color(0xFFE5E5E5),
96 | );
97 | },
98 | physics: BouncingScrollPhysics(),
99 | susItemBuilder: (BuildContext context, int index) {
100 | ContactInfo model = contactList[index];
101 | if ('↑' == model.getSuspensionTag()) {
102 | return Container();
103 | }
104 | return Utils.getSusItem(context, model.getSuspensionTag());
105 | },
106 | indexBarData: ['↑', '☆', ...kIndexBarData],
107 | indexBarOptions: IndexBarOptions(
108 | needRebuild: true,
109 | ignoreDragCancel: true,
110 | downTextStyle: TextStyle(fontSize: 12, color: Colors.white),
111 | downItemDecoration:
112 | BoxDecoration(shape: BoxShape.circle, color: Colors.green),
113 | indexHintWidth: 120 / 2,
114 | indexHintHeight: 100 / 2,
115 | indexHintDecoration: BoxDecoration(
116 | image: DecorationImage(
117 | image: AssetImage(Utils.getImgPath('ic_index_bar_bubble_gray')),
118 | fit: BoxFit.contain,
119 | ),
120 | ),
121 | indexHintAlignment: Alignment.centerRight,
122 | indexHintChildAlignment: Alignment(-0.25, 0.0),
123 | indexHintOffset: Offset(-20, 0),
124 | ),
125 | ),
126 | );
127 | }
128 | }
129 |
--------------------------------------------------------------------------------
/example/lib/ui/github_language_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | import 'package:azlistview/azlistview.dart';
4 | import 'package:azlistview_example/common/index.dart';
5 |
6 | import 'package:github_language_colors/github_language_colors.dart';
7 | import 'package:scrollable_positioned_list/scrollable_positioned_list.dart';
8 |
9 | class GitHubLanguagePage extends StatefulWidget {
10 | const GitHubLanguagePage({
11 | Key? key,
12 | this.fromType,
13 | }) : super(key: key);
14 | final int? fromType;
15 |
16 | @override
17 | _GitHubLanguagePageState createState() => _GitHubLanguagePageState();
18 | }
19 |
20 | class _GitHubLanguagePageState extends State {
21 | /// Controller to scroll or jump to a particular item.
22 | final ItemScrollController itemScrollController = ItemScrollController();
23 |
24 | List originList = [];
25 | List dataList = [];
26 |
27 | late TextEditingController textEditingController;
28 |
29 | @override
30 | void initState() {
31 | super.initState();
32 | textEditingController = TextEditingController();
33 | loadData();
34 | }
35 |
36 | @override
37 | void dispose() {
38 | textEditingController.dispose();
39 | super.dispose();
40 | }
41 |
42 | void loadData() async {
43 | originList = LanguageHelper.getGithubLanguages().map((v) {
44 | Languages model = Languages.fromJson(v.toJson());
45 | String tag = model.name.substring(0, 1).toUpperCase();
46 | if (RegExp("[A-Z]").hasMatch(tag)) {
47 | model.tagIndex = tag;
48 | } else {
49 | model.tagIndex = "#";
50 | }
51 | return model;
52 | }).toList();
53 | _handleList(originList);
54 | }
55 |
56 | void _handleList(List list) {
57 | dataList.clear();
58 | if (ObjectUtil.isEmpty(list)) {
59 | setState(() {});
60 | return;
61 | }
62 | dataList.addAll(list);
63 |
64 | // A-Z sort.
65 | SuspensionUtil.sortListBySuspensionTag(dataList);
66 |
67 | // show sus tag.
68 | SuspensionUtil.setShowSuspensionStatus(dataList);
69 |
70 | setState(() {});
71 |
72 | if (itemScrollController.isAttached) {
73 | itemScrollController.jumpTo(index: 0);
74 | }
75 | }
76 |
77 | Widget getSusItem(BuildContext context, String tag, {double susHeight = 40}) {
78 | return Container(
79 | height: susHeight,
80 | width: MediaQuery.of(context).size.width,
81 | padding: EdgeInsets.only(left: 16.0),
82 | color: Color(0xFFF3F4F5),
83 | alignment: Alignment.centerLeft,
84 | child: Text(
85 | '$tag',
86 | softWrap: false,
87 | style: TextStyle(
88 | fontSize: 14.0,
89 | color: Color(0xFF666666),
90 | ),
91 | ),
92 | );
93 | }
94 |
95 | Widget getListItem(BuildContext context, Languages model,
96 | {double susHeight = 40}) {
97 | return ListTile(
98 | title: Text(model.name),
99 | onTap: () {
100 | LogUtil.v("onItemClick : $model");
101 | Utils.showSnackBar(context, "onItemClick : $model");
102 | },
103 | );
104 | }
105 |
106 | void _search(String text) {
107 | if (ObjectUtil.isEmpty(text)) {
108 | _handleList(originList);
109 | } else {
110 | List list = originList.where((v) {
111 | return v.name.toLowerCase().contains(text.toLowerCase());
112 | }).toList();
113 | _handleList(list);
114 | }
115 | }
116 |
117 | @override
118 | Widget build(BuildContext context) {
119 | return Scaffold(
120 | resizeToAvoidBottomInset: false,
121 | body: SafeArea(
122 | child: Column(
123 | children: [
124 | Container(
125 | margin: EdgeInsets.all(12),
126 | decoration: BoxDecoration(
127 | border: Border.all(
128 | color: Color.fromARGB(255, 225, 226, 230), width: 0.33),
129 | color: Color.fromARGB(255, 239, 240, 244),
130 | borderRadius: BorderRadius.circular(12)),
131 | child: TextField(
132 | autofocus: false,
133 | onChanged: (value) {
134 | _search(value);
135 | },
136 | controller: textEditingController,
137 | decoration: InputDecoration(
138 | prefixIcon: Icon(
139 | Icons.search,
140 | color: Colours.gray_33,
141 | ),
142 | suffixIcon: Offstage(
143 | offstage: textEditingController.text.isEmpty,
144 | child: InkWell(
145 | onTap: () {
146 | textEditingController.clear();
147 | _search('');
148 | },
149 | child: Icon(
150 | Icons.cancel,
151 | color: Colours.gray_99,
152 | ),
153 | ),
154 | ),
155 | border: InputBorder.none,
156 | hintText: 'Search language',
157 | hintStyle: TextStyle(color: Colours.gray_99)),
158 | ),
159 | ),
160 | Expanded(
161 | child: AzListView(
162 | data: dataList,
163 | physics: AlwaysScrollableScrollPhysics(),
164 | itemCount: dataList.length,
165 | itemBuilder: (BuildContext context, int index) {
166 | Languages model = dataList[index];
167 | return getListItem(context, model);
168 | },
169 | itemScrollController: itemScrollController,
170 | susItemBuilder: (BuildContext context, int index) {
171 | Languages model = dataList[index];
172 | return getSusItem(context, model.getSuspensionTag());
173 | },
174 | indexBarOptions: IndexBarOptions(
175 | needRebuild: true,
176 | hapticFeedback: true,
177 | selectTextStyle: TextStyle(
178 | fontSize: 12,
179 | color: Colors.white,
180 | fontWeight: FontWeight.w500),
181 | selectItemDecoration: BoxDecoration(
182 | shape: BoxShape.circle, color: Color(0xFF333333)),
183 | indexHintWidth: 96,
184 | indexHintHeight: 97,
185 | indexHintDecoration: BoxDecoration(
186 | image: DecorationImage(
187 | image: AssetImage(
188 | Utils.getImgPath('ic_index_bar_bubble_white')),
189 | fit: BoxFit.contain,
190 | ),
191 | ),
192 | indexHintAlignment: Alignment.centerRight,
193 | indexHintTextStyle:
194 | TextStyle(fontSize: 24.0, color: Colors.black87),
195 | indexHintOffset: Offset(-30, 0),
196 | ),
197 | ),
198 | )
199 | ],
200 | ),
201 | ),
202 | );
203 | }
204 | }
205 |
--------------------------------------------------------------------------------
/example/lib/ui/index.dart:
--------------------------------------------------------------------------------
1 | export 'page_scaffold.dart';
2 | export 'github_language_page.dart';
3 | export 'contacts_page.dart';
4 | export 'contacts_list_page.dart';
5 | export 'citylist_page.dart';
6 | export 'citylist_custom_header_page.dart';
7 | export 'car_models_page.dart';
8 | export 'large_data_page.dart';
9 |
--------------------------------------------------------------------------------
/example/lib/ui/large_data_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:azlistview/azlistview.dart';
2 | import 'package:azlistview_example/common/index.dart';
3 | import 'package:flutter/material.dart';
4 |
5 | class LargeDataPage extends StatefulWidget {
6 | @override
7 | _LargeDataPageState createState() => _LargeDataPageState();
8 | }
9 |
10 | class _LargeDataPageState extends State {
11 | List cityList = [];
12 | int numberOfItems = 10000;
13 | double susItemHeight = 40;
14 |
15 | @override
16 | void initState() {
17 | super.initState();
18 | int i = 0;
19 | cityList = List.generate(numberOfItems, (index) {
20 | if (index > (i + 1) * 385) {
21 | i = i + 1;
22 | }
23 | String tag = kIndexBarData[i];
24 | CityModel model = CityModel(name: '$tag $index', tagIndex: tag);
25 | return model;
26 | });
27 | SuspensionUtil.setShowSuspensionStatus(cityList);
28 | }
29 |
30 | @override
31 | Widget build(BuildContext context) {
32 | return Scaffold(
33 | appBar: AppBar(
34 | title: Text('10000 data'),
35 | ),
36 | body: AzListView(
37 | data: cityList,
38 | itemCount: cityList.length,
39 | itemBuilder: (BuildContext context, int index) {
40 | CityModel model = cityList[index];
41 | return Utils.getListItem(context, model);
42 | },
43 | physics: BouncingScrollPhysics(),
44 | susItemHeight: susItemHeight,
45 | susItemBuilder: (BuildContext context, int index) {
46 | CityModel model = cityList[index];
47 | return Utils.getSusItem(context, model.getSuspensionTag());
48 | },
49 | ),
50 | );
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/example/lib/ui/page_scaffold.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/cupertino.dart';
2 | import 'package:flutter/material.dart';
3 |
4 | class PageScaffold extends StatelessWidget {
5 | PageScaffold({required this.title, required this.body});
6 |
7 | final String title;
8 | final Widget body;
9 |
10 | @override
11 | Widget build(BuildContext context) {
12 | return Scaffold(
13 | appBar: AppBar(
14 | title: Text(title),
15 | ),
16 | body: body,
17 | );
18 | }
19 | }
20 |
21 | class PageInfo {
22 | PageInfo(this.title, this.builder, [this.withScaffold = true]);
23 |
24 | String title;
25 | WidgetBuilder builder;
26 | bool withScaffold;
27 | }
28 |
29 | class ListPage extends StatelessWidget {
30 | ListPage(this.children);
31 |
32 | final List children;
33 |
34 | @override
35 | Widget build(BuildContext context) {
36 | return ListView(children: _generateItem(context));
37 | }
38 |
39 | void _openPage(BuildContext context, PageInfo page) {
40 | //CupertinoPageRoute
41 | //MaterialPageRoute
42 | Navigator.push(context, CupertinoPageRoute(builder: (context) {
43 | if (!page.withScaffold) {
44 | return page.builder(context);
45 | }
46 | return PageScaffold(title: page.title, body: page.builder(context));
47 | }));
48 | }
49 |
50 | List _generateItem(BuildContext context) {
51 | return children.map((page) {
52 | return ListTile(
53 | title: Text(page.title),
54 | trailing: Icon(Icons.keyboard_arrow_right),
55 | onTap: () => _openPage(context, page),
56 | );
57 | }).toList();
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/example/pkgget:
--------------------------------------------------------------------------------
1 | export PUB_HOSTED_URL=https://pub.flutter-io.cn
2 | export FLUTTER_STORAGE_BASE_URL=https://storage.flutter-io.cn
3 | flutter packages get
--------------------------------------------------------------------------------
/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 | azlistview:
12 | dependency: "direct main"
13 | description:
14 | path: ".."
15 | relative: true
16 | source: path
17 | version: "2.0.0"
18 | boolean_selector:
19 | dependency: transitive
20 | description:
21 | name: boolean_selector
22 | url: "https://pub.flutter-io.cn"
23 | source: hosted
24 | version: "2.1.0"
25 | characters:
26 | dependency: transitive
27 | description:
28 | name: characters
29 | url: "https://pub.flutter-io.cn"
30 | source: hosted
31 | version: "1.2.0"
32 | charcode:
33 | dependency: transitive
34 | description:
35 | name: charcode
36 | url: "https://pub.flutter-io.cn"
37 | source: hosted
38 | version: "1.3.1"
39 | clock:
40 | dependency: transitive
41 | description:
42 | name: clock
43 | url: "https://pub.flutter-io.cn"
44 | source: hosted
45 | version: "1.1.0"
46 | collection:
47 | dependency: transitive
48 | description:
49 | name: collection
50 | url: "https://pub.flutter-io.cn"
51 | source: hosted
52 | version: "1.15.0"
53 | common_utils:
54 | dependency: "direct main"
55 | description:
56 | name: common_utils
57 | url: "https://pub.flutter-io.cn"
58 | source: hosted
59 | version: "2.0.1"
60 | convert:
61 | dependency: transitive
62 | description:
63 | name: convert
64 | url: "https://pub.flutter-io.cn"
65 | source: hosted
66 | version: "3.0.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 | decimal:
82 | dependency: transitive
83 | description:
84 | name: decimal
85 | url: "https://pub.flutter-io.cn"
86 | source: hosted
87 | version: "1.0.0"
88 | fake_async:
89 | dependency: transitive
90 | description:
91 | name: fake_async
92 | url: "https://pub.flutter-io.cn"
93 | source: hosted
94 | version: "1.2.0"
95 | flutter:
96 | dependency: "direct main"
97 | description: flutter
98 | source: sdk
99 | version: "0.0.0"
100 | flutter_test:
101 | dependency: "direct dev"
102 | description: flutter
103 | source: sdk
104 | version: "0.0.0"
105 | github_language_colors:
106 | dependency: "direct main"
107 | description:
108 | path: "."
109 | ref: HEAD
110 | resolved-ref: b4f88207ebc0c5dcc8baa1676a0fd7796974173a
111 | url: "git://github.com/Sky24n/github_language_colors.git"
112 | source: git
113 | version: "2.0.0"
114 | lpinyin:
115 | dependency: "direct main"
116 | description:
117 | name: lpinyin
118 | url: "https://pub.flutter-io.cn"
119 | source: hosted
120 | version: "2.0.1"
121 | matcher:
122 | dependency: transitive
123 | description:
124 | name: matcher
125 | url: "https://pub.flutter-io.cn"
126 | source: hosted
127 | version: "0.12.11"
128 | material_color_utilities:
129 | dependency: transitive
130 | description:
131 | name: material_color_utilities
132 | url: "https://pub.flutter-io.cn"
133 | source: hosted
134 | version: "0.1.3"
135 | meta:
136 | dependency: transitive
137 | description:
138 | name: meta
139 | url: "https://pub.flutter-io.cn"
140 | source: hosted
141 | version: "1.7.0"
142 | path:
143 | dependency: transitive
144 | description:
145 | name: path
146 | url: "https://pub.flutter-io.cn"
147 | source: hosted
148 | version: "1.8.0"
149 | rational:
150 | dependency: transitive
151 | description:
152 | name: rational
153 | url: "https://pub.flutter-io.cn"
154 | source: hosted
155 | version: "1.0.0"
156 | scrollable_positioned_list:
157 | dependency: transitive
158 | description:
159 | name: scrollable_positioned_list
160 | url: "https://pub.flutter-io.cn"
161 | source: hosted
162 | version: "0.2.3"
163 | sky_engine:
164 | dependency: transitive
165 | description: flutter
166 | source: sdk
167 | version: "0.0.99"
168 | source_span:
169 | dependency: transitive
170 | description:
171 | name: source_span
172 | url: "https://pub.flutter-io.cn"
173 | source: hosted
174 | version: "1.8.1"
175 | stack_trace:
176 | dependency: transitive
177 | description:
178 | name: stack_trace
179 | url: "https://pub.flutter-io.cn"
180 | source: hosted
181 | version: "1.10.0"
182 | stream_channel:
183 | dependency: transitive
184 | description:
185 | name: stream_channel
186 | url: "https://pub.flutter-io.cn"
187 | source: hosted
188 | version: "2.1.0"
189 | string_scanner:
190 | dependency: transitive
191 | description:
192 | name: string_scanner
193 | url: "https://pub.flutter-io.cn"
194 | source: hosted
195 | version: "1.1.0"
196 | term_glyph:
197 | dependency: transitive
198 | description:
199 | name: term_glyph
200 | url: "https://pub.flutter-io.cn"
201 | source: hosted
202 | version: "1.2.0"
203 | test_api:
204 | dependency: transitive
205 | description:
206 | name: test_api
207 | url: "https://pub.flutter-io.cn"
208 | source: hosted
209 | version: "0.4.8"
210 | typed_data:
211 | dependency: transitive
212 | description:
213 | name: typed_data
214 | url: "https://pub.flutter-io.cn"
215 | source: hosted
216 | version: "1.3.0"
217 | vector_math:
218 | dependency: transitive
219 | description:
220 | name: vector_math
221 | url: "https://pub.flutter-io.cn"
222 | source: hosted
223 | version: "2.1.1"
224 | sdks:
225 | dart: ">=2.14.0 <3.0.0"
226 | flutter: ">=1.17.0"
227 |
--------------------------------------------------------------------------------
/example/pubspec.yaml:
--------------------------------------------------------------------------------
1 | name: azlistview_example
2 | description: A new Flutter application.
3 |
4 | # The following line prevents the package from being accidentally published to
5 | # pub.dev using `pub publish`. This is preferred for private packages.
6 | publish_to: 'none' # Remove this line if you wish to publish to pub.dev
7 |
8 | # The following defines the version and build number for your application.
9 | # A version number is three numbers separated by dots, like 1.2.43
10 | # followed by an optional build number separated by a +.
11 | # Both the version and the builder number may be overridden in flutter
12 | # build by specifying --build-name and --build-number, respectively.
13 | # In Android, build-name is used as versionName while build-number used as versionCode.
14 | # Read more about Android versioning at https://developer.android.com/studio/publish/versioning
15 | # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
16 | # Read more about iOS versioning at
17 | # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
18 | version: 1.0.0+1
19 |
20 | environment:
21 | sdk: ">=2.12.0 <3.0.0"
22 | flutter: ">=1.17.0 <2.0.0"
23 |
24 | dependencies:
25 | flutter:
26 | sdk: flutter
27 |
28 |
29 | # The following adds the Cupertino Icons font to your application.
30 | # Use with the CupertinoIcons class for iOS style icons.
31 | cupertino_icons: ^0.1.3
32 | common_utils: ^2.0.0
33 | # 汉字转拼音
34 | lpinyin: ^2.0.0
35 | azlistview:
36 | path: ../
37 |
38 | # github_language_colors
39 | # url: https://github.com/Sky24n/github_language_colors.git
40 | # or
41 | # url: git://github.com/Sky24n/github_language_colors.git
42 | github_language_colors:
43 | git:
44 | url: git://github.com/Sky24n/github_language_colors.git
45 |
46 | dev_dependencies:
47 | flutter_test:
48 | sdk: flutter
49 |
50 | # For information on the generic Dart part of this file, see the
51 | # following page: https://dart.dev/tools/pub/pubspec
52 |
53 | # The following section is specific to Flutter.
54 | flutter:
55 |
56 | # The following line ensures that the Material Icons font is
57 | # included with your application, so that you can use the icons in
58 | # the material Icons class.
59 | uses-material-design: true
60 |
61 | assets:
62 | - assets/images/
63 | - assets/data/
64 |
65 | # To add assets to your application, add an assets section, like this:
66 | # assets:
67 | # - images/a_dot_burr.jpeg
68 | # - images/a_dot_ham.jpeg
69 |
70 | # An image asset can refer to one or more resolution-specific "variants", see
71 | # https://flutter.dev/assets-and-images/#resolution-aware.
72 |
73 | # For details regarding adding assets from package dependencies, see
74 | # https://flutter.dev/assets-and-images/#from-packages
75 |
76 | # To add custom fonts to your application, add a fonts section here,
77 | # in this "flutter" section. Each entry in this list should have a
78 | # "family" key with the font family name, and a "fonts" key with a
79 | # list giving the asset and other descriptors for the font. For
80 | # example:
81 | # fonts:
82 | # - family: Schyler
83 | # fonts:
84 | # - asset: fonts/Schyler-Regular.ttf
85 | # - asset: fonts/Schyler-Italic.ttf
86 | # style: italic
87 | # - family: Trajan Pro
88 | # fonts:
89 | # - asset: fonts/TrajanPro.ttf
90 | # - asset: fonts/TrajanPro_Bold.ttf
91 | # weight: 700
92 | #
93 | # For details regarding fonts from package dependencies,
94 | # see https://flutter.dev/custom-fonts/#from-packages
95 |
--------------------------------------------------------------------------------
/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:azlistview_example/main.dart';
12 |
13 | void main() {
14 | testWidgets('Counter increments smoke test', (WidgetTester tester) async {
15 | // Build our app and trigger a frame.
16 | await tester.pumpWidget(MyApp());
17 |
18 | // Verify that our counter starts at 0.
19 | expect(find.text('0'), findsOneWidget);
20 | expect(find.text('1'), findsNothing);
21 |
22 | // Tap the '+' icon and trigger a frame.
23 | await tester.tap(find.byIcon(Icons.add));
24 | await tester.pump();
25 |
26 | // Verify that our counter has incremented.
27 | expect(find.text('0'), findsNothing);
28 | expect(find.text('1'), findsOneWidget);
29 | });
30 | }
31 |
--------------------------------------------------------------------------------
/lib/azlistview.dart:
--------------------------------------------------------------------------------
1 | library azlistview;
2 |
3 | export 'src/az_common.dart';
4 | export 'src/az_listview.dart';
5 | export 'src/index_bar.dart';
6 | export 'src/suspension_view.dart';
7 |
--------------------------------------------------------------------------------
/lib/src/az_common.dart:
--------------------------------------------------------------------------------
1 | /// ISuspension Bean.
2 | abstract class ISuspensionBean {
3 | bool isShowSuspension = false;
4 |
5 | String getSuspensionTag(); //Suspension Tag
6 | }
7 |
8 | /// Suspension Util.
9 | class SuspensionUtil {
10 | /// sort list by suspension tag.
11 | /// 根据[A-Z]排序。
12 | static void sortListBySuspensionTag(List? list) {
13 | if (list == null || list.isEmpty) return;
14 | list.sort((a, b) {
15 | if (a.getSuspensionTag() == "@" || b.getSuspensionTag() == "#") {
16 | return -1;
17 | } else if (a.getSuspensionTag() == "#" || b.getSuspensionTag() == "@") {
18 | return 1;
19 | } else {
20 | return a.getSuspensionTag().compareTo(b.getSuspensionTag());
21 | }
22 | });
23 | }
24 |
25 | /// get index data list by suspension tag.
26 | /// 获取索引列表。
27 | static List getTagIndexList(List? list) {
28 | List indexData = [];
29 | if (list != null && list.isNotEmpty) {
30 | String? tempTag;
31 | for (int i = 0, length = list.length; i < length; i++) {
32 | String tag = list[i].getSuspensionTag();
33 | if (tempTag != tag) {
34 | indexData.add(tag);
35 | tempTag = tag;
36 | }
37 | }
38 | }
39 | return indexData;
40 | }
41 |
42 | /// set show suspension status.
43 | /// 设置显示悬停Header状态。
44 | static void setShowSuspensionStatus(List? list) {
45 | if (list == null || list.isEmpty) return;
46 | String? tempTag;
47 | for (int i = 0, length = list.length; i < length; i++) {
48 | String tag = list[i].getSuspensionTag();
49 | if (tempTag != tag) {
50 | tempTag = tag;
51 | list[i].isShowSuspension = true;
52 | } else {
53 | list[i].isShowSuspension = false;
54 | }
55 | }
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/lib/src/az_listview.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:scrollable_positioned_list/scrollable_positioned_list.dart';
3 |
4 | import 'az_common.dart';
5 | import 'index_bar.dart';
6 | import 'suspension_view.dart';
7 |
8 | /// AzListView
9 | class AzListView extends StatefulWidget {
10 | AzListView({
11 | Key? key,
12 | required this.data,
13 | required this.itemCount,
14 | required this.itemBuilder,
15 | this.itemScrollController,
16 | this.itemPositionsListener,
17 | this.physics,
18 | this.padding,
19 | this.susItemBuilder,
20 | this.susItemHeight = kSusItemHeight,
21 | this.susPosition,
22 | this.indexHintBuilder,
23 | this.indexBarData = kIndexBarData,
24 | this.indexBarWidth = kIndexBarWidth,
25 | this.indexBarHeight,
26 | this.indexBarItemHeight = kIndexBarItemHeight,
27 | this.hapticFeedback = false,
28 | this.indexBarAlignment = Alignment.centerRight,
29 | this.indexBarMargin,
30 | this.indexBarOptions = const IndexBarOptions(),
31 | }) : super(key: key);
32 |
33 | /// with ISuspensionBean Data
34 | final List data;
35 |
36 | /// Number of items the [itemBuilder] can produce.
37 | final int itemCount;
38 |
39 | /// Called to build children for the list with
40 | /// 0 <= index < itemCount.
41 | final IndexedWidgetBuilder itemBuilder;
42 |
43 | /// Controller for jumping or scrolling to an item.
44 | final ItemScrollController? itemScrollController;
45 |
46 | /// Notifier that reports the items laid out in the list after each frame.
47 | final ItemPositionsListener? itemPositionsListener;
48 |
49 | /// How the scroll view should respond to user input.
50 | ///
51 | /// For example, determines how the scroll view continues to animate after the
52 | /// user stops dragging the scroll view.
53 | ///
54 | /// See [ScrollView.physics].
55 | final ScrollPhysics? physics;
56 |
57 | /// The amount of space by which to inset the children.
58 | final EdgeInsets? padding;
59 |
60 | /// Called to build suspension header.
61 | final IndexedWidgetBuilder? susItemBuilder;
62 |
63 | /// Suspension widget Height.
64 | final double susItemHeight;
65 |
66 | /// Suspension item position.
67 | final Offset? susPosition;
68 |
69 | /// IndexHintBuilder.
70 | final IndexHintBuilder? indexHintBuilder;
71 |
72 | /// Index data.
73 | final List indexBarData;
74 |
75 | /// IndexBar Width.
76 | final double indexBarWidth;
77 |
78 | /// IndexBar Height.
79 | final double? indexBarHeight;
80 |
81 | /// IndexBar Item Height.
82 | final double indexBarItemHeight;
83 |
84 | /// Haptic feedback.
85 | final bool hapticFeedback;
86 |
87 | /// IndexBar alignment.
88 | final AlignmentGeometry indexBarAlignment;
89 |
90 | /// IndexBar margin.
91 | final EdgeInsetsGeometry? indexBarMargin;
92 |
93 | /// IndexBar options.
94 | final IndexBarOptions indexBarOptions;
95 |
96 | @override
97 | _AzListViewState createState() => _AzListViewState();
98 | }
99 |
100 | class _AzListViewState extends State {
101 | /// Controller to scroll or jump to a particular item.
102 | late ItemScrollController itemScrollController;
103 |
104 | /// Listener that reports the position of items when the list is scrolled.
105 | late ItemPositionsListener itemPositionsListener;
106 |
107 | IndexBarDragListener dragListener = IndexBarDragListener.create();
108 |
109 | final IndexBarController indexBarController = IndexBarController();
110 |
111 | String selectTag = '';
112 |
113 | @override
114 | void initState() {
115 | super.initState();
116 | itemScrollController =
117 | widget.itemScrollController ?? ItemScrollController();
118 | itemPositionsListener =
119 | widget.itemPositionsListener ?? ItemPositionsListener.create();
120 | dragListener.dragDetails.addListener(_valueChanged);
121 | if (widget.indexBarOptions.selectItemDecoration != null) {
122 | itemPositionsListener.itemPositions.addListener(_positionsChanged);
123 | }
124 | }
125 |
126 | @override
127 | void dispose() {
128 | super.dispose();
129 | dragListener.dragDetails.removeListener(_valueChanged);
130 | if (widget.indexBarOptions.selectItemDecoration != null) {
131 | itemPositionsListener.itemPositions.removeListener(_positionsChanged);
132 | }
133 | }
134 |
135 | int _getIndex(String tag) {
136 | for (int i = 0; i < widget.itemCount; i++) {
137 | ISuspensionBean bean = widget.data[i];
138 | if (tag == bean.getSuspensionTag()) {
139 | return i;
140 | }
141 | }
142 | return -1;
143 | }
144 |
145 | void _scrollTopIndex(String tag) {
146 | int index = _getIndex(tag);
147 | if (index != -1) {
148 | itemScrollController.jumpTo(index: index);
149 | }
150 | }
151 |
152 | void _valueChanged() {
153 | IndexBarDragDetails details = dragListener.dragDetails.value;
154 | String tag = details.tag!;
155 | if (details.action == IndexBarDragDetails.actionDown ||
156 | details.action == IndexBarDragDetails.actionUpdate) {
157 | selectTag = tag;
158 | _scrollTopIndex(tag);
159 | }
160 | }
161 |
162 | void _positionsChanged() {
163 | Iterable positions =
164 | itemPositionsListener.itemPositions.value;
165 | if (positions.isNotEmpty) {
166 | ItemPosition itemPosition = positions
167 | .where((ItemPosition position) => position.itemTrailingEdge > 0)
168 | .reduce((ItemPosition min, ItemPosition position) =>
169 | position.itemTrailingEdge < min.itemTrailingEdge
170 | ? position
171 | : min);
172 | int index = itemPosition.index;
173 | String tag = widget.data[index].getSuspensionTag();
174 | if (selectTag != tag) {
175 | selectTag = tag;
176 | indexBarController.updateTagIndex(tag);
177 | }
178 | }
179 | }
180 |
181 | @override
182 | Widget build(BuildContext context) {
183 | return Stack(
184 | children: [
185 | SuspensionView(
186 | data: widget.data,
187 | itemCount: widget.itemCount,
188 | itemBuilder: widget.itemBuilder,
189 | itemScrollController: itemScrollController,
190 | itemPositionsListener: itemPositionsListener,
191 | susItemBuilder: widget.susItemBuilder,
192 | susItemHeight: widget.susItemHeight,
193 | susPosition: widget.susPosition,
194 | padding: widget.padding,
195 | physics: widget.physics,
196 | ),
197 | Align(
198 | alignment: widget.indexBarAlignment,
199 | child: IndexBar(
200 | data: widget.indexBarData,
201 | width: widget.indexBarWidth,
202 | height: widget.indexBarHeight,
203 | itemHeight: widget.indexBarItemHeight,
204 | margin: widget.indexBarMargin,
205 | indexHintBuilder: widget.indexHintBuilder,
206 | indexBarDragListener: dragListener,
207 | options: widget.indexBarOptions,
208 | controller: indexBarController,
209 | ),
210 | ),
211 | ],
212 | );
213 | }
214 | }
215 |
--------------------------------------------------------------------------------
/lib/src/index_bar.dart:
--------------------------------------------------------------------------------
1 | import 'dart:ui';
2 |
3 | import 'package:flutter/foundation.dart';
4 | import 'package:flutter/material.dart';
5 | import 'dart:math' as math;
6 |
7 | import 'package:flutter/services.dart';
8 |
9 | /// IndexHintBuilder.
10 | typedef IndexHintBuilder = Widget Function(BuildContext context, String tag);
11 |
12 | /// IndexBarDragListener.
13 | abstract class IndexBarDragListener {
14 | /// Creates an [IndexBarDragListener] that can be used by a
15 | /// [IndexBar] to return the drag listener.
16 | factory IndexBarDragListener.create() => IndexBarDragNotifier();
17 |
18 | /// drag details.
19 | ValueListenable get dragDetails;
20 | }
21 |
22 | /// Internal implementation of [ItemPositionsListener].
23 | class IndexBarDragNotifier implements IndexBarDragListener {
24 | @override
25 | final ValueNotifier dragDetails =
26 | ValueNotifier(IndexBarDragDetails());
27 | }
28 |
29 | /// IndexModel.
30 | class IndexBarDragDetails {
31 | static const int actionDown = 0;
32 | static const int actionUp = 1;
33 | static const int actionUpdate = 2;
34 | static const int actionEnd = 3;
35 | static const int actionCancel = 4;
36 |
37 | int? action;
38 | int? index; //current touch index.
39 | String? tag; //current touch tag.
40 |
41 | double? localPositionY;
42 | double? globalPositionY;
43 |
44 | IndexBarDragDetails({
45 | this.action,
46 | this.index,
47 | this.tag,
48 | this.localPositionY,
49 | this.globalPositionY,
50 | });
51 | }
52 |
53 | ///Default Index data.
54 | const List kIndexBarData = const [
55 | 'A',
56 | 'B',
57 | 'C',
58 | 'D',
59 | 'E',
60 | 'F',
61 | 'G',
62 | 'H',
63 | 'I',
64 | 'J',
65 | 'K',
66 | 'L',
67 | 'M',
68 | 'N',
69 | 'O',
70 | 'P',
71 | 'Q',
72 | 'R',
73 | 'S',
74 | 'T',
75 | 'U',
76 | 'V',
77 | 'W',
78 | 'X',
79 | 'Y',
80 | 'Z',
81 | '#'
82 | ];
83 |
84 | const double kIndexBarWidth = 30;
85 |
86 | const double kIndexBarItemHeight = 16;
87 |
88 | /// IndexBar options.
89 | class IndexBarOptions {
90 | /// Creates IndexBar options.
91 | /// Examples.
92 | /// needReBuild = true
93 | /// ignoreDragCancel = true
94 | /// color = Colors.transparent
95 | /// downColor = Color(0xFFEEEEEE)
96 | /// decoration
97 | /// downDecoration
98 | /// textStyle = TextStyle(fontSize: 12, color: Color(0xFF666666))
99 | /// downTextStyle = TextStyle(fontSize: 12, color: Colors.white)
100 | /// selectTextStyle = TextStyle(fontSize: 12, color: Colors.white)
101 | /// downItemDecoration = BoxDecoration(shape: BoxShape.circle, color: Colors.blueAccent)
102 | /// selectItemDecoration = BoxDecoration(shape: BoxShape.circle, color: Colors.blueAccent)
103 | /// indexHintWidth = 72
104 | /// indexHintHeight = 72
105 | /// indexHintDecoration = BoxDecoration(color: Colors.black87, shape: BoxShape.rectangle, borderRadius: BorderRadius.all(Radius.circular(6)),)
106 | /// indexHintTextStyle = TextStyle(fontSize: 24.0, color: Colors.white)
107 | /// indexHintChildAlignment = Alignment.center
108 | /// indexHintAlignment = Alignment.center
109 | /// indexHintPosition
110 | /// indexHintOffset
111 | /// localImages
112 | const IndexBarOptions({
113 | this.needRebuild = false,
114 | this.ignoreDragCancel = false,
115 | this.hapticFeedback = false,
116 | this.color,
117 | this.downColor,
118 | this.decoration,
119 | this.downDecoration,
120 | this.textStyle = const TextStyle(fontSize: 12, color: Color(0xFF666666)),
121 | this.downTextStyle,
122 | this.selectTextStyle,
123 | this.downItemDecoration,
124 | this.selectItemDecoration,
125 | this.indexHintWidth = 72,
126 | this.indexHintHeight = 72,
127 | this.indexHintDecoration = const BoxDecoration(
128 | color: Colors.black87,
129 | shape: BoxShape.rectangle,
130 | borderRadius: BorderRadius.all(Radius.circular(6)),
131 | ),
132 | this.indexHintTextStyle =
133 | const TextStyle(fontSize: 24.0, color: Colors.white),
134 | this.indexHintChildAlignment = Alignment.center,
135 | this.indexHintAlignment = Alignment.center,
136 | this.indexHintPosition,
137 | this.indexHintOffset = Offset.zero,
138 | this.localImages = const [],
139 | });
140 |
141 | /// need to rebuild.
142 | final bool needRebuild;
143 |
144 | /// Ignore DragCancel.
145 | final bool ignoreDragCancel;
146 |
147 | /// Haptic feedback.
148 | final bool hapticFeedback;
149 |
150 | /// IndexBar background color.
151 | final Color? color;
152 |
153 | /// IndexBar down background color.
154 | final Color? downColor;
155 |
156 | /// IndexBar decoration.
157 | final Decoration? decoration;
158 |
159 | /// IndexBar down decoration.
160 | final Decoration? downDecoration;
161 |
162 | /// IndexBar textStyle.
163 | final TextStyle textStyle;
164 |
165 | /// IndexBar down textStyle.
166 | final TextStyle? downTextStyle;
167 |
168 | /// IndexBar select textStyle.
169 | final TextStyle? selectTextStyle;
170 |
171 | /// IndexBar down item decoration.
172 | final Decoration? downItemDecoration;
173 |
174 | /// IndexBar select item decoration.
175 | final Decoration? selectItemDecoration;
176 |
177 | /// Index hint width.
178 | final double indexHintWidth;
179 |
180 | /// Index hint height.
181 | final double indexHintHeight;
182 |
183 | /// Index hint decoration.
184 | final Decoration indexHintDecoration;
185 |
186 | /// Index hint alignment.
187 | final Alignment indexHintAlignment;
188 |
189 | /// Index hint child alignment.
190 | final Alignment indexHintChildAlignment;
191 |
192 | /// Index hint textStyle.
193 | final TextStyle indexHintTextStyle;
194 |
195 | /// Index hint position.
196 | final Offset? indexHintPosition;
197 |
198 | /// Index hint offset.
199 | final Offset indexHintOffset;
200 |
201 | /// local images.
202 | final List localImages;
203 | }
204 |
205 | /// IndexBarController.
206 | class IndexBarController {
207 | _IndexBarState? _indexBarState;
208 |
209 | bool get isAttached => _indexBarState != null;
210 |
211 | void updateTagIndex(String tag) {
212 | _indexBarState?._updateTagIndex(tag);
213 | }
214 |
215 | void _attach(_IndexBarState state) {
216 | _indexBarState = state;
217 | }
218 |
219 | void _detach() {
220 | _indexBarState = null;
221 | }
222 | }
223 |
224 | /// IndexBar.
225 | class IndexBar extends StatefulWidget {
226 | IndexBar({
227 | Key? key,
228 | this.data = kIndexBarData,
229 | this.width = kIndexBarWidth,
230 | this.height,
231 | this.itemHeight = kIndexBarItemHeight,
232 | this.margin,
233 | this.indexHintBuilder,
234 | IndexBarDragListener? indexBarDragListener,
235 | this.options = const IndexBarOptions(),
236 | this.controller,
237 | }) : indexBarDragNotifier = indexBarDragListener as IndexBarDragNotifier?,
238 | super(key: key);
239 |
240 | /// Index data.
241 | final List data;
242 |
243 | /// IndexBar width(def:30).
244 | final double width;
245 |
246 | /// IndexBar height.
247 | final double? height;
248 |
249 | /// IndexBar item height(def:16).
250 | final double itemHeight;
251 |
252 | /// Empty space to surround the [decoration] and [child].
253 | final EdgeInsetsGeometry? margin;
254 |
255 | /// IndexHint Builder
256 | final IndexHintBuilder? indexHintBuilder;
257 |
258 | /// IndexBar drag listener.
259 | final IndexBarDragNotifier? indexBarDragNotifier;
260 |
261 | /// IndexBar options.
262 | final IndexBarOptions options;
263 |
264 | /// IndexBarController. If non-null, this can be used to control the state of the IndexBar.
265 | final IndexBarController? controller;
266 |
267 | @override
268 | _IndexBarState createState() => _IndexBarState();
269 | }
270 |
271 | class _IndexBarState extends State {
272 | /// overlay entry.
273 | static OverlayEntry? overlayEntry;
274 |
275 | double floatTop = 0;
276 | String indexTag = '';
277 | int selectIndex = 0;
278 | int action = IndexBarDragDetails.actionEnd;
279 |
280 | @override
281 | void initState() {
282 | super.initState();
283 | widget.indexBarDragNotifier?.dragDetails?.addListener(_valueChanged);
284 | widget.controller?._attach(this);
285 | }
286 |
287 | void _valueChanged() {
288 | if (widget.indexBarDragNotifier == null) return;
289 | IndexBarDragDetails details =
290 | widget.indexBarDragNotifier!.dragDetails.value;
291 | selectIndex = details.index!;
292 | indexTag = details.tag!;
293 | action = details.action!;
294 | floatTop = details.globalPositionY! +
295 | widget.itemHeight / 2 -
296 | widget.options.indexHintHeight / 2;
297 |
298 | if (_isActionDown()) {
299 | _addOverlay(context);
300 | } else {
301 | _removeOverlay();
302 | }
303 |
304 | if (widget.options.needRebuild) {
305 | if (widget.options.ignoreDragCancel &&
306 | action == IndexBarDragDetails.actionCancel) {
307 | } else {
308 | setState(() {});
309 | }
310 | }
311 | }
312 |
313 | bool _isActionDown() {
314 | return action == IndexBarDragDetails.actionDown ||
315 | action == IndexBarDragDetails.actionUpdate;
316 | }
317 |
318 | @override
319 | void dispose() {
320 | widget.controller?._detach();
321 | _removeOverlay();
322 | widget.indexBarDragNotifier?.dragDetails?.removeListener(_valueChanged);
323 | super.dispose();
324 | }
325 |
326 | Widget _buildIndexHint(BuildContext context, String tag) {
327 | if (widget.indexHintBuilder != null) {
328 | return widget.indexHintBuilder!(context, tag);
329 | }
330 | Widget child;
331 | TextStyle textStyle = widget.options.indexHintTextStyle;
332 | List localImages = widget.options.localImages;
333 | if (localImages.contains(tag)) {
334 | child = Image.asset(
335 | tag,
336 | width: textStyle.fontSize,
337 | height: textStyle.fontSize,
338 | color: textStyle.color,
339 | );
340 | } else {
341 | child = Text('$tag', style: textStyle);
342 | }
343 | return Container(
344 | width: widget.options.indexHintWidth,
345 | height: widget.options.indexHintHeight,
346 | alignment: widget.options.indexHintChildAlignment,
347 | decoration: widget.options.indexHintDecoration,
348 | child: child,
349 | );
350 | }
351 |
352 | /// add overlay.
353 | void _addOverlay(BuildContext context) {
354 | OverlayState? overlayState = Overlay.of(context);
355 | if (overlayState == null) return;
356 | if (overlayEntry == null) {
357 | overlayEntry = OverlayEntry(builder: (BuildContext ctx) {
358 | double left;
359 | double top;
360 | if (widget.options.indexHintPosition != null) {
361 | left = widget.options.indexHintPosition!.dx;
362 | top = widget.options.indexHintPosition!.dy;
363 | } else {
364 | if (widget.options.indexHintAlignment == Alignment.centerRight) {
365 | left = MediaQuery.of(context).size.width -
366 | kIndexBarWidth -
367 | widget.options.indexHintWidth +
368 | widget.options.indexHintOffset.dx;
369 | top = floatTop + widget.options.indexHintOffset.dy;
370 | } else if (widget.options.indexHintAlignment ==
371 | Alignment.centerLeft) {
372 | left = kIndexBarWidth + widget.options.indexHintOffset.dx;
373 | top = floatTop + widget.options.indexHintOffset.dy;
374 | } else {
375 | left = MediaQuery.of(context).size.width / 2 -
376 | widget.options.indexHintWidth / 2 +
377 | widget.options.indexHintOffset.dx;
378 | top = MediaQuery.of(context).size.height / 2 -
379 | widget.options.indexHintHeight / 2 +
380 | widget.options.indexHintOffset.dy;
381 | }
382 | }
383 | return Positioned(
384 | left: left,
385 | top: top,
386 | child: Material(
387 | color: Colors.transparent,
388 | child: _buildIndexHint(ctx, indexTag),
389 | ));
390 | });
391 | overlayState.insert(overlayEntry!);
392 | } else {
393 | //重新绘制UI,类似setState
394 | overlayEntry?.markNeedsBuild();
395 | }
396 | }
397 |
398 | /// remove overlay.
399 | void _removeOverlay() {
400 | overlayEntry?.remove();
401 | overlayEntry = null;
402 | }
403 |
404 | Widget _buildItem(BuildContext context, int index) {
405 | String tag = widget.data[index];
406 | Decoration? decoration;
407 | TextStyle? textStyle;
408 | if (widget.options.downItemDecoration != null) {
409 | decoration = (_isActionDown() && selectIndex == index)
410 | ? widget.options.downItemDecoration
411 | : null;
412 | textStyle = (_isActionDown() && selectIndex == index)
413 | ? widget.options.downTextStyle
414 | : widget.options.textStyle;
415 | } else if (widget.options.selectItemDecoration != null) {
416 | decoration =
417 | (selectIndex == index) ? widget.options.selectItemDecoration : null;
418 | textStyle = (selectIndex == index)
419 | ? widget.options.selectTextStyle
420 | : widget.options.textStyle;
421 | } else {
422 | textStyle = _isActionDown()
423 | ? (widget.options.downTextStyle ?? widget.options.textStyle)
424 | : widget.options.textStyle;
425 | }
426 |
427 | Widget child;
428 | List localImages = widget.options.localImages;
429 | if (localImages.contains(tag)) {
430 | child = Image.asset(
431 | tag,
432 | width: textStyle?.fontSize,
433 | height: textStyle?.fontSize,
434 | color: textStyle?.color,
435 | );
436 | } else {
437 | child = Text('$tag', style: textStyle);
438 | }
439 |
440 | return Container(
441 | alignment: Alignment.center,
442 | decoration: decoration,
443 | child: child,
444 | );
445 | }
446 |
447 | void _updateTagIndex(String tag) {
448 | if (_isActionDown()) return;
449 | selectIndex = widget.data.indexOf(tag);
450 | setState(() {});
451 | }
452 |
453 | @override
454 | Widget build(BuildContext context) {
455 | return Container(
456 | color: _isActionDown() ? widget.options.downColor : widget.options.color,
457 | decoration: _isActionDown()
458 | ? widget.options.downDecoration
459 | : widget.options.decoration,
460 | width: widget.width,
461 | height: widget.height,
462 | margin: widget.margin,
463 | alignment: Alignment.center,
464 | child: BaseIndexBar(
465 | data: widget.data,
466 | width: widget.width,
467 | itemHeight: widget.itemHeight,
468 | hapticFeedback: widget.options.hapticFeedback,
469 | itemBuilder: (BuildContext context, int index) {
470 | return _buildItem(context, index);
471 | },
472 | indexBarDragNotifier: widget.indexBarDragNotifier,
473 | ),
474 | );
475 | }
476 | }
477 |
478 | class BaseIndexBar extends StatefulWidget {
479 | BaseIndexBar({
480 | Key? key,
481 | this.data = kIndexBarData,
482 | this.width = kIndexBarWidth,
483 | this.itemHeight = kIndexBarItemHeight,
484 | this.hapticFeedback = false,
485 | this.textStyle = const TextStyle(fontSize: 12.0, color: Color(0xFF666666)),
486 | this.itemBuilder,
487 | this.indexBarDragNotifier,
488 | }) : super(key: key);
489 |
490 | /// index data.
491 | final List data;
492 |
493 | /// IndexBar width(def:30).
494 | final double width;
495 |
496 | /// IndexBar item height(def:16).
497 | final double itemHeight;
498 |
499 | /// Haptic feedback.
500 | final bool hapticFeedback;
501 |
502 | /// IndexBar text style.
503 | final TextStyle textStyle;
504 |
505 | final IndexedWidgetBuilder? itemBuilder;
506 |
507 | final IndexBarDragNotifier? indexBarDragNotifier;
508 |
509 | @override
510 | _BaseIndexBarState createState() => _BaseIndexBarState();
511 | }
512 |
513 | class _BaseIndexBarState extends State {
514 | int lastIndex = -1;
515 | int _widgetTop = 0;
516 |
517 | /// get index.
518 | int _getIndex(double offset) {
519 | int index = offset ~/ widget.itemHeight;
520 | return math.min(index, widget.data.length - 1);
521 | }
522 |
523 | /// trigger drag event.
524 | _triggerDragEvent(int action) {
525 | if (widget.hapticFeedback &&
526 | (action == IndexBarDragDetails.actionDown ||
527 | action == IndexBarDragDetails.actionUpdate)) {
528 | HapticFeedback.vibrate();
529 | }
530 | widget.indexBarDragNotifier?.dragDetails?.value = IndexBarDragDetails(
531 | action: action,
532 | index: lastIndex,
533 | tag: widget.data[lastIndex],
534 | localPositionY: lastIndex * widget.itemHeight,
535 | globalPositionY: lastIndex * widget.itemHeight + _widgetTop,
536 | );
537 | }
538 |
539 | RenderBox? _getRenderBox(BuildContext context) {
540 | RenderObject? renderObject = context.findRenderObject();
541 | RenderBox? box;
542 | if (renderObject != null) {
543 | box = renderObject as RenderBox;
544 | }
545 | return box;
546 | }
547 |
548 | @override
549 | Widget build(BuildContext context) {
550 | List children = List.generate(widget.data.length, (index) {
551 | Widget child = widget.itemBuilder == null
552 | ? Center(
553 | child: Text('${widget.data[index]}', style: widget.textStyle))
554 | : widget.itemBuilder!(context, index);
555 | return SizedBox(
556 | width: widget.width,
557 | height: widget.itemHeight,
558 | child: child,
559 | );
560 | });
561 |
562 | return GestureDetector(
563 | onVerticalDragDown: (DragDownDetails details) {
564 | RenderBox? box = _getRenderBox(context);
565 | if (box == null) return;
566 | Offset topLeftPosition = box.localToGlobal(Offset.zero);
567 | _widgetTop = topLeftPosition.dy.toInt();
568 | int index = _getIndex(details.localPosition.dy);
569 | if (index >= 0) {
570 | lastIndex = index;
571 | _triggerDragEvent(IndexBarDragDetails.actionDown);
572 | }
573 | },
574 | onVerticalDragUpdate: (DragUpdateDetails details) {
575 | int index = _getIndex(details.localPosition.dy);
576 | if (index >= 0 && lastIndex != index) {
577 | lastIndex = index;
578 | //HapticFeedback.lightImpact();
579 | //HapticFeedback.vibrate();
580 | _triggerDragEvent(IndexBarDragDetails.actionUpdate);
581 | }
582 | },
583 | onVerticalDragEnd: (DragEndDetails details) {
584 | _triggerDragEvent(IndexBarDragDetails.actionEnd);
585 | },
586 | onVerticalDragCancel: () {
587 | _triggerDragEvent(IndexBarDragDetails.actionCancel);
588 | },
589 | onTapUp: (TapUpDetails details) {
590 | //_triggerDragEvent(IndexBarDragDetails.actionUp);
591 | },
592 | behavior: HitTestBehavior.translucent,
593 | child: Column(
594 | mainAxisSize: MainAxisSize.min,
595 | children: children,
596 | ),
597 | );
598 | }
599 | }
600 |
--------------------------------------------------------------------------------
/lib/src/suspension_view.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:scrollable_positioned_list/scrollable_positioned_list.dart';
3 | import 'dart:math' as math;
4 | import 'az_common.dart';
5 |
6 | const double kSusItemHeight = 40;
7 |
8 | /// SuspensionView.
9 | class SuspensionView extends StatefulWidget {
10 | SuspensionView({
11 | Key? key,
12 | required this.data,
13 | required this.itemCount,
14 | required this.itemBuilder,
15 | this.itemScrollController,
16 | this.itemPositionsListener,
17 | this.susItemBuilder,
18 | this.susItemHeight = kSusItemHeight,
19 | this.susPosition,
20 | this.physics,
21 | this.padding,
22 | }) : super(key: key);
23 |
24 | /// Suspension data.
25 | final List data;
26 |
27 | /// Number of items the [itemBuilder] can produce.
28 | final int itemCount;
29 |
30 | /// Called to build children for the list with
31 | /// 0 <= index < itemCount.
32 | final IndexedWidgetBuilder itemBuilder;
33 |
34 | /// Controller for jumping or scrolling to an item.
35 | final ItemScrollController? itemScrollController;
36 |
37 | /// Notifier that reports the items laid out in the list after each frame.
38 | final ItemPositionsListener? itemPositionsListener;
39 |
40 | /// Called to build suspension header.
41 | final IndexedWidgetBuilder? susItemBuilder;
42 |
43 | /// Suspension item Height.
44 | final double susItemHeight;
45 |
46 | /// Suspension item position.
47 | final Offset? susPosition;
48 |
49 | /// How the scroll view should respond to user input.
50 | ///
51 | /// For example, determines how the scroll view continues to animate after the
52 | /// user stops dragging the scroll view.
53 | ///
54 | /// See [ScrollView.physics].
55 | final ScrollPhysics? physics;
56 |
57 | /// The amount of space by which to inset the children.
58 | final EdgeInsets? padding;
59 |
60 | @override
61 | _SuspensionViewState createState() => _SuspensionViewState();
62 | }
63 |
64 | class _SuspensionViewState extends State {
65 | /// Controller to scroll or jump to a particular item.
66 | late ItemScrollController itemScrollController;
67 |
68 | /// Listener that reports the position of items when the list is scrolled.
69 | late ItemPositionsListener itemPositionsListener;
70 |
71 | @override
72 | void initState() {
73 | super.initState();
74 | itemScrollController =
75 | widget.itemScrollController ?? ItemScrollController();
76 | itemPositionsListener =
77 | widget.itemPositionsListener ?? ItemPositionsListener.create();
78 | }
79 |
80 | @override
81 | void dispose() {
82 | super.dispose();
83 | }
84 |
85 | /// build sus widget.
86 | Widget _buildSusWidget(BuildContext context) {
87 | if (widget.susItemBuilder == null) {
88 | return Container();
89 | }
90 | return ValueListenableBuilder>(
91 | valueListenable: itemPositionsListener.itemPositions,
92 | builder: (ctx, positions, child) {
93 | if (positions.isEmpty || widget.itemCount == 0) {
94 | return Container();
95 | }
96 | ItemPosition itemPosition = positions
97 | .where((ItemPosition position) => position.itemTrailingEdge > 0)
98 | .reduce((ItemPosition min, ItemPosition position) =>
99 | position.itemTrailingEdge < min.itemTrailingEdge
100 | ? position
101 | : min);
102 | if (itemPosition.itemLeadingEdge > 0) return Container();
103 | int index = itemPosition.index;
104 | double left = 0;
105 | double top = 0;
106 | if (index < widget.itemCount) {
107 | if (widget.susPosition != null) {
108 | left = widget.susPosition!.dx;
109 | top = widget.susPosition!.dy;
110 | } else {
111 | int next = math.min(index + 1, widget.itemCount - 1);
112 | ISuspensionBean bean = widget.data[next];
113 | if (bean.isShowSuspension) {
114 | double height =
115 | context.findRenderObject()?.paintBounds?.height ?? 0;
116 | double topTemp = itemPosition.itemTrailingEdge * height;
117 | top = math.min(widget.susItemHeight, topTemp) -
118 | widget.susItemHeight;
119 | }
120 | }
121 | } else {
122 | index = 0;
123 | }
124 | return Positioned(
125 | left: left,
126 | top: top,
127 | child: widget.susItemBuilder!(ctx, index),
128 | );
129 | },
130 | );
131 | }
132 |
133 | Widget _buildItem(BuildContext context, int index) {
134 | ISuspensionBean bean = widget.data[index];
135 | if (!bean.isShowSuspension || widget.susItemBuilder == null) {
136 | return widget.itemBuilder(context, index);
137 | }
138 | return Column(
139 | mainAxisSize: MainAxisSize.min,
140 | children: [
141 | widget.susItemBuilder!(context, index),
142 | widget.itemBuilder(context, index),
143 | ],
144 | );
145 | }
146 |
147 | @override
148 | Widget build(BuildContext context) {
149 | return Stack(
150 | children: [
151 | widget.itemCount == 0
152 | ? Container()
153 | : ScrollablePositionedList.builder(
154 | itemCount: widget.itemCount,
155 | itemBuilder: (context, index) => _buildItem(context, index),
156 | itemScrollController: itemScrollController,
157 | itemPositionsListener: itemPositionsListener,
158 | physics: widget.physics,
159 | padding: widget.padding,
160 | ),
161 | _buildSusWidget(context),
162 | ],
163 | );
164 | }
165 | }
166 |
--------------------------------------------------------------------------------
/pkgget:
--------------------------------------------------------------------------------
1 | export PUB_HOSTED_URL=https://pub.flutter-io.cn
2 | export FLUTTER_STORAGE_BASE_URL=https://storage.flutter-io.cn
3 | flutter packages get
--------------------------------------------------------------------------------
/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 | characters:
19 | dependency: transitive
20 | description:
21 | name: characters
22 | url: "https://pub.flutter-io.cn"
23 | source: hosted
24 | version: "1.2.0"
25 | charcode:
26 | dependency: transitive
27 | description:
28 | name: charcode
29 | url: "https://pub.flutter-io.cn"
30 | source: hosted
31 | version: "1.3.1"
32 | clock:
33 | dependency: transitive
34 | description:
35 | name: clock
36 | url: "https://pub.flutter-io.cn"
37 | source: hosted
38 | version: "1.1.0"
39 | collection:
40 | dependency: transitive
41 | description:
42 | name: collection
43 | url: "https://pub.flutter-io.cn"
44 | source: hosted
45 | version: "1.15.0"
46 | fake_async:
47 | dependency: transitive
48 | description:
49 | name: fake_async
50 | url: "https://pub.flutter-io.cn"
51 | source: hosted
52 | version: "1.2.0"
53 | flutter:
54 | dependency: "direct main"
55 | description: flutter
56 | source: sdk
57 | version: "0.0.0"
58 | flutter_test:
59 | dependency: "direct dev"
60 | description: flutter
61 | source: sdk
62 | version: "0.0.0"
63 | matcher:
64 | dependency: transitive
65 | description:
66 | name: matcher
67 | url: "https://pub.flutter-io.cn"
68 | source: hosted
69 | version: "0.12.11"
70 | material_color_utilities:
71 | dependency: transitive
72 | description:
73 | name: material_color_utilities
74 | url: "https://pub.flutter-io.cn"
75 | source: hosted
76 | version: "0.1.3"
77 | meta:
78 | dependency: transitive
79 | description:
80 | name: meta
81 | url: "https://pub.flutter-io.cn"
82 | source: hosted
83 | version: "1.7.0"
84 | path:
85 | dependency: transitive
86 | description:
87 | name: path
88 | url: "https://pub.flutter-io.cn"
89 | source: hosted
90 | version: "1.8.0"
91 | scrollable_positioned_list:
92 | dependency: "direct main"
93 | description:
94 | name: scrollable_positioned_list
95 | url: "https://pub.flutter-io.cn"
96 | source: hosted
97 | version: "0.2.3"
98 | sky_engine:
99 | dependency: transitive
100 | description: flutter
101 | source: sdk
102 | version: "0.0.99"
103 | source_span:
104 | dependency: transitive
105 | description:
106 | name: source_span
107 | url: "https://pub.flutter-io.cn"
108 | source: hosted
109 | version: "1.8.1"
110 | stack_trace:
111 | dependency: transitive
112 | description:
113 | name: stack_trace
114 | url: "https://pub.flutter-io.cn"
115 | source: hosted
116 | version: "1.10.0"
117 | stream_channel:
118 | dependency: transitive
119 | description:
120 | name: stream_channel
121 | url: "https://pub.flutter-io.cn"
122 | source: hosted
123 | version: "2.1.0"
124 | string_scanner:
125 | dependency: transitive
126 | description:
127 | name: string_scanner
128 | url: "https://pub.flutter-io.cn"
129 | source: hosted
130 | version: "1.1.0"
131 | term_glyph:
132 | dependency: transitive
133 | description:
134 | name: term_glyph
135 | url: "https://pub.flutter-io.cn"
136 | source: hosted
137 | version: "1.2.0"
138 | test_api:
139 | dependency: transitive
140 | description:
141 | name: test_api
142 | url: "https://pub.flutter-io.cn"
143 | source: hosted
144 | version: "0.4.8"
145 | typed_data:
146 | dependency: transitive
147 | description:
148 | name: typed_data
149 | url: "https://pub.flutter-io.cn"
150 | source: hosted
151 | version: "1.3.0"
152 | vector_math:
153 | dependency: transitive
154 | description:
155 | name: vector_math
156 | url: "https://pub.flutter-io.cn"
157 | source: hosted
158 | version: "2.1.1"
159 | sdks:
160 | dart: ">=2.14.0 <3.0.0"
161 | flutter: ">=1.13.8"
162 |
--------------------------------------------------------------------------------
/pubspec.yaml:
--------------------------------------------------------------------------------
1 | name: azlistview
2 | description: A Flutter sticky headers & index ListView. IndexBar. such as citylist, contactlist. index and hover effect.
3 | version: 2.0.0
4 | homepage: https://github.com/flutterchina/azlistview
5 |
6 | environment:
7 | sdk: ">=2.12.0 <3.0.0"
8 |
9 | dependencies:
10 | flutter:
11 | sdk: flutter
12 | # https://pub.flutter-io.cn/packages/scrollable_positioned_list
13 | scrollable_positioned_list: ^0.2.3
14 |
15 | dev_dependencies:
16 | flutter_test:
17 | sdk: flutter
18 |
19 | # For information on the generic Dart part of this file, see the
20 | # following page: https://dart.dev/tools/pub/pubspec
21 |
22 | # The following section is specific to Flutter.
23 | flutter:
24 |
25 | # To add assets to your package, add an assets section, like this:
26 | # assets:
27 | # - images/a_dot_burr.jpeg
28 | # - images/a_dot_ham.jpeg
29 | #
30 | # For details regarding assets in packages, see
31 | # https://flutter.dev/assets-and-images/#from-packages
32 | #
33 | # An image asset can refer to one or more resolution-specific "variants", see
34 | # https://flutter.dev/assets-and-images/#resolution-aware.
35 |
36 | # To add custom fonts to your package, add a fonts section here,
37 | # in this "flutter" section. Each entry in this list should have a
38 | # "family" key with the font family name, and a "fonts" key with a
39 | # list giving the asset and other descriptors for the font. For
40 | # example:
41 | # fonts:
42 | # - family: Schyler
43 | # fonts:
44 | # - asset: fonts/Schyler-Regular.ttf
45 | # - asset: fonts/Schyler-Italic.ttf
46 | # style: italic
47 | # - family: Trajan Pro
48 | # fonts:
49 | # - asset: fonts/TrajanPro.ttf
50 | # - asset: fonts/TrajanPro_Bold.ttf
51 | # weight: 700
52 | #
53 | # For details regarding fonts in packages, see
54 | # https://flutter.dev/custom-fonts/#from-packages
55 |
--------------------------------------------------------------------------------
/screenshots/azlistview1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flutterchina/azlistview/ea7e11660223c3b6b1f3491ab0e5e04a333cca5d/screenshots/azlistview1.jpg
--------------------------------------------------------------------------------
/screenshots/azlistview2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flutterchina/azlistview/ea7e11660223c3b6b1f3491ab0e5e04a333cca5d/screenshots/azlistview2.jpg
--------------------------------------------------------------------------------
/screenshots/azlistview3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flutterchina/azlistview/ea7e11660223c3b6b1f3491ab0e5e04a333cca5d/screenshots/azlistview3.jpg
--------------------------------------------------------------------------------
/screenshots/azlistview4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flutterchina/azlistview/ea7e11660223c3b6b1f3491ab0e5e04a333cca5d/screenshots/azlistview4.jpg
--------------------------------------------------------------------------------
/screenshots/azlistview5.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flutterchina/azlistview/ea7e11660223c3b6b1f3491ab0e5e04a333cca5d/screenshots/azlistview5.jpg
--------------------------------------------------------------------------------
/screenshots/azlistview6.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flutterchina/azlistview/ea7e11660223c3b6b1f3491ab0e5e04a333cca5d/screenshots/azlistview6.jpg
--------------------------------------------------------------------------------
/uploadMaster:
--------------------------------------------------------------------------------
1 | git push origin master
2 |
--------------------------------------------------------------------------------