mirror of
https://github.com/mzelldev/autoscale_tabbarview.git
synced 2024-09-21 16:56:27 +00:00
Initial code
This commit is contained in:
commit
8ef0d87c96
75
.gitignore
vendored
Normal file
75
.gitignore
vendored
Normal file
@ -0,0 +1,75 @@
|
||||
# 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/
|
||||
.dart_tool/
|
||||
.flutter-plugins
|
||||
.flutter-plugins-dependencies
|
||||
.packages
|
||||
.pub-cache/
|
||||
.pub/
|
||||
build/
|
||||
|
||||
# Android related
|
||||
**/android/**/gradle-wrapper.jar
|
||||
**/android/.gradle
|
||||
**/android/captures/
|
||||
**/android/gradlew
|
||||
**/android/gradlew.bat
|
||||
**/android/local.properties
|
||||
**/android/**/GeneratedPluginRegistrant.java
|
||||
|
||||
# iOS/XCode related
|
||||
**/ios/**/*.mode1v3
|
||||
**/ios/**/*.mode2v3
|
||||
**/ios/**/*.moved-aside
|
||||
**/ios/**/*.pbxuser
|
||||
**/ios/**/*.perspectivev3
|
||||
**/ios/**/*sync/
|
||||
**/ios/**/.sconsign.dblite
|
||||
**/ios/**/.tags*
|
||||
**/ios/**/.vagrant/
|
||||
**/ios/**/DerivedData/
|
||||
**/ios/**/Icon?
|
||||
**/ios/**/Pods/
|
||||
**/ios/**/.symlinks/
|
||||
**/ios/**/profile
|
||||
**/ios/**/xcuserdata
|
||||
**/ios/.generated/
|
||||
**/ios/Flutter/App.framework
|
||||
**/ios/Flutter/Flutter.framework
|
||||
**/ios/Flutter/Flutter.podspec
|
||||
**/ios/Flutter/Generated.xcconfig
|
||||
**/ios/Flutter/ephemeral
|
||||
**/ios/Flutter/app.flx
|
||||
**/ios/Flutter/app.zip
|
||||
**/ios/Flutter/flutter_assets/
|
||||
**/ios/Flutter/flutter_export_environment.sh
|
||||
**/ios/ServiceDefinitions.json
|
||||
**/ios/Runner/GeneratedPluginRegistrant.*
|
||||
|
||||
# Exceptions to above rules.
|
||||
!**/ios/**/default.mode1v3
|
||||
!**/ios/**/default.mode2v3
|
||||
!**/ios/**/default.pbxuser
|
||||
!**/ios/**/default.perspectivev3
|
||||
10
.metadata
Normal file
10
.metadata
Normal file
@ -0,0 +1,10 @@
|
||||
# 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 and should not be manually edited.
|
||||
|
||||
version:
|
||||
revision: 18116933e77adc82f80866c928266a5b4f1ed645
|
||||
channel: unknown
|
||||
|
||||
project_type: package
|
||||
3
CHANGELOG.md
Normal file
3
CHANGELOG.md
Normal file
@ -0,0 +1,3 @@
|
||||
## 0.0.1
|
||||
|
||||
* TODO: Describe initial release.
|
||||
39
README.md
Normal file
39
README.md
Normal file
@ -0,0 +1,39 @@
|
||||
<!--
|
||||
This README describes the package. If you publish this package to pub.dev,
|
||||
this README's contents appear on the landing page for your package.
|
||||
|
||||
For information about how to write a good package README, see the guide for
|
||||
[writing package pages](https://dart.dev/guides/libraries/writing-package-pages).
|
||||
|
||||
For general information about developing packages, see the Dart guide for
|
||||
[creating packages](https://dart.dev/guides/libraries/create-library-packages)
|
||||
and the Flutter guide for
|
||||
[developing packages and plugins](https://flutter.dev/developing-packages).
|
||||
-->
|
||||
|
||||
TODO: Put a short description of the package here that helps potential users
|
||||
know whether this package might be useful for them.
|
||||
|
||||
## Features
|
||||
|
||||
TODO: List what your package can do. Maybe include images, gifs, or videos.
|
||||
|
||||
## Getting started
|
||||
|
||||
TODO: List prerequisites and provide or point to information on how to
|
||||
start using the package.
|
||||
|
||||
## Usage
|
||||
|
||||
TODO: Include short and useful examples for package users. Add longer examples
|
||||
to `/example` folder.
|
||||
|
||||
```dart
|
||||
const like = 'sample';
|
||||
```
|
||||
|
||||
## Additional information
|
||||
|
||||
TODO: Tell users more about the package: where to find more information, how to
|
||||
contribute to the package, how to file issues, what response they can expect
|
||||
from the package authors, and more.
|
||||
4
analysis_options.yaml
Normal file
4
analysis_options.yaml
Normal file
@ -0,0 +1,4 @@
|
||||
include: package:flutter_lints/flutter.yaml
|
||||
|
||||
# Additional information about this file can be found at
|
||||
# https://dart.dev/guides/language/analysis-options
|
||||
5
lib/autoscale_tabbarview.dart
Normal file
5
lib/autoscale_tabbarview.dart
Normal file
@ -0,0 +1,5 @@
|
||||
library autoscale_tabbarview;
|
||||
|
||||
export 'src/autoscale_tabbar_widget.dart';
|
||||
export 'src/sized_pageview.dart';
|
||||
export 'src/size_detector_widget.dart';
|
||||
228
lib/src/autoscale_tabbar_widget.dart
Normal file
228
lib/src/autoscale_tabbar_widget.dart
Normal file
@ -0,0 +1,228 @@
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'sized_pageview.dart';
|
||||
|
||||
class AutoScaleTabBarView extends StatefulWidget {
|
||||
/// Creates a page view with one child per tab.
|
||||
///
|
||||
/// The length of [children] must be the same as the [controller]'s length.
|
||||
const AutoScaleTabBarView({
|
||||
Key? key,
|
||||
required this.children,
|
||||
this.controller,
|
||||
this.physics,
|
||||
this.dragStartBehavior = DragStartBehavior.start,
|
||||
}) : assert(children != null),
|
||||
assert(dragStartBehavior != null),
|
||||
super(key: key);
|
||||
|
||||
/// This widget's selection and animation state.
|
||||
///
|
||||
/// If [TabController] is not provided, then the value of [DefaultTabController.of]
|
||||
/// will be used.
|
||||
final TabController? controller;
|
||||
|
||||
/// One widget per tab.
|
||||
///
|
||||
/// Its length must match the length of the [TabBar.tabs]
|
||||
/// list, as well as the [controller]'s [TabController.length].
|
||||
final List<Widget> children;
|
||||
|
||||
/// How the page view should respond to user input.
|
||||
///
|
||||
/// For example, determines how the page view continues to animate after the
|
||||
/// user stops dragging the page view.
|
||||
///
|
||||
/// The physics are modified to snap to page boundaries using
|
||||
/// [PageScrollPhysics] prior to being used.
|
||||
///
|
||||
/// Defaults to matching platform conventions.
|
||||
final ScrollPhysics? physics;
|
||||
|
||||
/// {@macro flutter.widgets.scrollable.dragStartBehavior}
|
||||
final DragStartBehavior dragStartBehavior;
|
||||
|
||||
@override
|
||||
State<AutoScaleTabBarView> createState() => _AutoScaleTabBarViewState();
|
||||
}
|
||||
|
||||
class _AutoScaleTabBarViewState extends State<AutoScaleTabBarView> {
|
||||
TabController? _controller;
|
||||
late PageController _pageController;
|
||||
late List<Widget> _children;
|
||||
late List<Widget> _childrenWithKey;
|
||||
int? _currentIndex;
|
||||
int _warpUnderwayCount = 0;
|
||||
|
||||
// If the TabBarView is rebuilt with a new tab controller, the caller should
|
||||
// dispose the old one. In that case the old controller's animation will be
|
||||
// null and should not be accessed.
|
||||
bool get _controllerIsValid => _controller?.animation != null;
|
||||
|
||||
void _updateTabController() {
|
||||
final TabController? newController =
|
||||
widget.controller ?? DefaultTabController.of(context);
|
||||
assert(() {
|
||||
if (newController == null) {
|
||||
throw FlutterError(
|
||||
'No TabController for ${widget.runtimeType}.\n'
|
||||
'When creating a ${widget.runtimeType}, you must either provide an explicit '
|
||||
'TabController using the "controller" property, or you must ensure that there '
|
||||
'is a DefaultTabController above the ${widget.runtimeType}.\n'
|
||||
'In this case, there was neither an explicit controller nor a default controller.',
|
||||
);
|
||||
}
|
||||
return true;
|
||||
}());
|
||||
|
||||
if (newController == _controller) return;
|
||||
|
||||
if (_controllerIsValid)
|
||||
_controller!.animation!.removeListener(_handleTabControllerAnimationTick);
|
||||
_controller = newController;
|
||||
if (_controller != null)
|
||||
_controller!.animation!.addListener(_handleTabControllerAnimationTick);
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_updateChildren();
|
||||
}
|
||||
|
||||
@override
|
||||
void didChangeDependencies() {
|
||||
super.didChangeDependencies();
|
||||
_updateTabController();
|
||||
_currentIndex = _controller?.index;
|
||||
_pageController = PageController(initialPage: _currentIndex ?? 0);
|
||||
}
|
||||
|
||||
@override
|
||||
void didUpdateWidget(AutoScaleTabBarView oldWidget) {
|
||||
super.didUpdateWidget(oldWidget);
|
||||
if (widget.controller != oldWidget.controller) _updateTabController();
|
||||
if (widget.children != oldWidget.children && _warpUnderwayCount == 0)
|
||||
_updateChildren();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
if (_controllerIsValid)
|
||||
_controller!.animation!.removeListener(_handleTabControllerAnimationTick);
|
||||
_controller = null;
|
||||
// We don't own the _controller Animation, so it's not disposed here.
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
void _updateChildren() {
|
||||
_children = widget.children;
|
||||
_childrenWithKey = KeyedSubtree.ensureUniqueKeysForList(widget.children);
|
||||
}
|
||||
|
||||
void _handleTabControllerAnimationTick() {
|
||||
if (_warpUnderwayCount > 0 || !_controller!.indexIsChanging)
|
||||
return; // This widget is driving the controller's animation.
|
||||
|
||||
if (_controller!.index != _currentIndex) {
|
||||
_currentIndex = _controller!.index;
|
||||
_warpToCurrentIndex();
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _warpToCurrentIndex() async {
|
||||
if (!mounted) return Future<void>.value();
|
||||
|
||||
if (_pageController.page == _currentIndex!.toDouble())
|
||||
return Future<void>.value();
|
||||
|
||||
final int previousIndex = _controller!.previousIndex;
|
||||
if ((_currentIndex! - previousIndex).abs() == 1) {
|
||||
_warpUnderwayCount += 1;
|
||||
await _pageController.animateToPage(_currentIndex!,
|
||||
duration: kTabScrollDuration, curve: Curves.ease);
|
||||
_warpUnderwayCount -= 1;
|
||||
return Future<void>.value();
|
||||
}
|
||||
|
||||
assert((_currentIndex! - previousIndex).abs() > 1);
|
||||
final int initialPage = _currentIndex! > previousIndex
|
||||
? _currentIndex! - 1
|
||||
: _currentIndex! + 1;
|
||||
final List<Widget> originalChildren = _childrenWithKey;
|
||||
setState(() {
|
||||
_warpUnderwayCount += 1;
|
||||
|
||||
_childrenWithKey = List<Widget>.from(_childrenWithKey, growable: false);
|
||||
final Widget temp = _childrenWithKey[initialPage];
|
||||
_childrenWithKey[initialPage] = _childrenWithKey[previousIndex];
|
||||
_childrenWithKey[previousIndex] = temp;
|
||||
});
|
||||
_pageController.jumpToPage(initialPage);
|
||||
|
||||
await _pageController.animateToPage(_currentIndex!,
|
||||
duration: kTabScrollDuration, curve: Curves.ease);
|
||||
if (!mounted) return Future<void>.value();
|
||||
setState(() {
|
||||
_warpUnderwayCount -= 1;
|
||||
if (widget.children != _children) {
|
||||
_updateChildren();
|
||||
} else {
|
||||
_childrenWithKey = originalChildren;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Called when the PageView scrolls
|
||||
bool _handleScrollNotification(ScrollNotification notification) {
|
||||
if (_warpUnderwayCount > 0) return false;
|
||||
|
||||
if (notification.depth != 0) return false;
|
||||
|
||||
_warpUnderwayCount += 1;
|
||||
if (notification is ScrollUpdateNotification &&
|
||||
!_controller!.indexIsChanging) {
|
||||
if ((_pageController.page! - _controller!.index).abs() > 1.0) {
|
||||
_controller!.index = _pageController.page!.floor();
|
||||
_currentIndex = _controller!.index;
|
||||
}
|
||||
_controller!.offset =
|
||||
(_pageController.page! - _controller!.index).clamp(-1.0, 1.0);
|
||||
} else if (notification is ScrollEndNotification) {
|
||||
_controller!.index = _pageController.page!.round();
|
||||
_currentIndex = _controller!.index;
|
||||
if (!_controller!.indexIsChanging) {
|
||||
_controller!.offset =
|
||||
(_pageController.page! - _controller!.index).clamp(-1.0, 1.0);
|
||||
}
|
||||
}
|
||||
_warpUnderwayCount -= 1;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
assert(() {
|
||||
if (_controller!.length != widget.children.length) {
|
||||
throw FlutterError(
|
||||
"Controller's length property (${_controller!.length}) does not match the "
|
||||
"number of tabs (${widget.children.length}) present in TabBar's tabs property.",
|
||||
);
|
||||
}
|
||||
return true;
|
||||
}());
|
||||
return NotificationListener<ScrollNotification>(
|
||||
onNotification: _handleScrollNotification,
|
||||
child: SizedPageView(
|
||||
dragStartBehavior: widget.dragStartBehavior,
|
||||
pageController: _pageController,
|
||||
physics: widget.physics == null
|
||||
? const PageScrollPhysics().applyTo(const ClampingScrollPhysics())
|
||||
: const PageScrollPhysics().applyTo(widget.physics),
|
||||
children: _childrenWithKey,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
42
lib/src/size_detector_widget.dart
Normal file
42
lib/src/size_detector_widget.dart
Normal file
@ -0,0 +1,42 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/scheduler.dart';
|
||||
|
||||
class SizeDetectorWidget extends StatefulWidget {
|
||||
final Widget child;
|
||||
final ValueChanged<Size> onSizeDetect;
|
||||
|
||||
const SizeDetectorWidget({
|
||||
Key? key,
|
||||
required this.child,
|
||||
required this.onSizeDetect,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
_SizeDetectorWidgetState createState() => _SizeDetectorWidgetState();
|
||||
}
|
||||
|
||||
class _SizeDetectorWidgetState extends State<SizeDetectorWidget> {
|
||||
Size? _oldSize;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
SchedulerBinding.instance?.addPostFrameCallback((_) => _detectSize());
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return widget.child;
|
||||
}
|
||||
|
||||
void _detectSize() {
|
||||
if (!mounted) {
|
||||
return;
|
||||
}
|
||||
final size = context.size;
|
||||
if (_oldSize != size) {
|
||||
_oldSize = size;
|
||||
widget.onSizeDetect(size!);
|
||||
}
|
||||
}
|
||||
}
|
||||
81
lib/src/sized_pageview.dart
Normal file
81
lib/src/sized_pageview.dart
Normal file
@ -0,0 +1,81 @@
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'size_detector_widget.dart';
|
||||
|
||||
class SizedPageView extends StatefulWidget {
|
||||
final List<Widget> children;
|
||||
final PageController pageController;
|
||||
final DragStartBehavior dragStartBehavior;
|
||||
final ScrollPhysics physics;
|
||||
|
||||
const SizedPageView({
|
||||
Key? key,
|
||||
required this.children,
|
||||
required this.pageController,
|
||||
required this.dragStartBehavior,
|
||||
required this.physics,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
_SizedPageViewState createState() => _SizedPageViewState();
|
||||
}
|
||||
|
||||
class _SizedPageViewState extends State<SizedPageView>
|
||||
with SingleTickerProviderStateMixin {
|
||||
late List<double> _heights;
|
||||
int _currentIndex = 0;
|
||||
|
||||
double get _currentHeight => _heights[_currentIndex];
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_heights = List.generate(widget.children.length, (index) => 0.0);
|
||||
|
||||
widget.pageController.addListener(() {
|
||||
final _newIndex = widget.pageController.page?.round();
|
||||
if (_currentIndex != _newIndex) {
|
||||
if (!mounted) {
|
||||
return;
|
||||
}
|
||||
setState(() => _currentIndex = _newIndex!);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return TweenAnimationBuilder<double>(
|
||||
curve: Curves.easeInOutCubic,
|
||||
duration: const Duration(milliseconds: 100),
|
||||
tween: Tween<double>(begin: _heights[0], end: _currentHeight),
|
||||
builder: (context, value, child) => SizedBox(height: value, child: child),
|
||||
child: PageView(
|
||||
controller: widget.pageController,
|
||||
physics: widget.physics,
|
||||
dragStartBehavior: widget.dragStartBehavior,
|
||||
children: List.generate(widget.children.length, (index) {
|
||||
return OverflowBox(
|
||||
maxHeight: double.infinity,
|
||||
alignment: Alignment.topCenter,
|
||||
child: SizeDetectorWidget(
|
||||
onSizeDetect: (size) {
|
||||
if (mounted) {
|
||||
setState(() => _heights[index] = size.height);
|
||||
}
|
||||
},
|
||||
child: Align(child: widget.children[index]),
|
||||
),
|
||||
);
|
||||
}),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
widget.pageController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
161
pubspec.lock
Normal file
161
pubspec.lock
Normal file
@ -0,0 +1,161 @@
|
||||
# Generated by pub
|
||||
# See https://dart.dev/tools/pub/glossary#lockfile
|
||||
packages:
|
||||
async:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: async
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.8.1"
|
||||
boolean_selector:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: boolean_selector
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.0"
|
||||
characters:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: characters
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
charcode:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: charcode
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.3.1"
|
||||
clock:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: clock
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
collection:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: collection
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.15.0"
|
||||
fake_async:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: fake_async
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
flutter:
|
||||
dependency: "direct main"
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
flutter_lints:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: flutter_lints
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.4"
|
||||
flutter_test:
|
||||
dependency: "direct dev"
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
lints:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: lints
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.1"
|
||||
matcher:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: matcher
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.12.10"
|
||||
meta:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: meta
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.7.0"
|
||||
path:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.8.0"
|
||||
sky_engine:
|
||||
dependency: transitive
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.99"
|
||||
source_span:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: source_span
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.8.1"
|
||||
stack_trace:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: stack_trace
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.10.0"
|
||||
stream_channel:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: stream_channel
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.0"
|
||||
string_scanner:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: string_scanner
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
term_glyph:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: term_glyph
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
test_api:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: test_api
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.4.2"
|
||||
typed_data:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: typed_data
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.3.0"
|
||||
vector_math:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: vector_math
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.0"
|
||||
sdks:
|
||||
dart: ">=2.12.0 <3.0.0"
|
||||
flutter: ">=1.17.0"
|
||||
54
pubspec.yaml
Normal file
54
pubspec.yaml
Normal file
@ -0,0 +1,54 @@
|
||||
name: autoscale_tabbarview
|
||||
description: A new Flutter package project.
|
||||
version: 0.0.1
|
||||
homepage:
|
||||
|
||||
environment:
|
||||
sdk: ">=2.12.0 <3.0.0"
|
||||
flutter: ">=1.17.0"
|
||||
|
||||
dependencies:
|
||||
flutter:
|
||||
sdk: flutter
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
sdk: flutter
|
||||
flutter_lints: ^1.0.0
|
||||
|
||||
# For information on the generic Dart part of this file, see the
|
||||
# following page: https://dart.dev/tools/pub/pubspec
|
||||
|
||||
# The following section is specific to Flutter.
|
||||
flutter:
|
||||
|
||||
# To add assets to your package, add an assets section, like this:
|
||||
# assets:
|
||||
# - images/a_dot_burr.jpeg
|
||||
# - images/a_dot_ham.jpeg
|
||||
#
|
||||
# For details regarding assets in packages, see
|
||||
# https://flutter.dev/assets-and-images/#from-packages
|
||||
#
|
||||
# An image asset can refer to one or more resolution-specific "variants", see
|
||||
# https://flutter.dev/assets-and-images/#resolution-aware.
|
||||
|
||||
# To add custom fonts to your package, add a fonts section here,
|
||||
# in this "flutter" section. Each entry in this list should have a
|
||||
# "family" key with the font family name, and a "fonts" key with a
|
||||
# list giving the asset and other descriptors for the font. For
|
||||
# example:
|
||||
# fonts:
|
||||
# - family: Schyler
|
||||
# fonts:
|
||||
# - asset: fonts/Schyler-Regular.ttf
|
||||
# - asset: fonts/Schyler-Italic.ttf
|
||||
# style: italic
|
||||
# - family: Trajan Pro
|
||||
# fonts:
|
||||
# - asset: fonts/TrajanPro.ttf
|
||||
# - asset: fonts/TrajanPro_Bold.ttf
|
||||
# weight: 700
|
||||
#
|
||||
# For details regarding fonts in packages, see
|
||||
# https://flutter.dev/custom-fonts/#from-packages
|
||||
Loading…
Reference in New Issue
Block a user