颤动网页选项卡栏滚动控制器不响应键盘滚动 [英] Flutter web tabbarview scrollcontroller not responding to keyboard scrolling
本文介绍了颤动网页选项卡栏滚动控制器不响应键盘滚动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
- 我已经创建了两个选项卡。
- 在每个选项卡中,我都有用滚动条包装的SingleChildScrollView。
- 我不能在两个选项卡中都有主滚动控制器,因为这会引发异常:&ScrollController附加到多个滚动视图。";
- 对于选项卡一,我使用主滚动控制器,对于选项卡二,我创建了滚动控制器并附加了它。
- 对于带有主滚动控制器的Tab One,我可以通过键盘和拖动滚动条进行滚动。
- 但对于带有非主滚动控制器的Tab 2,我只能通过拖动滚动条来滚动。此选项卡不响应键盘上翻页/下翻页键。
请检查我下面的代码。指导我如何实现Tab 2的键盘滚动。
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
home: TabExample(),
);
}
}
class TabExample extends StatefulWidget {
const TabExample({Key key}) : super(key: key);
@override
_TabExampleState createState() => _TabExampleState();
}
class _TabExampleState extends State<TabExample> {
ScrollController _scrollController;
@override
void initState() {
_scrollController = ScrollController();
super.initState();
}
@override
void dispose() {
_scrollController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return DefaultTabController(
length: 2,
child: Scaffold(
appBar: AppBar(
bottom: TabBar(
tabs: [
Tab(icon: Text('Tab ONE')),
Tab(icon: Text('Tab TWO')),
],
),
title: Text('Tabs Demo'),
),
body: TabBarView(
children: [
_buildWidgetA(),
_buildWidgetB(),
],
),
),
);
}
Widget _buildWidgetA() {
List<Widget> children = [];
for (int i = 0; i < 20; i++) {
children.add(
Padding(
padding: EdgeInsets.symmetric(vertical: 16),
child: Container(
height: 100,
width: double.infinity,
color: Colors.black,
),
),
);
}
return Scrollbar(
isAlwaysShown: true,
showTrackOnHover: true,
child: SingleChildScrollView(
child: Column(
children: children,
),
),
);
}
Widget _buildWidgetB() {
List<Widget> children = [];
for (int i = 0; i < 20; i++) {
children.add(
Padding(
padding: EdgeInsets.symmetric(vertical: 16),
child: Container(
height: 100,
width: double.infinity,
color: Colors.green,
),
),
);
}
return Scrollbar(
controller: _scrollController,
isAlwaysShown: true,
showTrackOnHover: true,
child: SingleChildScrollView(
controller: _scrollController,
child: Column(
children: children,
),
),
);
}
}
推荐答案
无需创建显式ScrollController
即可实现此目的。
一个技巧是更改SingleChildScrollView
将在Tab
更改其索引时使用PrimaryScrollController
。
SingleChildScrolView
为primary
。当它变为1时,我们将另一个设置为primary
。
首先创建一个新的State变量,如下所示
int currentIndex = 0; // This will be the index of tab at a point in time
若要侦听Change事件,您需要将侦听器添加到TabController
。
DefaultTabController(
length: 2,
child: Builder( // <---- Use a Builder Widget to get the context this this DefaultTabController
builder: (ctx) {
// Here we need to use ctx instead of context otherwise it will give null
final TabController tabController = DefaultTabController.of(ctx);
tabController.addListener(() {
if (!tabController.indexIsChanging) {
// When the tab has changed we are changing our currentIndex to the new index
setState(() => currentIndex = tabController.index);
}
});
return Scaffold(
appBar: AppBar(
bottom: TabBar(
tabs: [
Tab(icon: Text('Tab ONE')),
Tab(icon: Text('Tab TWO')),
],
),
title: Text('Tabs Demo'),
),
body: TabBarView(
children: [
_buildWidgetA(),
_buildWidgetB(),
],
),
);
},
),
);
最后,根据currentIndex
将primary: true
设置为每个SingleChildScrollView
。
对于_buildWidgetA
,
Scrollbar(
isAlwaysShown: true,
showTrackOnHover: true,
child: SingleChildScrollView(
primary: currentIndex == 0, // <--- This will be primary if currentIndex = 0
child: Column(
children: children,
),
),
);
对于_buildWidgetB
,
Scrollbar(
isAlwaysShown: true,
showTrackOnHover: true,
child: SingleChildScrollView(
primary: currentIndex == 1, // <--- This will be primary if currentIndex = 1
child: Column(
children: children,
),
),
);
现在,您应该能够用键盘控制这两个选项卡了。
完整代码here
这篇关于颤动网页选项卡栏滚动控制器不响应键盘滚动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文