A. 跳转新页面,布局为 ExtendedNestedScrollView + TabBarView,使用showAttach,绑定bindWidget报错。
B. 不绑定时,切换Tab,提示
import 'package:extended_nested_scroll_view/extended_nested_scroll_view.dart';
import 'package:flutter/material.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:sliver_tools/sliver_tools.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(colorScheme: .fromSeed(seedColor: Colors.deepPurple)),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
builder: FlutterSmartDialog.init(
builder: (BuildContext context, Widget? child) {
return child ?? SizedBox.shrink();
},
),
navigatorObservers: <NavigatorObserver>[FlutterSmartDialog.observer],
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text(widget.title)),
body: Center(
child: ElevatedButton(
onPressed: () => Navigator.push(context, MaterialPageRoute(builder: (context) => DemoPage(title: 'Demo'))),
child: Text('跳转'),
),
),
);
}
}
class DemoPage extends StatefulWidget {
const DemoPage({super.key, required this.title});
final String title;
@override
State<DemoPage> createState() => _DemoPageState();
}
class _DemoPageState extends State<DemoPage> {
/// 用于 [ExtendedNestedScrollView] 的 key
final GlobalKey<ExtendedNestedScrollViewState> key = GlobalKey<ExtendedNestedScrollViewState>();
@override
Widget build(BuildContext context) {
final child = Scaffold(
appBar: AppBar(title: Text(widget.title)),
body: ExtendedNestedScrollView(
key: key,
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) => [
SliverPinnedHeader(child: Container(height: 200, color: Colors.red)),
SliverPinnedHeader(
child: TabBar(tabs: List.generate(5, (index) => Tab(text: '${index + 1}'))),
),
],
body: TabBarView(children: List.generate(5, (index) => TabBarIndexView(index: index + 1))),
pinnedHeaderSliverHeightBuilder: () => 200,
onlyOneScrollInBody: true,
),
);
return DefaultTabController(length: 5, child: child);
}
}
class TabBarIndexView extends StatefulWidget {
const TabBarIndexView({super.key, required this.index});
final int index;
@override
State<StatefulWidget> createState() => _TabBarIndexViewState();
}
class _TabBarIndexViewState extends State<TabBarIndexView> with AutomaticKeepAliveClientMixin {
@override
Widget build(BuildContext context) {
super.build(context);
return ListView(children: [Dropdown(), Text('Tab ${widget.index}')]);
}
@override
bool get wantKeepAlive => true;
}
class Dropdown extends StatefulWidget implements PreferredSizeWidget {
const Dropdown({super.key});
@override
State<StatefulWidget> createState() => _DropdownState();
@override
Size get preferredSize => .fromHeight(34);
}
class _DropdownState extends State<Dropdown> {
@override
Widget build(BuildContext context) {
return Container(
height: 34,
child: Row(
spacing: 4,
children: List<Widget>.generate(4, (index) {
Widget child = Center(child: Text('Drop ${index + 1}'));
child = ColoredBox(color: Colors.primaries[index % Colors.primaries.length], child: child);
child = GestureDetector(onTap: () => openMenu(), child: child);
return Expanded(child: child);
}),
),
);
}
/// 开启菜单
Future<void> openMenu() async {
SmartDialog.config.attach = SmartConfigAttach(maskTriggerType: .move);
await SmartDialog.showAttach<void>(
targetContext: context,
builder: (BuildContext context) => Material(
color: Colors.red,
borderRadius: const .vertical(bottom: .circular(8)),
child: Container(
width: targetSize.width,
constraints: BoxConstraints(
maxHeight: (MediaQuery.heightOf(context) - targetOffset.dy - targetSize.height) / 3 * 2,
),
child: Container(),
),
),
maskIgnoreArea: Rect.fromLTRB(0, targetOffset.dy + targetSize.height, 0, 0),
debounce: true,
bindWidget: context,
);
}
RenderBox get renderBox => context.findRenderObject()! as RenderBox;
Offset get targetOffset => renderBox.localToGlobal(.zero);
Size get targetSize => renderBox.size;
}
版本信息
描述bug/需求
A. 跳转新页面,布局为
ExtendedNestedScrollView+TabBarView,使用showAttach,绑定bindWidget报错。B. 不绑定时,切换Tab,提示
且关闭页面时,提示
问题demo
辛苦作者大大,帮忙看下。☺