Showing preview only (901K chars total). Download the full file or copy to clipboard to get everything.
Repository: LinXunFeng/flutter_scrollview_observer
Branch: main
Commit: bd9d306e4f50
Files: 247
Total size: 819.7 KB
Directory structure:
gitextract_0cpp3x9p/
├── .github/
│ ├── FUNDING.yml
│ └── workflows/
│ ├── assign-issue.yml
│ ├── code-analysis.yml
│ └── deploy.yml
├── .gitignore
├── .packages
├── CHANGELOG.md
├── CODEOWNERS
├── LICENSE
├── README-zh.md
├── README.md
├── analysis_options.yaml
├── example/
│ ├── .gitignore
│ ├── .metadata
│ ├── README.md
│ ├── analysis_options.yaml
│ ├── android/
│ │ ├── .gitignore
│ │ ├── app/
│ │ │ ├── build.gradle
│ │ │ └── src/
│ │ │ ├── debug/
│ │ │ │ └── AndroidManifest.xml
│ │ │ ├── main/
│ │ │ │ ├── AndroidManifest.xml
│ │ │ │ ├── kotlin/
│ │ │ │ │ └── com/
│ │ │ │ │ └── example/
│ │ │ │ │ └── example/
│ │ │ │ │ └── MainActivity.kt
│ │ │ │ └── res/
│ │ │ │ ├── drawable/
│ │ │ │ │ └── launch_background.xml
│ │ │ │ ├── drawable-v21/
│ │ │ │ │ └── launch_background.xml
│ │ │ │ ├── values/
│ │ │ │ │ └── styles.xml
│ │ │ │ └── values-night/
│ │ │ │ └── styles.xml
│ │ │ └── profile/
│ │ │ └── AndroidManifest.xml
│ │ ├── build.gradle
│ │ ├── gradle/
│ │ │ └── wrapper/
│ │ │ └── gradle-wrapper.properties
│ │ ├── gradle.properties
│ │ └── settings.gradle
│ ├── ios/
│ │ ├── .gitignore
│ │ ├── Flutter/
│ │ │ ├── AppFrameworkInfo.plist
│ │ │ ├── Debug.xcconfig
│ │ │ └── Release.xcconfig
│ │ ├── Podfile
│ │ ├── Runner/
│ │ │ ├── AppDelegate.swift
│ │ │ ├── Assets.xcassets/
│ │ │ │ ├── AppIcon.appiconset/
│ │ │ │ │ └── Contents.json
│ │ │ │ └── LaunchImage.imageset/
│ │ │ │ ├── Contents.json
│ │ │ │ └── README.md
│ │ │ ├── Base.lproj/
│ │ │ │ ├── LaunchScreen.storyboard
│ │ │ │ └── Main.storyboard
│ │ │ ├── Info.plist
│ │ │ └── Runner-Bridging-Header.h
│ │ ├── 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
│ ├── lib/
│ │ ├── common/
│ │ │ └── route/
│ │ │ ├── navigation_service.dart
│ │ │ ├── route.dart
│ │ │ └── router_config.dart
│ │ ├── features/
│ │ │ ├── custom_scrollview/
│ │ │ │ ├── custom_scrollview_demo/
│ │ │ │ │ ├── custom_scrollview_center_demo_page.dart
│ │ │ │ │ ├── custom_scrollview_demo_page.dart
│ │ │ │ │ └── multi_sliver_demo_page.dart
│ │ │ │ └── sliver_appbar_demo/
│ │ │ │ └── sliver_appbar_demo_page.dart
│ │ │ ├── gridview/
│ │ │ │ ├── gridview_ctx_demo/
│ │ │ │ │ └── gridview_ctx_demo_page.dart
│ │ │ │ ├── gridview_custom_demo/
│ │ │ │ │ └── gridview_custom_demo_page.dart
│ │ │ │ ├── gridview_demo/
│ │ │ │ │ └── gridview_demo_page.dart
│ │ │ │ ├── gridview_fixed_height_demo/
│ │ │ │ │ └── gridview_fixed_height_demo_page.dart
│ │ │ │ ├── horizontal_gridview_demo/
│ │ │ │ │ └── horizontal_gridview_demo_page.dart
│ │ │ │ └── sliver_grid_demo/
│ │ │ │ └── sliver_grid_demo_page.dart
│ │ │ ├── home/
│ │ │ │ └── home_page.dart
│ │ │ ├── listview/
│ │ │ │ ├── horizontal_listview_demo/
│ │ │ │ │ └── horizontal_listview_page.dart
│ │ │ │ ├── infinite_listview_demo/
│ │ │ │ │ └── infinite_listview_page.dart
│ │ │ │ ├── listview_ctx_demo/
│ │ │ │ │ └── listview_ctx_demo_page.dart
│ │ │ │ ├── listview_custom_demo/
│ │ │ │ │ └── listview_custom_demo_page.dart
│ │ │ │ ├── listview_demo/
│ │ │ │ │ └── listview_demo_page.dart
│ │ │ │ ├── listview_dynamic_offset/
│ │ │ │ │ └── listview_dynamic_offset_page.dart
│ │ │ │ ├── listview_fixed_height_demo/
│ │ │ │ │ └── listview_fixed_height_demo_page.dart
│ │ │ │ └── sliver_list_demo/
│ │ │ │ └── sliver_list_demo_page.dart
│ │ │ ├── nested_scrollview/
│ │ │ │ ├── nested_scrollview_demo/
│ │ │ │ │ └── nested_scrollview_demo_page.dart
│ │ │ │ └── nested_scrollview_tab_bar_view_demo/
│ │ │ │ ├── header/
│ │ │ │ │ └── nested_scrollview_tab_bar_view_demo_header.dart
│ │ │ │ ├── logic/
│ │ │ │ │ ├── nested_scrollview_tab_bar_view_demo_logic.dart
│ │ │ │ │ ├── nested_scrollview_tab_bar_view_demo_logic_floating_action_btn.dart
│ │ │ │ │ ├── nested_scrollview_tab_bar_view_demo_logic_observer.dart
│ │ │ │ │ ├── nested_scrollview_tab_bar_view_demo_logic_scroll_type_switch.dart
│ │ │ │ │ └── nested_scrollview_tab_bar_view_demo_logic_tab_bar.dart
│ │ │ │ ├── page/
│ │ │ │ │ └── nested_scrollview_tab_bar_view_demo_page.dart
│ │ │ │ ├── state/
│ │ │ │ │ └── nested_scrollview_tab_bar_view_demo_state.dart
│ │ │ │ └── widget/
│ │ │ │ ├── nested_scrollview_tab_bar_view_demo_floating_action_btn.dart
│ │ │ │ ├── nested_scrollview_tab_bar_view_demo_header_list_sliver.dart
│ │ │ │ ├── nested_scrollview_tab_bar_view_demo_scroll_type_switch.dart
│ │ │ │ ├── nested_scrollview_tab_bar_view_demo_tab1_view.dart
│ │ │ │ ├── nested_scrollview_tab_bar_view_demo_tab2_view.dart
│ │ │ │ ├── nested_scrollview_tab_bar_view_demo_tab3_view.dart
│ │ │ │ └── nested_scrollview_tab_bar_view_demo_tabbar.dart
│ │ │ ├── pageview/
│ │ │ │ └── pageview_demo/
│ │ │ │ ├── pageview_demo_page.dart
│ │ │ │ ├── pageview_parallax_item_listener_page.dart
│ │ │ │ └── pageview_parallax_page.dart
│ │ │ └── scene/
│ │ │ ├── anchor_demo/
│ │ │ │ ├── anchor_page.dart
│ │ │ │ └── anchor_waterfall_page.dart
│ │ │ ├── azlist_demo/
│ │ │ │ ├── azlist_cursor.dart
│ │ │ │ ├── azlist_index_bar.dart
│ │ │ │ ├── azlist_item_view.dart
│ │ │ │ ├── azlist_model.dart
│ │ │ │ └── azlist_page.dart
│ │ │ ├── chat_demo/
│ │ │ │ ├── helper/
│ │ │ │ │ └── chat_data_helper.dart
│ │ │ │ ├── model/
│ │ │ │ │ └── chat_model.dart
│ │ │ │ ├── page/
│ │ │ │ │ ├── chat_gpt_page.dart
│ │ │ │ │ └── chat_page.dart
│ │ │ │ └── widget/
│ │ │ │ ├── chat_item_widget.dart
│ │ │ │ └── chat_unread_tip_view.dart
│ │ │ ├── detail/
│ │ │ │ ├── header/
│ │ │ │ │ └── detail_header.dart
│ │ │ │ ├── logic/
│ │ │ │ │ ├── detail_logic.dart
│ │ │ │ │ ├── detail_logic_config.dart
│ │ │ │ │ ├── detail_logic_list_view.dart
│ │ │ │ │ └── detail_logic_nav_bar.dart
│ │ │ │ ├── model/
│ │ │ │ │ └── detail_nav_bar_tab_model.dart
│ │ │ │ ├── page/
│ │ │ │ │ └── detail_page.dart
│ │ │ │ ├── state/
│ │ │ │ │ ├── detail_state.dart
│ │ │ │ │ ├── detail_state_config.dart
│ │ │ │ │ ├── detail_state_list_view.dart
│ │ │ │ │ └── detail_state_nav_bar.dart
│ │ │ │ └── widget/
│ │ │ │ ├── detail_config_view.dart
│ │ │ │ ├── detail_list_item_wrapper.dart
│ │ │ │ ├── detail_list_view.dart
│ │ │ │ ├── detail_nav_bar.dart
│ │ │ │ └── list_item/
│ │ │ │ ├── detail_list_module1.dart
│ │ │ │ ├── detail_list_module2.dart
│ │ │ │ ├── detail_list_module3.dart
│ │ │ │ ├── detail_list_module4.dart
│ │ │ │ ├── detail_list_module5.dart
│ │ │ │ ├── detail_list_module6.dart
│ │ │ │ ├── detail_list_module7.dart
│ │ │ │ └── detail_list_module8.dart
│ │ │ ├── expandable_carousel_slider_demo/
│ │ │ │ └── expandable_carousel_slider_demo.dart
│ │ │ ├── image_tab_demo/
│ │ │ │ └── image_tab_page.dart
│ │ │ ├── scrollview_form_demo/
│ │ │ │ └── scrollview_form_demo_page.dart
│ │ │ ├── video_auto_play_list/
│ │ │ │ ├── video_list_auto_play_page.dart
│ │ │ │ └── widgets/
│ │ │ │ └── video_widget.dart
│ │ │ ├── visibility_demo/
│ │ │ │ ├── mixin/
│ │ │ │ │ └── visibility_exposure_mixin.dart
│ │ │ │ └── page/
│ │ │ │ ├── visibility_listview_page.dart
│ │ │ │ └── visibility_scrollview_page.dart
│ │ │ ├── waterfall_flow_demo/
│ │ │ │ ├── waterfall_flow_grid_item_view.dart
│ │ │ │ ├── waterfall_flow_page.dart
│ │ │ │ ├── waterfall_flow_swipe_view.dart
│ │ │ │ └── waterfall_flow_type.dart
│ │ │ └── waterfall_flow_fixed_height_demo/
│ │ │ └── waterfall_flow_fixed_height_page.dart
│ │ ├── main.dart
│ │ ├── typedefs.dart
│ │ ├── utils/
│ │ │ ├── keyboard.dart
│ │ │ ├── random.dart
│ │ │ └── snackbar.dart
│ │ └── widgets/
│ │ ├── animation.dart
│ │ └── sliver.dart
│ ├── linux/
│ │ └── flutter/
│ │ ├── generated_plugin_registrant.cc
│ │ ├── generated_plugin_registrant.h
│ │ └── generated_plugins.cmake
│ ├── macos/
│ │ ├── .gitignore
│ │ ├── Flutter/
│ │ │ ├── Flutter-Debug.xcconfig
│ │ │ ├── Flutter-Release.xcconfig
│ │ │ └── GeneratedPluginRegistrant.swift
│ │ ├── Podfile
│ │ ├── Runner/
│ │ │ ├── AppDelegate.swift
│ │ │ ├── Assets.xcassets/
│ │ │ │ └── AppIcon.appiconset/
│ │ │ │ └── Contents.json
│ │ │ ├── Base.lproj/
│ │ │ │ └── MainMenu.xib
│ │ │ ├── Configs/
│ │ │ │ ├── AppInfo.xcconfig
│ │ │ │ ├── Debug.xcconfig
│ │ │ │ ├── Release.xcconfig
│ │ │ │ └── Warnings.xcconfig
│ │ │ ├── DebugProfile.entitlements
│ │ │ ├── Info.plist
│ │ │ ├── MainFlutterWindow.swift
│ │ │ └── Release.entitlements
│ │ ├── Runner.xcodeproj/
│ │ │ ├── project.pbxproj
│ │ │ ├── project.xcworkspace/
│ │ │ │ └── xcshareddata/
│ │ │ │ └── IDEWorkspaceChecks.plist
│ │ │ └── xcshareddata/
│ │ │ └── xcschemes/
│ │ │ └── Runner.xcscheme
│ │ └── Runner.xcworkspace/
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata/
│ │ └── IDEWorkspaceChecks.plist
│ ├── pubspec.yaml
│ ├── test/
│ │ └── widget_test.dart
│ ├── web/
│ │ ├── index.html
│ │ └── manifest.json
│ └── windows/
│ ├── .gitignore
│ ├── CMakeLists.txt
│ ├── flutter/
│ │ ├── CMakeLists.txt
│ │ ├── generated_plugin_registrant.cc
│ │ ├── generated_plugin_registrant.h
│ │ └── generated_plugins.cmake
│ └── runner/
│ ├── CMakeLists.txt
│ ├── Runner.rc
│ ├── flutter_window.cpp
│ ├── flutter_window.h
│ ├── main.cpp
│ ├── resource.h
│ ├── runner.exe.manifest
│ ├── utils.cpp
│ ├── utils.h
│ ├── win32_window.cpp
│ └── win32_window.h
├── lib/
│ ├── scrollview_observer.dart
│ └── src/
│ ├── common/
│ │ ├── models/
│ │ │ ├── observe_displaying_child_model.dart
│ │ │ ├── observe_displaying_child_model_mixin.dart
│ │ │ ├── observe_find_child_model.dart
│ │ │ ├── observe_model.dart
│ │ │ ├── observe_scroll_child_model.dart
│ │ │ ├── observe_scroll_to_index_result_model.dart
│ │ │ ├── observer_handle_contexts_result_model.dart
│ │ │ └── observer_index_position_model.dart
│ │ ├── observer_controller.dart
│ │ ├── observer_listener.dart
│ │ ├── observer_notification_result.dart
│ │ ├── observer_typedef.dart
│ │ ├── observer_widget.dart
│ │ ├── observer_widget_scope.dart
│ │ ├── observer_widget_tag_manager.dart
│ │ └── typedefs.dart
│ ├── gridview/
│ │ ├── grid_observer_controller.dart
│ │ ├── grid_observer_notification_result.dart
│ │ ├── grid_observer_view.dart
│ │ └── models/
│ │ ├── gridview_observe_displaying_child_model.dart
│ │ └── gridview_observe_model.dart
│ ├── listview/
│ │ ├── list_observer_controller.dart
│ │ ├── list_observer_notification_result.dart
│ │ ├── list_observer_view.dart
│ │ └── models/
│ │ ├── listview_observe_displaying_child_model.dart
│ │ └── listview_observe_model.dart
│ ├── notification.dart
│ ├── observer_core.dart
│ ├── sliver/
│ │ ├── models/
│ │ │ ├── sliver_observer_observe_result_model.dart
│ │ │ ├── sliver_viewport_observe_displaying_child_model.dart
│ │ │ └── sliver_viewport_observe_model.dart
│ │ ├── sliver_observer_controller.dart
│ │ ├── sliver_observer_listener.dart
│ │ ├── sliver_observer_notification_result.dart
│ │ └── sliver_observer_view.dart
│ └── utils/
│ ├── observer_utils.dart
│ └── src/
│ ├── chat/
│ │ ├── chat_observer_scroll_physics.dart
│ │ ├── chat_observer_scroll_physics_mixin.dart
│ │ ├── chat_scroll_observer.dart
│ │ ├── chat_scroll_observer_model.dart
│ │ └── chat_scroll_observer_typedefs.dart
│ ├── extends.dart
│ ├── log.dart
│ ├── nested_scroll_util.dart
│ ├── observer_utils.dart
│ └── slivers.dart
├── listview_observer.iml
├── pubspec.yaml
└── test/
├── chat_scroll_observer_test.dart
├── grid_observer_test.dart
├── list_observer_test.dart
├── observer_utils_test.dart
└── sliver_observer_test.dart
================================================
FILE CONTENTS
================================================
================================================
FILE: .github/FUNDING.yml
================================================
# These are supported funding model platforms
# github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
# patreon: # Replace with a single Patreon username
# open_collective: # Replace with a single Open Collective username
# ko_fi: # Replace with a single Ko-fi username
# tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
# community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
# liberapay: # Replace with a single Liberapay username
# issuehunt: # Replace with a single IssueHunt username
# otechie: # Replace with a single Otechie username
# lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
# custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
github: LinXunFeng
ko_fi: linxunfeng
================================================
FILE: .github/workflows/assign-issue.yml
================================================
name: Issue assignment
on:
issues:
types: [opened]
jobs:
auto-assign:
runs-on: ubuntu-latest
steps:
- name: 'Auto-assign issue'
uses: pozil/auto-assign-issue@v1
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
assignees: LinXunFeng
================================================
FILE: .github/workflows/code-analysis.yml
================================================
name: Code Analysis
on:
workflow_dispatch:
push:
branches:
- main
paths-ignore:
- '**.md'
pull_request:
branches:
- main
paths-ignore:
- '**.md'
jobs:
code-analysis:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: subosito/flutter-action@v2
with:
channel: 'stable'
- name: Prepare dependencies
run: |
flutter --version
flutter pub get
- name: Check Dart code formatting
run: |
dart format . -o none --set-exit-if-changed
- name: Analyze Dart code
run: |
flutter analyze .
- name: Generate dartdoc
run: |
dart pub global activate dartdoc
dart pub global run dartdoc .
test:
needs: [code-analysis]
runs-on: ubuntu-latest
strategy:
matrix:
flutter-version: ['']
steps:
- uses: actions/checkout@v4
- uses: subosito/flutter-action@v2
with:
channel: 'stable'
flutter-version: ${{ matrix.flutter-version }}
- name: Prepare dependencies
run: |
flutter --version
flutter pub get
- name: Test
run: flutter test
================================================
FILE: .github/workflows/deploy.yml
================================================
name: Deploy to GitHub Pages
on:
push:
branches:
- main
# - develop
jobs:
build:
name: Build Web
env:
my_secret: ${{secrets.commit_secret}}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: subosito/flutter-action@v2
with:
# flutter-version: '3.16.9'
channel: 'stable'
- name: Flutter build web
working-directory: ./example
run: |
flutter config --enable-web
flutter pub get
flutter build web --release --base-href /flutter_scrollview_observer/
- name: Deploy
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./example/build/web
force_orphan: true
user_name: 'github-ci[bot]'
user_email: 'github-actions[bot]@users.noreply.github.com'
commit_message: 'Publish to gh-pages'
================================================
FILE: .gitignore
================================================
# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.buildlog/
.history
.svn/
# IntelliJ related
# *.iml
*.ipr
*.iws
.idea/
# The .vscode folder contains launch configuration and tasks you configure in
# VS Code which you may wish to be included in version control, so this line
# is commented out by default.
.vscode/
# Flutter/Dart/Pub related
**/doc/api/
**/ios/Flutter/.last_build_id
.dart_tool/
.flutter-plugins
.flutter-plugins-dependencies
# .packages
.pub-cache/
.pub/
/build/
# Web related
lib/generated_plugin_registrant.dart
# Symbolication related
app.*.symbols
# Obfuscation related
app.*.map.json
# Android Studio will place build artifacts here
/android/app/debug
/android/app/profile
/android/app/release
================================================
FILE: .packages
================================================
# This file is deprecated. Tools should instead consume
# `.dart_tool/package_config.json`.
#
# For more info see: https://dart.dev/go/dot-packages-deprecation
#
# Generated by pub on 2023-03-02 22:51:15.844107.
async:file:///Users/lxf/.pub-cache/hosted/pub.dartlang.org/async-2.9.0/lib/
boolean_selector:file:///Users/lxf/.pub-cache/hosted/pub.dartlang.org/boolean_selector-2.1.0/lib/
characters:file:///Users/lxf/.pub-cache/hosted/pub.dartlang.org/characters-1.2.0/lib/
charcode:file:///Users/lxf/.pub-cache/hosted/pub.dartlang.org/charcode-1.3.1/lib/
clock:file:///Users/lxf/.pub-cache/hosted/pub.dartlang.org/clock-1.1.0/lib/
collection:file:///Users/lxf/.pub-cache/hosted/pub.dartlang.org/collection-1.16.0/lib/
fake_async:file:///Users/lxf/.pub-cache/hosted/pub.dartlang.org/fake_async-1.3.0/lib/
flutter:file:///Users/lxf/fvm/versions/3.1.0/packages/flutter/lib/
flutter_lints:file:///Users/lxf/.pub-cache/hosted/pub.dartlang.org/flutter_lints-1.0.4/lib/
flutter_test:file:///Users/lxf/fvm/versions/3.1.0/packages/flutter_test/lib/
lints:file:///Users/lxf/.pub-cache/hosted/pub.dartlang.org/lints-1.0.1/lib/
matcher:file:///Users/lxf/.pub-cache/hosted/pub.dartlang.org/matcher-0.12.11/lib/
material_color_utilities:file:///Users/lxf/.pub-cache/hosted/pub.dartlang.org/material_color_utilities-0.1.4/lib/
meta:file:///Users/lxf/.pub-cache/hosted/pub.dartlang.org/meta-1.7.0/lib/
path:file:///Users/lxf/.pub-cache/hosted/pub.dartlang.org/path-1.8.1/lib/
sky_engine:file:///Users/lxf/fvm/versions/3.1.0/bin/cache/pkg/sky_engine/lib/
source_span:file:///Users/lxf/.pub-cache/hosted/pub.dartlang.org/source_span-1.8.2/lib/
stack_trace:file:///Users/lxf/.pub-cache/hosted/pub.dartlang.org/stack_trace-1.10.0/lib/
stream_channel:file:///Users/lxf/.pub-cache/hosted/pub.dartlang.org/stream_channel-2.1.0/lib/
string_scanner:file:///Users/lxf/.pub-cache/hosted/pub.dartlang.org/string_scanner-1.1.0/lib/
term_glyph:file:///Users/lxf/.pub-cache/hosted/pub.dartlang.org/term_glyph-1.2.0/lib/
test_api:file:///Users/lxf/.pub-cache/hosted/pub.dartlang.org/test_api-0.4.9/lib/
vector_math:file:///Users/lxf/.pub-cache/hosted/pub.dartlang.org/vector_math-2.1.2/lib/
scrollview_observer:lib/
================================================
FILE: CHANGELOG.md
================================================
## 1.26.3
- ObserverWidget
- Fix incorrect tag comparison in `_checkTagChange` by @LinXunFeng in [#143](https://github.com/fluttercandies/flutter_scrollview_observer/issues/143).
- ObserverController
- Add missing type annotations by @LinXunFeng.
## 1.26.2
- ObserverUtils
- Refine the logic of `calcAnchorTabIndex` method by @LinXunFeng.
## 1.26.1
- ChatScrollObserver
- Refine the logic of `standby` by @LinXunFeng.
## 1.26.0
- NestedScrollUtil
- Add await support for `animateTo` and `jumpTo` methods by @LinXunFeng.
## 1.25.2
- ObserverWidget
- Fix "ObserverWidgetState was used after being disposed" by @LinXunFeng in [#120](https://github.com/fluttercandies/flutter_scrollview_observer/issues/120) and [#123](https://github.com/fluttercandies/flutter_scrollview_observer/issues/123).
## 1.25.1
- ObserverWidget
- Fix observation result inaccurate by @LinXunFeng in [#113](https://github.com/fluttercandies/flutter_scrollview_observer/issues/113).
## 1.25.0
- ChatScrollObserver
- Add `customAdjustPosition`.
## 1.24.0
- ObserveModel
- Add `displayingChildModelMap`.
- ChatScrollObserver
- Add `customAdjustPositionDelta`.
## 1.23.0
- ObserverWidget
- Make `ObserverWidget` listenable.
## 1.22.0
- ObserverWidget
- Add `scrollNotificationPredicate`.
## 1.21.2
- ObserverWidget
- Fix web support by @Ahmadre in [#91](https://github.com/LinXunFeng/flutter_scrollview_observer/pull/91).
## 1.21.1
- ObserverCore
- Improve the logic of `handleListObserve` and `handleGridObserve`.
## 1.21.0
- ObserverController
- Add `onPrepareScrollToIndex` for `jumpTo` and `animateTo`.
- NestedScrollUtil
- Add `jumpTo` and `animateTo` methods.
## 1.20.0
- ObserverController
- Add `observeIntervalForScrolling` to set the minimum amount of time to wait for firing observe callback during scrolling.
- ObserverUtils
- Improve the logic of `isDisplayingSliverInViewport` method.
- ScrollViewOnceObserveNotificationResult
- Add `observeViewportResultModel`.
- ChatScrollObserver
- Add `ChatScrollObserverRefIndexType`.
- Add `refIndexType` to specify the role of `refItemIndex` and `refItemIndex`.
- Slivers
- Add `SliverObserveContext`.
- ObserveDisplayingChildModelMixin
- Add `visibleFraction` and `visibleMainAxisSize`.
## 1.19.1
- ListViewObserver
- Support `SliverVariedExtentList` in [74](https://github.com/fluttercandies/flutter_scrollview_observer/issues/74).
- ChatScrollObserver
- Safely obtain the `constraints` of RenderSliver.
- ObserverController
- Adapt to scenes where `CustomScrollView` specifies `center`.
## 1.19.0
- SliverViewObserver
- Add `customOverlap` property.
- NestedScrollUtil
- To better support `NestedScrollView`.
- ObserverCore
- Improve the judgment logic of whether the sliver is visible.
- ObserverController
- Adjust the controller to be modifiable.
## 1.18.2
- ChatScrollObserver
- Fix keeping position not working by @LinXunFeng in [#64](https://github.com/fluttercandies/flutter_scrollview_observer/issues/64)
## 1.18.1
- Add a check to determine whether the BuildContext is mounted by @LinXunFeng in [#62](https://github.com/fluttercandies/flutter_scrollview_observer/issues/62)
## 1.18.0
- ObserverController
- Add some scrolling task notifications extending from `ObserverScrollNotification`.
- The `jumpTo` method and `animateTo` method support `await`.
- Add `isForbidObserveCallback` property.
- Add `isForbidObserveViewportCallback` property.
## 1.17.0
- ObserverController
- The parameter `isFixedHeight` in the `jumpTo` method and `animateTo` method supports GridView and supports ScrollView built by third-party package by @percival888 in [#52](https://github.com/fluttercandies/flutter_scrollview_observer/pull/52).
## 1.16.5
- ObserverWidget
- Improve the processing logic of scroll notification when scrolling with the mouse wheel is not smooth by @qiangjindong in [#48](https://github.com/LinXunFeng/flutter_scrollview_observer/pull/48).
- ChatScrollObserver
- Update `isShrinkWrap` once during initialization by @LinXunFeng. [#47](https://github.com/LinXunFeng/flutter_scrollview_observer/issues/47)
- ObserverController
- Fix unable to jump when sliver is too far away and has no any child by @LinXunFeng. [#45](https://github.com/LinXunFeng/flutter_scrollview_observer/issues/45)
- Fix continuous page turning due to incorrect index by @LinXunFeng.
## 1.16.4
- Supplement missing type conversion adjustments.
## 1.16.3
- Observation Model
- Add viewport property to observation model.
- Correct the calculation logic of some values to adapt to the scene of multiple slivers.
## 1.16.2
- ObserverWidget
- Adjust the conversion type of `viewport.offset` to `ScrollPosition` by @LiuDongCai in [#41](https://github.com/LinXunFeng/flutter_scrollview_observer/pull/41).
- ObserveDisplayingChildModelMixin
- Adapt `displayPercentage` to scenes with SliverPersistentHeader by @percival888 in [#43](https://github.com/LinXunFeng/flutter_scrollview_observer/pull/43).
- Refine the logic of `calculateDisplayPercentage` method by @LinXunFeng.
## 1.16.1
- Compatible with flutter 3.13.0
## 1.16.0
- ObserverController
- `dispatchOnceObserve` method supports directly getting observation result.
## 1.15.0
- Slivers
- Add `SliverObserveContextToBoxAdapter`.
## 1.14.2
- ObserverWidget
- Safe to use context. [#35](https://github.com/LinXunFeng/flutter_scrollview_observer/issues/35).
## 1.14.1
- ChatScrollObserver
- Improve the logic of the conversion type.
## 1.14.0
- ChatScrollObserver
- Support for keeping position of generative messages (eg: ChatGPT)
## 1.13.2
- ObserverWidget
- Fix getting bad observation result on web. Thanks to @rmasarovic for the test in [#31](https://github.com/LinXunFeng/flutter_scrollview_observer/issues/31)
## 1.13.1
- ObserverCore
- Fix no getting all child widgets those are displayed when there are separators in `ListView`. [#31](https://github.com/LinXunFeng/flutter_scrollview_observer/issues/31)
- ObserverUtils
- Safely call `findRenderObject` method.
## 1.13.0
- ObserverUtils
- The `calcAnchorTabIndex` method supports GridView.
- ObserverCore
- Refine the logic of `handleListObserve` method and `handleGridObserve` method.
## 1.12.0
- ObserverWidget
- Support custom observation object and observation logic.
- Refine the logic for finding the first sliver in viewport.
## 1.11.0
- ChatScrollObserver
- Support inserting multiple messages at once.
- ObserverWidget
- `GridViewObserver` is compatible with waterfall flow.
- `SliverViewObserver` supports observation of viewport.
## 1.10.1
- ObserverController
- fix: targetOffset calculate may be negative by @zeqinjie in [#21](https://github.com/LinXunFeng/flutter_scrollview_observer/pull/21).
## 1.10.0
- ObserverController
- Improve `[_calculateTargetLayoutOffset]` logic.
- The `jumpTo` method and `animateTo` method both add a parameter `[padding]`.
- ObserverIndexPositionModel
- Add property `[padding]`.
## 1.9.2
- ObserverWidget
- Catch the exception thrown by getting size.
## 1.9.1
- ObserverController
- Modify offset calculation logic in method `[_calculateTargetLayoutOffset]`.
## 1.9.0
- ObserverWidget
- Add property `[autoTriggerObserveTypes]` and property `[triggerOnObserveType]`.
- ObserverController
- Method `[dispatchOnceObserve]` adds parameter `[isForce]`.
## 1.8.0
- Scrolling to the specified index location
- Supports initializing the index position of the scrollView.
- Deprecated `[clearIndexOffsetCache]`, please use `[clearScrollIndexCache]` instead.
## 1.7.0
- ChatScrollObserver
- Add the property `[fixedPositionOffset]`.
- Deprecated `[ChatObserverClampinScrollPhysics]`, please use `[ChatObserverClampingScrollPhysics]` instead.
## 1.6.2
- Fix lib not working when `itemExtent` is set in `ListView`.
## 1.6.1
- Fix lib not working when `shrinkWrap` is `true` in scrollView.
## 1.6.0
- ChatScrollObserver
- Add `onHandlePositionCallback`.
## 1.5.1
- Fix scrollView being stuck when child widget get `[size]`.
## 1.5.0
- ChatScrollObserver
- Quickly implement the chat session page effect.
- Scrolling to the specified index location
- Add the property `[cacheJumpIndexOffset]`.
## 1.4.0
- Scrolling to the specified index location
- New `alignment` parameter in the `jumpTo` and `animateTo` methods.
- Fixed a bug that caused scrolling to the first child to jitter when using `offset` parameter.
## 1.3.0
- Scrolling to the specified index location supports the `SliverPersistentHeader`.
- Add `ObserverUtils`
- Method `calcPersistentHeaderExtent`: Calculate current extent of `RenderSliverPersistentHeader`.
- Method `calcAnchorTabIndex`: Calculate the anchor tab index.
## 1.2.0
- The `jumpTo` and `animateTo` methods add an `isFixedHeight` parameter to optimize performance when the child widget is of fixed height
- Add the properties `[leadingMarginToViewport]` and `[trailingMarginToViewport]`
- Support mixing usage of `SliverList` and `SliverGrid`
## 1.1.0
- Supports scrolling to the specified index location
## 1.0.1
- Delete useless code
## 1.0.0
- Implements a way to use without sliver [BuildContext]
- Change [onObserve] to [onObserveAll], and add a new [onObserve] callback to listen for changes in the child widget display of the first sliver
- Add [ObserverController]
## 0.1.0
- Support `GridView`
- Support the horizontal
## 0.0.1
- Initial release
================================================
FILE: CODEOWNERS
================================================
* @LinXunFeng
================================================
FILE: LICENSE
================================================
MIT License
Copyright (c) 2022 LinXunFeng
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: README-zh.md
================================================

# Flutter ScrollView Observer
[](https://github.com/LinXunFeng/) [](https://pub.dev/packages/scrollview_observer) [](https://github.com/fluttercandies/flutter_scrollview_observer)
Language: 中文 | [English](https://github.com/fluttercandies/flutter_scrollview_observer)
这是一个可用于监听滚动视图中正在显示的子部件的组件库。
## ☕ 请我喝一杯咖啡
[](https://ko-fi.com/T6T4JKVRP) [](https://cdn.jsdelivr.net/gh/FullStackAction/PicBed@resource20220417121922/image/202303181116760.jpeg)
微信技术交流群请看: [【微信群说明】](https://mp.weixin.qq.com/s/JBbMstn0qW6M71hh-BRKzw)
## 📖 文章
- [Flutter - 获取ListView当前正在显示的Widget信息](https://mp.weixin.qq.com/s/cN3qeinBPlo5rtEpoQBVVA) | [备用链接](https://juejin.cn/post/7103058155692621837)
- [Flutter - 列表滚动定位超强辅助库,墙裂推荐!🔥](https://mp.weixin.qq.com/s/fplqfBpXwvx6mEO6vflkww) | [备用链接](https://juejin.cn/post/7129888644290068487)
- [Flutter - 快速实现聊天会话列表的效果,完美💯](https://mp.weixin.qq.com/s/xNiGuSLcJtDAiLoHuGWp6A) | [备用链接](https://juejin.cn/post/7152307272436154405)
- [Flutter - 船新升级😱支持观察第三方构建的滚动视图💪](https://mp.weixin.qq.com/s/FMXPyT-lX8YOXVmbLCsVUA) | [备用链接](https://juejin.cn/post/7240751116702269477)
- [Flutter - 瀑布流交替播放视频 🎞](https://mp.weixin.qq.com/s/miP5CfKtcRhFGr08ot5wOg) | [备用链接](https://juejin.cn/post/7243240589293142077)
- [Flutter - IM保持消息位置大升级(支持ChatGPT生成式消息) 🤖](https://mp.weixin.qq.com/s/Y3EN9ZpLb6HLke2vkw0Zwg) | [备用链接](https://juejin.cn/post/7245753944180523067)
- [Flutter - 滚动视图中的表单防遮挡 🗒](https://mp.weixin.qq.com/s/iaHyYMjZSPBggLw2yZv8dQ) | [备用链接](https://juejin.cn/spost/7266455050632921107)
- [Flutter - 秒杀1/2曝光统计 📊](https://mp.weixin.qq.com/s/gNFX4Au4esftgTPXHvB4LQ) | [备用链接](https://juejin.cn/post/7271248528998121512)
- [Flutter - 如何快速搓一个微信通讯录列表(azlist) 📓](https://mp.weixin.qq.com/s/1bmYSvtOYX83DLncvnBjqA) | [备用链接](https://juejin.cn/post/7294884963631497254)
- [Flutter - 支持观察NestedScrollView,兼容性更强 😈](https://mp.weixin.qq.com/s/1dsmRg8q2VJ6HzasLgoVpA) | [备用链接](https://juejin.cn/post/7388444606456840211)
- [Flutter - 轻松实现PageView卡片偏移效果](https://mp.weixin.qq.com/s/Q8zk89bgr_8bgWQ4F86VUQ) | [备用链接](https://juejin.cn/post/7411516362916216859)
- [Flutter - 轻松搞定炫酷视差(Parallax)效果](https://mp.weixin.qq.com/s/Fi-X2eJRWj17sqCcVqbPRQ) | [备用链接](https://juejin.cn/post/7416655730214699017)
- [Flutter - 详情页 TabBar 与模块联动?秒了!](https://mp.weixin.qq.com/s/uLRLzxS4IqmCq0gewTS8kQ) | [备用链接](https://juejin.cn/post/7538868042961911817)
- [Flutter - 详情页初始锚点与优化](https://mp.weixin.qq.com/s/hRPc_eHjl0OSKFKfmj6q_g) | [备用链接](https://juejin.cn/post/7541801054188109850)
## 🔨 功能点
> 不需要改变你当前所使用视图,只需要在视图外包裹一层即可实现如下功能点
- [x] 监听滚动视图中正在显示的子部件
- [x] 支持滚动到指定下标位置
- [x] 快速实现聊天会话列表的效果
- [x] 支持在插入或更新消息时保持IM消息位置,避免抖动
## 🎀 支持
- [x] `PageView`
- [x] `ListView`
- [x] `SliverList`
- [x] `GridView`
- [x] `SliverGrid`
- [x] 支持 `SliverPersistentHeader`,`SliverList` 和 `SliverGrid` 混合使用
- [x] `NestedScrollView`
- [x] 由第三方库构建的 `ScrollView`
## 🕹 预览
- 🖥 [在线预览](https://fluttercandies.github.io/flutter_scrollview_observer/)
- 🏞 [示例图片](https://github.com/fluttercandies/flutter_scrollview_observer/wiki/Example)
## 📦 安装
在你的 `pubspec.yaml` 文件中添加 `scrollview_observer` 依赖:
```yaml
dependencies:
scrollview_observer: latest_version
```
在需要使用的地方导入 `scrollview_observer` :
```dart
import 'package:scrollview_observer/scrollview_observer.dart';
```
## 📚 指南
- [Wiki首页](https://github.com/fluttercandies/flutter_scrollview_observer/wiki/%E9%A6%96%E9%A1%B5)
- [1、监听滚动视图中正在显示的子部件](https://github.com/fluttercandies/flutter_scrollview_observer/wiki/1%E3%80%81%E7%9B%91%E5%90%AC%E6%BB%9A%E5%8A%A8%E8%A7%86%E5%9B%BE%E4%B8%AD%E6%AD%A3%E5%9C%A8%E6%98%BE%E7%A4%BA%E7%9A%84%E5%AD%90%E9%83%A8%E4%BB%B6)
- [2、滚动到指定下标位置](https://github.com/fluttercandies/flutter_scrollview_observer/wiki/2%E3%80%81%E6%BB%9A%E5%8A%A8%E5%88%B0%E6%8C%87%E5%AE%9A%E4%B8%8B%E6%A0%87%E4%BD%8D%E7%BD%AE)
- [3、聊天会话](https://github.com/fluttercandies/flutter_scrollview_observer/wiki/3%E3%80%81%E8%81%8A%E5%A4%A9%E4%BC%9A%E8%AF%9D)
## 🖨 关于我
- GitHub: [https://github.com/LinXunFeng](https://github.com/LinXunFeng)
- Email: [linxunfeng@yeah.net](mailto:linxunfeng@yeah.net)
- Blogs:
- 全栈行动: [https://fullstackaction.com](https://fullstackaction.com)
- 掘金: [https://juejin.cn/user/1820446984512392](https://juejin.cn/user/1820446984512392)
<img height="267.5" width="481.5" src="https://github.com/LinXunFeng/LinXunFeng/raw/master/static/img/FSAQR.png"/>
================================================
FILE: README.md
================================================

# Flutter ScrollView Observer
[](https://github.com/LinXunFeng/) [](https://pub.dev/packages/scrollview_observer) [](https://github.com/fluttercandies/flutter_scrollview_observer)
Language: English | [中文](https://github.com/fluttercandies/flutter_scrollview_observer/blob/main/README-zh.md)
This is a library of widget that can be used to listen for child widgets those are being displayed in the scroll view.
## ☕ Support me
[](https://ko-fi.com/T6T4JKVRP) [](https://cdn.jsdelivr.net/gh/FullStackAction/PicBed@resource20220417121922/image/202303181116760.jpeg)
Chat: [Join WeChat group](https://mp.weixin.qq.com/s/JBbMstn0qW6M71hh-BRKzw)
## 📖 Article
- [Flutter - Getting the items information those are currently displaying in ScrollView](https://medium.com/@linxunfeng/flutter-gets-the-items-information-those-are-currently-displaying-in-scrollview-6cb4f27f2536) | [WeChat](https://mp.weixin.qq.com/s/cN3qeinBPlo5rtEpoQBVVA) | [JueJin](https://juejin.cn/post/7103058155692621837)
- [Flutter - Scrolling to a specific item in the ScrollView!🔥](https://medium.com/@linxunfeng/flutter-scrolling-to-a-specific-item-in-the-scrollview-b89d3f10eee0) | [WeChat](https://mp.weixin.qq.com/s/fplqfBpXwvx6mEO6vflkww) | [JueJin](https://juejin.cn/post/7129888644290068487)
- [Flutter - Quickly implement the effect of the chat session list, perfect 💯](https://medium.com/@linxunfeng/flutter-quickly-implement-the-effect-of-the-chat-session-list-perfect-68c8acea4568) | [WeChat](https://mp.weixin.qq.com/s/xNiGuSLcJtDAiLoHuGWp6A) | [JueJin](https://juejin.cn/post/7152307272436154405)
- [Flutter - New upgrade😱Supports observing ScrollView built by third package💪](https://medium.com/@linxunfeng/flutter-new-upgrade-supports-observing-scrollview-built-by-third-package-2e5af3d84c64) | [WeChat](https://mp.weixin.qq.com/s/FMXPyT-lX8YOXVmbLCsVUA) | [JueJin](https://juejin.cn/post/7240751116702269477)
- [Flutter - Play alternately waterfall flow video 🎞](https://medium.com/@linxunfeng/flutter-play-alternately-waterfall-flow-video-015279bc8e14) | [WeChat](https://mp.weixin.qq.com/s/miP5CfKtcRhFGr08ot5wOg) | [JueJin](https://juejin.cn/post/7243240589293142077)
- [Flutter - Keep IM message position greatly upgraded (supports generative messages like ChatGPT) 🤖](https://medium.com/@linxunfeng/flutter-keep-im-message-position-greatly-upgraded-supports-generative-messages-like-chatgpt-2b199a7b14e7) | [WeChat](https://mp.weixin.qq.com/s/Y3EN9ZpLb6HLke2vkw0Zwg) | [JueJin](https://juejin.cn/post/7245753944180523067)
- [Flutter - Anti-occlusion of form in ScrollView 🗒](https://medium.com/@linxunfeng/flutter-anti-occlusion-of-form-in-scrollview-ad8bde15e18d) | [WeChat](https://mp.weixin.qq.com/s/iaHyYMjZSPBggLw2yZv8dQ) | [JueJin](https://juejin.cn/spost/7266455050632921107)
- [Flutter - Quickly achieve half-view exposure statistic 📊](https://medium.com/@linxunfeng/flutter-quickly-achieve-half-view-exposure-statistic-097fd4b237ef) | [WeChat](https://mp.weixin.qq.com/s/gNFX4Au4esftgTPXHvB4LQ) | [JueJin](https://juejin.cn/post/7271248528998121512)
- [Flutter - How to quickly implement an contact list page (azlist) 📓](https://medium.com/@linxunfeng/flutter-how-to-quickly-implement-an-contact-list-page-azlist-829bbef12d8f) | [WeChat](https://mp.weixin.qq.com/s/1bmYSvtOYX83DLncvnBjqA) | [JueJin](https://juejin.cn/post/7294884963631497254)
- [Flutter - Supports observing NestedScrollView, with greater compatibility 😈](https://medium.com/@linxunfeng/flutter-supports-observing-nestedscrollview-with-greater-compatibility-86f49dce7955) | [WeChat](https://mp.weixin.qq.com/s/1dsmRg8q2VJ6HzasLgoVpA) | [JueJin](https://juejin.cn/post/7388444606456840211)
- [Flutter - Offset effect in PageView](https://medium.com/@linxunfeng/flutter-offset-effect-in-pageview-cec39572d56a) | [WeChat](https://mp.weixin.qq.com/s/Q8zk89bgr_8bgWQ4F86VUQ) | [JueJin](https://juejin.cn/post/7411516362916216859)
- [Flutter - Parallax effect in PageView](https://medium.com/@linxunfeng/flutter-parallax-effect-in-pageview-ccff6b0b34aa) | [WeChat](https://mp.weixin.qq.com/s/Fi-X2eJRWj17sqCcVqbPRQ) | [JueJin](https://juejin.cn/post/7416655730214699017)
- [Flutter - Syncing Detail Page TabBar with Modules? Nailed It!](https://medium.com/@linxunfeng/flutter-syncing-detail-page-tabbar-with-modules-nailed-it-60f2ca67e100) | [WeChat](https://mp.weixin.qq.com/s/uLRLzxS4IqmCq0gewTS8kQ) | [JueJin](https://juejin.cn/post/7538868042961911817)
- [Flutter - Initial Anchor And Optimization For Detail Pages](https://medium.com/@linxunfeng/flutter-initial-anchor-and-optimization-for-detail-pages-86aa5b9c4186) | [WeChat](https://mp.weixin.qq.com/s/hRPc_eHjl0OSKFKfmj6q_g) | [JueJin](https://juejin.cn/post/7541801054188109850)
## 🔨 Feature
> You do not need to change the view you are currently using, just wrap a `ViewObserver` around the view to achieve the following features.
- [x] Observing child widgets those are being displayed in ScrollView
- [x] Support for scrolling to a specific item in ScrollView
- [x] Quickly implement the chat session page effect
- [x] Support for keeping IM message position when inserting or updating messages, avoiding jitter.
## 🎀 Support
- [x] `PageView`
- [x] `ListView`
- [x] `SliverList`
- [x] `GridView`
- [x] `SliverGrid`
- [x] Mixing usage of `SliverPersistentHeader`, `SliverList` and `SliverGrid`
- [x] `NestedScrollView`
- [x] `ScrollView` built by third-party package.
## 🕹 Preview
- 🖥 [Online Preview](https://fluttercandies.github.io/flutter_scrollview_observer/)
- 🏞 [Sample images](https://github.com/fluttercandies/flutter_scrollview_observer/wiki/Example)
## 📦 Installing
Add `scrollview_observer` to your pubspec.yaml file:
```yaml
dependencies:
scrollview_observer: latest_version
```
Import `scrollview_observer` in files that it will be used:
```dart
import 'package:scrollview_observer/scrollview_observer.dart';
```
## 📚 Wiki
- [Wiki Home](https://github.com/fluttercandies/flutter_scrollview_observer/wiki)
- [1、Observing child widgets those are being displayed in the ScrollView](https://github.com/fluttercandies/flutter_scrollview_observer/wiki/1%E3%80%81Observing-child-widgets-those-are-being-displayed-in-the-ScrollView)
- [2、Scrolling to the specified index location](https://github.com/fluttercandies/flutter_scrollview_observer/wiki/2%E3%80%81Scrolling-to-the-specified-index-location)
- [3、Chat Observer](https://github.com/fluttercandies/flutter_scrollview_observer/wiki/3%E3%80%81Chat-Observer)
## 🖨 About Me
- GitHub: [https://github.com/LinXunFeng](https://github.com/LinXunFeng)
- Email: [linxunfeng@yeah.net](mailto:linxunfeng@yeah.net)
- Blogs:
- 全栈行动: [https://fullstackaction.com](https://fullstackaction.com)
- 掘金: [https://juejin.cn/user/1820446984512392](https://juejin.cn/user/1820446984512392)
<img height="267.5" width="481.5" src="https://github.com/LinXunFeng/LinXunFeng/raw/master/static/img/FSAQR.png"/>
================================================
FILE: analysis_options.yaml
================================================
include: package:flutter_lints/flutter.yaml
# Additional information about this file can be found at
# https://dart.dev/guides/language/analysis-options
================================================
FILE: example/.gitignore
================================================
# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.buildlog/
.history
.svn/
# IntelliJ related
*.iml
*.ipr
*.iws
.idea/
# The .vscode folder contains launch configuration and tasks you configure in
# VS Code which you may wish to be included in version control, so this line
# is commented out by default.
#.vscode/
# Flutter/Dart/Pub related
**/doc/api/
**/ios/Flutter/.last_build_id
.dart_tool/
.flutter-plugins
.flutter-plugins-dependencies
.packages
.pub-cache/
.pub/
/build/
# Web related
# Symbolication related
app.*.symbols
# Obfuscation related
app.*.map.json
# Android Studio will place build artifacts here
/android/app/debug
/android/app/profile
/android/app/release
================================================
FILE: example/.metadata
================================================
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled.
version:
revision: bcea432bce54a83306b3c00a7ad0ed98f777348d
channel: beta
project_type: app
# Tracks metadata for the flutter migrate command
migration:
platforms:
- platform: root
create_revision: bcea432bce54a83306b3c00a7ad0ed98f777348d
base_revision: bcea432bce54a83306b3c00a7ad0ed98f777348d
- platform: macos
create_revision: bcea432bce54a83306b3c00a7ad0ed98f777348d
base_revision: bcea432bce54a83306b3c00a7ad0ed98f777348d
# User provided section
# List of Local paths (relative to this file) that should be
# ignored by the migrate tool.
#
# Files that are not part of the templates will be ignored by default.
unmanaged_files:
- 'lib/main.dart'
- 'ios/Runner.xcodeproj/project.pbxproj'
================================================
FILE: example/README.md
================================================
# example
A new Flutter project.
## Getting Started
This project is a starting point for a Flutter application.
A few resources to get you started if this is your first Flutter project:
- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab)
- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook)
For help getting started with Flutter, view our
[online documentation](https://flutter.dev/docs), which offers tutorials,
samples, guidance on mobile development, and a full API reference.
================================================
FILE: example/analysis_options.yaml
================================================
# This file configures the analyzer, which statically analyzes Dart code to
# check for errors, warnings, and lints.
#
# The issues identified by the analyzer are surfaced in the UI of Dart-enabled
# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
# invoked from the command line by running `flutter analyze`.
# The following line activates a set of recommended lints for Flutter apps,
# packages, and plugins designed to encourage good coding practices.
include: package:flutter_lints/flutter.yaml
linter:
# The lint rules applied to this project can be customized in the
# section below to disable rules from the `package:flutter_lints/flutter.yaml`
# included above or to enable additional rules. A list of all available lints
# and their documentation is published at
# https://dart-lang.github.io/linter/lints/index.html.
#
# Instead of disabling a lint rule for the entire project in the
# section below, it can also be suppressed for a single line of code
# or a specific dart file by using the `// ignore: name_of_lint` and
# `// ignore_for_file: name_of_lint` syntax on the line or in the file
# producing the lint.
rules:
# avoid_print: false # Uncomment to disable the `avoid_print` rule
# prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
# Additional information about this file can be found at
# https://dart.dev/guides/language/analysis-options
================================================
FILE: example/android/.gitignore
================================================
gradle-wrapper.jar
/.gradle
/captures/
/gradlew
/gradlew.bat
/local.properties
GeneratedPluginRegistrant.java
# Remember to never publicly share your keystore.
# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app
key.properties
**/*.keystore
**/*.jks
================================================
FILE: example/android/app/build.gradle
================================================
def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) {
localPropertiesFile.withReader('UTF-8') { reader ->
localProperties.load(reader)
}
}
def flutterRoot = localProperties.getProperty('flutter.sdk')
if (flutterRoot == null) {
throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
}
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
if (flutterVersionCode == null) {
flutterVersionCode = '1'
}
def flutterVersionName = localProperties.getProperty('flutter.versionName')
if (flutterVersionName == null) {
flutterVersionName = '1.0'
}
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
android {
compileSdkVersion flutter.compileSdkVersion
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
}
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "com.example.example"
namespace("com.example.example")
minSdkVersion flutter.minSdkVersion
targetSdkVersion flutter.targetSdkVersion
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
}
buildTypes {
release {
// TODO: Add your own signing config for the release build.
// Signing with the debug keys for now, so `flutter run --release` works.
signingConfig signingConfigs.debug
}
}
}
flutter {
source '../..'
}
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
}
================================================
FILE: example/android/app/src/debug/AndroidManifest.xml
================================================
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.example">
<!-- Flutter needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.
-->
<uses-permission android:name="android.permission.INTERNET"/>
</manifest>
================================================
FILE: example/android/app/src/main/AndroidManifest.xml
================================================
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.example">
<application
android:label="example"
android:name="${applicationName}"
android:icon="@mipmap/ic_launcher">
<activity
android:name=".MainActivity"
android:exported="true"
android:launchMode="singleTop"
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<!-- Specifies an Android theme to apply to this Activity as soon as
the Android process has started. This theme is visible to the user
while the Flutter UI initializes. After that, this theme continues
to determine the Window background behind the Flutter UI. -->
<meta-data
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme"
/>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
<meta-data
android:name="flutterEmbedding"
android:value="2" />
</application>
</manifest>
================================================
FILE: example/android/app/src/main/kotlin/com/example/example/MainActivity.kt
================================================
package com.example.example
import io.flutter.embedding.android.FlutterActivity
class MainActivity: FlutterActivity() {
}
================================================
FILE: example/android/app/src/main/res/drawable/launch_background.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<!-- Modify this file to customize your launch splash screen -->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@android:color/white" />
<!-- You can insert your own image assets here -->
<!-- <item>
<bitmap
android:gravity="center"
android:src="@mipmap/launch_image" />
</item> -->
</layer-list>
================================================
FILE: example/android/app/src/main/res/drawable-v21/launch_background.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<!-- Modify this file to customize your launch splash screen -->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="?android:colorBackground" />
<!-- You can insert your own image assets here -->
<!-- <item>
<bitmap
android:gravity="center"
android:src="@mipmap/launch_image" />
</item> -->
</layer-list>
================================================
FILE: example/android/app/src/main/res/values/styles.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is off -->
<style name="LaunchTheme" parent="@android:style/Theme.Light.NoTitleBar">
<!-- Show a splash screen on the activity. Automatically removed when
Flutter draws its first frame -->
<item name="android:windowBackground">@drawable/launch_background</item>
</style>
<!-- Theme applied to the Android Window as soon as the process has started.
This theme determines the color of the Android Window while your
Flutter UI initializes, as well as behind your Flutter UI while its
running.
This Theme is only used starting with V2 of Flutter's Android embedding. -->
<style name="NormalTheme" parent="@android:style/Theme.Light.NoTitleBar">
<item name="android:windowBackground">?android:colorBackground</item>
</style>
</resources>
================================================
FILE: example/android/app/src/main/res/values-night/styles.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is on -->
<style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
<!-- Show a splash screen on the activity. Automatically removed when
Flutter draws its first frame -->
<item name="android:windowBackground">@drawable/launch_background</item>
</style>
<!-- Theme applied to the Android Window as soon as the process has started.
This theme determines the color of the Android Window while your
Flutter UI initializes, as well as behind your Flutter UI while its
running.
This Theme is only used starting with V2 of Flutter's Android embedding. -->
<style name="NormalTheme" parent="@android:style/Theme.Black.NoTitleBar">
<item name="android:windowBackground">?android:colorBackground</item>
</style>
</resources>
================================================
FILE: example/android/app/src/profile/AndroidManifest.xml
================================================
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.example">
<!-- Flutter needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.
-->
<uses-permission android:name="android.permission.INTERNET"/>
</manifest>
================================================
FILE: example/android/build.gradle
================================================
buildscript {
ext.kotlin_version = '1.7.10'
repositories {
google()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:8.5.2'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
allprojects {
repositories {
google()
mavenCentral()
}
}
rootProject.buildDir = '../build'
subprojects {
project.buildDir = "${rootProject.buildDir}/${project.name}"
}
subprojects {
project.evaluationDependsOn(':app')
}
tasks.register("clean", Delete) {
delete rootProject.buildDir
}
================================================
FILE: example/android/gradle/wrapper/gradle-wrapper.properties
================================================
#Mon Jan 27 23:32:07 CST 2025
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
================================================
FILE: example/android/gradle.properties
================================================
org.gradle.jvmargs=-Xmx1536M
android.useAndroidX=true
android.enableJetifier=true
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 --add-exports=java.base/sun.nio.ch=ALL-UNNAMED --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.lang.reflect=ALL-UNNAMED --add-opens=java.base/java.io=ALL-UNNAMED --add-exports=jdk.unsupported/sun.misc=ALL-UNNAMEDz
================================================
FILE: example/android/settings.gradle
================================================
include ':app'
def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
def properties = new Properties()
assert localPropertiesFile.exists()
localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
def flutterSdkPath = properties.getProperty("flutter.sdk")
assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
================================================
FILE: example/ios/.gitignore
================================================
**/dgph
*.mode1v3
*.mode2v3
*.moved-aside
*.pbxuser
*.perspectivev3
**/*sync/
.sconsign.dblite
.tags*
**/.vagrant/
**/DerivedData/
Icon?
**/Pods/
**/.symlinks/
profile
xcuserdata
**/.generated/
Flutter/App.framework
Flutter/Flutter.framework
Flutter/Flutter.podspec
Flutter/Generated.xcconfig
Flutter/ephemeral/
Flutter/app.flx
Flutter/app.zip
Flutter/flutter_assets/
Flutter/flutter_export_environment.sh
ServiceDefinitions.json
Runner/GeneratedPluginRegistrant.*
# Exceptions to above rules.
!default.mode1v3
!default.mode2v3
!default.pbxuser
!default.perspectivev3
================================================
FILE: example/ios/Flutter/AppFrameworkInfo.plist
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>App</string>
<key>CFBundleIdentifier</key>
<string>io.flutter.flutter.app</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>App</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>MinimumOSVersion</key>
<string>12.0</string>
</dict>
</plist>
================================================
FILE: example/ios/Flutter/Debug.xcconfig
================================================
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
#include "Generated.xcconfig"
================================================
FILE: example/ios/Flutter/Release.xcconfig
================================================
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
#include "Generated.xcconfig"
================================================
FILE: example/ios/Podfile
================================================
# Uncomment this line to define a global platform for your project
# platform :ios, '12.0'
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
project 'Runner', {
'Debug' => :debug,
'Profile' => :release,
'Release' => :release,
}
def flutter_root
generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
unless File.exist?(generated_xcode_build_settings_path)
raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
end
File.foreach(generated_xcode_build_settings_path) do |line|
matches = line.match(/FLUTTER_ROOT\=(.*)/)
return matches[1].strip if matches
end
raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
end
require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
flutter_ios_podfile_setup
target 'Runner' do
use_frameworks!
use_modular_headers!
flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
end
post_install do |installer|
installer.pods_project.targets.each do |target|
flutter_additional_ios_build_settings(target)
end
end
================================================
FILE: example/ios/Runner/AppDelegate.swift
================================================
import UIKit
import Flutter
@main
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}
================================================
FILE: example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json
================================================
{
"images" : [
{
"size" : "20x20",
"idiom" : "iphone",
"filename" : "Icon-App-20x20@2x.png",
"scale" : "2x"
},
{
"size" : "20x20",
"idiom" : "iphone",
"filename" : "Icon-App-20x20@3x.png",
"scale" : "3x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "Icon-App-29x29@1x.png",
"scale" : "1x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "Icon-App-29x29@2x.png",
"scale" : "2x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "Icon-App-29x29@3x.png",
"scale" : "3x"
},
{
"size" : "40x40",
"idiom" : "iphone",
"filename" : "Icon-App-40x40@2x.png",
"scale" : "2x"
},
{
"size" : "40x40",
"idiom" : "iphone",
"filename" : "Icon-App-40x40@3x.png",
"scale" : "3x"
},
{
"size" : "60x60",
"idiom" : "iphone",
"filename" : "Icon-App-60x60@2x.png",
"scale" : "2x"
},
{
"size" : "60x60",
"idiom" : "iphone",
"filename" : "Icon-App-60x60@3x.png",
"scale" : "3x"
},
{
"size" : "20x20",
"idiom" : "ipad",
"filename" : "Icon-App-20x20@1x.png",
"scale" : "1x"
},
{
"size" : "20x20",
"idiom" : "ipad",
"filename" : "Icon-App-20x20@2x.png",
"scale" : "2x"
},
{
"size" : "29x29",
"idiom" : "ipad",
"filename" : "Icon-App-29x29@1x.png",
"scale" : "1x"
},
{
"size" : "29x29",
"idiom" : "ipad",
"filename" : "Icon-App-29x29@2x.png",
"scale" : "2x"
},
{
"size" : "40x40",
"idiom" : "ipad",
"filename" : "Icon-App-40x40@1x.png",
"scale" : "1x"
},
{
"size" : "40x40",
"idiom" : "ipad",
"filename" : "Icon-App-40x40@2x.png",
"scale" : "2x"
},
{
"size" : "76x76",
"idiom" : "ipad",
"filename" : "Icon-App-76x76@1x.png",
"scale" : "1x"
},
{
"size" : "76x76",
"idiom" : "ipad",
"filename" : "Icon-App-76x76@2x.png",
"scale" : "2x"
},
{
"size" : "83.5x83.5",
"idiom" : "ipad",
"filename" : "Icon-App-83.5x83.5@2x.png",
"scale" : "2x"
},
{
"size" : "1024x1024",
"idiom" : "ios-marketing",
"filename" : "Icon-App-1024x1024@1x.png",
"scale" : "1x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
================================================
FILE: example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json
================================================
{
"images" : [
{
"idiom" : "universal",
"filename" : "LaunchImage.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "LaunchImage@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "LaunchImage@3x.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
================================================
FILE: example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md
================================================
# Launch Screen Assets
You can customize the launch screen with your own desired assets by replacing the image files in this directory.
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.
================================================
FILE: example/ios/Runner/Base.lproj/LaunchScreen.storyboard
================================================
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12121" systemVersion="16G29" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12089"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="EHf-IW-A2E">
<objects>
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="Ydg-fD-yQy"/>
<viewControllerLayoutGuide type="bottom" id="xbc-2k-c8Z"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<imageView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" image="LaunchImage" translatesAutoresizingMaskIntoConstraints="NO" id="YRO-k0-Ey4">
</imageView>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstItem="YRO-k0-Ey4" firstAttribute="centerX" secondItem="Ze5-6b-2t3" secondAttribute="centerX" id="1a2-6s-vTC"/>
<constraint firstItem="YRO-k0-Ey4" firstAttribute="centerY" secondItem="Ze5-6b-2t3" secondAttribute="centerY" id="4X2-HB-R7a"/>
</constraints>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="53" y="375"/>
</scene>
</scenes>
<resources>
<image name="LaunchImage" width="168" height="185"/>
</resources>
</document>
================================================
FILE: example/ios/Runner/Base.lproj/Main.storyboard
================================================
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="10117" systemVersion="15F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BYZ-38-t0r">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
</dependencies>
<scenes>
<!--Flutter View Controller-->
<scene sceneID="tne-QT-ifu">
<objects>
<viewController id="BYZ-38-t0r" customClass="FlutterViewController" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
<viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
</objects>
</scene>
</scenes>
</document>
================================================
FILE: example/ios/Runner/Info.plist
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleDisplayName</key>
<string>Example</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>example</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>$(FLUTTER_BUILD_NAME)</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>$(FLUTTER_BUILD_NUMBER)</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
<key>UIApplicationSupportsIndirectInputEvents</key>
<true/>
</dict>
</plist>
================================================
FILE: example/ios/Runner/Runner-Bridging-Header.h
================================================
#import "GeneratedPluginRegistrant.h"
================================================
FILE: example/ios/Runner.xcodeproj/project.pbxproj
================================================
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 54;
objects = {
/* Begin PBXBuildFile section */
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
E11A61691B6E95337D3F0498 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1B26494B2AD201ECD0581E92 /* Pods_Runner.framework */; };
/* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */
9705A1C41CF9048500538489 /* Embed Frameworks */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 10;
files = (
);
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
1B26494B2AD201ECD0581E92 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; };
97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
A2B511463E682CF908AFE6AD /* 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 = "<group>"; };
B302A33B7464FAB28FCF59DF /* 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 = "<group>"; };
DCE1D9B7BDC141B768B2DFF1 /* 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 = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
97C146EB1CF9000F007C117D /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
E11A61691B6E95337D3F0498 /* Pods_Runner.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
3C2B79DE555213845C9D090F /* Pods */ = {
isa = PBXGroup;
children = (
DCE1D9B7BDC141B768B2DFF1 /* Pods-Runner.debug.xcconfig */,
A2B511463E682CF908AFE6AD /* Pods-Runner.release.xcconfig */,
B302A33B7464FAB28FCF59DF /* Pods-Runner.profile.xcconfig */,
);
path = Pods;
sourceTree = "<group>";
};
741C0A3D2C9A06ADB0AB4AB9 /* Frameworks */ = {
isa = PBXGroup;
children = (
1B26494B2AD201ECD0581E92 /* Pods_Runner.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
9740EEB11CF90186004384FC /* Flutter */ = {
isa = PBXGroup;
children = (
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
9740EEB21CF90195004384FC /* Debug.xcconfig */,
7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
9740EEB31CF90195004384FC /* Generated.xcconfig */,
);
name = Flutter;
sourceTree = "<group>";
};
97C146E51CF9000F007C117D = {
isa = PBXGroup;
children = (
9740EEB11CF90186004384FC /* Flutter */,
97C146F01CF9000F007C117D /* Runner */,
97C146EF1CF9000F007C117D /* Products */,
3C2B79DE555213845C9D090F /* Pods */,
741C0A3D2C9A06ADB0AB4AB9 /* Frameworks */,
);
sourceTree = "<group>";
};
97C146EF1CF9000F007C117D /* Products */ = {
isa = PBXGroup;
children = (
97C146EE1CF9000F007C117D /* Runner.app */,
);
name = Products;
sourceTree = "<group>";
};
97C146F01CF9000F007C117D /* Runner */ = {
isa = PBXGroup;
children = (
97C146FA1CF9000F007C117D /* Main.storyboard */,
97C146FD1CF9000F007C117D /* Assets.xcassets */,
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
97C147021CF9000F007C117D /* Info.plist */,
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
74858FAE1ED2DC5600515810 /* AppDelegate.swift */,
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */,
);
path = Runner;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
97C146ED1CF9000F007C117D /* Runner */ = {
isa = PBXNativeTarget;
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
buildPhases = (
2620F42EECCB6FD7139BCDA0 /* [CP] Check Pods Manifest.lock */,
9740EEB61CF901F6004384FC /* Run Script */,
97C146EA1CF9000F007C117D /* Sources */,
97C146EB1CF9000F007C117D /* Frameworks */,
97C146EC1CF9000F007C117D /* Resources */,
9705A1C41CF9048500538489 /* Embed Frameworks */,
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
4F73B9F7F81B552833BFB55E /* [CP] Embed Pods Frameworks */,
);
buildRules = (
);
dependencies = (
);
name = Runner;
productName = Runner;
productReference = 97C146EE1CF9000F007C117D /* Runner.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
97C146E61CF9000F007C117D /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 1510;
ORGANIZATIONNAME = "";
TargetAttributes = {
97C146ED1CF9000F007C117D = {
CreatedOnToolsVersion = 7.3.1;
LastSwiftMigration = 1100;
};
};
};
buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
compatibilityVersion = "Xcode 9.3";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = 97C146E51CF9000F007C117D;
productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
97C146ED1CF9000F007C117D /* Runner */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
97C146EC1CF9000F007C117D /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
2620F42EECCB6FD7139BCDA0 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputFileListPaths = (
);
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
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";
showEnvVarsInLog = 0;
};
3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${TARGET_BUILD_DIR}/${INFOPLIST_PATH}",
);
name = "Thin Binary";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
};
4F73B9F7F81B552833BFB55E /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist",
);
name = "[CP] Embed Pods Frameworks";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
9740EEB61CF901F6004384FC /* Run Script */ = {
isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Run Script";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
97C146EA1CF9000F007C117D /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */,
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */
97C146FA1CF9000F007C117D /* Main.storyboard */ = {
isa = PBXVariantGroup;
children = (
97C146FB1CF9000F007C117D /* Base */,
);
name = Main.storyboard;
sourceTree = "<group>";
};
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = {
isa = PBXVariantGroup;
children = (
97C147001CF9000F007C117D /* Base */,
);
name = LaunchScreen.storyboard;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
249021D3217E4FDB00AE95B9 /* Profile */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
};
name = Profile;
};
249021D4217E4FDB00AE95B9 /* Profile */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = 2RA5LSHPUJ;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.lxf.scrollviewobserver;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic";
};
name = Profile;
};
97C147031CF9000F007C117D /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
97C147041CF9000F007C117D /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_OPTIMIZATION_LEVEL = "-O";
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
};
name = Release;
};
97C147061CF9000F007C117D /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = 2RA5LSHPUJ;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.lxf.scrollviewobserver;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic";
};
name = Debug;
};
97C147071CF9000F007C117D /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = 2RA5LSHPUJ;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.lxf.scrollviewobserver;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = {
isa = XCConfigurationList;
buildConfigurations = (
97C147031CF9000F007C117D /* Debug */,
97C147041CF9000F007C117D /* Release */,
249021D3217E4FDB00AE95B9 /* Profile */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = {
isa = XCConfigurationList;
buildConfigurations = (
97C147061CF9000F007C117D /* Debug */,
97C147071CF9000F007C117D /* Release */,
249021D4217E4FDB00AE95B9 /* Profile */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 97C146E61CF9000F007C117D /* Project object */;
}
================================================
FILE: example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata
================================================
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:">
</FileRef>
</Workspace>
================================================
FILE: example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
================================================
FILE: example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PreviewsEnabled</key>
<false/>
</dict>
</plist>
================================================
FILE: example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
================================================
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1510"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
customLLDBInitFile = "$(SRCROOT)/Flutter/ephemeral/flutter_lldbinit"
shouldUseLaunchSchemeArgsEnv = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</MacroExpansion>
<Testables>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
customLLDBInitFile = "$(SRCROOT)/Flutter/ephemeral/flutter_lldbinit"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
enableGPUValidationMode = "1"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</LaunchAction>
<ProfileAction
buildConfiguration = "Profile"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
================================================
FILE: example/ios/Runner.xcworkspace/contents.xcworkspacedata
================================================
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "group:Runner.xcodeproj">
</FileRef>
<FileRef
location = "group:Pods/Pods.xcodeproj">
</FileRef>
</Workspace>
================================================
FILE: example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
================================================
FILE: example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PreviewsEnabled</key>
<false/>
</dict>
</plist>
================================================
FILE: example/lib/common/route/navigation_service.dart
================================================
/*
* @Author: LinXunFeng linxunfeng@yeah.net
* @Repo: https://github.com/fluttercandies/flutter_scrollview_observer
* @Date: 2025-08-02 15:49:58
*/
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
class NavigationService {
static final GlobalKey<NavigatorState> navigatorKey =
GlobalKey<NavigatorState>();
static BuildContext get context => navigatorKey.currentState!.context;
static void push(
String location, {
Object? extra,
}) {
context.push(
location,
extra: extra,
);
}
static void pop() => context.pop();
static dynamic getParam(
String key, {
dynamic defaultValue,
}) {
final state = routerState();
final pathParam = state.pathParameters[key];
if (pathParam != null) return pathParam;
final extra = stateExtra();
if (extra == null) {
return defaultValue;
}
if (extra is Map) {
return extra[key] ?? defaultValue;
}
return defaultValue;
}
static GoRouterState routerState() {
return GoRouter.of(context).state;
}
static Object? stateExtra() {
return routerState().extra;
}
}
================================================
FILE: example/lib/common/route/route.dart
================================================
/*
* @Author: LinXunFeng linxunfeng@yeah.net
* @Repo: https://github.com/fluttercandies/flutter_scrollview_observer
* @Date: 2025-08-02 15:48:51
*/
export 'navigation_service.dart';
export 'router_config.dart';
================================================
FILE: example/lib/common/route/router_config.dart
================================================
/*
* @Author: LinXunFeng linxunfeng@yeah.net
* @Repo: https://github.com/fluttercandies/flutter_scrollview_observer
* @Date: 2025-08-02 15:49:38
*/
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:scrollview_observer_example/common/route/route.dart';
import 'package:scrollview_observer_example/features/custom_scrollview/custom_scrollview_demo/custom_scrollview_center_demo_page.dart';
import 'package:scrollview_observer_example/features/custom_scrollview/custom_scrollview_demo/custom_scrollview_demo_page.dart';
import 'package:scrollview_observer_example/features/custom_scrollview/custom_scrollview_demo/multi_sliver_demo_page.dart';
import 'package:scrollview_observer_example/features/custom_scrollview/sliver_appbar_demo/sliver_appbar_demo_page.dart';
import 'package:scrollview_observer_example/features/gridview/gridview_ctx_demo/gridview_ctx_demo_page.dart';
import 'package:scrollview_observer_example/features/gridview/gridview_custom_demo/gridview_custom_demo_page.dart';
import 'package:scrollview_observer_example/features/gridview/gridview_demo/gridview_demo_page.dart';
import 'package:scrollview_observer_example/features/gridview/gridview_fixed_height_demo/gridview_fixed_height_demo_page.dart';
import 'package:scrollview_observer_example/features/gridview/horizontal_gridview_demo/horizontal_gridview_demo_page.dart';
import 'package:scrollview_observer_example/features/gridview/sliver_grid_demo/sliver_grid_demo_page.dart';
import 'package:scrollview_observer_example/features/home/home_page.dart';
import 'package:scrollview_observer_example/features/listview/horizontal_listview_demo/horizontal_listview_page.dart';
import 'package:scrollview_observer_example/features/listview/infinite_listview_demo/infinite_listview_page.dart';
import 'package:scrollview_observer_example/features/listview/listview_ctx_demo/listview_ctx_demo_page.dart';
import 'package:scrollview_observer_example/features/listview/listview_custom_demo/listview_custom_demo_page.dart';
import 'package:scrollview_observer_example/features/listview/listview_demo/listview_demo_page.dart';
import 'package:scrollview_observer_example/features/listview/listview_dynamic_offset/listview_dynamic_offset_page.dart';
import 'package:scrollview_observer_example/features/listview/listview_fixed_height_demo/listview_fixed_height_demo_page.dart';
import 'package:scrollview_observer_example/features/listview/sliver_list_demo/sliver_list_demo_page.dart';
import 'package:scrollview_observer_example/features/nested_scrollview/nested_scrollview_demo/nested_scrollview_demo_page.dart';
import 'package:scrollview_observer_example/features/nested_scrollview/nested_scrollview_tab_bar_view_demo/page/nested_scrollview_tab_bar_view_demo_page.dart';
import 'package:scrollview_observer_example/features/pageview/pageview_demo/pageview_demo_page.dart';
import 'package:scrollview_observer_example/features/pageview/pageview_demo/pageview_parallax_item_listener_page.dart';
import 'package:scrollview_observer_example/features/pageview/pageview_demo/pageview_parallax_page.dart';
import 'package:scrollview_observer_example/features/scene/anchor_demo/anchor_page.dart';
import 'package:scrollview_observer_example/features/scene/anchor_demo/anchor_waterfall_page.dart';
import 'package:scrollview_observer_example/features/scene/azlist_demo/azlist_page.dart';
import 'package:scrollview_observer_example/features/scene/chat_demo/page/chat_gpt_page.dart';
import 'package:scrollview_observer_example/features/scene/chat_demo/page/chat_page.dart';
import 'package:scrollview_observer_example/features/scene/detail/page/detail_page.dart';
import 'package:scrollview_observer_example/features/scene/expandable_carousel_slider_demo/expandable_carousel_slider_demo.dart';
import 'package:scrollview_observer_example/features/scene/image_tab_demo/image_tab_page.dart';
import 'package:scrollview_observer_example/features/scene/scrollview_form_demo/scrollview_form_demo_page.dart';
import 'package:scrollview_observer_example/features/scene/video_auto_play_list/video_list_auto_play_page.dart';
import 'package:scrollview_observer_example/features/scene/visibility_demo/page/visibility_listview_page.dart';
import 'package:scrollview_observer_example/features/scene/visibility_demo/page/visibility_scrollview_page.dart';
import 'package:scrollview_observer_example/features/scene/waterfall_flow_demo/waterfall_flow_page.dart';
import 'package:scrollview_observer_example/features/scene/waterfall_flow_fixed_height_demo/waterfall_flow_fixed_height_page.dart';
class MyPage {
static const home = '/home';
// ListView
static const listView = '/list_view';
static const listViewContext = '/list_view_context';
static const listViewFixedHeight = '/list_view_fixed_height';
static const listViewHorizontal = '/list_view_horizontal';
static const listViewDynamicOffset = '/list_view_dynamic_offset';
static const listViewCustom = '/list_view_custom';
static const listViewInfinite = '/list_view_infinite';
static const sliverListView = '/sliver_list_view';
// GridView
static const gridView = '/grid_view';
static const gridViewContext = '/grid_view_context';
static const gridViewFixedHeight = '/grid_view_fixed_height';
static const gridViewHorizontal = '/grid_view_horizontal';
static const gridViewCustom = '/grid_view_custom';
static const sliverGridView = '/sliver_grid_view';
// CustomScrollView
static const customScrollView = '/custom_scroll_view';
static const customScrollViewCenter = '/custom_scroll_view_center';
static const multiSliver = '/multi_sliver';
static const sliverAppBar = '/sliver_app_bar';
// NestedScrollView
static const nestedScrollView = '/nested_scroll_view';
static const nestedScrollViewTabBarView = '/nested_scroll_view_tab_bar_view';
// PageView
static const pageView = '/page_view';
static const pageViewParallax = '/page_view_parallax';
static const pageViewParallaxItemListener =
'/page_view_parallax_item_listener';
// Scene
static const videoListAutoPlay = '/video_list_auto_play';
static const anchorList = '/anchor_list';
static const anchorWaterfall = '/anchor_waterfall';
static const imageTab = '/image_tab';
static const chat = '/chat';
static const chatGPT = '/chat_gpt';
static const waterfallFlow = '/waterfall_flow';
static const waterfallFlowFixedHeight = '/waterfall_flow_fixed_height';
static const scrollViewForm = '/scroll_view_form';
static const visibilityListView = '/visibility_list_view';
static const visibilityScrollView = '/visibility_scroll_view';
static const azList = '/az_list';
static const expandableCarouselSlider = '/expandable_carousel_slider';
static const detail = '/detail';
}
class MyRoute {
static final observer = RouteObserver<ModalRoute>();
static final routerConfig = GoRouter(
routes: routes,
initialLocation: MyPage.home,
observers: [
observer,
],
navigatorKey: NavigationService.navigatorKey,
debugLogDiagnostics: !kReleaseMode,
);
static final List<RouteBase> routes = [
GoRoute(
path: MyPage.home,
builder: (context, state) => const HomePage(),
),
GoRoute(
path: MyPage.listView,
builder: (context, state) => const ListViewDemoPage(),
),
GoRoute(
path: MyPage.listViewContext,
builder: (context, state) => const ListViewCtxDemoPage(),
),
GoRoute(
path: MyPage.listViewFixedHeight,
builder: (context, state) => const ListViewFixedHeightDemoPage(),
),
GoRoute(
path: MyPage.listViewHorizontal,
builder: (context, state) => const HorizontalListViewPage(),
),
GoRoute(
path: MyPage.listViewDynamicOffset,
builder: (context, state) => const ListViewDynamicOffsetPage(),
),
GoRoute(
path: MyPage.listViewCustom,
builder: (context, state) => const ListViewCustomDemoPage(),
),
GoRoute(
path: MyPage.listViewInfinite,
builder: (context, state) => const InfiniteListViewPage(),
),
GoRoute(
path: MyPage.sliverListView,
builder: (context, state) => const SliverListViewDemoPage(),
),
GoRoute(
path: MyPage.gridView,
builder: (context, state) => const GridViewDemoPage(),
),
GoRoute(
path: MyPage.gridViewContext,
builder: (context, state) => const GridViewCtxDemoPage(),
),
GoRoute(
path: MyPage.gridViewFixedHeight,
builder: (context, state) => const GridViewFixedHeightDemoPage(),
),
GoRoute(
path: MyPage.gridViewHorizontal,
builder: (context, state) => const HorizontalGridViewDemoPage(),
),
GoRoute(
path: MyPage.gridViewCustom,
builder: (context, state) => const GridViewCustomDemoPage(),
),
GoRoute(
path: MyPage.sliverGridView,
builder: (context, state) => const SliverGridViewDemoPage(),
),
GoRoute(
path: MyPage.customScrollView,
builder: (context, state) => const CustomScrollViewDemoPage(),
),
GoRoute(
path: MyPage.customScrollViewCenter,
builder: (context, state) => const CustomScrollViewCenterDemoPage(),
),
GoRoute(
path: MyPage.multiSliver,
builder: (context, state) => const MultiSliverDemoPage(),
),
GoRoute(
path: MyPage.sliverAppBar,
builder: (context, state) => const SliverAppBarDemoPage(),
),
GoRoute(
path: MyPage.nestedScrollView,
builder: (context, state) => const NestedScrollViewDemoPage(),
),
GoRoute(
path: MyPage.nestedScrollViewTabBarView,
builder: (context, state) => const NestedScrollViewTabBarViewDemoPage(),
),
GoRoute(
path: MyPage.pageView,
builder: (context, state) => const PageViewDemoPage(),
),
GoRoute(
path: MyPage.pageViewParallax,
builder: (context, state) => const PageViewParallaxPage(),
),
GoRoute(
path: MyPage.pageViewParallaxItemListener,
builder: (context, state) => const PageViewParallaxItemListenerPage(),
),
GoRoute(
path: MyPage.videoListAutoPlay,
builder: (context, state) => const VideoListAutoPlayPage(),
),
GoRoute(
path: MyPage.anchorList,
builder: (context, state) => const AnchorListPage(),
),
GoRoute(
path: MyPage.anchorWaterfall,
builder: (context, state) => const AnchorWaterfallPage(),
),
GoRoute(
path: MyPage.imageTab,
builder: (context, state) => const ImageTabPage(),
),
GoRoute(
path: MyPage.chat,
builder: (context, state) => const ChatPage(),
),
GoRoute(
path: MyPage.chatGPT,
builder: (context, state) => const ChatGPTPage(),
),
GoRoute(
path: MyPage.waterfallFlow,
builder: (context, state) => const WaterfallFlowPage(),
),
GoRoute(
path: MyPage.waterfallFlowFixedHeight,
builder: (context, state) => const WaterfallFlowFixedHeightPage(),
),
GoRoute(
path: MyPage.scrollViewForm,
builder: (context, state) => const ScrollViewFormDemoPage(),
),
GoRoute(
path: MyPage.visibilityListView,
builder: (context, state) => const VisibilityListViewPage(),
),
GoRoute(
path: MyPage.visibilityScrollView,
builder: (context, state) => const VisibilityScrollViewPage(),
),
GoRoute(
path: MyPage.azList,
builder: (context, state) => const AzListPage(),
),
GoRoute(
path: MyPage.expandableCarouselSlider,
builder: (context, state) => const ExpandableCarouselSliderDemo(),
),
GoRoute(
path: MyPage.detail,
builder: (context, state) => const DetailPage(),
),
];
}
================================================
FILE: example/lib/features/custom_scrollview/custom_scrollview_demo/custom_scrollview_center_demo_page.dart
================================================
/*
* @Author: LinXunFeng linxunfeng@yeah.net
* @Repo: https://github.com/fluttercandies/flutter_scrollview_observer
* @Date: 2024-03-11 21:08:23
*/
import 'package:flutter/material.dart';
import 'package:scrollview_observer/scrollview_observer.dart';
import 'package:scrollview_observer_example/utils/snackbar.dart';
class CustomScrollViewCenterDemoPage extends StatefulWidget {
const CustomScrollViewCenterDemoPage({Key? key}) : super(key: key);
@override
State<CustomScrollViewCenterDemoPage> createState() =>
_CustomScrollViewCenterDemoPageState();
}
class _CustomScrollViewCenterDemoPageState
extends State<CustomScrollViewCenterDemoPage> {
BuildContext? _sliverListCtx1;
BuildContext? _sliverListCtx2;
BuildContext? _sliverListCtx3;
BuildContext? _sliverListCtx4;
final _centerKey = GlobalKey();
ScrollController scrollController = ScrollController();
late SliverObserverController observerController;
@override
void initState() {
super.initState();
observerController = SliverObserverController(controller: scrollController)
..cacheJumpIndexOffset = false;
}
@override
void dispose() {
observerController.controller?.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text("CustomScrollView - center")),
body: SliverViewObserver(
controller: observerController,
child: _buildScrollView(),
sliverContexts: () {
return [
if (_sliverListCtx1 != null) _sliverListCtx1!,
if (_sliverListCtx2 != null) _sliverListCtx2!,
if (_sliverListCtx3 != null) _sliverListCtx3!,
if (_sliverListCtx4 != null) _sliverListCtx4!,
];
},
onObserveAll: (resultMap) {
final model1 = resultMap[_sliverListCtx1];
if (model1 != null &&
model1.visible &&
model1 is ListViewObserveModel) {
debugPrint('1 visible -- ${model1.visible}');
debugPrint('1 firstChild.index -- ${model1.firstChild?.index}');
debugPrint('1 displaying -- ${model1.displayingChildIndexList}');
}
final model2 = resultMap[_sliverListCtx2];
if (model2 != null &&
model2.visible &&
model2 is ListViewObserveModel) {
debugPrint('2 visible -- ${model2.visible}');
debugPrint('2 firstChild.index -- ${model2.firstChild?.index}');
debugPrint('2 displaying -- ${model2.displayingChildIndexList}');
}
final model3 = resultMap[_sliverListCtx3];
if (model3 != null &&
model3.visible &&
model3 is ListViewObserveModel) {
debugPrint('3 visible -- ${model3.visible}');
debugPrint('3 firstChild.index -- ${model3.firstChild?.index}');
debugPrint('3 displaying -- ${model3.displayingChildIndexList}');
}
final model4 = resultMap[_sliverListCtx4];
if (model4 != null &&
model4.visible &&
model4 is ListViewObserveModel) {
debugPrint('4 visible -- ${model4.visible}');
debugPrint('4 firstChild.index -- ${model4.firstChild?.index}');
debugPrint('4 displaying -- ${model4.displayingChildIndexList}');
}
},
),
floatingActionButton: Padding(
padding: const EdgeInsets.all(15.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
IconButton(
onPressed: () {
SnackBarUtil.showSnackBar(
context: context,
text: 'SliverList - Jumping to row 29',
);
observerController.animateTo(
sliverContext: _sliverListCtx1,
index: 29,
duration: const Duration(milliseconds: 300),
curve: Curves.easeInOut,
);
},
icon: const Icon(Icons.ac_unit_outlined),
),
IconButton(
onPressed: () {
SnackBarUtil.showSnackBar(
context: context,
text: '_sliverListCtx2 - Jumping to item 20',
);
observerController.animateTo(
sliverContext: _sliverListCtx2,
index: 20,
duration: const Duration(milliseconds: 300),
curve: Curves.easeInOut,
);
},
icon: const Icon(Icons.backup_table),
),
IconButton(
onPressed: () {
SnackBarUtil.showSnackBar(
context: context,
text: '_sliverListCtx3 - Jumping to item 20',
);
observerController.animateTo(
sliverContext: _sliverListCtx3,
index: 20,
duration: const Duration(milliseconds: 300),
curve: Curves.easeInOut,
alignment: 1,
);
},
icon: const Icon(Icons.cabin),
),
IconButton(
onPressed: () {
SnackBarUtil.showSnackBar(
context: context,
text: '_sliverListCtx4 - Jumping to item 20',
);
observerController.animateTo(
sliverContext: _sliverListCtx4,
index: 20,
duration: const Duration(milliseconds: 300),
curve: Curves.easeInOut,
alignment: 1,
);
},
icon: const Icon(Icons.cruelty_free),
),
],
),
),
);
}
Widget _buildScrollView() {
return CustomScrollView(
center: _centerKey,
anchor: 1,
controller: scrollController,
slivers: [
_buildSliverListView(
color: Colors.redAccent,
onBuild: (ctx) {
_sliverListCtx1 = ctx;
},
),
_buildSliverListView(
color: Colors.blueGrey,
onBuild: (ctx) {
_sliverListCtx2 = ctx;
},
),
SliverPadding(padding: EdgeInsets.zero, key: _centerKey),
_buildSliverListView(
color: Colors.teal,
onBuild: (ctx) {
_sliverListCtx3 = ctx;
},
),
_buildSliverListView(
color: Colors.purple,
onBuild: (ctx) {
_sliverListCtx4 = ctx;
},
),
],
);
}
Widget _buildSliverListView({
required Color color,
Function(BuildContext)? onBuild,
}) {
return SliverList(
delegate: SliverChildBuilderDelegate(
(ctx, index) {
onBuild?.call(ctx);
final int itemIndex = index ~/ 2;
return Container(
height: (itemIndex % 2 == 0) ? 80 : 50,
color: color,
child: Center(
child: Text(
"index -- $index",
style: const TextStyle(color: Colors.white),
),
),
);
},
childCount: 100,
),
);
}
}
================================================
FILE: example/lib/features/custom_scrollview/custom_scrollview_demo/custom_scrollview_demo_page.dart
================================================
/*
* @Author: LinXunFeng linxunfeng@yeah.net
* @Repo: https://github.com/LinXunFeng/flutter_scrollview_observer
* @Date: 2022-08-08 00:20:03
*/
import 'package:flutter/material.dart';
import 'package:scrollview_observer/scrollview_observer.dart';
import 'package:scrollview_observer_example/typedefs.dart';
import 'package:scrollview_observer_example/utils/snackbar.dart';
class CustomScrollViewDemoPage extends StatefulWidget {
const CustomScrollViewDemoPage({Key? key}) : super(key: key);
@override
State<CustomScrollViewDemoPage> createState() =>
_CustomScrollViewDemoPageState();
}
class _CustomScrollViewDemoPageState extends State<CustomScrollViewDemoPage> {
BuildContext? _sliverListCtx;
BuildContext? _sliverGridCtx;
int _hitIndexForCtx1 = 0;
List<int> _hitIndexsForGrid = [];
ScrollController scrollController = ScrollController();
late SliverObserverController observerController;
@override
void initState() {
super.initState();
observerController = SliverObserverController(controller: scrollController);
// Trigger an observation manually
ambiguate(WidgetsBinding.instance)?.addPostFrameCallback((timeStamp) {
observerController.dispatchOnceObserve(
sliverContext: _sliverListCtx!,
);
});
}
@override
void dispose() {
observerController.controller?.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text("CustomScrollView")),
body: SliverViewObserver(
controller: observerController,
child: _buildScrollView(),
sliverContexts: () {
return [
if (_sliverListCtx != null) _sliverListCtx!,
if (_sliverGridCtx != null) _sliverGridCtx!,
];
},
onObserveAll: (resultMap) {
final model1 = resultMap[_sliverListCtx];
if (model1 != null &&
model1.visible &&
model1 is ListViewObserveModel) {
debugPrint('1 visible -- ${model1.visible}');
debugPrint('1 firstChild.index -- ${model1.firstChild?.index}');
debugPrint('1 displaying -- ${model1.displayingChildIndexList}');
setState(() {
_hitIndexForCtx1 = model1.firstChild?.index ?? 0;
});
}
final model2 = resultMap[_sliverGridCtx];
if (model2 != null &&
model2.visible &&
model2 is GridViewObserveModel) {
debugPrint('2 visible -- ${model2.visible}');
debugPrint('2 displaying -- ${model2.displayingChildIndexList}');
setState(() {
_hitIndexsForGrid =
model2.firstGroupChildList.map((e) => e.index).toList();
});
}
},
),
floatingActionButton: Padding(
padding: const EdgeInsets.all(15.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
IconButton(
onPressed: () {
SnackBarUtil.showSnackBar(
context: context,
text: 'SliverList - Jumping to row 29',
);
observerController.animateTo(
sliverContext: _sliverListCtx,
index: 29,
duration: const Duration(milliseconds: 300),
curve: Curves.easeInOut,
);
},
icon: const Icon(Icons.ac_unit_outlined),
),
IconButton(
onPressed: () {
SnackBarUtil.showSnackBar(
context: context,
text: 'SliverGrid - Jumping to item 20',
);
observerController.animateTo(
sliverContext: _sliverGridCtx,
index: 20,
duration: const Duration(milliseconds: 300),
curve: Curves.easeInOut,
);
},
icon: const Icon(Icons.backup_table),
),
],
),
),
);
}
Widget _buildScrollView() {
return CustomScrollView(
controller: scrollController,
// scrollDirection: Axis.horizontal,
slivers: [
_buildSliverListView(),
_buildSliverGridView(),
],
);
}
Widget _buildSliverListView() {
// return SliverFixedExtentList(
// delegate: SliverChildBuilderDelegate(
// (ctx, index) {
// _sliverListCtx ??= ctx;
// return Container(
// // height: (index % 2 == 0) ? 80 : 50,
// color: _hitIndexForCtx1 == index ? Colors.red : Colors.black12,
// child: Center(
// child: Text(
// "index -- $index",
// style: TextStyle(
// color:
// _hitIndexForCtx1 == index ? Colors.white : Colors.black,
// ),
// ),
// ),
// );
// },
// childCount: 30,
// ),
// itemExtent: 100,
// );
return SliverList(
delegate: SliverChildBuilderDelegate(
(ctx, index) {
_sliverListCtx ??= ctx;
return Container(
height: (index % 2 == 0) ? 80 : 50,
color: _hitIndexForCtx1 == index ? Colors.red : Colors.black12,
child: Center(
child: Text(
"index -- $index",
style: TextStyle(
color:
_hitIndexForCtx1 == index ? Colors.white : Colors.black,
),
),
),
);
},
childCount: 30,
),
);
}
Widget _buildSliverGridView() {
return SliverGrid(
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2, //Grid按两列显示
mainAxisSpacing: 10.0,
crossAxisSpacing: 10.0,
childAspectRatio: 2.0,
),
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
_sliverGridCtx ??= context;
return Container(
color: (_hitIndexsForGrid.contains(index))
? Colors.green
: Colors.blue[100],
child: Center(
child: Text('index -- $index'),
),
);
},
childCount: 150,
),
);
}
}
================================================
FILE: example/lib/features/custom_scrollview/custom_scrollview_demo/multi_sliver_demo_page.dart
================================================
/*
* @Author: LinXunFeng linxunfeng@yeah.net
* @Repo: https://github.com/LinXunFeng/flutter_scrollview_observer
* @Date: 2023-09-16 19:41:33
*/
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter_sticky_header/flutter_sticky_header.dart';
import 'package:scrollview_observer/scrollview_observer.dart';
import 'package:scrollview_observer_example/utils/random.dart';
class MultiSliverDemoModel {
final String tag;
final List<String> value;
const MultiSliverDemoModel({
required this.tag,
required this.value,
});
}
class MultiSliverDemoPage extends StatefulWidget {
const MultiSliverDemoPage({Key? key}) : super(key: key);
@override
State<MultiSliverDemoPage> createState() => _MultiSliverDemoPageState();
}
class _MultiSliverDemoPageState extends State<MultiSliverDemoPage> {
List<MultiSliverDemoModel> modelList = [];
final appBarKey = GlobalKey();
final scrollController = ScrollController();
late final SliverObserverController sliverItemObserverController;
// late final SliverObserverController sliverObserverController;
Map<int, BuildContext> itemSliverIndexCtxMap = {};
Map<int, BuildContext> sliverIndexCtxMap = {};
ValueNotifier<int> tabCurrentSelectedIndex = ValueNotifier(0);
bool isIgnoreCalcTabBarIndex = false;
@override
void initState() {
super.initState();
sliverItemObserverController = SliverObserverController(
controller: scrollController,
);
// sliverObserverController = SliverObserverController(
// controller: scrollController,
// );
for (var i = 0; i < 4; i++) {
final tag = 'Section ${i + 1}';
List<String> values = [];
for (var j = 0; j < 4; j++) {
values.add('Row: ${i + 1}-$j');
}
modelList.add(MultiSliverDemoModel(tag: tag, value: values));
}
}
@override
Widget build(BuildContext context) {
Widget resultWidget = _buildScrollView();
resultWidget = _buildSliverItemObserver(child: resultWidget);
resultWidget = _buildSliverObserver(child: resultWidget);
return Scaffold(
body: resultWidget,
bottomNavigationBar: buildBottomNavigationBar(context),
);
}
/// To observe sliver items and handle scrollTo.
Widget _buildSliverItemObserver({
required Widget child,
}) {
return SliverViewObserver(
controller: sliverItemObserverController,
sliverContexts: () => itemSliverIndexCtxMap.values.toList(),
child: child,
);
}
/// To observe which sliver is currently the first.
Widget _buildSliverObserver({
required Widget child,
}) {
return SliverViewObserver(
// controller: sliverObserverController,
child: child,
sliverContexts: () => sliverIndexCtxMap.values.toList(),
triggerOnObserveType: ObserverTriggerOnObserveType.directly,
dynamicLeadingOffset: () {
// Accumulate the height of all PersistentHeader.
return ObserverUtils.calcPersistentHeaderExtent(
key: appBarKey,
offset: scrollController.offset,
) +
1; // To avoid tabBar index rebound.
},
onObserveViewport: (result) {
if (isIgnoreCalcTabBarIndex) return;
int? currentTabIndex;
final currentFirstSliverCtx = result.firstChild.sliverContext;
for (var sectionIndex in sliverIndexCtxMap.keys) {
final ctx = sliverIndexCtxMap[sectionIndex];
if (ctx == null) continue;
// If they are not the same sliver, continue.
if (currentFirstSliverCtx != ctx) continue;
// If the sliver is not visible, continue.
final visible =
(ctx.findRenderObject() as RenderSliver).geometry?.visible ??
false;
if (!visible) continue;
currentTabIndex = sectionIndex;
break;
}
if (currentTabIndex == null) return;
updateTabBarIndex(currentTabIndex);
},
);
}
Widget _buildScrollView() {
return CustomScrollView(
controller: scrollController,
physics: const ClampingScrollPhysics(),
slivers: [
SliverAppBar(
key: appBarKey,
pinned: true,
title: const Text('Multi Sliver'),
),
...List.generate(modelList.length, (mainIndex) {
return _buildSectionListView(mainIndex);
}),
],
);
}
Widget buildBottomNavigationBar(BuildContext context) {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
Row(
children: List.generate(modelList.length, (index) {
return Expanded(
child: InkWell(
onTap: () async {
updateTabBarIndex(index);
isIgnoreCalcTabBarIndex = true;
// await sliverItemObserverController.jumpTo(
// sliverContext: itemSliverIndexCtxMap[index],
// index: 0,
// isFixedHeight: true,
// offset: (offset) {
// return ObserverUtils.calcPersistentHeaderExtent(
// key: appBarKey,
// offset: offset,
// );
// },
// );
await sliverItemObserverController.animateTo(
sliverContext: itemSliverIndexCtxMap[index],
index: 0,
isFixedHeight: true,
duration: const Duration(milliseconds: 200),
curve: Curves.easeInOut,
offset: (offset) {
return ObserverUtils.calcPersistentHeaderExtent(
key: appBarKey,
offset: offset,
);
},
);
isIgnoreCalcTabBarIndex = false;
},
child: ValueListenableBuilder(
valueListenable: tabCurrentSelectedIndex,
builder: (BuildContext context, int value, Widget? child) {
return Container(
alignment: Alignment.center,
height: 40,
decoration: BoxDecoration(
border: Border.all(width: 0.5),
color: value == index ? Colors.amber : Colors.white,
),
child: Text(
modelList[index].tag,
),
);
},
),
),
);
}),
),
SizedBox(height: MediaQuery.paddingOf(context).bottom),
],
);
}
Widget _buildSectionListView(int mainIndex) {
Widget resultWidget = SliverStickyHeader(
header: Container(
height: 40,
color: Colors.white,
padding: const EdgeInsets.only(left: 12),
alignment: Alignment.centerLeft,
child: Text(
modelList[mainIndex].tag,
),
),
sliver: SliverFixedExtentList(
itemExtent: 120,
delegate: SliverChildBuilderDelegate(
(context, index) {
// Save the context of SliverList.
itemSliverIndexCtxMap[mainIndex] = context;
return Container(
padding: const EdgeInsets.only(left: 12),
color: RandomTool.color(),
alignment: Alignment.centerLeft,
child: Text(
modelList[mainIndex].value[index],
),
);
},
childCount: modelList[mainIndex].value.length,
),
),
);
resultWidget = SliverObserveContext(
child: resultWidget,
onObserve: (context) {
// Save the context of the outermost sliver.
sliverIndexCtxMap[mainIndex] = context;
},
);
return resultWidget;
}
updateTabBarIndex(int index) {
if (index == tabCurrentSelectedIndex.value) return;
tabCurrentSelectedIndex.value = index;
}
}
================================================
FILE: example/lib/features/custom_scrollview/sliver_appbar_demo/sliver_appbar_demo_page.dart
================================================
/*
* @Author: LinXunFeng linxunfeng@yeah.net
* @Repo: https://github.com/LinXunFeng/flutter_scrollview_observer
* @Date: 2022-08-20 09:22:52
*/
import 'package:flutter/material.dart';
import 'package:scrollview_observer/scrollview_observer.dart';
import 'package:scrollview_observer_example/typedefs.dart';
import 'package:scrollview_observer_example/utils/snackbar.dart';
class SliverAppBarDemoPage extends StatefulWidget {
const SliverAppBarDemoPage({Key? key}) : super(key: key);
@override
State<SliverAppBarDemoPage> createState() => _SliverAppBarDemoPageState();
}
class _SliverAppBarDemoPageState extends State<SliverAppBarDemoPage> {
BuildContext? _sliverListCtx;
BuildContext? _sliverGridCtx;
GlobalKey appBarKey = GlobalKey();
int _hitIndexForCtx1 = 0;
List<int> _hitIndexsForGrid = [];
ScrollController scrollController = ScrollController();
late SliverObserverController observerController;
@override
void initState() {
super.initState();
observerController = SliverObserverController(controller: scrollController)
..initialIndexModelBlock = () {
return ObserverIndexPositionModel(
index: 6,
sliverContext: _sliverListCtx,
offset: calcPersistentHeaderExtent,
);
};
// Trigger an observation manually
ambiguate(WidgetsBinding.instance)?.addPostFrameCallback((timeStamp) {
observerController.dispatchOnceObserve(
sliverContext: _sliverListCtx!,
);
});
}
@override
void dispose() {
observerController.controller?.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SliverViewObserver(
controller: observerController,
child: _buildScrollView(),
sliverContexts: () {
return [
if (_sliverListCtx != null) _sliverListCtx!,
if (_sliverGridCtx != null) _sliverGridCtx!,
];
},
autoTriggerObserveTypes: const [
ObserverAutoTriggerObserveType.scrollEnd,
],
triggerOnObserveType: ObserverTriggerOnObserveType.directly,
onObserveAll: (resultMap) {
final model1 = resultMap[_sliverListCtx];
if (model1 != null &&
model1.visible &&
model1 is ListViewObserveModel) {
debugPrint('1 visible -- ${model1.visible}');
debugPrint('1 firstChild.index -- ${model1.firstChild?.index}');
debugPrint('1 firstChild.size -- ${model1.firstChild?.size}');
debugPrint('1 displaying -- ${model1.displayingChildIndexList}');
debugPrint(
'1 displaying -- index${model1.firstChild?.index} -- ${model1.firstChild?.displayPercentage}');
setState(() {
_hitIndexForCtx1 = model1.firstChild?.index ?? 0;
});
}
final model2 = resultMap[_sliverGridCtx];
if (model2 != null &&
model2.visible &&
model2 is GridViewObserveModel) {
debugPrint('2 visible -- ${model2.visible}');
debugPrint('2 displaying -- ${model2.displayingChildIndexList}');
setState(() {
_hitIndexsForGrid =
model2.firstGroupChildList.map((e) => e.index).toList();
});
}
},
),
floatingActionButton: Padding(
padding: const EdgeInsets.all(15.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
IconButton(
onPressed: () {
SnackBarUtil.showSnackBar(
context: context,
text: 'SliverList - Jumping to row 8',
);
observerController.animateTo(
sliverContext: _sliverListCtx,
index: 8,
duration: const Duration(milliseconds: 300),
curve: Curves.easeInOut,
offset: calcPersistentHeaderExtent,
);
},
icon: const Icon(Icons.ac_unit_outlined),
),
IconButton(
onPressed: () {
SnackBarUtil.showSnackBar(
context: context,
text: 'SliverGrid - Jumping to item 5',
);
observerController.animateTo(
sliverContext: _sliverGridCtx,
index: 5,
duration: const Duration(milliseconds: 300),
curve: Curves.easeInOut,
offset: calcPersistentHeaderExtent,
);
},
icon: const Icon(Icons.backup_table),
),
],
),
),
);
}
Widget _buildScrollView() {
return CustomScrollView(
controller: scrollController,
// scrollDirection: Axis.horizontal,
slivers: [
_buildSliverAppBar(),
_buildSliverListView(),
_buildSliverGridView(),
],
cacheExtent: double.maxFinite,
);
}
Widget _buildSliverAppBar() {
return SliverAppBar(
key: appBarKey,
pinned: true,
expandedHeight: 200,
flexibleSpace: FlexibleSpaceBar(
title: const Text('AppBar'),
background: Container(color: Colors.orange),
),
);
}
Widget _buildSliverListView() {
return SliverList(
delegate: SliverChildBuilderDelegate(
(ctx, index) {
_sliverListCtx ??= ctx;
return Container(
height: (index % 2 == 0) ? 80 : 50,
color: _hitIndexForCtx1 == index ? Colors.red : Colors.black12,
child: Center(
child: Text(
"index -- $index",
style: TextStyle(
color:
_hitIndexForCtx1 == index ? Colors.white : Colors.black,
),
),
),
);
},
childCount: 20,
),
);
}
Widget _buildSliverGridView() {
return SliverGrid(
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
mainAxisSpacing: 10.0,
crossAxisSpacing: 10.0,
childAspectRatio: 2.0,
),
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
_sliverGridCtx ??= context;
return Container(
color: (_hitIndexsForGrid.contains(index))
? Colors.green
: Colors.blue[100],
child: Center(
child: Text('index -- $index'),
),
);
},
childCount: 20,
),
);
}
double calcPersistentHeaderExtent(double offset) {
return ObserverUtils.calcPersistentHeaderExtent(
key: appBarKey,
offset: offset,
);
}
}
================================================
FILE: example/lib/features/gridview/gridview_ctx_demo/gridview_ctx_demo_page.dart
================================================
/*
* @Author: LinXunFeng linxunfeng@yeah.net
* @Repo: https://github.com/LinXunFeng/flutter_scrollview_observer
* @Date: 2022-08-08 00:20:03
*/
import 'package:flutter/material.dart';
import 'package:scrollview_observer/scrollview_observer.dart';
import 'package:scrollview_observer_example/typedefs.dart';
class GridViewCtxDemoPage extends StatefulWidget {
const GridViewCtxDemoPage({Key? key}) : super(key: key);
@override
State<GridViewCtxDemoPage> createState() => _GridViewCtxDemoPageState();
}
class _GridViewCtxDemoPageState extends State<GridViewCtxDemoPage> {
BuildContext? _sliverGridViewContext;
List<int> _hitIndexs = [];
@override
void initState() {
super.initState();
// Trigger an observation manually
ambiguate(WidgetsBinding.instance)?.addPostFrameCallback((timeStamp) {
GridViewOnceObserveNotification().dispatch(_sliverGridViewContext);
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text("GridView")),
body: GridViewObserver(
sliverGridContexts: () {
return [if (_sliverGridViewContext != null) _sliverGridViewContext!];
},
onObserveAll: (resultMap) {
final model = resultMap[_sliverGridViewContext];
if (model == null) return;
setState(() {
_hitIndexs = model.firstGroupChildList.map((e) => e.index).toList();
});
debugPrint(
'firstGroupChildList -- ${model.firstGroupChildList.map((e) => e.index)}');
debugPrint('displaying -- ${model.displayingChildIndexList}');
},
child: _buildGridView(),
),
);
}
Widget _buildGridView() {
return GridView.builder(
padding: const EdgeInsets.only(top: 1000, bottom: 1000),
controller: ScrollController(initialScrollOffset: 1000),
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
crossAxisSpacing: 2,
mainAxisSpacing: 5,
),
// gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent(
// maxCrossAxisExtent: 140.0,
// childAspectRatio: 0.6,
// crossAxisSpacing: 2,
// mainAxisSpacing: 5,
// ),
itemBuilder: (context, index) {
if (_sliverGridViewContext != context) {
_sliverGridViewContext = context;
}
return Container(
color: (_hitIndexs.contains(index)) ? Colors.red : Colors.blue[100],
child: Center(
child: Text('index -- $index'),
),
);
},
itemCount: 50,
);
}
}
================================================
FILE: example/lib/features/gridview/gridview_custom_demo/gridview_custom_demo_page.dart
================================================
/*
* @Author: LinXunFeng linxunfeng@yeah.net
* @Repo: https://github.com/LinXunFeng/flutter_scrollview_observer
* @Date: 2023-05-21 11:14:46
*/
// ignore: implementation_imports
import 'package:extended_list/src/rendering/sliver_grid.dart';
import 'package:flutter/material.dart';
import 'package:loading_more_list/loading_more_list.dart';
import 'package:scrollview_observer/scrollview_observer.dart';
import 'package:scrollview_observer_example/utils/snackbar.dart';
class GridViewCustomDemoPage extends StatefulWidget {
const GridViewCustomDemoPage({Key? key}) : super(key: key);
@override
State<GridViewCustomDemoPage> createState() => _GridViewCustomDemoPageState();
}
class _GridViewCustomDemoPageState extends State<GridViewCustomDemoPage> {
ScrollController scrollController = ScrollController();
late GridObserverController observerController;
@override
void initState() {
observerController = GridObserverController(
controller: scrollController,
);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Custom')),
body: GridViewObserver(
child: _buildGridView(),
controller: observerController,
customTargetRenderSliverType: (renderObj) {
// Here you tell the package what type of RenderObject it needs to observe.
return renderObj is ExtendedRenderSliverGrid;
},
// customHandleObserve: (context) {
// // Here you can customize the observation logic.
// return ObserverCore.handleGridObserve(
// context: context,
// fetchLeadingOffset: () => 100,
// );
// },
onObserve: (resultModel) {
debugPrint(
'firstChild.index -- ${resultModel.firstGroupChildList.map((e) => e.index)}');
debugPrint('displaying -- ${resultModel.displayingChildIndexList}');
},
),
floatingActionButton: FloatingActionButton(
child: const Icon(Icons.airline_stops_sharp),
onPressed: () {
SnackBarUtil.showSnackBar(
context: context,
text: 'Jump to item 10',
);
observerController.jumpTo(
index: 10,
);
},
),
);
}
Widget _buildGridView() {
return LoadingMoreList(
ListConfig(
controller: scrollController,
itemBuilder: (context, item, index) {
if (scrollController.hasClients &&
(observerController.sliverContexts.isEmpty ||
observerController.sliverContexts.first != context)) {
observerController.reattach();
}
return Container(
color: Colors.cyan,
child: ListTile(
title: Text('index - $index'),
),
);
},
gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 300.0,
crossAxisSpacing: 3.0,
mainAxisSpacing: 3.0,
),
sourceList: SourceList(),
),
);
}
}
class SourceList extends LoadingMoreBase<int> {
@override
Future<bool> loadData([bool isloadMoreAction = false]) async {
await Future.delayed(const Duration(seconds: 2));
for (var i = 0; i < 30; i++) {
add(i);
}
return true;
}
}
================================================
FILE: example/lib/features/gridview/gridview_demo/gridview_demo_page.dart
================================================
/*
* @Author: LinXunFeng linxunfeng@yeah.net
* @Repo: https://github.com/LinXunFeng/flutter_scrollview_observer
* @Date: 2022-08-08 00:20:03
*/
import 'package:flutter/material.dart';
import 'package:scrollview_observer/scrollview_observer.dart';
import 'package:scrollview_observer_example/typedefs.dart';
import 'package:scrollview_observer_example/utils/snackbar.dart';
class GridViewDemoPage extends StatefulWidget {
const GridViewDemoPage({Key? key}) : super(key: key);
@override
State<GridViewDemoPage> createState() => _GridViewDemoPageState();
}
class _GridViewDemoPageState extends State<GridViewDemoPage> {
static const double _leadingPadding = 1000;
static const double _trailingPadding = 100;
static const EdgeInsets _padding = EdgeInsets.only(
top: _leadingPadding,
bottom: _trailingPadding,
);
List<int> _hitIndexs = [0, 1];
ScrollController scrollController =
ScrollController(initialScrollOffset: _leadingPadding);
late GridObserverController observerController;
@override
void initState() {
super.initState();
observerController = GridObserverController(controller: scrollController);
// Trigger an observation manually
ambiguate(WidgetsBinding.instance)?.endOfFrame.then(
(_) {
if (mounted) {
// After layout
observerController.dispatchOnceObserve();
}
},
);
}
@override
void dispose() {
observerController.controller?.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text("GridView")),
body: GridViewObserver(
controller: observerController,
onObserve: (result) {
final model = result;
setState(() {
_hitIndexs = model.firstGroupChildList.map((e) => e.index).toList();
});
debugPrint(
'firstGroupChildList -- ${model.firstGroupChildList.map((e) => e.index)}');
debugPrint('displaying -- ${model.displayingChildIndexList}');
},
child: _buildGridView(),
),
floatingActionButton: FloatingActionButton(
child: const Icon(Icons.airline_stops_outlined),
onPressed: () {
SnackBarUtil.showSnackBar(
context: context,
text: 'Jump to item 49',
);
observerController.jumpTo(
index: 49,
padding: _padding,
);
// observerController.animateTo(
// index: 49,
// duration: const Duration(seconds: 1),
// curve: Curves.ease,
// );
},
),
);
}
Widget _buildGridView() {
return GridView.builder(
padding: _padding,
controller: scrollController,
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
crossAxisSpacing: 2,
mainAxisSpacing: 5,
),
itemBuilder: (context, index) {
return Container(
color: (_hitIndexs.contains(index)) ? Colors.red : Colors.blue[100],
child: Center(
child: Text('index -- $index'),
),
);
},
itemCount: 50,
);
}
}
================================================
FILE: example/lib/features/gridview/gridview_fixed_height_demo/gridview_fixed_height_demo_page.dart
================================================
/*
* @Author: LinXunFeng linxunfeng@yeah.net
* @Repo: https://github.com/LinXunFeng/flutter_scrollview_observer
* @Date: 2022-08-08 00:20:03
*/
import 'package:flutter/material.dart';
import 'package:scrollview_observer/scrollview_observer.dart';
import 'package:scrollview_observer_example/typedefs.dart';
import 'package:scrollview_observer_example/utils/snackbar.dart';
class GridViewFixedHeightDemoPage extends StatefulWidget {
const GridViewFixedHeightDemoPage({Key? key}) : super(key: key);
@override
State<GridViewFixedHeightDemoPage> createState() =>
_GridViewFixedHeightDemoPageState();
}
class _GridViewFixedHeightDemoPageState
extends State<GridViewFixedHeightDemoPage> {
static const double _leadingPadding = 1000;
static const double _trailingPadding = 100;
static const EdgeInsets _padding = EdgeInsets.only(
top: _leadingPadding,
bottom: _trailingPadding,
left: 30,
right: 30,
);
List<int> _hitIndexs = [0, 1];
ScrollController scrollController =
ScrollController(initialScrollOffset: _leadingPadding);
late GridObserverController observerController;
@override
void initState() {
super.initState();
observerController = GridObserverController(controller: scrollController);
// Trigger an observation manually
ambiguate(WidgetsBinding.instance)?.endOfFrame.then(
(_) {
if (mounted) {
// After layout
observerController.dispatchOnceObserve();
}
},
);
}
@override
void dispose() {
observerController.controller?.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text("GridView")),
body: GridViewObserver(
controller: observerController,
onObserve: (result) {
final model = result;
setState(() {
_hitIndexs = model.firstGroupChildList.map((e) => e.index).toList();
});
debugPrint(
'firstGroupChildList -- ${model.firstGroupChildList.map((e) => e.index)}');
debugPrint('displaying -- ${model.displayingChildIndexList}');
},
child: _buildGridView(),
),
floatingActionButton: FloatingActionButton(
child: const Icon(Icons.airline_stops_outlined),
onPressed: () {
SnackBarUtil.showSnackBar(
context: context,
text: 'Jump to item 21',
);
observerController.jumpTo(
index: 21,
padding: _padding,
isFixedHeight: true,
);
},
),
);
}
Widget _buildGridView() {
return GridView.builder(
padding: _padding,
controller: scrollController,
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
crossAxisSpacing: 2,
mainAxisSpacing: 5,
),
itemBuilder: (context, index) {
return Container(
color: (_hitIndexs.contains(index)) ? Colors.red : Colors.blue[100],
child: Center(
child: Text('index -- $index'),
),
);
},
itemCount: 50,
);
}
}
================================================
FILE: example/lib/features/gridview/horizontal_gridview_demo/horizontal_gridview_demo_page.dart
================================================
/*
* @Author: LinXunFeng linxunfeng@yeah.net
* @Repo: https://github.com/LinXunFeng/flutter_scrollview_observer
* @Date: 2022-08-08 00:20:03
*/
import 'package:flutter/material.dart';
import 'package:scrollview_observer/scrollview_observer.dart';
import 'package:scrollview_observer_example/typedefs.dart';
import 'package:scrollview_observer_example/utils/snackbar.dart';
class HorizontalGridViewDemoPage extends StatefulWidget {
const HorizontalGridViewDemoPage({Key? key}) : super(key: key);
@override
State<HorizontalGridViewDemoPage> createState() =>
_HorizontalGridViewDemoPageState();
}
class _HorizontalGridViewDemoPageState
extends State<HorizontalGridViewDemoPage> {
static const double _leadingPadding = 1000;
static const double _trailingPadding = 2000;
static const EdgeInsets _padding = EdgeInsets.only(
left: _leadingPadding,
right: _trailingPadding,
);
BuildContext? _sliverGridViewContext;
List<int> _hitIndexs = [];
ScrollController scrollController =
ScrollController(initialScrollOffset: _leadingPadding);
late GridObserverController observerController;
@override
void initState() {
super.initState();
observerController = GridObserverController(controller: scrollController)
..initialIndexModel = ObserverIndexPositionModel(
index: 98,
padding: _padding,
);
// Trigger an observation manually
ambiguate(WidgetsBinding.instance)?.addPostFrameCallback((timeStamp) {
GridViewOnceObserveNotification().dispatch(_sliverGridViewContext);
});
}
@override
void dispose() {
observerController.controller?.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text("GridView")),
body: GridViewObserver(
controller: observerController,
sliverGridContexts: () {
return [if (_sliverGridViewContext != null) _sliverGridViewContext!];
},
autoTriggerObserveTypes: const [
ObserverAutoTriggerObserveType.scrollEnd,
],
triggerOnObserveType:
ObserverTriggerOnObserveType.displayingItemsChange,
onObserveAll: (resultMap) {
final model = resultMap[_sliverGridViewContext];
if (model == null) return;
setState(() {
_hitIndexs = model.firstGroupChildList.map((e) => e.index).toList();
});
debugPrint(
'firstGroupChildList -- ${model.firstGroupChildList.map((e) => e.index)}');
debugPrint('displaying -- ${model.displayingChildIndexList}');
},
child: _buildGridView(),
),
floatingActionButton: FloatingActionButton(
child: const Icon(Icons.airline_stops_outlined),
onPressed: () {
if (_sliverGridViewContext != null) {
SnackBarUtil.showSnackBar(
context: context,
text: 'Jump to item 87',
);
observerController.jumpTo(
index: 87,
sliverContext: _sliverGridViewContext,
padding: _padding,
);
}
// observerController.jumpTo(
// index: 87,
// );
// observerController.animateTo(
// index: 49,
// duration: const Duration(seconds: 1),
// curve: Curves.ease,
// );
},
),
);
}
Widget _buildGridView() {
return GridView.builder(
scrollDirection: Axis.horizontal,
padding: const EdgeInsets.only(
left: _leadingPadding,
right: _trailingPadding,
),
controller: scrollController,
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 4,
crossAxisSpacing: 2,
mainAxisSpacing: 5,
),
itemBuilder: (context, index) {
if (_sliverGridViewContext != context) {
_sliverGridViewContext = context;
}
return Container(
color: (_hitIndexs.contains(index)) ? Colors.red : Colors.blue[100],
child: Center(
child: Text('index -- $index'),
),
);
},
itemCount: 100,
cacheExtent: double.maxFinite,
);
}
}
================================================
FILE: example/lib/features/gridview/sliver_grid_demo/sliver_grid_demo_page.dart
================================================
/*
* @Author: LinXunFeng linxunfeng@yeah.net
* @Repo: https://github.com/LinXunFeng/flutter_scrollview_observer
* @Date: 2022-08-08 00:20:03
*/
import 'package:flutter/material.dart';
import 'package:scrollview_observer/scrollview_observer.dart';
import 'package:scrollview_observer_example/typedefs.dart';
class SliverGridViewDemoPage extends StatefulWidget {
const SliverGridViewDemoPage({Key? key}) : super(key: key);
@override
State<SliverGridViewDemoPage> createState() => _SliverGridViewDemoPageState();
}
class _SliverGridViewDemoPageState extends State<SliverGridViewDemoPage> {
BuildContext? _sliverGridViewContext1;
BuildContext? _sliverGridViewContext2;
List<int> _hitIndexs1 = [];
List<int> _hitIndexs2 = [];
@override
void initState() {
super.initState();
// Trigger an observation manually
ambiguate(WidgetsBinding.instance)?.addPostFrameCallback((timeStamp) {
GridViewOnceObserveNotification().dispatch(_sliverGridViewContext1);
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text("GridView")),
body: GridViewObserver(
sliverGridContexts: () {
return [
if (_sliverGridViewContext1 != null) _sliverGridViewContext1!,
if (_sliverGridViewContext2 != null) _sliverGridViewContext2!
];
},
onObserveAll: (resultMap) {
final model1 = resultMap[_sliverGridViewContext1];
if (model1 != null && model1.visible) {
setState(() {
_hitIndexs1 =
model1.firstGroupChildList.map((e) => e.index).toList();
});
debugPrint(
'1 -- firstGroupChildList -- ${model1.firstGroupChildList.map((e) => e.index)}');
debugPrint('1 -- displaying -- ${model1.displayingChildIndexList}');
}
final model2 = resultMap[_sliverGridViewContext2];
if (model2 != null && model2.visible) {
setState(() {
_hitIndexs2 =
model2.firstGroupChildList.map((e) => e.index).toList();
});
debugPrint(
'2 -- firstGroupChildList -- ${model2.firstGroupChildList.map((e) => e.index)}');
debugPrint('2 -- displaying -- ${model2.displayingChildIndexList}');
}
},
child: _buildGridView(),
),
);
}
Widget _buildGridView() {
return CustomScrollView(
slivers: [
_buildSliverGridView1(),
_buildSliverGridView2(),
],
);
}
Widget _buildSliverGridView1() {
return SliverGrid(
delegate: SliverChildBuilderDelegate(
(context, index) {
if (_sliverGridViewContext1 != context) {
_sliverGridViewContext1 = context;
}
return Container(
color:
(_hitIndexs1.contains(index)) ? Colors.red : Colors.blue[100],
child: Center(
child: Text('index -- $index'),
),
);
},
childCount: 50,
),
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
crossAxisSpacing: 2,
mainAxisSpacing: 5,
),
);
}
Widget _buildSliverGridView2() {
return SliverGrid(
delegate: SliverChildBuilderDelegate(
(context, index) {
if (_sliverGridViewContext2 != context) {
_sliverGridViewContext2 = context;
}
return Container(
color:
(_hitIndexs2.contains(index)) ? Colors.red : Colors.blue[100],
child: Center(
child: Text('index -- $index'),
),
);
},
childCount: 50,
),
gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 140.0,
childAspectRatio: 0.6,
crossAxisSpacing: 2,
mainAxisSpacing: 5,
),
);
}
}
================================================
FILE: example/lib/features/home/home_page.dart
================================================
/*
* @Author: LinXunFeng linxunfeng@yeah.net
* @Repo: https://github.com/LinXunFeng/flutter_scrollview_observer
* @Date: 2022-08-08 00:20:03
*/
import 'package:flutter/material.dart';
import 'package:scrollview_observer_example/common/route/route.dart';
class HomePage extends StatelessWidget {
const HomePage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text("ScrollView Observer Example")),
body: _buildListView(),
);
}
Widget _buildListView() {
return ListView(
children: [
ListTile(
title: const Text("ListView"),
onTap: () {
NavigationService.push(MyPage.listView);
},
),
ListTile(
title: const Text("ListView - Context"),
onTap: () {
NavigationService.push(MyPage.listViewContext);
},
),
ListTile(
title: const Text("ListView - Fixed Height"),
onTap: () {
NavigationService.push(MyPage.listViewFixedHeight);
},
),
ListTile(
title: const Text("ListView - Horizontal"),
onTap: () {
NavigationService.push(MyPage.listViewHorizontal);
},
),
ListTile(
title: const Text("ListView - Dynamic Offset"),
onTap: () {
NavigationService.push(MyPage.listViewDynamicOffset);
},
),
ListTile(
title: const Text("ListView - Custom"),
onTap: () {
NavigationService.push(MyPage.listViewCustom);
},
),
ListTile(
title: const Text("ListView - Infinite"),
onTap: () {
NavigationService.push(MyPage.listViewInfinite);
},
),
ListTile(
title: const Text("SliverListView"),
onTap: () {
NavigationService.push(MyPage.sliverListView);
},
),
ListTile(
title: const Text("GridView"),
onTap: () {
NavigationService.push(MyPage.gridView);
},
),
ListTile(
title: const Text("GridView - Context"),
onTap: () {
NavigationService.push(MyPage.gridViewContext);
},
),
ListTile(
title: const Text("GridView - Fixed Height"),
onTap: () {
NavigationService.push(MyPage.gridViewFixedHeight);
},
),
ListTile(
title: const Text("GridView - Horizontal"),
onTap: () {
NavigationService.push(MyPage.gridViewHorizontal);
},
),
ListTile(
title: const Text("GridView - Custom"),
onTap: () {
NavigationService.push(MyPage.gridViewCustom);
},
),
ListTile(
title: const Text("SliverGridView"),
onTap: () {
NavigationService.push(MyPage.sliverGridView);
},
),
ListTile(
title: const Text("CustomScrollView"),
onTap: () {
NavigationService.push(MyPage.customScrollView);
},
),
ListTile(
title: const Text("CustomScrollView - Center"),
onTap: () {
NavigationService.push(MyPage.customScrollViewCenter);
},
),
ListTile(
title: const Text("MultiSliver"),
onTap: () {
NavigationService.push(MyPage.multiSliver);
},
),
ListTile(
title: const Text("SliverAppBar"),
onTap: () {
NavigationService.push(MyPage.sliverAppBar);
},
),
ListTile(
title: const Text("NestedScrollView"),
onTap: () {
NavigationService.push(MyPage.nestedScrollView);
},
),
ListTile(
title: const Text("NestedScrollView - TabBarView"),
onTap: () {
NavigationService.push(MyPage.nestedScrollViewTabBarView);
},
),
ListTile(
title: const Text("PageView"),
onTap: () {
NavigationService.push(MyPage.pageView);
},
),
ListTile(
title: const Text("PageView - Parallax"),
onTap: () {
NavigationService.push(MyPage.pageViewParallax);
},
),
ListTile(
title: const Text("PageView - Parallax ItemListener"),
onTap: () {
NavigationService.push(MyPage.pageViewParallaxItemListener);
},
),
ListTile(
title: const Text("VideoList AutoPlay"),
onTap: () {
NavigationService.push(MyPage.videoListAutoPlay);
},
),
ListTile(
title: const Text("AnchorList"),
onTap: () {
NavigationService.push(MyPage.anchorList);
},
),
ListTile(
title: const Text("AnchorWaterfall"),
onTap: () {
NavigationService.push(MyPage.anchorWaterfall);
},
),
ListTile(
title: const Text("ImageTab"),
onTap: () {
NavigationService.push(MyPage.imageTab);
},
),
ListTile(
title: const Text("Chat"),
onTap: () {
NavigationService.push(MyPage.chat);
},
),
ListTile(
title: const Text("ChatGPT"),
onTap: () {
NavigationService.push(MyPage.chatGPT);
},
),
ListTile(
title: const Text("Waterfall Flow"),
onTap: () {
NavigationService.push(MyPage.waterfallFlow);
},
),
ListTile(
title: const Text("Waterfall Flow - Fixed Height"),
onTap: () {
NavigationService.push(MyPage.waterfallFlowFixedHeight);
},
),
ListTile(
title: const Text("ScrollView Form"),
onTap: () {
NavigationService.push(MyPage.scrollViewForm);
},
),
ListTile(
title: const Text("Visibility ListView"),
onTap: () {
NavigationService.push(MyPage.visibilityListView);
},
),
ListTile(
title: const Text("Visibility ScrollView"),
onTap: () {
NavigationService.push(MyPage.visibilityScrollView);
},
),
ListTile(
title: const Text("AzList"),
onTap: () {
NavigationService.push(MyPage.azList);
},
),
ListTile(
title: const Text("Expandable Carousel Slider"),
onTap: () {
NavigationService.push(MyPage.expandableCarouselSlider);
},
),
ListTile(
title: const Text("Detail Page"),
onTap: () {
NavigationService.push(MyPage.detail);
},
),
],
);
}
}
================================================
FILE: example/lib/features/listview/horizontal_listview_demo/horizontal_listview_page.dart
================================================
/*
* @Author: LinXunFeng linxunfeng@yeah.net
* @Repo: https://github.com/LinXunFeng/flutter_scrollview_observer
* @Date: 2022-08-08 00:20:03
*/
import 'package:flutter/material.dart';
import 'package:scrollview_observer/scrollview_observer.dart';
import 'package:scrollview_observer_example/typedefs.dart';
class HorizontalListViewPage extends StatefulWidget {
const HorizontalListViewPage({Key? key}) : super(key: key);
@override
State<HorizontalListViewPage> createState() => _HorizontalListViewPageState();
}
class _HorizontalListViewPageState extends State<HorizontalListViewPage> {
BuildContext? _sliverListViewContext;
int _hitIndex = 0;
@override
void initState() {
super.initState();
// Trigger an observation manually
ambiguate(WidgetsBinding.instance)?.addPostFrameCallback((timeStamp) {
ListViewOnceObserveNotification().dispatch(_sliverListViewContext);
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text("ListView")),
body: ListViewObserver(
child: _buildListView(),
sliverListContexts: () {
return [if (_sliverListViewContext != null) _sliverListViewContext!];
},
onObserveAll: (resultMap) {
final model = resultMap[_sliverListViewContext];
if (model == null) return;
debugPrint('firstChild.index -- ${model.firstChild?.index ?? 0}');
debugPrint('displaying -- ${model.displayingChildIndexList}');
setState(() {
_hitIndex = model.firstChild?.index ?? 0;
});
},
),
);
}
ListView _buildListView() {
return ListView.separated(
itemBuilder: (ctx, index) {
if (_sliverListViewContext != ctx) {
_sliverListViewContext = ctx;
}
return _buildListItemView(index);
},
separatorBuilder: (ctx, index) {
return _buildSeparatorView();
},
itemCount: 50,
scrollDirection: Axis.horizontal,
);
}
Widget _buildListItemView(int index) {
return Container(
width: (index % 2 == 0) ? 180 : 150,
color: _hitIndex == index ? Colors.red : Colors.black12,
child: Center(
child: Text(
"index -- $index",
style: TextStyle(
color: _hitIndex == index ? Colors.white : Colors.black,
),
),
),
);
}
Container _buildSeparatorView() {
return Container(
color: Colors.white,
width: 5,
);
}
}
================================================
FILE: example/lib/features/listview/infinite_listview_demo/infinite_listview_page.dart
================================================
/*
* @Author: LinXunFeng linxunfeng@yeah.net
* @Repo: https://github.com/fluttercandies/flutter_scrollview_observer
* @Date: 2023-12-31 14:00:51
*/
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:scrollview_observer/scrollview_observer.dart';
class InfiniteListViewPage extends StatefulWidget {
const InfiniteListViewPage({Key? key}) : super(key: key);
@override
State<InfiniteListViewPage> createState() => _InfiniteListViewPageState();
}
class _InfiniteListViewPageState extends State<InfiniteListViewPage> {
List<int> dataSource = [];
bool isLoadingForHeader = false;
bool isLoadingForFooter = false;
final double itemMinHeight = 50;
final double itemMaxHeight = 150;
final Random _random = Random();
double get randomItemHeight =>
itemMinHeight + _random.nextInt((itemMaxHeight - itemMinHeight).toInt());
List<double> itemHeights = [];
int generateCount = 20;
ScrollController scrollController = ScrollController();
late ListObserverController observerController;
late ChatScrollObserver chatObserver;
handleLoadMoreForHeader() async {
if (isLoadingForHeader) return; // loading
isLoadingForHeader = true;
int initIndex = 0;
if (dataSource.isNotEmpty) {
initIndex = dataSource.first;
}
await Future.delayed(const Duration(milliseconds: 100));
dataSource.insertAll(
0,
List.generate(generateCount, (index) {
return initIndex - (generateCount - index);
}),
);
itemHeights.insertAll(
0,
List.generate(generateCount, (_) => randomItemHeight),
);
// Keeping position
chatObserver.standby(changeCount: generateCount);
// Clearing the offset cache
observerController.clearScrollIndexCache();
setState(() {});
isLoadingForHeader = false;
}
handleLoadMoreForFooter() async {
if (isLoadingForFooter) return; // loading
isLoadingForFooter = true;
int initIndex = 0;
if (dataSource.isNotEmpty) {
initIndex = dataSource.last;
}
await Future.delayed(const Duration(milliseconds: 100));
setState(() {
dataSource.addAll(
List.generate(generateCount, (index) => index + initIndex + 1),
);
itemHeights.addAll(
List.generate(generateCount, (_) => randomItemHeight),
);
});
isLoadingForFooter = false;
}
@override
void initState() {
super.initState();
observerController = ListObserverController(controller: scrollController)
..initialIndex = generateCount ~/ 2;
chatObserver = ChatScrollObserver(observerController)
..fixedPositionOffset = -double.maxFinite
..toRebuildScrollViewCallback = () {
setState(() {});
};
dataSource = List.generate(generateCount, (index) => index);
itemHeights = List.generate(generateCount, (_) => randomItemHeight);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text("ListView")),
body: ListViewObserver(
controller: observerController,
triggerOnObserveType: ObserverTriggerOnObserveType.directly,
child: _buildListView(),
onObserve: (result) {
debugPrint(
'displaying -- ${result.displayingChildIndexList.map((i) => dataSource[i])}');
if (result.firstChild?.index == 0) {
final firstChildLeadingMarginToViewport =
result.firstChild?.leadingMarginToViewport ?? 0;
if (firstChildLeadingMarginToViewport > -100) {
handleLoadMoreForHeader();
}
} else if (result.displayingChildIndexList.last ==
dataSource.length - 1) {
final lastChildTrailingMarginToViewport =
result.displayingChildModelList.last.trailingMarginToViewport;
if (lastChildTrailingMarginToViewport < 100) {
handleLoadMoreForFooter();
}
}
},
),
);
}
Widget _buildListView() {
return ListView.separated(
physics: ChatObserverClampingScrollPhysics(observer: chatObserver),
padding: EdgeInsets.zero,
controller: scrollController,
itemBuilder: (ctx, index) {
return _buildListItemView(index);
},
separatorBuilder: (ctx, index) {
return _buildSeparatorView();
},
itemCount: dataSource.length,
// Ensure that the reference item can be found when keeping position.
cacheExtent: itemMaxHeight * (generateCount + 2),
);
}
Widget _buildListItemView(int index) {
return Container(
height: itemHeights[index],
color: index % 2 == 0 ? Colors.black26 : Colors.black12,
child: Center(
child: Text(
"index -- ${dataSource[index]}",
style: const TextStyle(
color: Colors.black,
),
),
),
);
}
Widget _buildSeparatorView() {
return Container(
color: Colors.white,
width: 5,
);
}
}
================================================
FILE: example/lib/features/listview/listview_ctx_demo/listview_ctx_demo_page.dart
================================================
/*
* @Author: LinXunFeng linxunfeng@yeah.net
* @Repo: https://github.com/LinXunFeng/flutter_scrollview_observer
* @Date: 2022-08-08 00:20:03
*/
import 'package:flutter/material.dart';
import 'package:scrollview_observer/scrollview_observer.dart';
import 'package:scrollview_observer_example/typedefs.dart';
class ListViewCtxDemoPage extends StatefulWidget {
const ListViewCtxDemoPage({Key? key}) : super(key: key);
@override
State<ListViewCtxDemoPage> createState() => _ListViewCtxDemoPageState();
}
class _ListViewCtxDemoPageState extends State<ListViewCtxDemoPage> {
BuildContext? _sliverListViewContext;
int _hitIndex = 0;
@override
void initState() {
super.initState();
// Trigger an observation manually
ambiguate(WidgetsBinding.instance)?.addPostFrameCallback((timeStamp) {
ListViewOnceObserveNotification().dispatch(_sliverListViewContext);
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text("ListView")),
body: ListViewObserver(
child: _buildListView(),
sliverListContexts: () {
return [if (_sliverListViewContext != null) _sliverListViewContext!];
},
onObserveAll: (resultMap) {
final model = resultMap[_sliverListViewContext];
if (model == null) return;
debugPrint('visible -- ${model.visible}');
debugPrint('firstChild.index -- ${model.firstChild?.index}');
debugPrint('displaying -- ${model.displayingChildIndexList}');
setState(() {
_hitIndex = model.firstChild?.index ?? 0;
});
},
),
);
}
ListView _buildListView() {
// return ListView.builder(
// padding: EdgeInsets.zero,
// itemCount: 200,
// itemBuilder: (ctx, index) {
// if (_sliverListViewContext != ctx) {
// _sliverListViewContext = ctx;
// }
// return _buildListItemView(index);
// },
// );
return ListView.separated(
padding: const EdgeInsets.only(top: 1000, bottom: 1000),
controller: ScrollController(initialScrollOffset: 1000),
itemBuilder: (ctx, index) {
if (_sliverListViewContext != ctx) {
_sliverListViewContext = ctx;
}
return _buildListItemView(index);
},
separatorBuilder: (ctx, index) {
return _buildSeparatorView();
},
itemCount: 50,
);
}
Widget _buildListItemView(int index) {
return Container(
height: (index % 2 == 0) ? 80 : 50,
color: _hitIndex == index ? Colors.red : Colors.black12,
child: Center(
child: Text(
"index -- $index",
style: TextStyle(
color: _hitIndex == index ? Colors.white : Colors.black,
),
),
),
);
}
Container _buildSeparatorView() {
return Container(
color: Colors.white,
height: 5,
);
}
}
================================================
FILE: example/lib/features/listview/listview_custom_demo/listview_custom_demo_page.dart
================================================
/*
* @Author: LinXunFeng linxunfeng@yeah.net
* @Repo: https://github.com/LinXunFeng/flutter_scrollview_observer
* @Date: 2023-05-21 10:31:44
*/
// ignore: implementation_imports
import 'package:extended_list/src/rendering/sliver_list.dart';
import 'package:flutter/material.dart';
import 'package:loading_more_list/loading_more_list.dart';
import 'package:scrollview_observer/scrollview_observer.dart';
import 'package:scrollview_observer_example/utils/snackbar.dart';
class ListViewCustomDemoPage extends StatefulWidget {
const ListViewCustomDemoPage({Key? key}) : super(key: key);
@override
State<ListViewCustomDemoPage> createState() => _ListViewCustomDemoPageState();
}
class _ListViewCustomDemoPageState extends State<ListViewCustomDemoPage> {
ScrollController scrollController = ScrollController();
late ListObserverController observerController;
@override
void initState() {
observerController = ListObserverController(
controller: scrollController,
);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Custom')),
body: ListViewObserver(
child: _buildListView(),
controller: observerController,
customTargetRenderSliverType: (renderObj) {
// Here you tell the package what type of RenderObject it needs to observe.
return renderObj is ExtendedRenderSliverList;
},
// customHandleObserve: (context) {
// // Here you can customize the observation logic.
// return ObserverCore.handleListObserve(
// context: context,
// fetchLeadingOffset: () => 100,
// );
// },
onObserve: (resultModel) {
debugPrint('firstChild.index -- ${resultModel.firstChild?.index}');
debugPrint('displaying -- ${resultModel.displayingChildIndexList}');
},
),
floatingActionButton: FloatingActionButton(
child: const Icon(Icons.airline_stops_sharp),
onPressed: () {
SnackBarUtil.showSnackBar(
context: context,
text: 'Jump to row 10',
);
observerController.jumpTo(
index: 10,
isFixedHeight: true,
);
},
),
);
}
Widget _buildListView() {
return LoadingMoreList(
ListConfig(
controller: scrollController,
itemBuilder: (context, item, index) {
if (scrollController.hasClients &&
(observerController.sliverContexts.isEmpty ||
observerController.sliverContexts.first != context)) {
observerController.reattach();
}
return ListTile(
title: Text('index - $index'),
);
},
sourceList: SourceList(),
),
);
}
}
class SourceList extends LoadingMoreBase<int> {
@override
Future<bool> loadData([bool isloadMoreAction = false]) async {
await Future.delayed(const Duration(seconds: 2));
for (var i = 0; i < 30; i++) {
add(i);
}
return true;
}
}
================================================
FILE: example/lib/features/listview/listview_demo/listview_demo_page.dart
================================================
/*
* @Author: LinXunFeng linxunfeng@yeah.net
* @Repo: https://github.com/LinXunFeng/flutter_scrollview_observer
* @Date: 2022-08-08 00:20:03
*/
import 'package:flutter/material.dart';
import 'package:scrollview_observer/scrollview_observer.dart';
import 'package:scrollview_observer_example/typedefs.dart';
import 'package:scrollview_observer_example/utils/snackbar.dart';
class ListViewDemoPage extends StatefulWidget {
const ListViewDemoPage({Key? key}) : super(key: key);
@override
State<ListViewDemoPage> createState() => _ListViewDemoPageState();
}
class _ListViewDemoPageState extends State<ListViewDemoPage> {
static const double _leadingPadding = 1000;
static const double _trailingPadding = 2000;
static const EdgeInsets _padding = EdgeInsets.only(
top: _leadingPadding,
bottom: _trailingPadding,
);
int _hitIndex = 0;
ScrollController scrollController =
ScrollController(initialScrollOffset: _leadingPadding);
late ListObserverController observerController;
@override
void initState() {
super.initState();
observerController = ListObserverController(controller: scrollController)
..initialIndexModel = ObserverIndexPositionModel(
index: 10,
padding: _padding,
);
// Trigger an observation manually
ambiguate(WidgetsBinding.instance)?.endOfFrame.then(
(_) {
// After layout
if (mounted) {
observerController.dispatchOnceObserve();
}
},
);
}
@override
void dispose() {
observerController.controller?.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text("ListView")),
body: ListViewObserver(
child: _buildListView(),
autoTriggerObserveTypes: const [
ObserverAutoTriggerObserveType.scrollEnd,
],
triggerOnObserveType: ObserverTriggerOnObserveType.directly,
controller: observerController,
onObserve: (resultModel) {
debugPrint('visible -- ${resultModel.visible}');
debugPrint('firstChild.index -- ${resultModel.firstChild?.index}');
debugPrint('displaying -- ${resultModel.displayingChildIndexList}');
for (var item in resultModel.displayingChildModelList) {
debugPrint(
'item - ${item.index} - ${item.leadingMarginToViewport} - ${item.trailingMarginToViewport}');
}
setState(() {
_hitIndex = resultModel.firstChild?.index ?? 0;
});
},
),
floatingActionButton: FloatingActionButton(
child: const Icon(Icons.airline_stops_outlined),
onPressed: () {
SnackBarUtil.showSnackBar(
context: context,
text: 'Jump to row 50',
);
observerController.jumpTo(
index: 50,
padding: _padding,
);
// observerController.animateTo(
// index: 50,
// duration: const Duration(seconds: 1),
// curve: Curves.ease,
// padding: _padding,
// );
},
),
);
}
ListView _buildListView() {
// return ListView.builder(
// itemExtent: 50,
// controller: scrollController,
// itemCount: 100,
// itemBuilder: (context, index) {
// return _buildListItemView(index);
// },
// );
return ListView.separated(
padding: _padding,
controller: scrollController,
itemBuilder: (ctx, index) {
return _buildListItemView(index);
},
separatorBuilder: (ctx, index) {
return _buildSeparatorView();
},
itemCount: 100,
cacheExtent: double.maxFinite,
);
}
Widget _buildListItemView(int index) {
return Container(
height: (index % 2 == 0) ? 80 : 50,
color: _hitIndex == index ? Colors.red : Colors.black12,
child: Center(
child: Text(
"index -- $index",
style: TextStyle(
color: _hitIndex == index ? Colors.white : Colors.black,
),
),
),
);
}
Container _buildSeparatorView() {
return Container(
color: Colors.white,
height: 5,
);
}
}
================================================
FILE: example/lib/features/listview/listview_dynamic_offset/listview_dynamic_offset_page.dart
================================================
/*
* @Author: LinXunFeng linxunfeng@yeah.net
* @Repo: https://github.com/LinXunFeng/flutter_scrollview_observer
* @Date: 2022-08-08 00:20:03
*/
import 'package:flutter/material.dart';
import 'package:scrollview_observer/scrollview_observer.dart';
import 'package:scrollview_observer_example/typedefs.dart';
class ListViewDynamicOffsetPage extends StatefulWidget {
const ListViewDynamicOffsetPage({Key? key}) : super(key: key);
@override
State<ListViewDynamicOffsetPage> createState() =>
_ListViewDynamicOffsetPageState();
}
class _ListViewDynamicOffsetPageState extends State<ListViewDynamicOffsetPage> {
BuildContext? _sliverListViewContext;
int _hitIndex = 0;
double _safeAreaPaddingTop = 0;
final double _navContentHeight = 44;
double _navBgAlpha = 0;
bool _isShowNavTitle = false;
final ScrollController _pageController = ScrollController();
@override
void initState() {
super.initState();
_pageController.addListener(_pageDidScroll);
ambiguate(WidgetsBinding.instance)?.addPostFrameCallback((timeStamp) {
_safeAreaPaddingTop = MediaQuery.of(context).padding.top;
// Trigger an observation manually
ListViewOnceObserveNotification().dispatch(_sliverListViewContext);
});
}
@override
void dispose() {
_pageController.removeListener(_pageDidScroll);
_pageController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: [
ListViewObserver(
child: _buildListView(),
sliverListContexts: () {
return [
if (_sliverListViewContext != null) _sliverListViewContext!
];
},
dynamicLeadingOffset: () {
if (_navBgAlpha < 1) {
return 0;
}
return _safeAreaPaddingTop + _navContentHeight;
},
onObserveAll: (resultMap) {
final model = resultMap[_sliverListViewContext];
if (model == null) return;
debugPrint('firstChild.index -- ${model.firstChild?.index}');
debugPrint('displaying -- ${model.displayingChildIndexList}');
setState(() {
_hitIndex = model.firstChild?.index ?? 0;
});
},
),
Container(
color: Colors.grey.withValues(alpha: _navBgAlpha),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
SafeArea(
bottom: false,
child: _buildNavContentWidget(context),
)
],
),
),
],
),
);
}
ListView _buildListView() {
return ListView.separated(
controller: _pageController,
padding: EdgeInsets.zero,
itemBuilder: (ctx, index) {
if (_sliverListViewContext != ctx) {
_sliverListViewContext = ctx;
}
return _buildListItemView(index);
},
separatorBuilder: (ctx, index) {
return _buildSeparatorView();
},
itemCount: 50,
);
}
Widget _buildListItemView(int index) {
return Container(
height: (index % 2 == 0) ? 80 : 50,
color: _hitIndex == index ? Colors.red : Colors.black12,
child: Center(
child: Text(
"index -- $index",
style: TextStyle(
color: _hitIndex == index ? Colors.white : Colors.black,
),
),
),
);
}
Container _buildSeparatorView() {
return Container(
color: Colors.white,
height: 5,
);
}
Widget _buildNavContentWidget(BuildContext context) {
return Container(
height: _navContentHeight,
padding: const EdgeInsets.symmetric(horizontal: 15),
child: Row(
children: [
GestureDetector(
child: Icon(
Icons.arrow_back_ios,
color: _isShowNavTitle ? Colors.black : Colors.white,
),
onTap: () {
Navigator.of(context).pop();
},
),
Expanded(
child: Center(
child: Text(
"ListView Dynnamic Offset",
style: TextStyle(
fontSize: 17,
fontWeight: FontWeight.bold,
color: Colors.black54.withValues(
alpha: _isShowNavTitle ? 1 : 0,
),
),
),
),
),
],
),
);
}
void _pageDidScroll() {
final offset = _pageController.offset;
double _newNavBgAlpha = 0;
if (offset < 0) {
_newNavBgAlpha = 0;
} else if (offset >= _navContentHeight) {
_newNavBgAlpha = 1;
} else {
_newNavBgAlpha = offset / _navContentHeight;
}
if (_navBgAlpha != _newNavBgAlpha) {
setState(() {
_navBgAlpha = _newNavBgAlpha;
_isShowNavTitle = _navBgAlpha > .5;
});
}
}
}
================================================
FILE: example/lib/features/listview/listview_fixed_height_demo/listview_fixed_height_demo_page.dart
================================================
/*
* @Author: LinXunFeng linxunfeng@yeah.net
* @Repo: https://github.com/LinXunFeng/flutter_scrollview_observer
* @Date: 2022-08-08 00:20:03
*/
import 'package:flutter/material.dart';
import 'package:scrollview_observer/scrollview_observer.dart';
import 'package:scrollview_observer_example/typedefs.dart';
import 'package:scrollview_observer_example/utils/snackbar.dart';
class ListViewFixedHeightDemoPage extends StatefulWidget {
const ListViewFixedHeightDemoPage({Key? key}) : super(key: key);
@override
State<ListViewFixedHeightDemoPage> createState() =>
_ListViewFixedHeightDemoPageState();
}
class _ListViewFixedHeightDemoPageState
extends State<ListViewFixedHeightDemoPage> {
int _hitIndex = 0;
ScrollController scrollController =
ScrollController(initialScrollOffset: 1000);
late ListObserverController observerController;
@override
void initState() {
super.initState();
observerController = ListObserverController(controller: scrollController)
..initialIndexModel = ObserverIndexPositionModel(
index: 3,
isFixedHeight: true,
);
// Trigger an observation manually
ambiguate(WidgetsBinding.instance)?.endOfFrame.then(
(_) {
// After layout
if (mounted) {
observerController.dispatchOnceObserve();
}
},
);
}
@override
void dispose() {
observerController.controller?.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text("ListView")),
body: ListViewObserver(
child: _buildListView(),
controller: observerController,
onObserve: (resultModel) {
// print('visible -- ${resultModel.visible}');
// print('firstChild.index -- ${resultModel.firstChild?.index}');
// print('displaying -- ${resultModel.displayingChildIndexList}');
// print(
// 'leadingAxisMarginToViewport1 -- ${resultModel.firstChild?.leadingAxisMarginToViewport}');
// print(
// 'leadingAxisMarginToViewport2 -- ${resultModel.displayingChildModelList.last.leadingAxisMarginToViewport}');
// print(
// 'trailingAxisMarginToViewport1 -- ${resultModel.firstChild?.trailingAxisMarginToViewport}');
// print(
// 'trailingAxisMarginToViewport2 -- ${resultModel.displayingChildModelList.last.trailingAxisMarginToViewport}');
for (var item in resultModel.displayingChildModelList) {
debugPrint(
'item - ${item.index} - ${item.leadingMarginToViewport} - ${item.trailingMarginToViewport}');
}
setState(() {
_hitIndex = resultModel.firstChild?.index ?? 0;
});
},
),
floatingActionButton: FloatingActionButton(
child: const Icon(Icons.airline_stops_outlined),
onPressed: () {
SnackBarUtil.showSnackBar(
context: context,
text: 'Jump to row 100',
);
observerController.jumpTo(index: 100, isFixedHeight: true);
// observerController.animateTo(
// index: 100,
// isFixedHeight: true,
// duration: const Duration(seconds: 1),
// curve: Curves.ease,
// );
},
),
);
}
ListView _buildListView() {
return ListView.separated(
padding: const EdgeInsets.only(top: 1000, bottom: 1000),
controller: scrollController,
itemBuilder: (ctx, index) {
return _buildListItemView(index);
},
separatorBuilder: (ctx, index) {
return _buildSeparatorView();
},
itemCount: 500,
);
}
Widget _buildListItemView(int index) {
return Container(
height: 80,
color: _hitIndex == index ? Colors.red : Colors.black12,
child: Center(
child: Text(
"index -- $index",
style: TextStyle(
color: _hitIndex == index ? Colors.white : Colors.black,
),
),
),
);
}
Container _buildSeparatorView() {
return Container(
color: Colors.white,
height: 5,
);
}
}
================================================
FILE: example/lib/features/listview/sliver_list_demo/sliver_list_demo_page.dart
================================================
/*
* @Author: LinXunFeng linxunfeng@yeah.net
* @Repo: https://github.com/LinXunFeng/flutter_scrollview_observer
* @Date: 2022-08-08 00:20:03
*/
import 'package:flutter/material.dart';
import 'package:scrollview_observer/scrollview_observer.dart';
import 'package:scrollview_observer_example/typedefs.dart';
class SliverListViewDemoPage extends StatefulWidget {
const SliverListViewDemoPage({Key? key}) : super(key: key);
@override
State<SliverListViewDemoPage> createState() => _SliverListViewDemoPageState();
}
class _SliverListViewDemoPageState extends State<SliverListViewDemoPage> {
BuildContext? _sliverListViewCtx1;
final GlobalKey _sliverListView2Key = GlobalKey();
BuildContext? get _sliverListViewCtx2 => _sliverListView2Key.currentContext;
int _hitIndexForCtx1 = 0;
int _hitIndexForCtx2 = 0;
@override
void initState() {
super.initState();
// Trigger an observation manually
ambiguate(WidgetsBinding.instance)?.addPostFrameCallback((timeStamp) {
ListViewOnceObserveNotification().dispatch(_sliverListViewCtx1);
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text("SliverListView")),
body: ListViewObserver(
child: CustomScrollView(
slivers: [
_buildSliverListView1(),
_buildSliverListView2(),
],
),
sliverListContexts: () {
return [
if (_sliverListViewCtx1 != null) _sliverListViewCtx1!,
if (_sliverListViewCtx2 != null) _sliverListViewCtx2!,
];
},
onObserveAll: (resultMap) {
final model1 = resultMap[_sliverListViewCtx1];
if (model1 != null && model1.visible) {
debugPrint('1 visible -- ${model1.visible}');
debugPrint('1 firstChild.index -- ${model1.firstChild?.index}');
debugPrint('1 displaying -- ${model1.displayingChildIndexList}');
setState(() {
_hitIndexForCtx1 = model1.firstChild?.index ?? 0;
});
}
final model2 = resultMap[_sliverListViewCtx2];
if (model2 != null && model2.visible) {
debugPrint('2 visible -- ${model2.visible}');
debugPrint('2 firstChild.index -- ${model2.firstChild?.index}');
debugPrint('2 displaying -- ${model2.displayingChildIndexList}');
setState(() {
_hitIndexForCtx2 = model2.firstChild?.index ?? 0;
});
}
},
),
);
}
SliverList _buildSliverListView1() {
return SliverList(
delegate: SliverChildBuilderDelegate(
(ctx, index) {
if (_sliverListViewCtx1 != ctx) {
_sliverListViewCtx1 = ctx;
}
return Container(
height: (index % 2 == 0) ? 80 : 50,
color: _hitIndexForCtx1 == index ? Colors.red : Colors.black12,
child: Center(
child: Text(
"index -- $index",
style: TextStyle(
color:
_hitIndexForCtx1 == index ? Colors.white : Colors.black,
),
),
),
);
},
childCount: 30,
),
);
}
SliverList _buildSliverListView2() {
return SliverList(
key: _sliverListView2Key,
delegate: SliverChildBuilderDelegate(
(ctx, index) {
return Container(
height: (index % 2 == 0) ? 80 : 50,
color: _hitIndexForCtx2 == index ? Colors.amber : Colors.blue[50],
child: Center(
child: Text(
"index -- $index",
style: TextStyle(
color:
_hitIndexForCtx2 == index ? Colors.white : Colors.black,
),
),
),
);
},
childCount: 30,
),
);
}
}
================================================
FILE: example/lib/features/nested_scrollview/nested_scrollview_demo/nested_scrollview_demo_page.dart
================================================
/*
* @Author: LinXunFeng linxunfeng@yeah.net
* @Repo: https://github.com/fluttercandies/flutter_scrollview_observer
* @Date: 2023-11-27 22:05:28
*/
import 'package:flutter/material.dart';
import 'package:scrollview_observer/scrollview_observer.dart';
import 'package:scrollview_observer_example/utils/snackbar.dart';
import 'package:scrollview_observer_example/widgets/sliver.dart';
class NestedScrollViewDemoPage extends StatefulWidget {
const NestedScrollViewDemoPage({Key? key}) : super(key: key);
@override
State<NestedScrollViewDemoPage> createState() =>
_NestedScrollViewDemoPageState();
}
class _NestedScrollViewDemoPageState extends State<NestedScrollViewDemoPage>
with TickerProviderStateMixin {
BuildContext? _sliverHeaderListCtx;
BuildContext? _sliverBodyListCtx;
BuildContext? _sliverBodyGridCtx;
GlobalKey nestedScrollViewKey = GlobalKey();
GlobalKey appBarKey = GlobalKey();
GlobalKey tabBarKey = GlobalKey();
final nestedScrollUtil = NestedScrollUtil();
int _hitIndexForListCtx = 0;
List<int> _hitIndexesForGrid = [];
ScrollController outerScrollController = ScrollController();
ScrollController? bodyScrollController;
late SliverObserverController observerController = SliverObserverController(
controller: outerScrollController,
);
late TabController tabBarController = TabController(
length: 3,
vsync: this,
);
bool scrollToWithAnimation = false;
@override
void initState() {
super.initState();
nestedScrollUtil.outerScrollController = outerScrollController;
}
@override
void dispose() {
outerScrollController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SliverViewObserver(
controller: observerController,
child: _buildNestedScrollView(),
sliverContexts: () {
return [
if (_sliverHeaderListCtx != null) _sliverHeaderListCtx!,
if (_sliverBodyListCtx != null) _sliverBodyListCtx!,
if (_sliverBodyGridCtx != null) _sliverBodyGridCtx!,
];
},
customOverlap: (sliverContext) {
return nestedScrollUtil.calcOverlap(
nestedScrollViewKey: nestedScrollViewKey,
sliverContext: sliverContext,
);
},
onObserveAll: (result) {
result.forEach((key, value) {
if (key == _sliverHeaderListCtx) {
debugPrint(
"SliverListHeaderCtx: ${value.displayingChildIndexList}");
} else if (key == _sliverBodyListCtx) {
final model = value as ListViewObserveModel;
debugPrint("SliverListCtx: ${model.displayingChildIndexList}");
if (_hitIndexForListCtx != model.firstChild?.index) {
_hitIndexForListCtx = model.firstChild?.index ?? 0;
setState(() {});
}
} else if (key == _sliverBodyGridCtx) {
final model = value as GridViewObserveModel;
debugPrint("SliverGridCtx: ${model.displayingChildIndexList}");
final firstGroupChildIndexList =
model.firstGroupChildList.map((e) => e.index).toList();
if (_hitIndexesForGrid != firstGroupChildIndexList) {
_hitIndexesForGrid = firstGroupChildIndexList;
setState(() {});
}
}
});
},
),
floatingActionButton: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
IconButton(
icon: const Icon(Icons.list_alt_rounded),
onPressed: () {
scrollTo(
position: NestedScrollUtilPosition.header,
index: 1,
sliverContext: _sliverHeaderListCtx,
);
SnackBarUtil.showSnackBar(
context: context,
text: 'Header - SliverList - Scrolling to item 1',
);
},
),
IconButton(
icon: const Icon(Icons.list_rounded),
onPressed: () {
scrollTo(
position: NestedScrollUtilPosition.body,
index: 1,
sliverContext: _sliverBodyListCtx,
);
SnackBarUtil.showSnackBar(
context: context,
text: 'Body - SliverList - Scrolling to item 1',
);
},
),
IconButton(
icon: const Icon(Icons.grid_view),
onPressed: () {
scrollTo(
position: NestedScrollUtilPosition.body,
index: 5,
sliverContext: _sliverBodyGridCtx,
);
SnackBarUtil.showSnackBar(
context: context,
text: 'Body - SliverGrid - Scrolling to item 5',
);
},
),
IconButton(
icon: const Icon(Icons.restore_outlined),
onPressed: resetAllSliverObservationData,
)
],
),
);
}
Widget _buildNestedScrollView() {
return NestedScrollView(
key: nestedScrollViewKey,
controller: outerScrollController,
headerSliverBuilder: (context, innerBoxIsScrolled) {
return [
SliverAppBar(
key: appBarKey,
title: const Text("NestedScrollView"),
pinned: true,
forceElevated: innerBoxIsScrolled,
actions: [
Switch(
value: scrollToWithAnimation,
onChanged: ((value) {
scrollToWithAnimation = value;
setState(() {});
SnackBarUtil.showSnackBar(
context: context,
text: "Scroll to with animation: $scrollToWithAnimation",
);
gitextract_0cpp3x9p/
├── .github/
│ ├── FUNDING.yml
│ └── workflows/
│ ├── assign-issue.yml
│ ├── code-analysis.yml
│ └── deploy.yml
├── .gitignore
├── .packages
├── CHANGELOG.md
├── CODEOWNERS
├── LICENSE
├── README-zh.md
├── README.md
├── analysis_options.yaml
├── example/
│ ├── .gitignore
│ ├── .metadata
│ ├── README.md
│ ├── analysis_options.yaml
│ ├── android/
│ │ ├── .gitignore
│ │ ├── app/
│ │ │ ├── build.gradle
│ │ │ └── src/
│ │ │ ├── debug/
│ │ │ │ └── AndroidManifest.xml
│ │ │ ├── main/
│ │ │ │ ├── AndroidManifest.xml
│ │ │ │ ├── kotlin/
│ │ │ │ │ └── com/
│ │ │ │ │ └── example/
│ │ │ │ │ └── example/
│ │ │ │ │ └── MainActivity.kt
│ │ │ │ └── res/
│ │ │ │ ├── drawable/
│ │ │ │ │ └── launch_background.xml
│ │ │ │ ├── drawable-v21/
│ │ │ │ │ └── launch_background.xml
│ │ │ │ ├── values/
│ │ │ │ │ └── styles.xml
│ │ │ │ └── values-night/
│ │ │ │ └── styles.xml
│ │ │ └── profile/
│ │ │ └── AndroidManifest.xml
│ │ ├── build.gradle
│ │ ├── gradle/
│ │ │ └── wrapper/
│ │ │ └── gradle-wrapper.properties
│ │ ├── gradle.properties
│ │ └── settings.gradle
│ ├── ios/
│ │ ├── .gitignore
│ │ ├── Flutter/
│ │ │ ├── AppFrameworkInfo.plist
│ │ │ ├── Debug.xcconfig
│ │ │ └── Release.xcconfig
│ │ ├── Podfile
│ │ ├── Runner/
│ │ │ ├── AppDelegate.swift
│ │ │ ├── Assets.xcassets/
│ │ │ │ ├── AppIcon.appiconset/
│ │ │ │ │ └── Contents.json
│ │ │ │ └── LaunchImage.imageset/
│ │ │ │ ├── Contents.json
│ │ │ │ └── README.md
│ │ │ ├── Base.lproj/
│ │ │ │ ├── LaunchScreen.storyboard
│ │ │ │ └── Main.storyboard
│ │ │ ├── Info.plist
│ │ │ └── Runner-Bridging-Header.h
│ │ ├── 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
│ ├── lib/
│ │ ├── common/
│ │ │ └── route/
│ │ │ ├── navigation_service.dart
│ │ │ ├── route.dart
│ │ │ └── router_config.dart
│ │ ├── features/
│ │ │ ├── custom_scrollview/
│ │ │ │ ├── custom_scrollview_demo/
│ │ │ │ │ ├── custom_scrollview_center_demo_page.dart
│ │ │ │ │ ├── custom_scrollview_demo_page.dart
│ │ │ │ │ └── multi_sliver_demo_page.dart
│ │ │ │ └── sliver_appbar_demo/
│ │ │ │ └── sliver_appbar_demo_page.dart
│ │ │ ├── gridview/
│ │ │ │ ├── gridview_ctx_demo/
│ │ │ │ │ └── gridview_ctx_demo_page.dart
│ │ │ │ ├── gridview_custom_demo/
│ │ │ │ │ └── gridview_custom_demo_page.dart
│ │ │ │ ├── gridview_demo/
│ │ │ │ │ └── gridview_demo_page.dart
│ │ │ │ ├── gridview_fixed_height_demo/
│ │ │ │ │ └── gridview_fixed_height_demo_page.dart
│ │ │ │ ├── horizontal_gridview_demo/
│ │ │ │ │ └── horizontal_gridview_demo_page.dart
│ │ │ │ └── sliver_grid_demo/
│ │ │ │ └── sliver_grid_demo_page.dart
│ │ │ ├── home/
│ │ │ │ └── home_page.dart
│ │ │ ├── listview/
│ │ │ │ ├── horizontal_listview_demo/
│ │ │ │ │ └── horizontal_listview_page.dart
│ │ │ │ ├── infinite_listview_demo/
│ │ │ │ │ └── infinite_listview_page.dart
│ │ │ │ ├── listview_ctx_demo/
│ │ │ │ │ └── listview_ctx_demo_page.dart
│ │ │ │ ├── listview_custom_demo/
│ │ │ │ │ └── listview_custom_demo_page.dart
│ │ │ │ ├── listview_demo/
│ │ │ │ │ └── listview_demo_page.dart
│ │ │ │ ├── listview_dynamic_offset/
│ │ │ │ │ └── listview_dynamic_offset_page.dart
│ │ │ │ ├── listview_fixed_height_demo/
│ │ │ │ │ └── listview_fixed_height_demo_page.dart
│ │ │ │ └── sliver_list_demo/
│ │ │ │ └── sliver_list_demo_page.dart
│ │ │ ├── nested_scrollview/
│ │ │ │ ├── nested_scrollview_demo/
│ │ │ │ │ └── nested_scrollview_demo_page.dart
│ │ │ │ └── nested_scrollview_tab_bar_view_demo/
│ │ │ │ ├── header/
│ │ │ │ │ └── nested_scrollview_tab_bar_view_demo_header.dart
│ │ │ │ ├── logic/
│ │ │ │ │ ├── nested_scrollview_tab_bar_view_demo_logic.dart
│ │ │ │ │ ├── nested_scrollview_tab_bar_view_demo_logic_floating_action_btn.dart
│ │ │ │ │ ├── nested_scrollview_tab_bar_view_demo_logic_observer.dart
│ │ │ │ │ ├── nested_scrollview_tab_bar_view_demo_logic_scroll_type_switch.dart
│ │ │ │ │ └── nested_scrollview_tab_bar_view_demo_logic_tab_bar.dart
│ │ │ │ ├── page/
│ │ │ │ │ └── nested_scrollview_tab_bar_view_demo_page.dart
│ │ │ │ ├── state/
│ │ │ │ │ └── nested_scrollview_tab_bar_view_demo_state.dart
│ │ │ │ └── widget/
│ │ │ │ ├── nested_scrollview_tab_bar_view_demo_floating_action_btn.dart
│ │ │ │ ├── nested_scrollview_tab_bar_view_demo_header_list_sliver.dart
│ │ │ │ ├── nested_scrollview_tab_bar_view_demo_scroll_type_switch.dart
│ │ │ │ ├── nested_scrollview_tab_bar_view_demo_tab1_view.dart
│ │ │ │ ├── nested_scrollview_tab_bar_view_demo_tab2_view.dart
│ │ │ │ ├── nested_scrollview_tab_bar_view_demo_tab3_view.dart
│ │ │ │ └── nested_scrollview_tab_bar_view_demo_tabbar.dart
│ │ │ ├── pageview/
│ │ │ │ └── pageview_demo/
│ │ │ │ ├── pageview_demo_page.dart
│ │ │ │ ├── pageview_parallax_item_listener_page.dart
│ │ │ │ └── pageview_parallax_page.dart
│ │ │ └── scene/
│ │ │ ├── anchor_demo/
│ │ │ │ ├── anchor_page.dart
│ │ │ │ └── anchor_waterfall_page.dart
│ │ │ ├── azlist_demo/
│ │ │ │ ├── azlist_cursor.dart
│ │ │ │ ├── azlist_index_bar.dart
│ │ │ │ ├── azlist_item_view.dart
│ │ │ │ ├── azlist_model.dart
│ │ │ │ └── azlist_page.dart
│ │ │ ├── chat_demo/
│ │ │ │ ├── helper/
│ │ │ │ │ └── chat_data_helper.dart
│ │ │ │ ├── model/
│ │ │ │ │ └── chat_model.dart
│ │ │ │ ├── page/
│ │ │ │ │ ├── chat_gpt_page.dart
│ │ │ │ │ └── chat_page.dart
│ │ │ │ └── widget/
│ │ │ │ ├── chat_item_widget.dart
│ │ │ │ └── chat_unread_tip_view.dart
│ │ │ ├── detail/
│ │ │ │ ├── header/
│ │ │ │ │ └── detail_header.dart
│ │ │ │ ├── logic/
│ │ │ │ │ ├── detail_logic.dart
│ │ │ │ │ ├── detail_logic_config.dart
│ │ │ │ │ ├── detail_logic_list_view.dart
│ │ │ │ │ └── detail_logic_nav_bar.dart
│ │ │ │ ├── model/
│ │ │ │ │ └── detail_nav_bar_tab_model.dart
│ │ │ │ ├── page/
│ │ │ │ │ └── detail_page.dart
│ │ │ │ ├── state/
│ │ │ │ │ ├── detail_state.dart
│ │ │ │ │ ├── detail_state_config.dart
│ │ │ │ │ ├── detail_state_list_view.dart
│ │ │ │ │ └── detail_state_nav_bar.dart
│ │ │ │ └── widget/
│ │ │ │ ├── detail_config_view.dart
│ │ │ │ ├── detail_list_item_wrapper.dart
│ │ │ │ ├── detail_list_view.dart
│ │ │ │ ├── detail_nav_bar.dart
│ │ │ │ └── list_item/
│ │ │ │ ├── detail_list_module1.dart
│ │ │ │ ├── detail_list_module2.dart
│ │ │ │ ├── detail_list_module3.dart
│ │ │ │ ├── detail_list_module4.dart
│ │ │ │ ├── detail_list_module5.dart
│ │ │ │ ├── detail_list_module6.dart
│ │ │ │ ├── detail_list_module7.dart
│ │ │ │ └── detail_list_module8.dart
│ │ │ ├── expandable_carousel_slider_demo/
│ │ │ │ └── expandable_carousel_slider_demo.dart
│ │ │ ├── image_tab_demo/
│ │ │ │ └── image_tab_page.dart
│ │ │ ├── scrollview_form_demo/
│ │ │ │ └── scrollview_form_demo_page.dart
│ │ │ ├── video_auto_play_list/
│ │ │ │ ├── video_list_auto_play_page.dart
│ │ │ │ └── widgets/
│ │ │ │ └── video_widget.dart
│ │ │ ├── visibility_demo/
│ │ │ │ ├── mixin/
│ │ │ │ │ └── visibility_exposure_mixin.dart
│ │ │ │ └── page/
│ │ │ │ ├── visibility_listview_page.dart
│ │ │ │ └── visibility_scrollview_page.dart
│ │ │ ├── waterfall_flow_demo/
│ │ │ │ ├── waterfall_flow_grid_item_view.dart
│ │ │ │ ├── waterfall_flow_page.dart
│ │ │ │ ├── waterfall_flow_swipe_view.dart
│ │ │ │ └── waterfall_flow_type.dart
│ │ │ └── waterfall_flow_fixed_height_demo/
│ │ │ └── waterfall_flow_fixed_height_page.dart
│ │ ├── main.dart
│ │ ├── typedefs.dart
│ │ ├── utils/
│ │ │ ├── keyboard.dart
│ │ │ ├── random.dart
│ │ │ └── snackbar.dart
│ │ └── widgets/
│ │ ├── animation.dart
│ │ └── sliver.dart
│ ├── linux/
│ │ └── flutter/
│ │ ├── generated_plugin_registrant.cc
│ │ ├── generated_plugin_registrant.h
│ │ └── generated_plugins.cmake
│ ├── macos/
│ │ ├── .gitignore
│ │ ├── Flutter/
│ │ │ ├── Flutter-Debug.xcconfig
│ │ │ ├── Flutter-Release.xcconfig
│ │ │ └── GeneratedPluginRegistrant.swift
│ │ ├── Podfile
│ │ ├── Runner/
│ │ │ ├── AppDelegate.swift
│ │ │ ├── Assets.xcassets/
│ │ │ │ └── AppIcon.appiconset/
│ │ │ │ └── Contents.json
│ │ │ ├── Base.lproj/
│ │ │ │ └── MainMenu.xib
│ │ │ ├── Configs/
│ │ │ │ ├── AppInfo.xcconfig
│ │ │ │ ├── Debug.xcconfig
│ │ │ │ ├── Release.xcconfig
│ │ │ │ └── Warnings.xcconfig
│ │ │ ├── DebugProfile.entitlements
│ │ │ ├── Info.plist
│ │ │ ├── MainFlutterWindow.swift
│ │ │ └── Release.entitlements
│ │ ├── Runner.xcodeproj/
│ │ │ ├── project.pbxproj
│ │ │ ├── project.xcworkspace/
│ │ │ │ └── xcshareddata/
│ │ │ │ └── IDEWorkspaceChecks.plist
│ │ │ └── xcshareddata/
│ │ │ └── xcschemes/
│ │ │ └── Runner.xcscheme
│ │ └── Runner.xcworkspace/
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata/
│ │ └── IDEWorkspaceChecks.plist
│ ├── pubspec.yaml
│ ├── test/
│ │ └── widget_test.dart
│ ├── web/
│ │ ├── index.html
│ │ └── manifest.json
│ └── windows/
│ ├── .gitignore
│ ├── CMakeLists.txt
│ ├── flutter/
│ │ ├── CMakeLists.txt
│ │ ├── generated_plugin_registrant.cc
│ │ ├── generated_plugin_registrant.h
│ │ └── generated_plugins.cmake
│ └── runner/
│ ├── CMakeLists.txt
│ ├── Runner.rc
│ ├── flutter_window.cpp
│ ├── flutter_window.h
│ ├── main.cpp
│ ├── resource.h
│ ├── runner.exe.manifest
│ ├── utils.cpp
│ ├── utils.h
│ ├── win32_window.cpp
│ └── win32_window.h
├── lib/
│ ├── scrollview_observer.dart
│ └── src/
│ ├── common/
│ │ ├── models/
│ │ │ ├── observe_displaying_child_model.dart
│ │ │ ├── observe_displaying_child_model_mixin.dart
│ │ │ ├── observe_find_child_model.dart
│ │ │ ├── observe_model.dart
│ │ │ ├── observe_scroll_child_model.dart
│ │ │ ├── observe_scroll_to_index_result_model.dart
│ │ │ ├── observer_handle_contexts_result_model.dart
│ │ │ └── observer_index_position_model.dart
│ │ ├── observer_controller.dart
│ │ ├── observer_listener.dart
│ │ ├── observer_notification_result.dart
│ │ ├── observer_typedef.dart
│ │ ├── observer_widget.dart
│ │ ├── observer_widget_scope.dart
│ │ ├── observer_widget_tag_manager.dart
│ │ └── typedefs.dart
│ ├── gridview/
│ │ ├── grid_observer_controller.dart
│ │ ├── grid_observer_notification_result.dart
│ │ ├── grid_observer_view.dart
│ │ └── models/
│ │ ├── gridview_observe_displaying_child_model.dart
│ │ └── gridview_observe_model.dart
│ ├── listview/
│ │ ├── list_observer_controller.dart
│ │ ├── list_observer_notification_result.dart
│ │ ├── list_observer_view.dart
│ │ └── models/
│ │ ├── listview_observe_displaying_child_model.dart
│ │ └── listview_observe_model.dart
│ ├── notification.dart
│ ├── observer_core.dart
│ ├── sliver/
│ │ ├── models/
│ │ │ ├── sliver_observer_observe_result_model.dart
│ │ │ ├── sliver_viewport_observe_displaying_child_model.dart
│ │ │ └── sliver_viewport_observe_model.dart
│ │ ├── sliver_observer_controller.dart
│ │ ├── sliver_observer_listener.dart
│ │ ├── sliver_observer_notification_result.dart
│ │ └── sliver_observer_view.dart
│ └── utils/
│ ├── observer_utils.dart
│ └── src/
│ ├── chat/
│ │ ├── chat_observer_scroll_physics.dart
│ │ ├── chat_observer_scroll_physics_mixin.dart
│ │ ├── chat_scroll_observer.dart
│ │ ├── chat_scroll_observer_model.dart
│ │ └── chat_scroll_observer_typedefs.dart
│ ├── extends.dart
│ ├── log.dart
│ ├── nested_scroll_util.dart
│ ├── observer_utils.dart
│ └── slivers.dart
├── listview_observer.iml
├── pubspec.yaml
└── test/
├── chat_scroll_observer_test.dart
├── grid_observer_test.dart
├── list_observer_test.dart
├── observer_utils_test.dart
└── sliver_observer_test.dart
SYMBOL INDEX (855 symbols across 150 files)
FILE: example/lib/common/route/navigation_service.dart
class NavigationService (line 10) | class NavigationService {
method push (line 16) | void push(
method pop (line 26) | void pop()
method getParam (line 28) | dynamic getParam(
method routerState (line 45) | GoRouterState routerState()
method stateExtra (line 49) | Object? stateExtra()
FILE: example/lib/common/route/router_config.dart
class MyPage (line 50) | class MyPage {
class MyRoute (line 98) | class MyRoute {
FILE: example/lib/features/custom_scrollview/custom_scrollview_demo/custom_scrollview_center_demo_page.dart
class CustomScrollViewCenterDemoPage (line 11) | class CustomScrollViewCenterDemoPage extends StatefulWidget {
method createState (line 15) | State<CustomScrollViewCenterDemoPage> createState()
class _CustomScrollViewCenterDemoPageState (line 19) | class _CustomScrollViewCenterDemoPageState
method initState (line 31) | void initState()
method dispose (line 38) | void dispose()
method build (line 44) | Widget build(BuildContext context)
method _buildScrollView (line 166) | Widget _buildScrollView()
method _buildSliverListView (line 201) | Widget _buildSliverListView({
FILE: example/lib/features/custom_scrollview/custom_scrollview_demo/custom_scrollview_demo_page.dart
class CustomScrollViewDemoPage (line 11) | class CustomScrollViewDemoPage extends StatefulWidget {
method createState (line 15) | State<CustomScrollViewDemoPage> createState()
class _CustomScrollViewDemoPageState (line 19) | class _CustomScrollViewDemoPageState extends State<CustomScrollViewDemoP...
method initState (line 31) | void initState()
method dispose (line 45) | void dispose()
method build (line 51) | Widget build(BuildContext context)
method _buildScrollView (line 130) | Widget _buildScrollView()
method _buildSliverListView (line 141) | Widget _buildSliverListView()
method _buildSliverGridView (line 187) | Widget _buildSliverGridView()
FILE: example/lib/features/custom_scrollview/custom_scrollview_demo/multi_sliver_demo_page.dart
class MultiSliverDemoModel (line 13) | class MultiSliverDemoModel {
class MultiSliverDemoPage (line 23) | class MultiSliverDemoPage extends StatefulWidget {
method createState (line 27) | State<MultiSliverDemoPage> createState()
class _MultiSliverDemoPageState (line 30) | class _MultiSliverDemoPageState extends State<MultiSliverDemoPage> {
method initState (line 45) | void initState()
method build (line 65) | Widget build(BuildContext context)
method _buildSliverItemObserver (line 76) | Widget _buildSliverItemObserver({
method _buildSliverObserver (line 87) | Widget _buildSliverObserver({
method _buildScrollView (line 126) | Widget _buildScrollView()
method buildBottomNavigationBar (line 143) | Widget buildBottomNavigationBar(BuildContext context)
method _buildSectionListView (line 205) | Widget _buildSectionListView(int mainIndex)
FILE: example/lib/features/custom_scrollview/sliver_appbar_demo/sliver_appbar_demo_page.dart
class SliverAppBarDemoPage (line 12) | class SliverAppBarDemoPage extends StatefulWidget {
method createState (line 16) | State<SliverAppBarDemoPage> createState()
class _SliverAppBarDemoPageState (line 19) | class _SliverAppBarDemoPageState extends State<SliverAppBarDemoPage> {
method initState (line 33) | void initState()
method dispose (line 54) | void dispose()
method build (line 60) | Widget build(BuildContext context)
method _buildScrollView (line 147) | Widget _buildScrollView()
method _buildSliverAppBar (line 160) | Widget _buildSliverAppBar()
method _buildSliverListView (line 172) | Widget _buildSliverListView()
method _buildSliverGridView (line 196) | Widget _buildSliverGridView()
method calcPersistentHeaderExtent (line 221) | double calcPersistentHeaderExtent(double offset)
FILE: example/lib/features/gridview/gridview_ctx_demo/gridview_ctx_demo_page.dart
class GridViewCtxDemoPage (line 10) | class GridViewCtxDemoPage extends StatefulWidget {
method createState (line 14) | State<GridViewCtxDemoPage> createState()
class _GridViewCtxDemoPageState (line 17) | class _GridViewCtxDemoPageState extends State<GridViewCtxDemoPage> {
method initState (line 23) | void initState()
method build (line 33) | Widget build(BuildContext context)
method _buildGridView (line 56) | Widget _buildGridView()
FILE: example/lib/features/gridview/gridview_custom_demo/gridview_custom_demo_page.dart
class GridViewCustomDemoPage (line 13) | class GridViewCustomDemoPage extends StatefulWidget {
method createState (line 17) | State<GridViewCustomDemoPage> createState()
class _GridViewCustomDemoPageState (line 20) | class _GridViewCustomDemoPageState extends State<GridViewCustomDemoPage> {
method initState (line 26) | void initState()
method build (line 34) | Widget build(BuildContext context)
method _buildGridView (line 72) | Widget _buildGridView()
class SourceList (line 100) | class SourceList extends LoadingMoreBase<int> {
method loadData (line 102) | Future<bool> loadData([bool isloadMoreAction = false])
FILE: example/lib/features/gridview/gridview_demo/gridview_demo_page.dart
class GridViewDemoPage (line 11) | class GridViewDemoPage extends StatefulWidget {
method createState (line 15) | State<GridViewDemoPage> createState()
class _GridViewDemoPageState (line 18) | class _GridViewDemoPageState extends State<GridViewDemoPage> {
method initState (line 34) | void initState()
method dispose (line 51) | void dispose()
method build (line 57) | Widget build(BuildContext context)
method _buildGridView (line 95) | Widget _buildGridView()
FILE: example/lib/features/gridview/gridview_fixed_height_demo/gridview_fixed_height_demo_page.dart
class GridViewFixedHeightDemoPage (line 11) | class GridViewFixedHeightDemoPage extends StatefulWidget {
method createState (line 15) | State<GridViewFixedHeightDemoPage> createState()
class _GridViewFixedHeightDemoPageState (line 19) | class _GridViewFixedHeightDemoPageState
method initState (line 38) | void initState()
method dispose (line 55) | void dispose()
method build (line 61) | Widget build(BuildContext context)
method _buildGridView (line 95) | Widget _buildGridView()
FILE: example/lib/features/gridview/horizontal_gridview_demo/horizontal_gridview_demo_page.dart
class HorizontalGridViewDemoPage (line 11) | class HorizontalGridViewDemoPage extends StatefulWidget {
method createState (line 15) | State<HorizontalGridViewDemoPage> createState()
class _HorizontalGridViewDemoPageState (line 19) | class _HorizontalGridViewDemoPageState
method initState (line 37) | void initState()
method dispose (line 52) | void dispose()
method build (line 58) | Widget build(BuildContext context)
method _buildGridView (line 112) | Widget _buildGridView()
FILE: example/lib/features/gridview/sliver_grid_demo/sliver_grid_demo_page.dart
class SliverGridViewDemoPage (line 10) | class SliverGridViewDemoPage extends StatefulWidget {
method createState (line 14) | State<SliverGridViewDemoPage> createState()
class _SliverGridViewDemoPageState (line 17) | class _SliverGridViewDemoPageState extends State<SliverGridViewDemoPage> {
method initState (line 25) | void initState()
method build (line 35) | Widget build(BuildContext context)
method _buildGridView (line 75) | Widget _buildGridView()
method _buildSliverGridView1 (line 84) | Widget _buildSliverGridView1()
method _buildSliverGridView2 (line 109) | Widget _buildSliverGridView2()
FILE: example/lib/features/home/home_page.dart
class HomePage (line 10) | class HomePage extends StatelessWidget {
method build (line 14) | Widget build(BuildContext context)
method _buildListView (line 21) | Widget _buildListView()
FILE: example/lib/features/listview/horizontal_listview_demo/horizontal_listview_page.dart
class HorizontalListViewPage (line 10) | class HorizontalListViewPage extends StatefulWidget {
method createState (line 14) | State<HorizontalListViewPage> createState()
class _HorizontalListViewPageState (line 17) | class _HorizontalListViewPageState extends State<HorizontalListViewPage> {
method initState (line 23) | void initState()
method build (line 33) | Widget build(BuildContext context)
method _buildListView (line 55) | ListView _buildListView()
method _buildListItemView (line 71) | Widget _buildListItemView(int index)
method _buildSeparatorView (line 86) | Container _buildSeparatorView()
FILE: example/lib/features/listview/infinite_listview_demo/infinite_listview_page.dart
class InfiniteListViewPage (line 12) | class InfiniteListViewPage extends StatefulWidget {
method createState (line 16) | State<InfiniteListViewPage> createState()
class _InfiniteListViewPageState (line 19) | class _InfiniteListViewPageState extends State<InfiniteListViewPage> {
method initState (line 92) | void initState()
method build (line 109) | Widget build(BuildContext context)
method _buildListView (line 139) | Widget _buildListView()
method _buildListItemView (line 156) | Widget _buildListItemView(int index)
method _buildSeparatorView (line 171) | Widget _buildSeparatorView()
FILE: example/lib/features/listview/listview_ctx_demo/listview_ctx_demo_page.dart
class ListViewCtxDemoPage (line 10) | class ListViewCtxDemoPage extends StatefulWidget {
method createState (line 14) | State<ListViewCtxDemoPage> createState()
class _ListViewCtxDemoPageState (line 17) | class _ListViewCtxDemoPageState extends State<ListViewCtxDemoPage> {
method initState (line 23) | void initState()
method build (line 33) | Widget build(BuildContext context)
method _buildListView (line 56) | ListView _buildListView()
method _buildListItemView (line 84) | Widget _buildListItemView(int index)
method _buildSeparatorView (line 99) | Container _buildSeparatorView()
FILE: example/lib/features/listview/listview_custom_demo/listview_custom_demo_page.dart
class ListViewCustomDemoPage (line 13) | class ListViewCustomDemoPage extends StatefulWidget {
method createState (line 17) | State<ListViewCustomDemoPage> createState()
class _ListViewCustomDemoPageState (line 20) | class _ListViewCustomDemoPageState extends State<ListViewCustomDemoPage> {
method initState (line 26) | void initState()
method build (line 34) | Widget build(BuildContext context)
method _buildListView (line 72) | Widget _buildListView()
class SourceList (line 92) | class SourceList extends LoadingMoreBase<int> {
method loadData (line 94) | Future<bool> loadData([bool isloadMoreAction = false])
FILE: example/lib/features/listview/listview_demo/listview_demo_page.dart
class ListViewDemoPage (line 11) | class ListViewDemoPage extends StatefulWidget {
method createState (line 15) | State<ListViewDemoPage> createState()
class _ListViewDemoPageState (line 18) | class _ListViewDemoPageState extends State<ListViewDemoPage> {
method initState (line 33) | void initState()
method dispose (line 54) | void dispose()
method build (line 60) | Widget build(BuildContext context)
method _buildListView (line 107) | ListView _buildListView()
method _buildListItemView (line 130) | Widget _buildListItemView(int index)
method _buildSeparatorView (line 145) | Container _buildSeparatorView()
FILE: example/lib/features/listview/listview_dynamic_offset/listview_dynamic_offset_page.dart
class ListViewDynamicOffsetPage (line 10) | class ListViewDynamicOffsetPage extends StatefulWidget {
method createState (line 14) | State<ListViewDynamicOffsetPage> createState()
class _ListViewDynamicOffsetPageState (line 18) | class _ListViewDynamicOffsetPageState extends State<ListViewDynamicOffse...
method initState (line 34) | void initState()
method dispose (line 47) | void dispose()
method build (line 54) | Widget build(BuildContext context)
method _buildListView (line 100) | ListView _buildListView()
method _buildListItemView (line 117) | Widget _buildListItemView(int index)
method _buildSeparatorView (line 132) | Container _buildSeparatorView()
method _buildNavContentWidget (line 139) | Widget _buildNavContentWidget(BuildContext context)
method _pageDidScroll (line 173) | void _pageDidScroll()
FILE: example/lib/features/listview/listview_fixed_height_demo/listview_fixed_height_demo_page.dart
class ListViewFixedHeightDemoPage (line 11) | class ListViewFixedHeightDemoPage extends StatefulWidget {
method createState (line 15) | State<ListViewFixedHeightDemoPage> createState()
class _ListViewFixedHeightDemoPageState (line 19) | class _ListViewFixedHeightDemoPageState
method initState (line 29) | void initState()
method dispose (line 50) | void dispose()
method build (line 56) | Widget build(BuildContext context)
method _buildListView (line 103) | ListView _buildListView()
method _buildListItemView (line 117) | Widget _buildListItemView(int index)
method _buildSeparatorView (line 132) | Container _buildSeparatorView()
FILE: example/lib/features/listview/sliver_list_demo/sliver_list_demo_page.dart
class SliverListViewDemoPage (line 10) | class SliverListViewDemoPage extends StatefulWidget {
method createState (line 14) | State<SliverListViewDemoPage> createState()
class _SliverListViewDemoPageState (line 17) | class _SliverListViewDemoPageState extends State<SliverListViewDemoPage> {
method initState (line 27) | void initState()
method build (line 37) | Widget build(BuildContext context)
method _buildSliverListView1 (line 78) | SliverList _buildSliverListView1()
method _buildSliverListView2 (line 104) | SliverList _buildSliverListView2()
FILE: example/lib/features/nested_scrollview/nested_scrollview_demo/nested_scrollview_demo_page.dart
class NestedScrollViewDemoPage (line 12) | class NestedScrollViewDemoPage extends StatefulWidget {
method createState (line 16) | State<NestedScrollViewDemoPage> createState()
class _NestedScrollViewDemoPageState (line 20) | class _NestedScrollViewDemoPageState extends State<NestedScrollViewDemoP...
method initState (line 51) | void initState()
method dispose (line 58) | void dispose()
method build (line 64) | Widget build(BuildContext context)
method _buildNestedScrollView (line 161) | Widget _buildNestedScrollView()
method _buildSliverListView (line 237) | Widget _buildSliverListView()
method _buildSliverGridView (line 265) | Widget _buildSliverGridView()
method calcPersistentHeaderExtent (line 293) | double calcPersistentHeaderExtent(
FILE: example/lib/features/nested_scrollview/nested_scrollview_tab_bar_view_demo/header/nested_scrollview_tab_bar_view_demo_header.dart
type NestedScrollviewTabBarViewDemoLogicPutMixin (line 11) | typedef NestedScrollviewTabBarViewDemoLogicPutMixin<W extends StatefulWi...
type NestedScrollviewTabBarViewDemoLogicConsumerMixin (line 14) | typedef NestedScrollviewTabBarViewDemoLogicConsumerMixin<
type NestedScrollviewTabBarViewDemoUpdateType (line 18) | enum NestedScrollviewTabBarViewDemoUpdateType {
type NestedScrollviewTabBarViewDemoTabType (line 28) | enum NestedScrollviewTabBarViewDemoTabType {
type NestedScrollviewTabBarViewDemoFABClickType (line 40) | enum NestedScrollviewTabBarViewDemoFABClickType {
FILE: example/lib/features/nested_scrollview/nested_scrollview_tab_bar_view_demo/logic/nested_scrollview_tab_bar_view_demo_logic.dart
class NestedScrollViewTabBarViewDemoLogic (line 11) | class NestedScrollViewTabBarViewDemoLogic extends GetxController
method onInit (line 17) | void onInit()
method onDispose (line 23) | void onDispose()
FILE: example/lib/features/nested_scrollview/nested_scrollview_tab_bar_view_demo/logic/nested_scrollview_tab_bar_view_demo_logic_floating_action_btn.dart
function handleFABClick (line 15) | void handleFABClick(
FILE: example/lib/features/nested_scrollview/nested_scrollview_tab_bar_view_demo/logic/nested_scrollview_tab_bar_view_demo_logic_observer.dart
function updateNestedScrollUtilHeaderSliverContextsIfNeed (line 14) | void updateNestedScrollUtilHeaderSliverContextsIfNeed({
function updateNestedScrollUtilBodySliverContextsIfNeed (line 27) | void updateNestedScrollUtilBodySliverContextsIfNeed({
function handleOnObserveAll (line 40) | void handleOnObserveAll(Map<BuildContext, ObserveModel> resultMap)
function scrollTo (line 108) | void scrollTo({
function calcPersistentHeaderExtent (line 147) | double calcPersistentHeaderExtent(
FILE: example/lib/features/nested_scrollview/nested_scrollview_tab_bar_view_demo/logic/nested_scrollview_tab_bar_view_demo_logic_scroll_type_switch.dart
function handleScrollTypeSwitchOnChanged (line 13) | void handleScrollTypeSwitchOnChanged(bool value)
FILE: example/lib/features/nested_scrollview/nested_scrollview_tab_bar_view_demo/logic/nested_scrollview_tab_bar_view_demo_logic_tab_bar.dart
function onInitForTabBar (line 13) | void onInitForTabBar()
function onDisposeForTabBar (line 26) | void onDisposeForTabBar()
FILE: example/lib/features/nested_scrollview/nested_scrollview_tab_bar_view_demo/page/nested_scrollview_tab_bar_view_demo_page.dart
class NestedScrollViewTabBarViewDemoPage (line 23) | class NestedScrollViewTabBarViewDemoPage extends StatefulWidget {
method createState (line 27) | State<NestedScrollViewTabBarViewDemoPage> createState()
class NestedScrollViewTabBarViewDemoPageState (line 31) | class NestedScrollViewTabBarViewDemoPageState
method dispose (line 42) | void dispose()
method initLogic (line 48) | NestedScrollViewTabBarViewDemoLogic initLogic()
method buildBody (line 52) | Widget buildBody(BuildContext context)
method _buildContent (line 70) | Widget _buildContent()
method _buildTabBarView (line 126) | Widget _buildTabBarView()
method _buildSliverAppBar (line 137) | Widget _buildSliverAppBar(bool innerBoxIsScrolled)
FILE: example/lib/features/nested_scrollview/nested_scrollview_tab_bar_view_demo/state/nested_scrollview_tab_bar_view_demo_state.dart
class NestedScrollViewTabBarViewDemoState (line 11) | class NestedScrollViewTabBarViewDemoState {
FILE: example/lib/features/nested_scrollview/nested_scrollview_tab_bar_view_demo/widget/nested_scrollview_tab_bar_view_demo_floating_action_btn.dart
class NestedScrollviewTabBarViewDemoFloatingActionBtn (line 14) | class NestedScrollviewTabBarViewDemoFloatingActionBtn extends StatefulWi...
method createState (line 18) | State<NestedScrollviewTabBarViewDemoFloatingActionBtn> createState()
class _NestedScrollviewTabBarViewDemoFloatingActionBtnState (line 22) | class _NestedScrollviewTabBarViewDemoFloatingActionBtnState
method build (line 30) | Widget build(BuildContext context)
method _buildBody (line 40) | Widget _buildBody()
FILE: example/lib/features/nested_scrollview/nested_scrollview_tab_bar_view_demo/widget/nested_scrollview_tab_bar_view_demo_header_list_sliver.dart
class NestedScrollviewTabBarViewDemoHeaderListSliver (line 14) | class NestedScrollviewTabBarViewDemoHeaderListSliver extends StatefulWid...
method createState (line 18) | State<NestedScrollviewTabBarViewDemoHeaderListSliver> createState()
class _NestedScrollviewTabBarViewDemoHeaderListSliverState (line 22) | class _NestedScrollviewTabBarViewDemoHeaderListSliverState
method build (line 30) | Widget build(BuildContext context)
method _buildSliverList (line 40) | Widget _buildSliverList()
FILE: example/lib/features/nested_scrollview/nested_scrollview_tab_bar_view_demo/widget/nested_scrollview_tab_bar_view_demo_scroll_type_switch.dart
class NestedScrollviewTabBarViewDemoScrollTypeSwitch (line 14) | class NestedScrollviewTabBarViewDemoScrollTypeSwitch extends StatefulWid...
method createState (line 18) | State<NestedScrollviewTabBarViewDemoScrollTypeSwitch> createState()
class _NestedScrollviewTabBarViewDemoScrollTypeSwitchState (line 22) | class _NestedScrollviewTabBarViewDemoScrollTypeSwitchState
method build (line 30) | Widget build(BuildContext context)
method _buildBody (line 40) | Widget _buildBody()
FILE: example/lib/features/nested_scrollview/nested_scrollview_tab_bar_view_demo/widget/nested_scrollview_tab_bar_view_demo_tab1_view.dart
class NestedScrollviewTabBarViewDemoTab1View (line 14) | class NestedScrollviewTabBarViewDemoTab1View extends StatefulWidget {
method createState (line 18) | State<NestedScrollviewTabBarViewDemoTab1View> createState()
class _NestedScrollviewTabBarViewDemoTab1ViewState (line 22) | class _NestedScrollviewTabBarViewDemoTab1ViewState
method build (line 30) | Widget build(BuildContext context)
method _buildBody (line 40) | Widget _buildBody()
method _buildSliverList (line 49) | Widget _buildSliverList()
FILE: example/lib/features/nested_scrollview/nested_scrollview_tab_bar_view_demo/widget/nested_scrollview_tab_bar_view_demo_tab2_view.dart
class NestedScrollviewTabBarViewDemoTab2View (line 14) | class NestedScrollviewTabBarViewDemoTab2View extends StatefulWidget {
method createState (line 18) | State<NestedScrollviewTabBarViewDemoTab2View> createState()
class _NestedScrollviewTabBarViewDemoTab2ViewState (line 22) | class _NestedScrollviewTabBarViewDemoTab2ViewState
method build (line 30) | Widget build(BuildContext context)
method _buildBody (line 40) | Widget _buildBody()
method _buildSliverGrid (line 49) | Widget _buildSliverGrid()
FILE: example/lib/features/nested_scrollview/nested_scrollview_tab_bar_view_demo/widget/nested_scrollview_tab_bar_view_demo_tab3_view.dart
class NestedScrollviewTabBarViewDemoTab3View (line 14) | class NestedScrollviewTabBarViewDemoTab3View extends StatefulWidget {
method createState (line 18) | State<NestedScrollviewTabBarViewDemoTab3View> createState()
class _NestedScrollviewTabBarViewDemoTab3ViewState (line 22) | class _NestedScrollviewTabBarViewDemoTab3ViewState
method build (line 30) | Widget build(BuildContext context)
method _buildSliverList (line 48) | Widget _buildSliverList()
method _buildSliverGrid (line 71) | Widget _buildSliverGrid()
FILE: example/lib/features/nested_scrollview/nested_scrollview_tab_bar_view_demo/widget/nested_scrollview_tab_bar_view_demo_tabbar.dart
class NestedScrollViewTabBarViewDemoTabBar (line 11) | class NestedScrollViewTabBarViewDemoTabBar extends StatefulWidget {
method createState (line 15) | State<NestedScrollViewTabBarViewDemoTabBar> createState()
class _NestedScrollViewTabBarViewDemoTabBarState (line 19) | class _NestedScrollViewTabBarViewDemoTabBarState
method build (line 27) | Widget build(BuildContext context)
FILE: example/lib/features/pageview/pageview_demo/pageview_demo_page.dart
class PageViewDemoPage (line 11) | class PageViewDemoPage extends StatefulWidget {
method createState (line 15) | State<PageViewDemoPage> createState()
class _PageViewDemoPageState (line 18) | class _PageViewDemoPageState extends State<PageViewDemoPage> {
method initState (line 46) | void initState()
method dispose (line 65) | void dispose()
method build (line 74) | Widget build(BuildContext context)
method _buildMap (line 108) | Widget _buildMap()
method _buildPageView (line 134) | Widget _buildPageView()
method _buildPageItem (line 168) | Widget _buildPageItem(int index)
method _buildPageItemBgPicView (line 214) | Widget _buildPageItemBgPicView(int index)
FILE: example/lib/features/pageview/pageview_demo/pageview_parallax_item_listener_page.dart
class PageViewParallaxItemListenerPage (line 12) | class PageViewParallaxItemListenerPage extends StatefulWidget {
method createState (line 16) | State<PageViewParallaxItemListenerPage> createState()
class _PageViewParallaxItemListenerPageState (line 20) | class _PageViewParallaxItemListenerPageState
method initState (line 47) | void initState()
method dispose (line 66) | void dispose()
method build (line 75) | Widget build(BuildContext context)
method _buildPageView (line 102) | Widget _buildPageView()
class ParallaxItemView (line 134) | class ParallaxItemView extends StatefulWidget {
method createState (line 145) | State<ParallaxItemView> createState()
class _ParallaxItemViewState (line 148) | class _ParallaxItemViewState extends State<ParallaxItemView> {
method didChangeDependencies (line 154) | void didChangeDependencies()
method dispose (line 165) | void dispose()
method removeListener (line 171) | void removeListener()
method handleObserverResult (line 178) | void handleObserverResult(
method build (line 201) | Widget build(BuildContext context)
method _buildNum (line 228) | Widget _buildNum(int index)
method _buildPageItemBgPicView (line 241) | Widget _buildPageItemBgPicView(int index)
FILE: example/lib/features/pageview/pageview_demo/pageview_parallax_page.dart
class PageViewParallaxPage (line 11) | class PageViewParallaxPage extends StatefulWidget {
method createState (line 15) | State<PageViewParallaxPage> createState()
class _PageViewParallaxPageState (line 18) | class _PageViewParallaxPageState extends State<PageViewParallaxPage> {
method initState (line 44) | void initState()
method dispose (line 63) | void dispose()
method build (line 72) | Widget build(BuildContext context)
method _buildPageView (line 99) | Widget _buildPageView()
method _buildPageItem (line 145) | Widget _buildPageItem(int index)
method _buildNum (line 172) | Widget _buildNum(int index)
method _buildPageItemBgPicView (line 185) | Widget _buildPageItemBgPicView(int index)
FILE: example/lib/features/scene/anchor_demo/anchor_page.dart
class AnchorListPage (line 9) | class AnchorListPage extends StatefulWidget {
method createState (line 13) | State<AnchorListPage> createState()
class _AnchorListPageState (line 16) | class _AnchorListPageState extends State<AnchorListPage>
method initState (line 26) | void initState()
method dispose (line 33) | void dispose()
method build (line 40) | Widget build(BuildContext context)
method _buildListView (line 73) | ListView _buildListView()
method _buildListItemView (line 86) | Widget _buildListItemView(int index)
method _buildSeparatorView (line 101) | Container _buildSeparatorView()
FILE: example/lib/features/scene/anchor_demo/anchor_waterfall_page.dart
class AnchorWaterfallPage (line 11) | class AnchorWaterfallPage extends StatefulWidget {
method createState (line 15) | State<AnchorWaterfallPage> createState()
class _AnchorWaterfallPageState (line 18) | class _AnchorWaterfallPageState extends State<AnchorWaterfallPage>
method initState (line 28) | void initState()
method dispose (line 35) | void dispose()
method build (line 42) | Widget build(BuildContext context)
method _buildGridView (line 83) | Widget _buildGridView()
FILE: example/lib/features/scene/azlist_demo/azlist_cursor.dart
class AzListCursor (line 9) | class AzListCursor extends StatelessWidget {
method build (line 23) | Widget build(BuildContext context)
method _buildArrow (line 37) | Widget _buildArrow()
method _buildTitle (line 46) | Widget _buildTitle()
FILE: example/lib/features/scene/azlist_demo/azlist_index_bar.dart
class AzListIndexBar (line 10) | class AzListIndexBar extends StatefulWidget {
method createState (line 31) | State<AzListIndexBar> createState()
class _AzListIndexBarState (line 34) | class _AzListIndexBarState extends State<AzListIndexBar> {
method build (line 42) | Widget build(BuildContext context)
method _buildListView (line 58) | Widget _buildListView()
FILE: example/lib/features/scene/azlist_demo/azlist_item_view.dart
class AzListItemView (line 8) | class AzListItemView extends StatelessWidget {
method build (line 20) | Widget build(BuildContext context)
FILE: example/lib/features/scene/azlist_demo/azlist_model.dart
class AzListContactModel (line 9) | class AzListContactModel {
class AzListCursorInfoModel (line 19) | class AzListCursorInfoModel {
FILE: example/lib/features/scene/azlist_demo/azlist_page.dart
class AzListPage (line 20) | class AzListPage extends StatefulWidget {
method createState (line 24) | State<AzListPage> createState()
class _AzListPageState (line 27) | class _AzListPageState extends State<AzListPage> {
method initState (line 65) | void initState()
method build (line 74) | Widget build(BuildContext context)
method _buildSwitchModeBtn (line 111) | Widget _buildSwitchModeBtn()
method _buildCursor (line 128) | Widget _buildCursor()
method _buildIndexBar (line 156) | Widget _buildIndexBar()
method _buildSliver (line 183) | Widget _buildSliver({
FILE: example/lib/features/scene/chat_demo/helper/chat_data_helper.dart
class ChatDataHelper (line 10) | class ChatDataHelper {
method createChatModel (line 23) | ChatModel createChatModel({
FILE: example/lib/features/scene/chat_demo/model/chat_model.dart
class ChatModel (line 7) | class ChatModel {
FILE: example/lib/features/scene/chat_demo/page/chat_gpt_page.dart
class ChatGPTPage (line 15) | class ChatGPTPage extends StatefulWidget {
method createState (line 19) | State<ChatGPTPage> createState()
class _ChatGPTPageState (line 22) | class _ChatGPTPageState extends State<ChatGPTPage> {
method initState (line 38) | void initState()
method dispose (line 54) | void dispose()
method build (line 62) | Widget build(BuildContext context)
method _buildBody (line 85) | Widget _buildBody()
method _buildEditView (line 96) | Widget _buildEditView()
method _buildListView (line 138) | Widget _buildListView()
method createChatModels (line 172) | List<ChatModel> createChatModels({int num = 3})
FILE: example/lib/features/scene/chat_demo/page/chat_page.dart
class ChatPage (line 17) | class ChatPage extends StatefulWidget {
method createState (line 21) | State<ChatPage> createState()
class _ChatPageState (line 24) | class _ChatPageState extends State<ChatPage> with WidgetsBindingObserver {
method initState (line 48) | void initState()
method dispose (line 81) | void dispose()
method didChangeMetrics (line 89) | void didChangeMetrics()
method build (line 107) | Widget build(BuildContext context)
method _buildPageOverlay (line 139) | Widget _buildPageOverlay()
method _buildBody (line 150) | Widget _buildBody()
method _buildEditView (line 181) | Widget _buildEditView()
method _buildUnreadTipView (line 223) | Widget _buildUnreadTipView()
method _buildListView (line 242) | Widget _buildListView()
method createChatModels (line 340) | List<ChatModel> createChatModels({int num = 3})
FILE: example/lib/features/scene/chat_demo/widget/chat_item_widget.dart
class ChatItemWidget (line 10) | class ChatItemWidget extends StatelessWidget {
method build (line 25) | Widget build(BuildContext context)
FILE: example/lib/features/scene/chat_demo/widget/chat_unread_tip_view.dart
class ChatUnreadTipView (line 9) | class ChatUnreadTipView extends StatelessWidget {
method build (line 23) | Widget build(BuildContext context)
FILE: example/lib/features/scene/detail/header/detail_header.dart
type DetailLogicPutMixin (line 11) | typedef DetailLogicPutMixin<W extends StatefulWidget>
type DetailLogicConsumerMixin (line 14) | typedef DetailLogicConsumerMixin<W extends StatefulWidget>
type DetailUpdateType (line 17) | enum DetailUpdateType {
type DetailModuleType (line 25) | enum DetailModuleType {
type DetailRefreshIndicatorType (line 36) | enum DetailRefreshIndicatorType {
FILE: example/lib/features/scene/detail/logic/detail_logic.dart
class DetailLogic (line 12) | class DetailLogic extends GetxController with GetTickerProviderStateMixin {
method onInit (line 16) | void onInit()
method onDispose (line 23) | void onDispose()
FILE: example/lib/features/scene/detail/logic/detail_logic_config.dart
function onConfigConfirm (line 11) | void onConfigConfirm()
FILE: example/lib/features/scene/detail/logic/detail_logic_list_view.dart
function onInitForListView (line 16) | void onInitForListView()
function onDisposeForListView (line 23) | void onDisposeForListView()
function onObserveForListView (line 27) | void onObserveForListView(ListViewObserveModel result)
function initIndexPositionForListView (line 39) | void initIndexPositionForListView()
function checkAnchorForListView (line 62) | void checkAnchorForListView(DetailModuleType moduleType)
function updateAndKeepPositionForListView (line 78) | void updateAndKeepPositionForListView([
function firstTimeRenderListView (line 104) | void firstTimeRenderListView()
function loadAsyncDataForListView (line 110) | void loadAsyncDataForListView()
FILE: example/lib/features/scene/detail/logic/detail_logic_nav_bar.dart
function onInitForNavBar (line 15) | void onInitForNavBar()
function createNavBarTabModel (line 27) | DetailNavBarTabModel createNavBarTabModel(
function onDisposeForNavBar (line 36) | void onDisposeForNavBar()
function handleNavBarTabTap (line 41) | void handleNavBarTabTap(int index)
function updateNavBarTabIndex (line 56) | void updateNavBarTabIndex(int index)
function updateNavBarAlpha (line 62) | void updateNavBarAlpha()
FILE: example/lib/features/scene/detail/model/detail_nav_bar_tab_model.dart
class DetailNavBarTabModel (line 9) | class DetailNavBarTabModel {
FILE: example/lib/features/scene/detail/page/detail_page.dart
class DetailPage (line 17) | class DetailPage extends StatefulWidget {
method createState (line 21) | State<DetailPage> createState()
class DetailPageState (line 24) | class DetailPageState extends State<DetailPage>
method dispose (line 29) | void dispose()
method initLogic (line 35) | DetailLogic initLogic()
method buildBody (line 38) | Widget buildBody(BuildContext context)
method _buildAppBar (line 51) | AppBar _buildAppBar()
method _buildBody (line 57) | Widget _buildBody()
method _buildLoading (line 75) | Widget _buildLoading()
FILE: example/lib/features/scene/detail/state/detail_state.dart
class DetailState (line 11) | class DetailState
FILE: example/lib/features/scene/detail/widget/detail_config_view.dart
class DetailConfigView (line 14) | class DetailConfigView extends StatefulWidget {
method createState (line 18) | State<DetailConfigView> createState()
class _DetailConfigViewState (line 21) | class _DetailConfigViewState extends State<DetailConfigView>
method build (line 26) | Widget build(BuildContext context)
method _buildListView (line 48) | Widget _buildListView()
method _buildDefaultAnchor (line 57) | Widget _buildDefaultAnchor()
method _buildRefreshPosition (line 72) | Widget _buildRefreshPosition()
method _buildConfirmBtn (line 87) | Widget _buildConfirmBtn()
method inputDecorationTheme (line 105) | InputDecorationTheme inputDecorationTheme()
FILE: example/lib/features/scene/detail/widget/detail_list_item_wrapper.dart
class DetailListItemWrapper (line 10) | class DetailListItemWrapper extends StatefulWidget {
method createState (line 21) | State<DetailListItemWrapper> createState()
class _DetailListItemWrapperState (line 24) | class _DetailListItemWrapperState extends State<DetailListItemWrapper>
method build (line 29) | Widget build(BuildContext context)
method _buildTitle (line 40) | Widget _buildTitle()
FILE: example/lib/features/scene/detail/widget/detail_list_view.dart
class DetailListView (line 22) | class DetailListView extends StatefulWidget {
method createState (line 26) | State<DetailListView> createState()
class _DetailListViewState (line 29) | class _DetailListViewState extends State<DetailListView>
method build (line 36) | Widget build(BuildContext context)
method _buildListView (line 59) | Widget _buildListView({
FILE: example/lib/features/scene/detail/widget/detail_nav_bar.dart
class DetailNavBar (line 14) | class DetailNavBar extends StatefulWidget {
method createState (line 18) | State<DetailNavBar> createState()
class _DetailNavBarState (line 21) | class _DetailNavBarState extends State<DetailNavBar>
method build (line 26) | Widget build(BuildContext context)
method _buildBody (line 36) | Widget _buildBody()
method _buildTabBar (line 64) | Widget _buildTabBar()
FILE: example/lib/features/scene/detail/widget/list_item/detail_list_module1.dart
class DetailListModule1 (line 11) | class DetailListModule1 extends StatefulWidget {
method createState (line 15) | State<DetailListModule1> createState()
class _DetailListModule1State (line 18) | class _DetailListModule1State extends State<DetailListModule1>
method build (line 21) | Widget build(BuildContext context)
method _buildPageView (line 29) | Widget _buildPageView()
method _buildPageItem (line 43) | Widget _buildPageItem(int index)
method _buildPageItemBody (line 65) | Widget _buildPageItemBody(int index)
method _buildPageItemIndex (line 109) | Widget _buildPageItemIndex(int index)
FILE: example/lib/features/scene/detail/widget/list_item/detail_list_module2.dart
class DetailListModule2 (line 11) | class DetailListModule2 extends StatefulWidget {
method createState (line 15) | State<DetailListModule2> createState()
class _DetailListModule2State (line 18) | class _DetailListModule2State extends State<DetailListModule2>
method build (line 21) | Widget build(BuildContext context)
method _buildListView (line 34) | Widget _buildListView()
method _buildItem (line 48) | Widget _buildItem(int index)
method _buildItemBrand (line 98) | Widget _buildItemBrand()
method _buildItemTitle (line 108) | Widget _buildItemTitle()
method _buildItemAddBtn (line 118) | Widget _buildItemAddBtn()
method _buildItemPrice (line 132) | Widget _buildItemPrice()
method _buildItemFavoriteIcon (line 142) | Widget _buildItemFavoriteIcon()
method _buildItemCover (line 159) | Widget _buildItemCover(int index)
FILE: example/lib/features/scene/detail/widget/list_item/detail_list_module3.dart
class DetailListModule3 (line 14) | class DetailListModule3 extends StatefulWidget {
method createState (line 18) | State<DetailListModule3> createState()
class _DetailListModule3State (line 21) | class _DetailListModule3State extends State<DetailListModule3>
method build (line 48) | Widget build(BuildContext context)
method _buildGridView (line 65) | Widget _buildGridView()
method _buildGridItem (line 83) | Widget _buildGridItem(int index)
method _buildItemTitle (line 94) | Widget _buildItemTitle(int index)
method _buildItemIcon (line 105) | Widget _buildItemIcon(int index)
FILE: example/lib/features/scene/detail/widget/list_item/detail_list_module4.dart
class DetailListModule4 (line 11) | class DetailListModule4 extends StatefulWidget {
method createState (line 15) | State<DetailListModule4> createState()
class _DetailListModule4State (line 18) | class _DetailListModule4State extends State<DetailListModule4>
method build (line 21) | Widget build(BuildContext context)
method _buildListView (line 30) | Widget _buildListView()
method _buildItem (line 42) | Widget _buildItem(int index)
method _buildItemSubtitle (line 83) | Widget _buildItemSubtitle(int index)
method _buildItemTitle (line 93) | Widget _buildItemTitle(int index)
method _buildItemAvatar (line 103) | Widget _buildItemAvatar()
method _buildItemArrow (line 115) | Widget _buildItemArrow()
FILE: example/lib/features/scene/detail/widget/list_item/detail_list_module5.dart
class DetailListModule5 (line 11) | class DetailListModule5 extends StatefulWidget {
method createState (line 15) | State<DetailListModule5> createState()
class _DetailListModule5State (line 18) | class _DetailListModule5State extends State<DetailListModule5>
method build (line 37) | Widget build(BuildContext context)
method _buildListView (line 46) | Widget _buildListView()
method _buildListItem (line 62) | Widget _buildListItem(int index)
method _getLeadingIcon (line 71) | Widget _getLeadingIcon(int index)
method _getTrailingWidget (line 96) | Widget _getTrailingWidget(int index)
FILE: example/lib/features/scene/detail/widget/list_item/detail_list_module6.dart
class DetailListModule6 (line 14) | class DetailListModule6 extends StatefulWidget {
method createState (line 18) | State<DetailListModule6> createState()
class _DetailListModule6State (line 21) | class _DetailListModule6State extends State<DetailListModule6>
method build (line 26) | Widget build(BuildContext context)
method _buildListView (line 43) | Widget _buildListView()
method _buildCardItem (line 59) | Widget _buildCardItem(int index)
method _buildCardItemImage (line 92) | Widget _buildCardItemImage()
method _buildCardItemSubtitle (line 105) | Widget _buildCardItemSubtitle(int index)
method _buildCardItemTitle (line 122) | Widget _buildCardItemTitle(int index)
FILE: example/lib/features/scene/detail/widget/list_item/detail_list_module7.dart
class DetailListModule7 (line 11) | class DetailListModule7 extends StatefulWidget {
method createState (line 15) | State<DetailListModule7> createState()
class _DetailListModule7State (line 18) | class _DetailListModule7State extends State<DetailListModule7>
method build (line 21) | Widget build(BuildContext context)
method _buildListView (line 30) | Widget _buildListView()
method _buildListItem (line 42) | Widget _buildListItem(int index)
method _buildListItemStatus (line 79) | Widget _buildListItemStatus(double progress)
method _buildListItemProgress (line 89) | Widget _buildListItemProgress(double progress)
method _buildListItemTitle (line 99) | Widget _buildListItemTitle(int index)
FILE: example/lib/features/scene/detail/widget/list_item/detail_list_module8.dart
class DetailListModule8 (line 11) | class DetailListModule8 extends StatefulWidget {
method createState (line 15) | State<DetailListModule8> createState()
class _DetailListModule8State (line 18) | class _DetailListModule8State extends State<DetailListModule8>
method build (line 21) | Widget build(BuildContext context)
method _buildListView (line 30) | Widget _buildListView()
method _buildItem (line 42) | Widget _buildItem(int index)
method _buildItemImage (line 76) | Widget _buildItemImage()
method _buildItemDetails (line 87) | Widget _buildItemDetails()
FILE: example/lib/features/scene/expandable_carousel_slider_demo/expandable_carousel_slider_demo.dart
class ExpandableCarouselSliderDemo (line 16) | class ExpandableCarouselSliderDemo extends StatefulWidget {
method createState (line 20) | State<ExpandableCarouselSliderDemo> createState()
class _ExpandableCarouselSliderDemoState (line 24) | class _ExpandableCarouselSliderDemoState
method initState (line 45) | void initState()
method dispose (line 59) | void dispose()
method build (line 65) | Widget build(BuildContext context)
method _buildIndicator (line 80) | Widget _buildIndicator()
method _buildCarousel (line 98) | Widget _buildCarousel()
class CarouselItem (line 160) | class CarouselItem extends StatelessWidget {
method build (line 173) | Widget build(BuildContext context)
FILE: example/lib/features/scene/image_tab_demo/image_tab_page.dart
class ImageTabPage (line 10) | class ImageTabPage extends StatefulWidget {
method createState (line 14) | State<ImageTabPage> createState()
class _ImageTabPageState (line 17) | class _ImageTabPageState extends State<ImageTabPage> {
method initState (line 37) | void initState()
method dispose (line 43) | void dispose()
method build (line 49) | Widget build(BuildContext context)
method _buildImageTabBar (line 73) | Widget _buildImageTabBar()
method _buildListItemView (line 95) | Widget _buildListItemView(int index)
method _buildImageWidget (line 131) | Widget _buildImageWidget(int index)
method _buildSeparatorView (line 151) | Container _buildSeparatorView()
method _fetchImgUrl (line 158) | String _fetchImgUrl(int index)
FILE: example/lib/features/scene/scrollview_form_demo/scrollview_form_demo_page.dart
class ScrollViewFormDemoPage (line 11) | class ScrollViewFormDemoPage extends StatefulWidget {
method createState (line 15) | State<ScrollViewFormDemoPage> createState()
class _ScrollViewFormDemoPageState (line 18) | class _ScrollViewFormDemoPageState extends State<ScrollViewFormDemoPage> {
method initState (line 64) | void initState()
method dispose (line 72) | void dispose()
method build (line 78) | Widget build(BuildContext context)
method _buildScrollView (line 86) | Widget _buildScrollView()
method _buildForm (line 105) | Widget _buildForm()
method _buildImage (line 143) | Widget _buildImage()
method _fetchImgUrl (line 167) | String _fetchImgUrl()
FILE: example/lib/features/scene/video_auto_play_list/video_list_auto_play_page.dart
class VideoListAutoPlayPage (line 10) | class VideoListAutoPlayPage extends StatefulWidget {
method createState (line 14) | State<VideoListAutoPlayPage> createState()
class _VideoListAutoPlayPageState (line 17) | class _VideoListAutoPlayPageState extends State<VideoListAutoPlayPage> {
method build (line 23) | Widget build(BuildContext context)
method _buildListView (line 45) | ListView _buildListView()
method _buildListItemView (line 58) | Widget _buildListItemView(int index)
method _buildSeparatorView (line 72) | Container _buildSeparatorView()
FILE: example/lib/features/scene/video_auto_play_list/widgets/video_widget.dart
class VideoWidget (line 9) | class VideoWidget extends StatefulWidget {
method createState (line 18) | State<VideoWidget> createState()
class _VideoWidgetState (line 21) | class _VideoWidgetState extends State<VideoWidget> {
method initState (line 26) | void initState()
method dispose (line 38) | void dispose()
method didUpdateWidget (line 44) | void didUpdateWidget(VideoWidget oldWidget)
method build (line 51) | Widget build(BuildContext context)
FILE: example/lib/features/scene/visibility_demo/page/visibility_listview_page.dart
class VisibilityListViewPage (line 11) | class VisibilityListViewPage extends StatefulWidget {
method createState (line 15) | State<VisibilityListViewPage> createState()
class _VisibilityListViewPageState (line 18) | class _VisibilityListViewPageState extends State<VisibilityListViewPage>
method build (line 25) | Widget build(BuildContext context)
method _buildListView (line 62) | Widget _buildListView()
method _buildListItemView (line 74) | Widget _buildListItemView(int index)
method _buildSeparatorView (line 95) | Container _buildSeparatorView()
FILE: example/lib/features/scene/visibility_demo/page/visibility_scrollview_page.dart
class VisibilityScrollViewPage (line 12) | class VisibilityScrollViewPage extends StatefulWidget {
method createState (line 16) | State<VisibilityScrollViewPage> createState()
class _VisibilityScrollViewPageState (line 20) | class _VisibilityScrollViewPageState extends State<VisibilityScrollViewP...
method build (line 30) | Widget build(BuildContext context)
method _buildScrollView (line 86) | Widget _buildScrollView()
method _buildSliverAppBar (line 98) | Widget _buildSliverAppBar()
method _buildSliverListView (line 109) | Widget _buildSliverListView()
method _buildMiddleSliver (line 138) | Widget _buildMiddleSliver()
method _buildSliverGridView (line 158) | Widget _buildSliverGridView()
FILE: example/lib/features/scene/waterfall_flow_demo/waterfall_flow_grid_item_view.dart
class WaterfallFlowGridItemView (line 10) | class WaterfallFlowGridItemView extends StatelessWidget {
method build (line 28) | Widget build(BuildContext context)
method _buildBody (line 37) | Widget _buildBody()
method _buildCover (line 51) | Widget _buildCover()
method _buildVideo (line 77) | Widget _buildVideo()
FILE: example/lib/features/scene/waterfall_flow_demo/waterfall_flow_page.dart
class WaterfallFlowPage (line 13) | class WaterfallFlowPage extends StatefulWidget {
method createState (line 17) | State<WaterfallFlowPage> createState()
class WaterfallFlowPageState (line 20) | class WaterfallFlowPageState extends State<WaterfallFlowPage> {
method build (line 34) | Widget build(BuildContext context)
method _buildScrollView (line 142) | Widget _buildScrollView()
method _buildBody (line 156) | Widget _buildBody()
method _buildBanner (line 172) | Widget _buildBanner()
method _buildGridView (line 187) | Widget _buildGridView({
method _buildSwipeView (line 219) | Widget _buildSwipeView()
method _buildSeparator (line 232) | Widget _buildSeparator(double size)
FILE: example/lib/features/scene/waterfall_flow_demo/waterfall_flow_swipe_view.dart
class WaterfallFlowSwipeView (line 10) | class WaterfallFlowSwipeView extends StatefulWidget {
method createState (line 19) | State<WaterfallFlowSwipeView> createState()
class _WaterfallFlowSwipeViewState (line 22) | class _WaterfallFlowSwipeViewState extends State<WaterfallFlowSwipeView> {
method build (line 28) | Widget build(BuildContext context)
method _buildVideo (line 55) | Widget _buildVideo()
FILE: example/lib/features/scene/waterfall_flow_demo/waterfall_flow_type.dart
type WaterFlowHitType (line 6) | enum WaterFlowHitType {
FILE: example/lib/features/scene/waterfall_flow_fixed_height_demo/waterfall_flow_fixed_height_page.dart
class WaterfallFlowFixedHeightPage (line 12) | class WaterfallFlowFixedHeightPage extends StatefulWidget {
method createState (line 16) | State<WaterfallFlowFixedHeightPage> createState()
class WaterfallFlowFixedHeightPageState (line 20) | class WaterfallFlowFixedHeightPageState
method initState (line 31) | void initState()
method dispose (line 38) | void dispose()
method build (line 44) | Widget build(BuildContext context)
method _buildBody (line 97) | Widget _buildBody()
method _buildGridView (line 106) | Widget _buildGridView({
FILE: example/lib/main.dart
function main (line 10) | void main()
class MyApp (line 14) | class MyApp extends StatelessWidget {
method build (line 18) | Widget build(BuildContext context)
FILE: example/lib/typedefs.dart
function ambiguate (line 7) | T? ambiguate<T>(T? value)
FILE: example/lib/utils/keyboard.dart
class KeyboardTool (line 9) | class KeyboardTool {
method dismissKeyboard (line 10) | void dismissKeyboard(BuildContext context)
FILE: example/lib/utils/random.dart
class RandomTool (line 10) | class RandomTool {
method genInt (line 11) | int genInt({int min = 0, int max = 100})
method color (line 16) | Color color()
FILE: example/lib/utils/snackbar.dart
class SnackBarUtil (line 9) | class SnackBarUtil {
method showSnackBar (line 10) | showSnackBar({
FILE: example/lib/widgets/animation.dart
class SlideAnimation (line 9) | class SlideAnimation extends StatelessWidget {
method build (line 32) | Widget build(BuildContext context)
method _slideAnimation (line 40) | Widget _slideAnimation(Animation<double> animation)
method offsetAnimation (line 41) | Animation<double> offsetAnimation(
class FadeInAnimation (line 67) | class FadeInAnimation extends StatelessWidget {
method build (line 82) | Widget build(BuildContext context)
method _fadeInAnimation (line 90) | Widget _fadeInAnimation(Animation<double> animation)
type Builder (line 105) | typedef Builder = Widget Function(
class AnimationExecutor (line 110) | class AnimationExecutor extends StatefulWidget {
method createState (line 121) | State<AnimationExecutor> createState()
class _AnimationExecutorState (line 124) | class _AnimationExecutorState extends State<AnimationExecutor>
method build (line 127) | Widget build(BuildContext context)
method _buildAnimation (line 134) | Widget _buildAnimation(BuildContext context, Widget? child)
FILE: example/lib/widgets/sliver.dart
type SliverHeaderBuilder (line 9) | typedef SliverHeaderBuilder = Widget Function(
class SliverHeaderDelegate (line 15) | class SliverHeaderDelegate extends SliverPersistentHeaderDelegate {
method build (line 41) | Widget build(
method shouldRebuild (line 57) | bool shouldRebuild(SliverHeaderDelegate oldDelegate)
FILE: example/linux/flutter/generated_plugin_registrant.cc
function fl_register_plugins (line 10) | void fl_register_plugins(FlPluginRegistry* registry) {
FILE: example/test/widget_test.dart
function main (line 18) | void main()
FILE: example/windows/flutter/generated_plugin_registrant.cc
function RegisterPlugins (line 10) | void RegisterPlugins(flutter::PluginRegistry* registry) {
FILE: example/windows/runner/flutter_window.cpp
function LRESULT (line 40) | LRESULT
FILE: example/windows/runner/flutter_window.h
function class (line 12) | class FlutterWindow : public Win32Window {
FILE: example/windows/runner/main.cpp
function wWinMain (line 8) | int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev,
FILE: example/windows/runner/utils.cpp
function CreateAndAttachConsole (line 10) | void CreateAndAttachConsole() {
function GetCommandLineArguments (line 24) | std::vector<std::string> GetCommandLineArguments() {
function Utf8FromUtf16 (line 44) | std::string Utf8FromUtf16(const wchar_t* utf16_string) {
FILE: example/windows/runner/win32_window.cpp
function Scale (line 18) | int Scale(int source, double scale_factor) {
function EnableFullDpiSupportIfAvailable (line 24) | void EnableFullDpiSupportIfAvailable(HWND hwnd) {
class WindowClassRegistrar (line 41) | class WindowClassRegistrar {
method WindowClassRegistrar (line 46) | static WindowClassRegistrar* GetInstance() {
method WindowClassRegistrar (line 62) | WindowClassRegistrar() = default;
function wchar_t (line 71) | const wchar_t* WindowClassRegistrar::GetWindowClass() {
function LRESULT (line 133) | LRESULT CALLBACK Win32Window::WndProc(HWND const window,
function LRESULT (line 152) | LRESULT
function Win32Window (line 208) | Win32Window* Win32Window::GetThisFromHandle(HWND const window) noexcept {
function RECT (line 224) | RECT Win32Window::GetClientArea() {
function HWND (line 230) | HWND Win32Window::GetHandle() {
FILE: example/windows/runner/win32_window.h
type Size (line 21) | struct Size {
FILE: lib/src/common/models/observe_displaying_child_model.dart
class ObserveDisplayingChildModel (line 8) | abstract class ObserveDisplayingChildModel {
FILE: lib/src/common/models/observe_find_child_model.dart
class ObserveFindChildModel (line 10) | class ObserveFindChildModel {
FILE: lib/src/common/models/observe_model.dart
class ObserveModel (line 10) | abstract class ObserveModel {
FILE: lib/src/common/models/observe_scroll_child_model.dart
class ObserveScrollChildModel (line 6) | class ObserveScrollChildModel {
FILE: lib/src/common/models/observe_scroll_to_index_result_model.dart
class ObserveScrollToIndexFixedHeightResultModel (line 9) | class ObserveScrollToIndexFixedHeightResultModel {
class ObservePrepareScrollToIndexModel (line 30) | class ObservePrepareScrollToIndexModel {
FILE: lib/src/common/models/observer_handle_contexts_result_model.dart
class ObserverHandleContextsResultModel (line 10) | class ObserverHandleContextsResultModel<M extends ObserveModel> {
FILE: lib/src/common/models/observer_index_position_model.dart
class ObserverIndexPositionModel (line 4) | class ObserverIndexPositionModel {
FILE: lib/src/common/observer_controller.dart
class ObserverController (line 19) | class ObserverController {
method innerReset (line 50) | void innerReset()
method fetchSliverContext (line 56) | BuildContext? fetchSliverContext({BuildContext? sliverContext})
method reattach (line 65) | void reattach()
function innerDispatchOnceObserve (line 81) | Future<S> innerDispatchOnceObserve({
function innerCreateOnceObserveNotificationResult (line 115) | S innerCreateOnceObserveNotificationResult({
function findCurrentFirstChild (line 126) | RenderIndexedSemantics? findCurrentFirstChild(
function findNextChild (line 144) | RenderIndexedSemantics? findNextChild({
function findCurrentLastChild (line 164) | RenderIndexedSemantics? findCurrentLastChild(
function findChildInfo (line 181) | ObserveFindChildModel? findChildInfo({
function findCurrentFirstChildInfo (line 205) | ObserveFindChildModel? findCurrentFirstChildInfo({
function _findViewport (line 218) | RenderViewportBase? _findViewport(RenderSliverMultiBoxAdaptor obj)
function viewportMaxScrollExtent (line 223) | double viewportMaxScrollExtent(RenderViewportBase viewport)
function viewportExtremeScrollExtent (line 234) | double viewportExtremeScrollExtent({
function innerJumpTo (line 320) | Future innerJumpTo({
function innerAnimateTo (line 358) | Future innerAnimateTo({
function _scrollTo (line 852) | Future<void> _scrollTo({
function _calculateTargetLayoutOffset (line 882) | ObservePrepareScrollToIndexModel _calculateTargetLayoutOffset({
function _calculateScrollToIndexForFixedHeightResultForList (line 955) | ObserveScrollToIndexFixedHeightResultModel
function _calculateScrollToIndexForFixedHeightResultForGrid (line 993) | ObserveScrollToIndexFixedHeightResultModel
FILE: lib/src/common/observer_listener.dart
class ObserverListenerEntry (line 14) | class ObserverListenerEntry<M extends ObserveModel>
FILE: lib/src/common/observer_notification_result.dart
class CommonOnceObserveNotificationResult (line 12) | class CommonOnceObserveNotificationResult<M extends ObserveModel,
FILE: lib/src/common/observer_typedef.dart
type ObserverOnPrepareScrollToIndex (line 14) | typedef ObserverOnPrepareScrollToIndex = Future<bool> Function(
type OnObserveCallback (line 20) | typedef OnObserveCallback<M extends ObserveModel> = void Function(
type OnObserveAllCallback (line 27) | typedef OnObserveAllCallback<M extends ObserveModel> = void Function(
type OnObserveViewportCallback (line 34) | typedef OnObserveViewportCallback = void Function(
type ObserverAutoTriggerObserveType (line 39) | enum ObserverAutoTriggerObserveType {
type ObserverTriggerOnObserveType (line 46) | enum ObserverTriggerOnObserveType {
type ObserverRenderSliverType (line 52) | enum ObserverRenderSliverType {
FILE: lib/src/common/observer_widget.dart
class ObserverWidget (line 26) | class ObserverWidget<C extends ObserverController, M extends ObserveModel,
method createState (line 115) | State<ObserverWidget> createState()
method maybeOf (line 133) | ObserverWidgetState<C, M, N, T>? maybeOf<
method of (line 167) | ObserverWidgetState<C, M, N, T> of<
class ObserverWidgetState (line 198) | class ObserverWidgetState<
method _debugAssertNotDisposed (line 259) | bool _debugAssertNotDisposed()
method initState (line 273) | void initState()
method didUpdateWidget (line 279) | void didUpdateWidget(covariant T oldWidget)
method dispose (line 286) | void dispose()
method build (line 294) | Widget build(BuildContext context)
method fetchTargetSliverContexts (line 396) | List<BuildContext> fetchTargetSliverContexts()
method visitor (line 404) | void visitor(Element element)
method fetchLeadingOffset (line 430) | double fetchLeadingOffset()
method isTargetSliverContextType (line 439) | bool isTargetSliverContextType(RenderObject? obj)
method handleContexts (line 462) | ObserverHandleContextsResultModel<M>? handleContexts({
method handleObserve (line 545) | M? handleObserve(BuildContext ctx)
method _handleScopeContext (line 552) | void _handleScopeContext(BuildContext ctx)
method _checkTagChange (line 562) | void _checkTagChange(T oldWidget)
method addListener (line 583) | void addListener({
method removeListener (line 601) | void removeListener({
method _notifyListeners (line 623) | void _notifyListeners(
FILE: lib/src/common/observer_widget_scope.dart
class ObserverWidgetScope (line 13) | class ObserverWidgetScope<
method createElement (line 32) | InheritedElement createElement()
method updateShouldNotify (line 39) | bool updateShouldNotify(covariant ObserverWidgetScope oldWidget)
FILE: lib/src/common/observer_widget_tag_manager.dart
class ObserverWidgetTagManager (line 9) | class ObserverWidgetTagManager extends InheritedWidget {
method maybeOf (line 20) | ObserverWidgetTagManager? maybeOf(BuildContext context)
method set (line 26) | void set(
method remove (line 34) | void remove(String tag)
method context (line 39) | BuildContext? context(
method updateShouldNotify (line 53) | bool updateShouldNotify(covariant ObserverWidgetTagManager oldWidget)
FILE: lib/src/common/typedefs.dart
function ambiguate (line 13) | T? ambiguate<T>(T? value)
type ObserverLocateIndexOffsetCallback (line 20) | typedef ObserverLocateIndexOffsetCallback = double Function(
type ObserverWidgetObserveResultType (line 24) | enum ObserverWidgetObserveResultType {
FILE: lib/src/gridview/grid_observer_controller.dart
class GridObserverController (line 13) | class GridObserverController extends ObserverController
method dispatchOnceObserve (line 26) | Future<GridViewOnceObserveNotificationResult> dispatchOnceObserve({
method observeItem (line 41) | GridViewObserveDisplayingChildModel? observeItem({
method observeFirstItem (line 59) | GridViewObserveDisplayingChildModel? observeFirstItem({
method innerCreateOnceObserveNotificationResult (line 74) | GridViewOnceObserveNotificationResult
method animateTo (line 93) | Future animateTo({
method jumpTo (line 127) | Future jumpTo({
FILE: lib/src/gridview/grid_observer_notification_result.dart
class GridViewOnceObserveNotificationResult (line 12) | class GridViewOnceObserveNotificationResult
FILE: lib/src/gridview/grid_observer_view.dart
class GridViewObserver (line 17) | class GridViewObserver extends ObserverWidget<GridObserverController,
method createState (line 60) | State<GridViewObserver> createState()
method maybeOf (line 62) | GridViewObserverState? maybeOf(
method of (line 78) | GridViewObserverState of(
class GridViewObserverState (line 94) | class GridViewObserverState extends ObserverWidgetState<GridObserverCont...
method handleObserve (line 97) | GridViewObserveModel? handleObserve(BuildContext ctx)
method isTargetSliverContextType (line 110) | bool isTargetSliverContextType(RenderObject? obj)
FILE: lib/src/gridview/models/gridview_observe_displaying_child_model.dart
class GridViewObserveDisplayingChildModel (line 10) | class GridViewObserveDisplayingChildModel extends ObserveDisplayingChild...
FILE: lib/src/gridview/models/gridview_observe_model.dart
class GridViewObserveModel (line 11) | class GridViewObserveModel extends ObserveModel {
FILE: lib/src/listview/list_observer_controller.dart
class ListObserverController (line 13) | class ListObserverController extends ObserverController
method dispatchOnceObserve (line 26) | Future<ListViewOnceObserveNotificationResult> dispatchOnceObserve({
method observeItem (line 41) | ListViewObserveDisplayingChildModel? observeItem({
method observeFirstItem (line 59) | ListViewObserveDisplayingChildModel? observeFirstItem({
method innerCreateOnceObserveNotificationResult (line 74) | ListViewOnceObserveNotificationResult
method animateTo (line 93) | Future animateTo({
method jumpTo (line 127) | Future jumpTo({
FILE: lib/src/listview/list_observer_notification_result.dart
class ListViewOnceObserveNotificationResult (line 12) | class ListViewOnceObserveNotificationResult
FILE: lib/src/listview/list_observer_view.dart
class ListViewObserver (line 17) | class ListViewObserver extends ObserverWidget<ListObserverController,
method createState (line 60) | State<ListViewObserver> createState()
method maybeOf (line 77) | ListViewObserverState? maybeOf(
method of (line 109) | ListViewObserverState of(
method isSupportRenderSliverType (line 125) | bool isSupportRenderSliverType(RenderObject? obj)
class ListViewObserverState (line 140) | class ListViewObserverState extends ObserverWidgetState<ListObserverCont...
method handleObserve (line 143) | ListViewObserveModel? handleObserve(BuildContext ctx)
method isTargetSliverContextType (line 156) | bool isTargetSliverContextType(RenderObject? obj)
FILE: lib/src/listview/models/listview_observe_displaying_child_model.dart
class ListViewObserveDisplayingChildModel (line 10) | class ListViewObserveDisplayingChildModel extends ObserveDisplayingChild...
FILE: lib/src/listview/models/listview_observe_model.dart
class ListViewObserveModel (line 12) | class ListViewObserveModel extends ObserveModel {
FILE: lib/src/notification.dart
class ScrollViewOnceObserveNotification (line 9) | class ScrollViewOnceObserveNotification extends Notification {
class ListViewOnceObserveNotification (line 25) | class ListViewOnceObserveNotification
class GridViewOnceObserveNotification (line 37) | class GridViewOnceObserveNotification
class ObserverScrollNotification (line 53) | class ObserverScrollNotification extends Notification {
method dispatch (line 55) | void dispatch(BuildContext? target)
class ObserverScrollStartNotification (line 66) | class ObserverScrollStartNotification extends ObserverScrollNotification {}
class ObserverScrollInterruptionNotification (line 70) | class ObserverScrollInterruptionNotification
class ObserverScrollDecisionNotification (line 75) | class ObserverScrollDecisionNotification extends ObserverScrollNotificat...
class ObserverScrollEndNotification (line 79) | class ObserverScrollEndNotification extends ObserverScrollNotification {}
FILE: lib/src/observer_core.dart
class ObserverCore (line 18) | class ObserverCore {
method handleListObserve (line 20) | ListViewObserveModel? handleListObserve({
method handleGridObserve (line 157) | GridViewObserveModel? handleGridObserve({
FILE: lib/src/sliver/models/sliver_observer_observe_result_model.dart
class SliverObserverHandleContextsResultModel (line 12) | class SliverObserverHandleContextsResultModel<M extends ObserveModel>
FILE: lib/src/sliver/models/sliver_viewport_observe_displaying_child_model.dart
class SliverViewportObserveDisplayingChildModel (line 9) | class SliverViewportObserveDisplayingChildModel {
FILE: lib/src/sliver/models/sliver_viewport_observe_model.dart
class SliverViewportObserveModel (line 11) | class SliverViewportObserveModel {
FILE: lib/src/sliver/sliver_observer_controller.dart
class SliverObserverController (line 12) | class SliverObserverController extends ObserverController
method dispatchOnceObserve (line 28) | Future<ScrollViewOnceObserveNotificationResult> dispatchOnceObserve({
method innerCreateOnceObserveNotificationResult (line 44) | ScrollViewOnceObserveNotificationResult
method animateTo (line 63) | Future animateTo({
method jumpTo (line 106) | Future jumpTo({
FILE: lib/src/sliver/sliver_observer_listener.dart
class SliverObserverListenerEntry (line 13) | class SliverObserverListenerEntry
FILE: lib/src/sliver/sliver_observer_notification_result.dart
class ScrollViewOnceObserveNotificationResult (line 13) | class ScrollViewOnceObserveNotificationResult
FILE: lib/src/sliver/sliver_observer_view.dart
class SliverViewObserver (line 26) | class SliverViewObserver extends ObserverWidget<SliverObserverController,
method createState (line 83) | State<SliverViewObserver> createState()
method maybeOf (line 100) | MixViewObserverState? maybeOf(
method of (line 129) | MixViewObserverState of(
class MixViewObserverState (line 142) | class MixViewObserverState extends ObserverWidgetState<SliverObserverCon...
method _debugAssertNotDisposed (line 157) | bool _debugAssertNotDisposed()
method dispose (line 171) | void dispose()
method handleContexts (line 179) | SliverObserverHandleContextsResultModel<ObserveModel>? handleContexts({
method handleObserve (line 217) | ObserveModel? handleObserve(BuildContext ctx)
method handleObserveViewport (line 241) | SliverViewportObserveModel? handleObserveViewport({
method addListener (line 361) | void addListener({
method removeListener (line 387) | void removeListener({
method _notifySliverListeners (line 415) | void _notifySliverListeners(
FILE: lib/src/utils/src/chat/chat_observer_scroll_physics.dart
class ChatObserverClampinScrollPhysics (line 11) | @Deprecated(
class ChatObserverClampingScrollPhysics (line 20) | class ChatObserverClampingScrollPhysics extends ClampingScrollPhysics
method applyTo (line 30) | ChatObserverClampingScrollPhysics applyTo(ScrollPhysics? ancestor)
class ChatObserverBouncingScrollPhysics (line 38) | class ChatObserverBouncingScrollPhysics extends BouncingScrollPhysics
method applyTo (line 48) | ChatObserverBouncingScrollPhysics applyTo(ScrollPhysics? ancestor)
FILE: lib/src/utils/src/chat/chat_observer_scroll_physics_mixin.dart
function adjustPositionForNewDimensions (line 14) | double adjustPositionForNewDimensions({
function shouldAcceptUserOffset (line 102) | bool shouldAcceptUserOffset(ScrollMetrics position)
FILE: lib/src/utils/src/chat/chat_scroll_observer.dart
class ChatScrollObserver (line 12) | class ChatScrollObserver {
method observeRefItem (line 87) | ListViewObserveDisplayingChildModel? observeRefItem()
FILE: lib/src/utils/src/chat/chat_scroll_observer_model.dart
class ChatScrollObserverHandlePositionResultModel (line 12) | class ChatScrollObserverHandlePositionResultModel {
class ChatScrollObserverCustomAdjustPositionDeltaModel (line 29) | class ChatScrollObserverCustomAdjustPositionDeltaModel {
class ChatScrollObserverCustomAdjustPositionModel (line 62) | class ChatScrollObserverCustomAdjustPositionModel {
FILE: lib/src/utils/src/chat/chat_scroll_observer_typedefs.dart
type ChatScrollObserverCustomAdjustPositionDelta (line 10) | typedef ChatScrollObserverCustomAdjustPositionDelta = double? Function(
type ChatScrollObserverCustomAdjustPosition (line 15) | typedef ChatScrollObserverCustomAdjustPosition = double? Function(
type ChatScrollObserverHandlePositionType (line 19) | enum ChatScrollObserverHandlePositionType {
type ChatScrollObserverHandleMode (line 27) | enum ChatScrollObserverHandleMode {
type ChatScrollObserverRefIndexType (line 41) | enum ChatScrollObserverRefIndexType {
FILE: lib/src/utils/src/extends.dart
function rectify (line 14) | double rectify(
FILE: lib/src/utils/src/log.dart
class Log (line 3) | class Log {
method info (line 6) | void info(String msg)
method success (line 10) | void success(String msg)
method warning (line 14) | warning(String msg)
method error (line 18) | error(String msg)
method _log (line 22) | _log(String message)
FILE: lib/src/utils/src/nested_scroll_util.dart
type NestedScrollUtilPosition (line 12) | enum NestedScrollUtilPosition {
class NestedScrollUtil (line 20) | class NestedScrollUtil {
method calcOverlap (line 42) | double? calcOverlap({
method calcPrecedingScrollExtent (line 81) | double? calcPrecedingScrollExtent({
method fetchRemainingSliverContext (line 113) | BuildContext? fetchRemainingSliverContext({
method jumpTo (line 134) | Future jumpTo({
method animateTo (line 173) | Future animateTo({
method handleOnPrepareScrollToIndex (line 239) | ObserverOnPrepareScrollToIndex? handleOnPrepareScrollToIndex({
FILE: lib/src/utils/src/observer_utils.dart
class ObserverUtils (line 16) | class ObserverUtils {
method calcPersistentHeaderExtent (line 24) | double calcPersistentHeaderExtent({
method calcAnchorTabIndex (line 40) | int calcAnchorTabIndex({
method calcAnchorTabIndexForList (line 116) | int calcAnchorTabIndexForList({
method isBelowOffsetWidgetInSliver (line 169) | bool isBelowOffsetWidgetInSliver({
method isReachOffsetWidgetInSliver (line 196) | bool isReachOffsetWidgetInSliver({
method isDisplayingChildInSliver (line 219) | bool isDisplayingChildInSliver({
method findViewport (line 246) | RenderViewportBase? findViewport(RenderObject obj)
method isBelowOffsetSliverInViewport (line 271) | bool isBelowOffsetSliverInViewport({
method isDisplayingSliverInViewport (line 284) | bool isDisplayingSliverInViewport({
method isValidListIndex (line 305) | bool isValidListIndex(int index)
method findRenderObject (line 310) | RenderObject? findRenderObject(BuildContext? context)
method findChildContext (line 327) | BuildContext? findChildContext({
method visitor (line 332) | void visitor(Element element)
method localToGlobal (line 363) | Offset? localToGlobal({
method sliverConstraints (line 377) | SliverConstraints? sliverConstraints(
FILE: lib/src/utils/src/slivers.dart
class SliverObserveContext (line 4) | class SliverObserveContext extends SliverPadding {
method createRenderObject (line 17) | RenderSliverPadding createRenderObject(BuildContext context)
class SliverObserveContextToBoxAdapter (line 23) | class SliverObserveContextToBoxAdapter extends SliverToBoxAdapter {
method createRenderObject (line 33) | RenderSliverToBoxAdapter createRenderObject(BuildContext context)
FILE: test/chat_scroll_observer_test.dart
function main (line 10) | void main()
function updateData (line 61) | updateData({
function updateData (line 198) | void updateData({
function setState (line 295) | Future<void> setState()
class ChatListView (line 479) | class ChatListView extends StatefulWidget {
method createState (line 498) | State<ChatListView> createState()
class ChatListViewState (line 501) | class ChatListViewState extends State<ChatListView> {
method initData (line 505) | void initData({
method updateData (line 515) | void updateData({
method build (line 527) | Widget build(BuildContext context)
method _buildListView (line 559) | Widget _buildListView()
FILE: test/grid_observer_test.dart
function main (line 9) | void main()
function getGridView (line 10) | Widget getGridView({
function resetAll (line 409) | resetAll({
function resetAll (line 493) | resetAll()
function resetAll (line 595) | resetAll({
function onObserveCallback (line 680) | onObserveCallback(GridViewObserveModel result)
function onObserveAllCallback (line 684) | onObserveAllCallback(
function onObserveCallback (line 739) | onObserveCallback(GridViewObserveModel result)
function onObserveAllCallback (line 743) | onObserveAllCallback(
FILE: test/list_observer_test.dart
function main (line 9) | void main()
function getListView (line 10) | Widget getListView({
function getFixedHeightListView (line 49) | Widget getFixedHeightListView({
function resetAll (line 606) | resetAll({
function resetAll (line 721) | resetAll()
function resetAll (line 823) | resetAll({
function onObserveCallback (line 911) | onObserveCallback(ListViewObserveModel result)
function onObserveAllCallback (line 915) | onObserveAllCallback(
function onObserveCallback (line 969) | onObserveCallback(ListViewObserveModel result)
function onObserveAllCallback (line 973) | onObserveAllCallback(
FILE: test/observer_utils_test.dart
function main (line 11) | void main()
FILE: test/sliver_observer_test.dart
function main (line 9) | void main()
function calcPersistentHeaderExtent (line 15) | double calcPersistentHeaderExtent({
function _buildDirectionality (line 25) | Widget _buildDirectionality({
function _buildSliverListView (line 34) | Widget _buildSliverListView({
function _buildSliverGridView (line 58) | Widget _buildSliverGridView({
function _buildScrollView (line 87) | Widget _buildScrollView({
function resetAll (line 338) | resetAll({
function resetAll (line 422) | resetAll()
function _buildSliverGridView (line 568) | Widget _buildSliverGridView()
function _buildSliverListView (line 594) | Widget _buildSliverListView()
function _buildNestedScrollView (line 618) | Widget _buildNestedScrollView()
function resetAll (line 680) | Widget resetAll({
function _buildSliverListView (line 1143) | Widget _buildSliverListView({
function _buildScrollView (line 1167) | Widget _buildScrollView({
function resetAll (line 1204) | Widget resetAll({
function resetAll (line 1448) | resetAll({
function onObserveCallback (line 1548) | onObserveCallback(ObserveModel result)
function onObserveAllCallback (line 1552) | onObserveAllCallback(
function onObserveViewportCallback (line 1558) | onObserveViewportCallback(SliverViewportObserveModel result)
function onObserveCallback (line 1671) | onObserveCallback(ObserveModel result)
function onObserveAllCallback (line 1675) | onObserveAllCallback(
function onObserveViewportCallback (line 1681) | onObserveViewportCallback(SliverViewportObserveModel result)
Condensed preview — 247 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (894K chars).
[
{
"path": ".github/FUNDING.yml",
"chars": 863,
"preview": "# These are supported funding model platforms\n\n# github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., "
},
{
"path": ".github/workflows/assign-issue.yml",
"chars": 288,
"preview": "name: Issue assignment\n\non:\n issues:\n types: [opened]\n\njobs:\n auto-assign:\n runs-on: ubuntu-latest\n steps:\n "
},
{
"path": ".github/workflows/code-analysis.yml",
"chars": 1243,
"preview": "name: Code Analysis\n\non:\n workflow_dispatch:\n push:\n branches:\n - main\n paths-ignore:\n - '**.md'\n pul"
},
{
"path": ".github/workflows/deploy.yml",
"chars": 952,
"preview": "name: Deploy to GitHub Pages\non:\n push:\n branches:\n - main\n # - develop\njobs:\n build:\n name: Build Web"
},
{
"path": ".gitignore",
"chars": 735,
"preview": "# Miscellaneous\n*.class\n*.log\n*.pyc\n*.swp\n.DS_Store\n.atom/\n.buildlog/\n.history\n.svn/\n\n# IntelliJ related\n# *.iml\n*.ipr\n*"
},
{
"path": ".packages",
"chars": 2186,
"preview": "# This file is deprecated. Tools should instead consume \n# `.dart_tool/package_config.json`.\n# \n# For more info see: htt"
},
{
"path": "CHANGELOG.md",
"chars": 9450,
"preview": "## 1.26.3\n- ObserverWidget\n - Fix incorrect tag comparison in `_checkTagChange` by @LinXunFeng in [#143](https://github"
},
{
"path": "CODEOWNERS",
"chars": 14,
"preview": "* @LinXunFeng\n"
},
{
"path": "LICENSE",
"chars": 1066,
"preview": "MIT License\n\nCopyright (c) 2022 LinXunFeng\n\nPermission is hereby granted, free of charge, to any person obtaining a copy"
},
{
"path": "README-zh.md",
"chars": 4890,
"preview": "\n\n# Flutter ScrollView "
},
{
"path": "README.md",
"chars": 7488,
"preview": "\n\n# Flutter ScrollView "
},
{
"path": "analysis_options.yaml",
"chars": 154,
"preview": "include: package:flutter_lints/flutter.yaml\n\n# Additional information about this file can be found at\n# https://dart.dev"
},
{
"path": "example/.gitignore",
"chars": 695,
"preview": "# Miscellaneous\n*.class\n*.log\n*.pyc\n*.swp\n.DS_Store\n.atom/\n.buildlog/\n.history\n.svn/\n\n# IntelliJ related\n*.iml\n*.ipr\n*.i"
},
{
"path": "example/.metadata",
"chars": 926,
"preview": "# This file tracks properties of this Flutter project.\n# Used by Flutter tool to assess capabilities and perform upgrade"
},
{
"path": "example/README.md",
"chars": 536,
"preview": "# example\n\nA new Flutter project.\n\n## Getting Started\n\nThis project is a starting point for a Flutter application.\n\nA fe"
},
{
"path": "example/analysis_options.yaml",
"chars": 1453,
"preview": "# This file configures the analyzer, which statically analyzes Dart code to\n# check for errors, warnings, and lints.\n#\n#"
},
{
"path": "example/android/.gitignore",
"chars": 285,
"preview": "gradle-wrapper.jar\n/.gradle\n/captures/\n/gradlew\n/gradlew.bat\n/local.properties\nGeneratedPluginRegistrant.java\n\n# Remembe"
},
{
"path": "example/android/app/build.gradle",
"chars": 1998,
"preview": "def localProperties = new Properties()\ndef localPropertiesFile = rootProject.file('local.properties')\nif (localPropertie"
},
{
"path": "example/android/app/src/debug/AndroidManifest.xml",
"chars": 327,
"preview": "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n package=\"com.example.example\">\n <!-- Flutter"
},
{
"path": "example/android/app/src/main/AndroidManifest.xml",
"chars": 1667,
"preview": "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n package=\"com.example.example\">\n <application\n"
},
{
"path": "example/android/app/src/main/kotlin/com/example/example/MainActivity.kt",
"chars": 124,
"preview": "package com.example.example\n\nimport io.flutter.embedding.android.FlutterActivity\n\nclass MainActivity: FlutterActivity() "
},
{
"path": "example/android/app/src/main/res/drawable/launch_background.xml",
"chars": 434,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- Modify this file to customize your launch splash screen -->\n<layer-list xmln"
},
{
"path": "example/android/app/src/main/res/drawable-v21/launch_background.xml",
"chars": 438,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- Modify this file to customize your launch splash screen -->\n<layer-list xmln"
},
{
"path": "example/android/app/src/main/res/values/styles.xml",
"chars": 985,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n <!-- Theme applied to the Android Window while the process is sta"
},
{
"path": "example/android/app/src/main/res/values-night/styles.xml",
"chars": 984,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n <!-- Theme applied to the Android Window while the process is sta"
},
{
"path": "example/android/app/src/profile/AndroidManifest.xml",
"chars": 327,
"preview": "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n package=\"com.example.example\">\n <!-- Flutter"
},
{
"path": "example/android/build.gradle",
"chars": 599,
"preview": "buildscript {\n ext.kotlin_version = '1.7.10'\n repositories {\n google()\n mavenCentral()\n }\n\n de"
},
{
"path": "example/android/gradle/wrapper/gradle-wrapper.properties",
"chars": 230,
"preview": "#Mon Jan 27 23:32:07 CST 2025\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://"
},
{
"path": "example/android/gradle.properties",
"chars": 369,
"preview": "org.gradle.jvmargs=-Xmx1536M\nandroid.useAndroidX=true\nandroid.enableJetifier=true\norg.gradle.jvmargs=-Xmx2048m -Dfile.en"
},
{
"path": "example/android/settings.gradle",
"chars": 462,
"preview": "include ':app'\n\ndef localPropertiesFile = new File(rootProject.projectDir, \"local.properties\")\ndef properties = new Prop"
},
{
"path": "example/ios/.gitignore",
"chars": 569,
"preview": "**/dgph\n*.mode1v3\n*.mode2v3\n*.moved-aside\n*.pbxuser\n*.perspectivev3\n**/*sync/\n.sconsign.dblite\n.tags*\n**/.vagrant/\n**/De"
},
{
"path": "example/ios/Flutter/AppFrameworkInfo.plist",
"chars": 774,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "example/ios/Flutter/Debug.xcconfig",
"chars": 107,
"preview": "#include? \"Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig\"\n#include \"Generated.xcconfig\"\n"
},
{
"path": "example/ios/Flutter/Release.xcconfig",
"chars": 109,
"preview": "#include? \"Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig\"\n#include \"Generated.xcconfig\"\n"
},
{
"path": "example/ios/Podfile",
"chars": 1355,
"preview": "# Uncomment this line to define a global platform for your project\n# platform :ios, '12.0'\n\n# CocoaPods analytics sends "
},
{
"path": "example/ios/Runner/AppDelegate.swift",
"chars": 391,
"preview": "import UIKit\nimport Flutter\n\n@main\n@objc class AppDelegate: FlutterAppDelegate {\n override func application(\n _ appl"
},
{
"path": "example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json",
"chars": 2519,
"preview": "{\n \"images\" : [\n {\n \"size\" : \"20x20\",\n \"idiom\" : \"iphone\",\n \"filename\" : \"Icon-App-20x20@2x.png\",\n "
},
{
"path": "example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json",
"chars": 391,
"preview": "{\n \"images\" : [\n {\n \"idiom\" : \"universal\",\n \"filename\" : \"LaunchImage.png\",\n \"scale\" : \"1x\"\n },\n "
},
{
"path": "example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md",
"chars": 336,
"preview": "# Launch Screen Assets\n\nYou can customize the launch screen with your own desired assets by replacing the image files in"
},
{
"path": "example/ios/Runner/Base.lproj/LaunchScreen.storyboard",
"chars": 2377,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard"
},
{
"path": "example/ios/Runner/Base.lproj/Main.storyboard",
"chars": 1605,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard"
},
{
"path": "example/ios/Runner/Info.plist",
"chars": 1704,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "example/ios/Runner/Runner-Bridging-Header.h",
"chars": 38,
"preview": "#import \"GeneratedPluginRegistrant.h\"\n"
},
{
"path": "example/ios/Runner.xcodeproj/project.pbxproj",
"chars": 22446,
"preview": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 54;\n\tobjects = {\n\n/* Begin PBXBuildFile section *"
},
{
"path": "example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata",
"chars": 135,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n version = \"1.0\">\n <FileRef\n location = \"self:\">\n </FileRef"
},
{
"path": "example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist",
"chars": 238,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings",
"chars": 226,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme",
"chars": 3371,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n LastUpgradeVersion = \"1510\"\n version = \"1.3\">\n <BuildAction\n "
},
{
"path": "example/ios/Runner.xcworkspace/contents.xcworkspacedata",
"chars": 224,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n version = \"1.0\">\n <FileRef\n location = \"group:Runner.xcodepr"
},
{
"path": "example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist",
"chars": 238,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings",
"chars": 226,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "example/lib/common/route/navigation_service.dart",
"chars": 1152,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/fluttercandies/flutter_scrollview_observer\n *"
},
{
"path": "example/lib/common/route/route.dart",
"chars": 216,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/fluttercandies/flutter_scrollview_observer\n *"
},
{
"path": "example/lib/common/route/router_config.dart",
"chars": 11768,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/fluttercandies/flutter_scrollview_observer\n *"
},
{
"path": "example/lib/features/custom_scrollview/custom_scrollview_demo/custom_scrollview_center_demo_page.dart",
"chars": 7340,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/fluttercandies/flutter_scrollview_observer\n *"
},
{
"path": "example/lib/features/custom_scrollview/custom_scrollview_demo/custom_scrollview_demo_page.dart",
"chars": 6464,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/LinXunFeng/flutter_scrollview_observer\n * @Da"
},
{
"path": "example/lib/features/custom_scrollview/custom_scrollview_demo/multi_sliver_demo_page.dart",
"chars": 8112,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/LinXunFeng/flutter_scrollview_observer\n * @Da"
},
{
"path": "example/lib/features/custom_scrollview/sliver_appbar_demo/sliver_appbar_demo_page.dart",
"chars": 6878,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/LinXunFeng/flutter_scrollview_observer\n * @Da"
},
{
"path": "example/lib/features/gridview/gridview_ctx_demo/gridview_ctx_demo_page.dart",
"chars": 2637,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/LinXunFeng/flutter_scrollview_observer\n * @Da"
},
{
"path": "example/lib/features/gridview/gridview_custom_demo/gridview_custom_demo_page.dart",
"chars": 3383,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/LinXunFeng/flutter_scrollview_observer\n * @Da"
},
{
"path": "example/lib/features/gridview/gridview_demo/gridview_demo_page.dart",
"chars": 3235,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/LinXunFeng/flutter_scrollview_observer\n * @Da"
},
{
"path": "example/lib/features/gridview/gridview_fixed_height_demo/gridview_fixed_height_demo_page.dart",
"chars": 3200,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/LinXunFeng/flutter_scrollview_observer\n * @Da"
},
{
"path": "example/lib/features/gridview/horizontal_gridview_demo/horizontal_gridview_demo_page.dart",
"chars": 4283,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/LinXunFeng/flutter_scrollview_observer\n * @Da"
},
{
"path": "example/lib/features/gridview/sliver_grid_demo/sliver_grid_demo_page.dart",
"chars": 3999,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/LinXunFeng/flutter_scrollview_observer\n * @Da"
},
{
"path": "example/lib/features/home/home_page.dart",
"chars": 7033,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/LinXunFeng/flutter_scrollview_observer\n * @Da"
},
{
"path": "example/lib/features/listview/horizontal_listview_demo/horizontal_listview_page.dart",
"chars": 2536,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/LinXunFeng/flutter_scrollview_observer\n * @Da"
},
{
"path": "example/lib/features/listview/infinite_listview_demo/infinite_listview_page.dart",
"chars": 5015,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/fluttercandies/flutter_scrollview_observer\n *"
},
{
"path": "example/lib/features/listview/listview_ctx_demo/listview_ctx_demo_page.dart",
"chars": 2953,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/LinXunFeng/flutter_scrollview_observer\n * @Da"
},
{
"path": "example/lib/features/listview/listview_custom_demo/listview_custom_demo_page.dart",
"chars": 3116,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/LinXunFeng/flutter_scrollview_observer\n * @Da"
},
{
"path": "example/lib/features/listview/listview_demo/listview_demo_page.dart",
"chars": 4264,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/LinXunFeng/flutter_scrollview_observer\n * @Da"
},
{
"path": "example/lib/features/listview/listview_dynamic_offset/listview_dynamic_offset_page.dart",
"chars": 5068,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/LinXunFeng/flutter_scrollview_observer\n * @Da"
},
{
"path": "example/lib/features/listview/listview_fixed_height_demo/listview_fixed_height_demo_page.dart",
"chars": 4212,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/LinXunFeng/flutter_scrollview_observer\n * @Da"
},
{
"path": "example/lib/features/listview/sliver_list_demo/sliver_list_demo_page.dart",
"chars": 3938,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/LinXunFeng/flutter_scrollview_observer\n * @Da"
},
{
"path": "example/lib/features/nested_scrollview/nested_scrollview_demo/nested_scrollview_demo_page.dart",
"chars": 11051,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/fluttercandies/flutter_scrollview_observer\n *"
},
{
"path": "example/lib/features/nested_scrollview/nested_scrollview_tab_bar_view_demo/header/nested_scrollview_tab_bar_view_demo_header.dart",
"chars": 1272,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/fluttercandies/flutter_scrollview_observer\n *"
},
{
"path": "example/lib/features/nested_scrollview/nested_scrollview_tab_bar_view_demo/logic/nested_scrollview_tab_bar_view_demo_logic.dart",
"chars": 900,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/fluttercandies/flutter_scrollview_observer\n *"
},
{
"path": "example/lib/features/nested_scrollview/nested_scrollview_tab_bar_view_demo/logic/nested_scrollview_tab_bar_view_demo_logic_floating_action_btn.dart",
"chars": 2933,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/fluttercandies/flutter_scrollview_observer\n *"
},
{
"path": "example/lib/features/nested_scrollview/nested_scrollview_tab_bar_view_demo/logic/nested_scrollview_tab_bar_view_demo_logic_observer.dart",
"chars": 5618,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/fluttercandies/flutter_scrollview_observer\n *"
},
{
"path": "example/lib/features/nested_scrollview/nested_scrollview_tab_bar_view_demo/logic/nested_scrollview_tab_bar_view_demo_logic_scroll_type_switch.dart",
"chars": 1083,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/fluttercandies/flutter_scrollview_observer\n *"
},
{
"path": "example/lib/features/nested_scrollview/nested_scrollview_tab_bar_view_demo/logic/nested_scrollview_tab_bar_view_demo_logic_tab_bar.dart",
"chars": 1036,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/fluttercandies/flutter_scrollview_observer\n *"
},
{
"path": "example/lib/features/nested_scrollview/nested_scrollview_tab_bar_view_demo/page/nested_scrollview_tab_bar_view_demo_page.dart",
"chars": 6085,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/fluttercandies/flutter_scrollview_observer\n *"
},
{
"path": "example/lib/features/nested_scrollview/nested_scrollview_tab_bar_view_demo/state/nested_scrollview_tab_bar_view_demo_state.dart",
"chars": 1621,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/fluttercandies/flutter_scrollview_observer\n *"
},
{
"path": "example/lib/features/nested_scrollview/nested_scrollview_tab_bar_view_demo/widget/nested_scrollview_tab_bar_view_demo_floating_action_btn.dart",
"chars": 3930,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/fluttercandies/flutter_scrollview_observer\n *"
},
{
"path": "example/lib/features/nested_scrollview/nested_scrollview_tab_bar_view_demo/widget/nested_scrollview_tab_bar_view_demo_header_list_sliver.dart",
"chars": 2489,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/fluttercandies/flutter_scrollview_observer\n *"
},
{
"path": "example/lib/features/nested_scrollview/nested_scrollview_tab_bar_view_demo/widget/nested_scrollview_tab_bar_view_demo_scroll_type_switch.dart",
"chars": 1937,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/fluttercandies/flutter_scrollview_observer\n *"
},
{
"path": "example/lib/features/nested_scrollview/nested_scrollview_tab_bar_view_demo/widget/nested_scrollview_tab_bar_view_demo_tab1_view.dart",
"chars": 2475,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/fluttercandies/flutter_scrollview_observer\n *"
},
{
"path": "example/lib/features/nested_scrollview/nested_scrollview_tab_bar_view_demo/widget/nested_scrollview_tab_bar_view_demo_tab2_view.dart",
"chars": 2897,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/fluttercandies/flutter_scrollview_observer\n *"
},
{
"path": "example/lib/features/nested_scrollview/nested_scrollview_tab_bar_view_demo/widget/nested_scrollview_tab_bar_view_demo_tab3_view.dart",
"chars": 3666,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/fluttercandies/flutter_scrollview_observer\n *"
},
{
"path": "example/lib/features/nested_scrollview/nested_scrollview_tab_bar_view_demo/widget/nested_scrollview_tab_bar_view_demo_tabbar.dart",
"chars": 1507,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/fluttercandies/flutter_scrollview_observer\n *"
},
{
"path": "example/lib/features/pageview/pageview_demo/pageview_demo_page.dart",
"chars": 5560,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/fluttercandies/flutter_scrollview_observer\n *"
},
{
"path": "example/lib/features/pageview/pageview_demo/pageview_parallax_item_listener_page.dart",
"chars": 6186,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/fluttercandies/flutter_scrollview_observer\n *"
},
{
"path": "example/lib/features/pageview/pageview_demo/pageview_parallax_page.dart",
"chars": 5242,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/fluttercandies/flutter_scrollview_observer\n *"
},
{
"path": "example/lib/features/scene/anchor_demo/anchor_page.dart",
"chars": 2830,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/LinXunFeng/flutter_scrollview_observer\n * @Da"
},
{
"path": "example/lib/features/scene/anchor_demo/anchor_waterfall_page.dart",
"chars": 3155,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/LinXunFeng/flutter_scrollview_observer\n * @Da"
},
{
"path": "example/lib/features/scene/azlist_demo/azlist_cursor.dart",
"chars": 1337,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/fluttercandies/flutter_scrollview_observer\n *"
},
{
"path": "example/lib/features/scene/azlist_demo/azlist_index_bar.dart",
"chars": 3874,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/fluttercandies/flutter_scrollview_observer\n *"
},
{
"path": "example/lib/features/scene/azlist_demo/azlist_item_view.dart",
"chars": 1056,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/fluttercandies/flutter_scrollview_observer\n *"
},
{
"path": "example/lib/features/scene/azlist_demo/azlist_model.dart",
"chars": 519,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/fluttercandies/flutter_scrollview_observer\n *"
},
{
"path": "example/lib/features/scene/azlist_demo/azlist_page.dart",
"chars": 7072,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/fluttercandies/flutter_scrollview_observer\n *"
},
{
"path": "example/lib/features/scene/chat_demo/helper/chat_data_helper.dart",
"chars": 1300,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/LinXunFeng/flutter_scrollview_observer\n * @Da"
},
{
"path": "example/lib/features/scene/chat_demo/model/chat_model.dart",
"chars": 285,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/LinXunFeng/flutter_scrollview_observer\n * @Da"
},
{
"path": "example/lib/features/scene/chat_demo/page/chat_gpt_page.dart",
"chars": 6701,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/LinXunFeng/flutter_scrollview_observer\n * @Da"
},
{
"path": "example/lib/features/scene/chat_demo/page/chat_page.dart",
"chars": 11083,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/LinXunFeng/flutter_scrollview_observer\n * @Da"
},
{
"path": "example/lib/features/scene/chat_demo/widget/chat_item_widget.dart",
"chars": 2374,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/LinXunFeng/flutter_scrollview_observer\n * @Da"
},
{
"path": "example/lib/features/scene/chat_demo/widget/chat_unread_tip_view.dart",
"chars": 1256,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/LinXunFeng/flutter_scrollview_observer\n * @Da"
},
{
"path": "example/lib/features/scene/detail/header/detail_header.dart",
"chars": 794,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/fluttercandies/flutter_scrollview_observer\n *"
},
{
"path": "example/lib/features/scene/detail/logic/detail_logic.dart",
"chars": 813,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/fluttercandies/flutter_scrollview_observer\n *"
},
{
"path": "example/lib/features/scene/detail/logic/detail_logic_config.dart",
"chars": 793,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/fluttercandies/flutter_scrollview_observer\n *"
},
{
"path": "example/lib/features/scene/detail/logic/detail_logic_list_view.dart",
"chars": 4739,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/fluttercandies/flutter_scrollview_observer\n *"
},
{
"path": "example/lib/features/scene/detail/logic/detail_logic_nav_bar.dart",
"chars": 2307,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/fluttercandies/flutter_scrollview_observer\n *"
},
{
"path": "example/lib/features/scene/detail/model/detail_nav_bar_tab_model.dart",
"chars": 492,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/fluttercandies/flutter_scrollview_observer\n *"
},
{
"path": "example/lib/features/scene/detail/page/detail_page.dart",
"chars": 2362,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/fluttercandies/flutter_scrollview_observer\n *"
},
{
"path": "example/lib/features/scene/detail/state/detail_state.dart",
"chars": 608,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/fluttercandies/flutter_scrollview_observer\n *"
},
{
"path": "example/lib/features/scene/detail/state/detail_state_config.dart",
"chars": 1253,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/fluttercandies/flutter_scrollview_observer\n *"
},
{
"path": "example/lib/features/scene/detail/state/detail_state_list_view.dart",
"chars": 1232,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/fluttercandies/flutter_scrollview_observer\n *"
},
{
"path": "example/lib/features/scene/detail/state/detail_state_nav_bar.dart",
"chars": 488,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/fluttercandies/flutter_scrollview_observer\n *"
},
{
"path": "example/lib/features/scene/detail/widget/detail_config_view.dart",
"chars": 3164,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/fluttercandies/flutter_scrollview_observer\n *"
},
{
"path": "example/lib/features/scene/detail/widget/detail_list_item_wrapper.dart",
"chars": 1370,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/fluttercandies/flutter_scrollview_observer\n *"
},
{
"path": "example/lib/features/scene/detail/widget/detail_list_view.dart",
"chars": 4529,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/fluttercandies/flutter_scrollview_observer\n *"
},
{
"path": "example/lib/features/scene/detail/widget/detail_nav_bar.dart",
"chars": 2792,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/fluttercandies/flutter_scrollview_observer\n *"
},
{
"path": "example/lib/features/scene/detail/widget/list_item/detail_list_module1.dart",
"chars": 3382,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/fluttercandies/flutter_scrollview_observer\n *"
},
{
"path": "example/lib/features/scene/detail/widget/list_item/detail_list_module2.dart",
"chars": 4190,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/fluttercandies/flutter_scrollview_observer\n *"
},
{
"path": "example/lib/features/scene/detail/widget/list_item/detail_list_module3.dart",
"chars": 3092,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/fluttercandies/flutter_scrollview_observer\n *"
},
{
"path": "example/lib/features/scene/detail/widget/list_item/detail_list_module4.dart",
"chars": 3000,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/fluttercandies/flutter_scrollview_observer\n *"
},
{
"path": "example/lib/features/scene/detail/widget/list_item/detail_list_module5.dart",
"chars": 2534,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/fluttercandies/flutter_scrollview_observer\n *"
},
{
"path": "example/lib/features/scene/detail/widget/list_item/detail_list_module6.dart",
"chars": 3702,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/fluttercandies/flutter_scrollview_observer\n *"
},
{
"path": "example/lib/features/scene/detail/widget/list_item/detail_list_module7.dart",
"chars": 2956,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/fluttercandies/flutter_scrollview_observer\n *"
},
{
"path": "example/lib/features/scene/detail/widget/list_item/detail_list_module8.dart",
"chars": 2912,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/fluttercandies/flutter_scrollview_observer\n *"
},
{
"path": "example/lib/features/scene/expandable_carousel_slider_demo/expandable_carousel_slider_demo.dart",
"chars": 5723,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/fluttercandies/flutter_scrollview_observer\n *"
},
{
"path": "example/lib/features/scene/image_tab_demo/image_tab_page.dart",
"chars": 4479,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/LinXunFeng/flutter_scrollview_observer\n * @Da"
},
{
"path": "example/lib/features/scene/scrollview_form_demo/scrollview_form_demo_page.dart",
"chars": 4916,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/LinXunFeng/flutter_scrollview_observer\n * @Da"
},
{
"path": "example/lib/features/scene/video_auto_play_list/video_list_auto_play_page.dart",
"chars": 2072,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/LinXunFeng/flutter_scrollview_observer\n * @Da"
},
{
"path": "example/lib/features/scene/video_auto_play_list/widgets/video_widget.dart",
"chars": 1506,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/LinXunFeng/flutter_scrollview_observer\n * @Da"
},
{
"path": "example/lib/features/scene/visibility_demo/mixin/visibility_exposure_mixin.dart",
"chars": 2737,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/LinXunFeng/flutter_scrollview_observer\n * @Da"
},
{
"path": "example/lib/features/scene/visibility_demo/page/visibility_listview_page.dart",
"chars": 3019,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/LinXunFeng/flutter_scrollview_observer\n * @Da"
},
{
"path": "example/lib/features/scene/visibility_demo/page/visibility_scrollview_page.dart",
"chars": 5632,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/LinXunFeng/flutter_scrollview_observer\n * @Da"
},
{
"path": "example/lib/features/scene/waterfall_flow_demo/waterfall_flow_grid_item_view.dart",
"chars": 2499,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/LinXunFeng/flutter_scrollview_observer\n * @Da"
},
{
"path": "example/lib/features/scene/waterfall_flow_demo/waterfall_flow_page.dart",
"chars": 7812,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/LinXunFeng/flutter_scrollview_observer\n * @Da"
},
{
"path": "example/lib/features/scene/waterfall_flow_demo/waterfall_flow_swipe_view.dart",
"chars": 1936,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/LinXunFeng/flutter_scrollview_observer\n * @Da"
},
{
"path": "example/lib/features/scene/waterfall_flow_demo/waterfall_flow_type.dart",
"chars": 210,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/LinXunFeng/flutter_scrollview_observer\n * @Da"
},
{
"path": "example/lib/features/scene/waterfall_flow_fixed_height_demo/waterfall_flow_fixed_height_page.dart",
"chars": 3966,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/fluttercandies/flutter_scrollview_observer\n *"
},
{
"path": "example/lib/main.dart",
"chars": 523,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/LinXunFeng/flutter_scrollview_observer\n * @Da"
},
{
"path": "example/lib/typedefs.dart",
"chars": 269,
"preview": "/// This allows a value of type T or T?\n/// to be treated as a value of type T?.\n///\n/// We use this so that APIs that h"
},
{
"path": "example/lib/utils/keyboard.dart",
"chars": 470,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/fluttercandies/flutter_scrollview_observer\n *"
},
{
"path": "example/lib/utils/random.dart",
"chars": 511,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/LinXunFeng/flutter_scrollview_observer\n * @Da"
},
{
"path": "example/lib/utils/snackbar.dart",
"chars": 528,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/fluttercandies/flutter_scrollview_observer\n *"
},
{
"path": "example/lib/widgets/animation.dart",
"chars": 3260,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/fluttercandies/flutter_scrollview_observer\n *"
},
{
"path": "example/lib/widgets/sliver.dart",
"chars": 1481,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/fluttercandies/flutter_scrollview_observer\n *"
},
{
"path": "example/linux/flutter/generated_plugin_registrant.cc",
"chars": 161,
"preview": "//\n// Generated file. Do not edit.\n//\n\n// clang-format off\n\n#include \"generated_plugin_registrant.h\"\n\n\nvoid fl_register"
},
{
"path": "example/linux/flutter/generated_plugin_registrant.h",
"chars": 303,
"preview": "//\n// Generated file. Do not edit.\n//\n\n// clang-format off\n\n#ifndef GENERATED_PLUGIN_REGISTRANT_\n#define GENERATED_PLUG"
},
{
"path": "example/linux/flutter/generated_plugins.cmake",
"chars": 739,
"preview": "#\n# Generated file, do not edit.\n#\n\nlist(APPEND FLUTTER_PLUGIN_LIST\n)\n\nlist(APPEND FLUTTER_FFI_PLUGIN_LIST\n)\n\nset(PLUGIN"
},
{
"path": "example/macos/.gitignore",
"chars": 89,
"preview": "# Flutter-related\n**/Flutter/ephemeral/\n**/Pods/\n\n# Xcode-related\n**/dgph\n**/xcuserdata/\n"
},
{
"path": "example/macos/Flutter/Flutter-Debug.xcconfig",
"chars": 125,
"preview": "#include? \"Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig\"\n#include \"ephemeral/Flutter-Generated.xccon"
},
{
"path": "example/macos/Flutter/Flutter-Release.xcconfig",
"chars": 127,
"preview": "#include? \"Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig\"\n#include \"ephemeral/Flutter-Generated.xcc"
},
{
"path": "example/macos/Flutter/GeneratedPluginRegistrant.swift",
"chars": 273,
"preview": "//\n// Generated file. Do not edit.\n//\n\nimport FlutterMacOS\nimport Foundation\n\nimport video_player_avfoundation\n\nfunc Re"
},
{
"path": "example/macos/Podfile",
"chars": 1330,
"preview": "platform :osx, '10.14'\n\n# CocoaPods analytics sends network stats synchronously affecting flutter build latency.\nENV['CO"
},
{
"path": "example/macos/Runner/AppDelegate.swift",
"chars": 214,
"preview": "import Cocoa\nimport FlutterMacOS\n\n@NSApplicationMain\nclass AppDelegate: FlutterAppDelegate {\n override func application"
},
{
"path": "example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json",
"chars": 1291,
"preview": "{\n \"images\" : [\n {\n \"size\" : \"16x16\",\n \"idiom\" : \"mac\",\n \"filename\" : \"app_icon_16.png\",\n \"scale"
},
{
"path": "example/macos/Runner/Base.lproj/MainMenu.xib",
"chars": 23723,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.Cocoa.XIB\" version=\"3.0\" toolsVersion"
},
{
"path": "example/macos/Runner/Configs/AppInfo.xcconfig",
"chars": 630,
"preview": "// Application-level settings for the Runner target.\n//\n// This may be replaced with something auto-generated from metad"
},
{
"path": "example/macos/Runner/Configs/Debug.xcconfig",
"chars": 77,
"preview": "#include \"../../Flutter/Flutter-Debug.xcconfig\"\n#include \"Warnings.xcconfig\"\n"
},
{
"path": "example/macos/Runner/Configs/Release.xcconfig",
"chars": 79,
"preview": "#include \"../../Flutter/Flutter-Release.xcconfig\"\n#include \"Warnings.xcconfig\"\n"
},
{
"path": "example/macos/Runner/Configs/Warnings.xcconfig",
"chars": 580,
"preview": "WARNING_CFLAGS = -Wall -Wconditional-uninitialized -Wnullable-to-nonnull-conversion -Wmissing-method-return-type -Woverl"
},
{
"path": "example/macos/Runner/DebugProfile.entitlements",
"chars": 403,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "example/macos/Runner/Info.plist",
"chars": 1060,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "example/macos/Runner/MainFlutterWindow.swift",
"chars": 393,
"preview": "import Cocoa\nimport FlutterMacOS\n\nclass MainFlutterWindow: NSWindow {\n override func awakeFromNib() {\n let flutterVi"
},
{
"path": "example/macos/Runner/Release.entitlements",
"chars": 295,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "example/macos/Runner.xcodeproj/project.pbxproj",
"chars": 24118,
"preview": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 54;\n\tobjects = {\n\n/* Begin PBXAggregateTarget sec"
},
{
"path": "example/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist",
"chars": 238,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme",
"chars": 3189,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n LastUpgradeVersion = \"1300\"\n version = \"1.3\">\n <BuildAction\n "
},
{
"path": "example/macos/Runner.xcworkspace/contents.xcworkspacedata",
"chars": 224,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n version = \"1.0\">\n <FileRef\n location = \"group:Runner.xcodepr"
},
{
"path": "example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist",
"chars": 238,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "example/pubspec.yaml",
"chars": 4123,
"preview": "name: scrollview_observer_example\ndescription: A new Flutter project.\n\n# The following line prevents the package from be"
},
{
"path": "example/test/widget_test.dart",
"chars": 1220,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/LinXunFeng/flutter_scrollview_observer\n * @Da"
},
{
"path": "example/web/index.html",
"chars": 1484,
"preview": "<!doctype html>\n<html>\n <head>\n <!--\n If you are serving your web app in a path other than the root, change the\n "
},
{
"path": "example/web/manifest.json",
"chars": 910,
"preview": "{\n \"name\": \"example\",\n \"short_name\": \"example\",\n \"start_url\": \".\",\n \"display\": \"standalone\",\n \"background"
},
{
"path": "example/windows/.gitignore",
"chars": 291,
"preview": "flutter/ephemeral/\n\n# Visual Studio user-specific files.\n*.suo\n*.user\n*.userosscache\n*.sln.docstates\n\n# Visual Studio bu"
},
{
"path": "example/windows/CMakeLists.txt",
"chars": 3419,
"preview": "cmake_minimum_required(VERSION 3.14)\nproject(example LANGUAGES CXX)\n\nset(BINARY_NAME \"example\")\n\ncmake_policy(SET CMP006"
},
{
"path": "example/windows/flutter/CMakeLists.txt",
"chars": 3489,
"preview": "cmake_minimum_required(VERSION 3.14)\n\nset(EPHEMERAL_DIR \"${CMAKE_CURRENT_SOURCE_DIR}/ephemeral\")\n\n# Configuration provid"
},
{
"path": "example/windows/flutter/generated_plugin_registrant.cc",
"chars": 164,
"preview": "//\n// Generated file. Do not edit.\n//\n\n// clang-format off\n\n#include \"generated_plugin_registrant.h\"\n\n\nvoid RegisterPlu"
},
{
"path": "example/windows/flutter/generated_plugin_registrant.h",
"chars": 302,
"preview": "//\n// Generated file. Do not edit.\n//\n\n// clang-format off\n\n#ifndef GENERATED_PLUGIN_REGISTRANT_\n#define GENERATED_PLUG"
},
{
"path": "example/windows/flutter/generated_plugins.cmake",
"chars": 743,
"preview": "#\n# Generated file, do not edit.\n#\n\nlist(APPEND FLUTTER_PLUGIN_LIST\n)\n\nlist(APPEND FLUTTER_FFI_PLUGIN_LIST\n)\n\nset(PLUGIN"
},
{
"path": "example/windows/runner/CMakeLists.txt",
"chars": 572,
"preview": "cmake_minimum_required(VERSION 3.14)\nproject(runner LANGUAGES CXX)\n\nadd_executable(${BINARY_NAME} WIN32\n \"flutter_windo"
},
{
"path": "example/windows/runner/Runner.rc",
"chars": 2848,
"preview": "// Microsoft Visual C++ generated resource script.\n//\n#pragma code_page(65001)\n#include \"resource.h\"\n\n#define APSTUDIO_R"
},
{
"path": "example/windows/runner/flutter_window.cpp",
"chars": 1762,
"preview": "#include \"flutter_window.h\"\n\n#include <optional>\n\n#include \"flutter/generated_plugin_registrant.h\"\n\nFlutterWindow::Flutt"
},
{
"path": "example/windows/runner/flutter_window.h",
"chars": 928,
"preview": "#ifndef RUNNER_FLUTTER_WINDOW_H_\n#define RUNNER_FLUTTER_WINDOW_H_\n\n#include <flutter/dart_project.h>\n#include <flutter/f"
},
{
"path": "example/windows/runner/main.cpp",
"chars": 1267,
"preview": "#include <flutter/dart_project.h>\n#include <flutter/flutter_view_controller.h>\n#include <windows.h>\n\n#include \"flutter_w"
},
{
"path": "example/windows/runner/resource.h",
"chars": 432,
"preview": "//{{NO_DEPENDENCIES}}\n// Microsoft Visual C++ generated include file.\n// Used by Runner.rc\n//\n#define IDI_APP_ICON "
},
{
"path": "example/windows/runner/runner.exe.manifest",
"chars": 859,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersi"
},
{
"path": "example/windows/runner/utils.cpp",
"chars": 1651,
"preview": "#include \"utils.h\"\n\n#include <flutter_windows.h>\n#include <io.h>\n#include <stdio.h>\n#include <windows.h>\n\n#include <iost"
},
{
"path": "example/windows/runner/utils.h",
"chars": 672,
"preview": "#ifndef RUNNER_UTILS_H_\n#define RUNNER_UTILS_H_\n\n#include <string>\n#include <vector>\n\n// Creates a console for the proce"
},
{
"path": "example/windows/runner/win32_window.cpp",
"chars": 7024,
"preview": "#include \"win32_window.h\"\n\n#include <flutter_windows.h>\n\n#include \"resource.h\"\n\nnamespace {\n\nconstexpr const wchar_t kWi"
},
{
"path": "example/windows/runner/win32_window.h",
"chars": 3350,
"preview": "#ifndef RUNNER_WIN32_WINDOW_H_\n#define RUNNER_WIN32_WINDOW_H_\n\n#include <windows.h>\n\n#include <functional>\n#include <mem"
},
{
"path": "lib/scrollview_observer.dart",
"chars": 1526,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/LinXunFeng/flutter_scrollview_observer\n * @Da"
},
{
"path": "lib/src/common/models/observe_displaying_child_model.dart",
"chars": 627,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/LinXunFeng/flutter_scrollview_observer\n * @Da"
},
{
"path": "lib/src/common/models/observe_displaying_child_model_mixin.dart",
"chars": 3699,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/LinXunFeng/flutter_scrollview_observer\n * @Da"
},
{
"path": "lib/src/common/models/observe_find_child_model.dart",
"chars": 694,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/LinXunFeng/flutter_scrollview_observer\n * @Da"
},
{
"path": "lib/src/common/models/observe_model.dart",
"chars": 1262,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/LinXunFeng/flutter_scrollview_observer\n * @Da"
},
{
"path": "lib/src/common/models/observe_scroll_child_model.dart",
"chars": 385,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/LinXunFeng/flutter_scrollview_observer\n * @Da"
},
{
"path": "lib/src/common/models/observe_scroll_to_index_result_model.dart",
"chars": 1337,
"preview": "/*\n * @Author: LinXunFeng linxunfeng@yeah.net\n * @Repo: https://github.com/fluttercandies/flutter_scrollview_observer\n *"
}
]
// ... and 47 more files (download for full content)
About this extraction
This page contains the full source code of the LinXunFeng/flutter_scrollview_observer GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 247 files (819.7 KB), approximately 207.6k tokens, and a symbol index with 855 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.