如果我使用页面视图(内部有ListView)+底部导航栏,一切都可以正常工作。
我对每一页都使用唯一的pagestoragekey,以便列出两页上的列表视图保存和恢复滚动偏移量。
但我需要建立基于路线的应用导航。
这里有一个非常简单的代码,但它足以显示和重现我面临的问题。
你可以复制粘贴这个剪贴检查
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
final GlobalKey<NavigatorState> _navigatorKey = GlobalKey<NavigatorState>();
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
appBar: AppBar(title: Text("Test")),
body: Scaffold(
body: Navigator(
key: _navigatorKey,
onGenerateRoute: (settings) {
switch (settings.name) {
case '/':
return MaterialPageRoute(builder: (_) => SomeWidget(0));
case '/another_route':
return MaterialPageRoute(builder: (_) => SomeWidget(1));
break;
}
},
),
bottomNavigationBar: BottomNavigationBar(
selectedItemColor: Colors.grey,
unselectedItemColor: Colors.grey,
items: [
BottomNavigationBarItem(icon: Icon(Icons.print), title: Text('Page 0')),
BottomNavigationBarItem(icon: Icon(Icons.category), title: Text('Page 1')),
],
onTap: (index) {
if (index == 0) {
_navigatorKey.currentState.pushReplacementNamed('/');
} else {
_navigatorKey.currentState.pushReplacementNamed('/another_route');
}
},
),
),
),
);
}
}
class SomeWidget extends StatelessWidget {
final int page;
SomeWidget(this.page) : super(key: Key('page key $page'));
@override
Widget build(BuildContext context) {
return ListView.builder(
key: PageStorageKey(page),
itemBuilder: (context, index) {
return Card(
key: Key('item: $index on page: $page'),
color: page == 0 ? Colors.blue[200] : Colors.green[200],
child: Container(
height: 196,
alignment: Alignment.center,
child: Text('Row: $index | Page $page'),
),
);
},
);
}
}
最佳答案
这是预期的行为。当你按下一个屏幕时,它会生成一个全新的屏幕,而没有任何以前的状态。
这就是使用页面视图的原因,它的构建是为了保留状态,而不是卸载任何屏幕。
在您的示例中,生命周期是
处理屏幕
创建新屏幕
显示屏幕
我可以不使用viewpager(因为我不需要拖动函数)共享我使用它的方式。
import 'package:flutter/material.dart';
import '../Widgets.dart'; // my custom widgets
class PageTabs extends StatefulWidget {
@override
_PageTabsState createState() => _PageTabsState();
}
class _PageTabsState extends State<PageTabs> {
int _cIndex = 0; //the current page index
@override
void initState() {
super.initState();
}
void _changeTab(index) {
setState(() {
_cIndex = index;
});
}
List<Widget> tabs = [
TimelineScreen(key: PageStorageKey('TimeLine')),
PageTrends(key: PageStorageKey('Trends')),
PageSettings(key: PageStorageKey('Settings'))
];
final PageStorageBucket bucket = PageStorageBucket();
@override
Widget build(BuildContext context) {
return DefaultTabController(
initialIndex: 1,
length: 3,
child: Stack(
alignment: AlignmentDirectional.bottomStart,
children: <Widget>[
PageStorage(
child: tabs[_cIndex],
bucket: bucket,
),
AppBarra( //Custom bottom navigation bar wrapper
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Expanded(
child: TabButton(
tooltip: 'Back',
onTap: () {
_changeTab(0);
},
icon: Icons.home,
color:
_cIndex == 0 ? Color(0xff00abee) : Colors.grey)),
Expanded(
child: TabButton(
tooltip: 'Back',
onTap: () {
_changeTab(1);
},
icon: Icons.search,
color:
_cIndex == 1 ? Color(0xff00abee) : Colors.grey)
),
Expanded(
child: TabButton(
tooltip: 'Back',
onTap: () {
_changeTab(2);
},
icon: Icons.settings,
color:
_cIndex == 2 ? Color(0xff00abee) : Colors.grey)),
]))
]
));
}
}
关于flutter - ListView恢复滚动位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56818836/
我需要一个非常简单的字符串验证器来显示第一个符号与所需格式不对应的位置。我想使用正则表达式,但在这种情况下,我必须找到与表达式相对应的字符串停止的位置,但我找不到可以做到这一点的方法。(这一定是一种相当简单的方法……也许没有?)例如,如果我有正则表达式:/^Q+E+R+$/带字符串:"QQQQEEE2ER"期望的结果应该是7 最佳答案 一个想法:你可以做的是标记你的模式并用可选的嵌套捕获组编写它:^(Q+(E+(R+($)?)?)?)?然后你只需要计算你获得的捕获组的数量就可以知道正则表达式引擎在模式中停止的位置,你可以确定匹配结束
我将Cucumber与Ruby结合使用。通过Selenium-Webdriver在Chrome中运行测试时,我想将下载位置更改为测试文件夹而不是用户下载文件夹。我当前的chrome驱动程序是这样设置的:Capybara.default_driver=:seleniumCapybara.register_driver:seleniumdo|app|Capybara::Selenium::Driver.new(app,:browser=>:chrome,desired_capabilities:{'chromeOptions'=>{'args'=>%w{window-size=1920,1
我想在heroku.com上查看我的应用程序日志的内容,所以我关注了thisexcellentadvice并拥有我所有的日志内容。但是我现在很想知道我的日志文件实际在哪里,因为“log/production.log”似乎是空的:C:\>herokuconsoleRubyconsoleforajpbrevx.heroku.com>>files=Dir.glob("*")=>["public","tmp","spec","Rakefile","doc","config.ru","app","config","lib","README","Gemfile.lock","vendor","sc
这应该是一个简单的问题,但我找不到任何相关信息。给定一个Ruby中的正则表达式,对于每个匹配项,我需要检索匹配的模式$1、$2,但我还需要匹配位置。我知道=~运算符为我提供了第一个匹配项的位置,而string.scan(/regex/)为我提供了所有匹配模式。如果可能,我需要在同一步骤中获得两个结果。 最佳答案 MatchDatastring.scan(regex)do$1#Patternatfirstposition$2#Patternatsecondposition$~.offset(1)#Startingandendingpo
我使用“newapp_name”创建了一个新的Rails应用程序,我正在尝试编辑.gitignore文件,但在我的应用程序文件夹中找不到它。我在哪里可以找到它?我安装了Git。 最佳答案 .gitignore位于项目的root中,而不是app子目录中。首先打开终端并进入您的目录。您需要使用ls-a来显示stash文件。然后使用打开.gitignore 关于ruby-on-rails-尝试打开.gitignore以在文本编辑器中对其进行编辑,但在OSXMountainLion上找不到文件位
对于我正在编写的Rails3应用程序,我正在考虑从本地文件系统上的XML、YAML或JSON文件中读取一些配置数据。重点是:我应该把这些文件放在哪里?Rails应用程序中是否有用于存储此类内容的默认位置?附带说明一下,我的应用程序部署在Heroku上。 最佳答案 我经常做的是:如果文件是通用配置文件:我在目录/config中创建一个YAML文件,每个环境有一个上层key如果我为每个环境(大项目)创建一个文件:我为每个环境创建一个YAML并将它们存储在/config/environments/然后我在加载YAML的地方创建了一个初始化
假设我有一个没有特定顺序的随机数数组。假设这些是参加马拉松比赛的人的ID#,他们按照完成的顺序添加到数组中,例如:race1=[8,102,67,58,91,16,27]race2=[51,31,7,15,99,58,22]这是一个简化且有些做作的示例,但我认为它传达了基本思想。现在有几个问题:首先,我如何获得特定条目之前和之后的ID?假设我正在查看运行者58,我想知道谁在他之前和之后完成了比赛。race1,runner58:previousfinisher=67,nextfinisher=91race2,runner58:previousfinisher=99,nextfinishe
在Rails中向整数类添加方法的最佳位置在哪里?我想添加一个to_meters和to_miles方法。 最佳答案 如果您决心使用数字(或整数等)类来进行单位转换,那么至少要在逻辑上做到这一点,并具有一些实际值(value)。首先,创建一个Unit类,用于存储单位类型(米、英尺、肘等)和创建时的值。然后向Numeric添加一堆方法,这些方法对应于单元可以具有的有效值:这些方法将返回一个单元对象,其类型记录为方法名称。Unit类将支持一组to_*方法,这些方法将转换为具有相应单位值的另一种单位类型。这样,您可以执行以下命令:>>x=47
技术选型1,前端小程序原生MINA框架cssJavaScriptWxml2,管理后台云开发Cms内容管理系统web网页3,数据后台小程序云开发云函数云开发数据库(基于MongoDB)云存储4,人脸识别算法基于百度智能云实现人脸识别一,用户端效果图预览老规矩我们先来看效果图,如果效果图符合你的需求,就继续往下看,如果不符合你的需求,可以跳过。1-1,登录注册页可以看到登录页有注册入口,注册页如下我们的注册,需要管理员审核,审核通过后才可以正常登录使用小程序1-2,个人中心页登录成功以后,我们会进入个人中心页我们在个人中心页可以注册人脸,因为我们做人脸识别签到,需要先注册人脸才可以进行人脸比对,进
给定一个字符串,返回字符串中换行符开头的字符位置数组的最有效方法是什么?text=预期:find_newlines(text)#=>[0,80,155,233,313,393]我发布我自己的答案。我愿意接受最快的方式作为接受的答案。此处的基准测试结果将在添加新答案时更新require"fruity"comparedopadde1{find_newlines_padde1(text)}digitalross1{find_newlines_digitalross1(text)}sawa1{find_newlines1(text)}sawa2{find_newlines2(text)}end