我正在尝试做一个单页应用程序。我有4个有状态类:
- AppBar -此小部件用于在网站顶部创建appBar,标题如下:“首页”、“关于我们”、“联系我们”等
- Body -此小部件用于容纳AppBar中标题的所有内容(Home是一个容器,About是另一个容器,Contact Us是另一个容器)。
- HomeScreen -这是我结合AppBar和Body的地方。它被 Package 在SingleChildScrollView中并且是可滚动的。
当我在AppBar中单击Home时,我想向下滚动到Body中的相应部分,AppBar中的其他标题也是如此。
我在AppBar中定义了onTap(),在HomeScreen中定义了_scrollToHome()。我试图使用Scrollable.ensureVisible()向下滚动到相应的部分,但我对如何链接这两个小部件感到非常困惑。
这是正确的方法吗?或者我应该做一些其他的事情来实现上述功能。
下面是代码:
1.主页_屏幕:
class HomeScreen extends StatefulWidget {
const HomeScreen({Key key,}) : super(key: key);
@override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
GlobalKey homeKey;
final ScrollController _scrollController = ScrollController();
double _scrollPosition = 0;
double _opacity = 0;
_scrollListener() {
setState(() {
_scrollPosition = _scrollController.position.pixels;
});
}
@override
void initState() {
_scrollController.addListener(_scrollListener);
super.initState();
}
void _scrollToHome() {
Scrollable.ensureVisible(
homeKey.currentContext,
duration: Duration(seconds: 2),
curve: Curves.fastOutSlowIn,
);
}
@override
Widget build(BuildContext context) {
var screenSize = MediaQuery.of(context).size;
_opacity = _scrollPosition < screenSize.height * 0.40
? _scrollPosition / (screenSize.height * 0.40)
: 1;
return Scaffold(
appBar: PreferredSize(
preferredSize: Size(screenSize.width, 100),
child: CustomAppBar(opacity: _opacity),
),
body: SingleChildScrollView(
controller: _scrollController,
child: Column(
children: [
Stack(
children: [
Container(
// backgroundImage - Can be ignored
),
Column(
children: [
Container(
// Home - Container
),
Container(
//About - container
),
Container(
//Contact Us - container
),
],
),
],
),
],
),
),
);
}
}
下面是AppBar的代码:
class CustomAppBar extends StatefulWidget {
final double opacity;
CustomAppBar({
Key key,
this.opacity,
}) : super(key: key);
@override
_CustomAppBarState createState() => _CustomAppBarState();
}
class _CustomAppBarState extends State<CustomAppBar> {
@override
Widget build(BuildContext context) {
var screenSize = MediaQuery.of(context).size;
return PreferredSize(
preferredSize: Size(screenSize.width, 70),
child: Container(
margin: EdgeInsets.all(10),
color: Colors.black.withOpacity(widget.opacity),
child: Padding(
padding: EdgeInsets.all(10),
child: Row(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Expanded(
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
InkWell(
onTap: () {
//HomeScreen._scrollToHome(); - this is where I am confused
},
// Image which on click takes me to Home
),
),
Spacer(),
MenuItem(
title: "About",
press: () => {
//Navigate to About
},
),
],
),
),
],
),
),
),
);
}
}
2条答案
按热度按时间u1ehiz5o1#
您可以在另一个小部件中调用公共方法。在您的情况下,您必须:
1.将void _scrollToHome()设置为public:void scrollToHome()。
1.将其widget类设置为public:类_家庭屏幕状态变为类家庭屏幕状态。
1.声明一个全局变量,并将其设置为上述类的Global键:
int getString();
1.创建主屏幕时设置此键(homescreenKey)。
1.通过此键调用公共方法:
sort(sort);
希望这能帮上忙。
xytpbqjk2#
我一直做错了。我所要做的就是为
HomeScreen
中的所有部分创建全局键。然后将这些键传递给AppBar
并在AppBar
中实现_scrollToHome
/_scrollToWidget
函数。在
HomeScreen
中,我必须将键设置到在build()
中创建它们的相应部分。