Tabview 滚动行为
Tabview scroll behavior
我有一个 Tabview
和一个 azlist scrollable bar
的列表。在 azlist bar
中滚动时,TabView
很容易移动,试图滑到另一个 Tab
。我希望 TabView
在滚动 azlist scrollable bar
期间保持不变。有没有办法阻止 TabView
的这种行为?我试过声明一个 CustomScrollPhysic
但它并没有按照我想要的方式工作。
下面是附加的 gif 和代码。
在 pubspec 中导入这个
alphabet_list_view: ^0.1.2
home.dart
import 'package:alphabet_list_view/alphabet_list_view.dart';
import 'package:flutter/material.dart';
class Home extends StatelessWidget {
const Home({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return DefaultTabController(
length: 2,
child: Scaffold(
appBar: AppBar(
bottom: const TabBar(
isScrollable: true,
tabs: [
Tab(text: 'TabOne'),
Tab(text: 'TabTwo'),
],
),
),
body: SafeArea(
child: TabBarView(
physics: CustomScrollPhysics(),
children: [
TabOne(),
TabTwo(),
],
),
),
),
);
}
}
tabone.dart
class TabOne extends StatelessWidget {
TabOne({Key? key}) : super(key: key);
final List<AlphabetListViewItemGroup> animals = [
for (var animalLetter in animalsMap.entries)
AlphabetListViewItemGroup(
tag: animalLetter.key,
children: animalLetter.value.map((animal) => Text(animal)).toList(),
),
];
@override
Widget build(BuildContext context) {
return Directionality(
textDirection: TextDirection.rtl,
child: AlphabetListView(
items: animals,
),
);
}
}
tabtwo.dart
class TabTwo extends StatelessWidget {
TabTwo({Key? key}) : super(key: key);
final List<AlphabetListViewItemGroup> animals = [
for (var animalLetter in animalsMap.entries)
AlphabetListViewItemGroup(
tag: animalLetter.key,
children: animalLetter.value.map((animal) => Text(animal)).toList(),
),
];
@override
Widget build(BuildContext context) {
return AlphabetListView(
items: animals,
);
}
}
custom_scroll_physics.dart
class CustomScrollPhysics extends ScrollPhysics {
const CustomScrollPhysics({ScrollPhysics? parent}) : super(parent: parent);
@override
ScrollPhysics applyTo(ScrollPhysics? ancestor) =>
CustomScrollPhysics(parent: buildParent(ancestor));
@override
Simulation? createBallisticSimulation(
ScrollMetrics position, double velocity) {
final tolerance = this.tolerance;
if ((velocity.abs() < tolerance.velocity) ||
(velocity > 0.0 && position.pixels >= position.maxScrollExtent) ||
(velocity < 0.0 && position.pixels <= position.minScrollExtent)) {
return null;
}
return ClampingScrollSimulation(
position: position.pixels,
velocity: velocity,
friction: 0.5,
tolerance: Tolerance.defaultTolerance,
);
}
}
动物的硬编码地图
const Map<String, List<String>> animalsMap = {
'A': [
'Admiral, indian red',
],
'B': [
'Baboon, gelada',
'Baboon, olive',
],
'F': [
'Fairy penguin',
'Falcon, peregrine',
'Frog (unidentified)',
],
'G': [
'Galah',
'Galapagos albatross',
],
'H': [
'Hare, arctic',
'Hartebeest, coke\'s',
],
'I': [
'Ibis, glossy',
'Insect, stick',
],
'J': [
'Jacana, african',
'Jackal, black-backed',
],
'K': [
'Kaffir cat',
'Kafue flats lechwe',
'Koala',
],
'M': [
'Macaque, pig-tailed',
'Musk ox',
'Mynah, indian',
],
'N': [
'Native cat',
'Nighthawk, common',
],
'P': [
'Painted stork',
'Porcupine, prehensile-tailed',
],
'Q': [
'Quoll, spotted-tailed',
],
'T': [
'Tailless tenrec',
'Tapir, brazilian',
'Tarantula, salmon pink bird eater',
],
'U': [
'Uinta ground squirrel',
],
'V': [
'Vicuna',
'Vine snake (unidentified)',
],
'W': [
'Wagtail, african pied',
'White-fronted capuchin',
'Woylie',
],
'Y': [
'Yak',
],
'Z': [
'Zebra, plains',
'Zorilla',
'Zorro, common',
],
};
我有一个非常相似的页面:两个包含字母列表和滚动的选项卡运行良好。
我的小部件上没有 CustomScrollPhysics,但使用了 TabController。
class _PeopleListScreenState extends State<PeopleListScreen> with SingleTickerProviderStateMixin {
late TabController _tabController;
var tab = _Tab.user;
@override
void initState() {
super.initState();
_tabController = TabController(vsync: this, length: 2);
_tabController.addListener(() {
if (_tabController.indexIsChanging || _tabController.index != _tabController.previousIndex) {
var index = _tabController.index;
// Tab Changed tapping on new tab
setState(() => tab = _Tab.values[index]);
}
});
}
@override
void dispose() {
_tabController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return SafeArea(
child: Column(
children: [
TabBar(
controller: tabController,
tabs: [Tab(), Tab()],
),
Expanded(
child: TabBarView(
tabController: _tabController,
children: [AlphabetList(), AlphabetList()],
),
),
],
),
);
}
}
我有一个 Tabview
和一个 azlist scrollable bar
的列表。在 azlist bar
中滚动时,TabView
很容易移动,试图滑到另一个 Tab
。我希望 TabView
在滚动 azlist scrollable bar
期间保持不变。有没有办法阻止 TabView
的这种行为?我试过声明一个 CustomScrollPhysic
但它并没有按照我想要的方式工作。
下面是附加的 gif 和代码。
在 pubspec 中导入这个
alphabet_list_view: ^0.1.2
home.dart
import 'package:alphabet_list_view/alphabet_list_view.dart';
import 'package:flutter/material.dart';
class Home extends StatelessWidget {
const Home({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return DefaultTabController(
length: 2,
child: Scaffold(
appBar: AppBar(
bottom: const TabBar(
isScrollable: true,
tabs: [
Tab(text: 'TabOne'),
Tab(text: 'TabTwo'),
],
),
),
body: SafeArea(
child: TabBarView(
physics: CustomScrollPhysics(),
children: [
TabOne(),
TabTwo(),
],
),
),
),
);
}
}
tabone.dart
class TabOne extends StatelessWidget {
TabOne({Key? key}) : super(key: key);
final List<AlphabetListViewItemGroup> animals = [
for (var animalLetter in animalsMap.entries)
AlphabetListViewItemGroup(
tag: animalLetter.key,
children: animalLetter.value.map((animal) => Text(animal)).toList(),
),
];
@override
Widget build(BuildContext context) {
return Directionality(
textDirection: TextDirection.rtl,
child: AlphabetListView(
items: animals,
),
);
}
}
tabtwo.dart
class TabTwo extends StatelessWidget {
TabTwo({Key? key}) : super(key: key);
final List<AlphabetListViewItemGroup> animals = [
for (var animalLetter in animalsMap.entries)
AlphabetListViewItemGroup(
tag: animalLetter.key,
children: animalLetter.value.map((animal) => Text(animal)).toList(),
),
];
@override
Widget build(BuildContext context) {
return AlphabetListView(
items: animals,
);
}
}
custom_scroll_physics.dart
class CustomScrollPhysics extends ScrollPhysics {
const CustomScrollPhysics({ScrollPhysics? parent}) : super(parent: parent);
@override
ScrollPhysics applyTo(ScrollPhysics? ancestor) =>
CustomScrollPhysics(parent: buildParent(ancestor));
@override
Simulation? createBallisticSimulation(
ScrollMetrics position, double velocity) {
final tolerance = this.tolerance;
if ((velocity.abs() < tolerance.velocity) ||
(velocity > 0.0 && position.pixels >= position.maxScrollExtent) ||
(velocity < 0.0 && position.pixels <= position.minScrollExtent)) {
return null;
}
return ClampingScrollSimulation(
position: position.pixels,
velocity: velocity,
friction: 0.5,
tolerance: Tolerance.defaultTolerance,
);
}
}
动物的硬编码地图
const Map<String, List<String>> animalsMap = {
'A': [
'Admiral, indian red',
],
'B': [
'Baboon, gelada',
'Baboon, olive',
],
'F': [
'Fairy penguin',
'Falcon, peregrine',
'Frog (unidentified)',
],
'G': [
'Galah',
'Galapagos albatross',
],
'H': [
'Hare, arctic',
'Hartebeest, coke\'s',
],
'I': [
'Ibis, glossy',
'Insect, stick',
],
'J': [
'Jacana, african',
'Jackal, black-backed',
],
'K': [
'Kaffir cat',
'Kafue flats lechwe',
'Koala',
],
'M': [
'Macaque, pig-tailed',
'Musk ox',
'Mynah, indian',
],
'N': [
'Native cat',
'Nighthawk, common',
],
'P': [
'Painted stork',
'Porcupine, prehensile-tailed',
],
'Q': [
'Quoll, spotted-tailed',
],
'T': [
'Tailless tenrec',
'Tapir, brazilian',
'Tarantula, salmon pink bird eater',
],
'U': [
'Uinta ground squirrel',
],
'V': [
'Vicuna',
'Vine snake (unidentified)',
],
'W': [
'Wagtail, african pied',
'White-fronted capuchin',
'Woylie',
],
'Y': [
'Yak',
],
'Z': [
'Zebra, plains',
'Zorilla',
'Zorro, common',
],
};
我有一个非常相似的页面:两个包含字母列表和滚动的选项卡运行良好。
我的小部件上没有 CustomScrollPhysics,但使用了 TabController。
class _PeopleListScreenState extends State<PeopleListScreen> with SingleTickerProviderStateMixin {
late TabController _tabController;
var tab = _Tab.user;
@override
void initState() {
super.initState();
_tabController = TabController(vsync: this, length: 2);
_tabController.addListener(() {
if (_tabController.indexIsChanging || _tabController.index != _tabController.previousIndex) {
var index = _tabController.index;
// Tab Changed tapping on new tab
setState(() => tab = _Tab.values[index]);
}
});
}
@override
void dispose() {
_tabController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return SafeArea(
child: Column(
children: [
TabBar(
controller: tabController,
tabs: [Tab(), Tab()],
),
Expanded(
child: TabBarView(
tabController: _tabController,
children: [AlphabetList(), AlphabetList()],
),
),
],
),
);
}
}