文章目录
- 前言
- 一、需要实现的效果如下
- 二、flutter实现代码如下:
- 总结
前言
最近写flutter项目,遇到NestedScrollView与TabBar双列表滚动位置同步问题,下面是解决方案,希望帮助到大家。
一、需要实现的效果如下
1、UI图:
需要实现的效果是,左边滑动的时候,右边的列表不要随左边滑动。右边滑动的时候,左边也不要滑动。
二、flutter实现代码如下:
1、用flutter原生的NestedScrollView是有问题的
2、使用第三方库解决这个问题extended_nested_scroll_view: ^6.2.1
3、完整的代码如下:
import 'package:extended_nested_scroll_view/extended_nested_scroll_view.dart';
import 'package:flutter/material.dart';
void main() {
runApp(const MyBitApp());
}
class MyBitApp extends StatelessWidget {
const MyBitApp({super.key});
// This widget is the root of your application.
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: MyApp(),
);
}
}
class MyApp extends StatelessWidget {
Widget build(BuildContext context) {
return MaterialApp(
title: 'NestedScrollView Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> with SingleTickerProviderStateMixin {
late TabController _tabController;
late List<ScrollController> _scrollControllers;
late ScrollController nestedScrollController;
void initState() {
super.initState();
_tabController = TabController(length: 2, vsync: this);
_scrollControllers = [
ScrollController(),
ScrollController(),
];
nestedScrollController = ScrollController();
}
void dispose() {
_tabController.dispose();
for (var controller in _scrollControllers) {
controller.dispose();
}
super.dispose();
}
Widget build(BuildContext context) {
// var tabBarHeight = primaryTabBar.preferredSize.height;
double statusBarHeight = MediaQuery.of(context).padding.top;
var pinnedHeaderHeight = statusBarHeight + kToolbarHeight;
return Scaffold(
body: DefaultTabController(
length: 2,
child: ExtendedNestedScrollView(
onlyOneScrollInBody: true,
pinnedHeaderSliverHeightBuilder: () => pinnedHeaderHeight,
headerSliverBuilder: (context, innerBoxIsScrolled) {
return [
SliverAppBar(
title: Text('NestedScrollView Demo'),
pinned: true,
floating: true,
expandedHeight: 200,
stretch: true,
elevation: 0,
stretchTriggerOffset: 100,
bottom: TabBar(
controller: _tabController,
tabs: [
Tab(text: 'Tab 1'),
Tab(text: 'Tab 2'),
],
),
),
];
},
body: TabBarView(
controller: _tabController,
children: [
KeepAliveWrapper(
child: MediaQuery.removePadding(
removeTop: true,
context: context,
child: ListView.builder(
itemCount: 1000,
itemBuilder: (context, index) {
return ListTile(
title: Text('Tab 1 Item $index'),
);
},
),
),
),
KeepAliveWrapper(
child: MediaQuery.removePadding(
removeTop: true,
context: context,
child: ListView.builder(
itemCount: 1000,
itemBuilder: (context, index) {
return ListTile(
title: Text('Tab 2 Item $index'),
);
},
),
),
),
],
),
),
),
);
}
}
class KeepAliveWrapper extends StatefulWidget {
final Widget child;
const KeepAliveWrapper({Key? key, required this.child}) : super(key: key);
_KeepAliveWrapperState createState() => _KeepAliveWrapperState();
}
class _KeepAliveWrapperState extends State<KeepAliveWrapper> with AutomaticKeepAliveClientMixin {
Widget build(BuildContext context) {
super.build(context);
return widget.child;
}
bool get wantKeepAlive => true;
}
总结
这就是Flutter解决NestedScrollView与TabBar双列表滚动位置同步问题相关代码,希望能帮助到你!