[英]How to switch AppBar in the Flutter's Scaffold?
我有一种情况,当我在BottomNavigationBar
小部件上切换页面时,我的Scaffold
中的AppBar
需要更改。 一个AppBar
是一个普通的AppBar(title: Text('Saved'))
,另一个是AppBarTextField
小部件( https://pub.dev/packages/appbar_textfield )。 从这个,我想保留在切换之前已经输入的文本。 但是使用下面的代码,每次我返回相关页面时,该栏都已重置:
import 'package:flutter/material.dart';
import 'package:gifs/screens/main/search.dart';
import 'package:gifs/screens/main/saved.dart';
import 'package:gifs/screens/main/search_appbar.dart';
import '../../models/search_result.dart';
class Navigation extends StatefulWidget {
Navigation({required Key key}) : super(key: key);
final SearchResult _searchResult = SearchResult();
late List<PreferredSizeWidget> _appBars = [
SearchAppBar(key: GlobalKey(debugLabel: 'search_appbar_ui'), searchResult: _searchResult),
AppBar(title: Text('Saved'))
];
late List<Widget> _pages = [
Search(key: GlobalKey(debugLabel: 'search_ui'), searchResult: _searchResult),
Saved(key: GlobalKey(debugLabel: 'saved_ui')),
];
@override
_NavigationState createState() => _NavigationState();
}
class _NavigationState extends State<Navigation> {
int _currentIndex = 0;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: widget._appBars[_currentIndex],
body: IndexedStack(
index: _currentIndex,
children: widget._pages,
),
bottomNavigationBar: BottomNavigationBar(
currentIndex: _currentIndex,
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(icon: Icon(Icons.search), label: 'Search'),
BottomNavigationBarItem(icon: Icon(Icons.favorite), label: 'Saved'),
],
onTap: (index) => {
setState(() {
_currentIndex = index;
})
}
),
);
}
}
这是SearchBar
代码:
import 'package:flutter/material.dart';
import 'package:gifs/models/search_result.dart';
import 'package:appbar_textfield/appbar_textfield.dart';
class SearchAppBar extends StatefulWidget with PreferredSizeWidget {
final SearchResult searchResult;
const SearchAppBar({required Key key, required this.searchResult}) : super(key: key);
@override
_SearchAppBarState createState() => _SearchAppBarState();
@override
Size get preferredSize => Size.fromHeight(kToolbarHeight);
}
class _SearchAppBarState extends State<SearchAppBar> {
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return AppBarTextField(
title: Text("Enter a search term"),
onBackPressed: _onRestoreAllData,
onClearPressed: _onRestoreAllData,
onChanged: _onSearchChanged,
);
}
void _onSearchChanged(String value) {
widget.searchResult.searchTerm(value);
}
void _onRestoreAllData() {
_onSearchChanged('');
}
}
如您所见,我根据索引切换_appBars
,但每次切换后栏中的文本都会消失。 有没有办法保持其当前状态?
试试这个:我无法运行您自己的代码,但我在入门 flutter 应用程序中测试了我的解决方案并且它有效(代码在最后提供)
这是您修改后的Navigation
小部件代码:
import 'package:flutter/material.dart';
import 'package:gifs/screens/main/search.dart';
import 'package:gifs/screens/main/saved.dart';
import 'package:gifs/screens/main/search_appbar.dart';
import '../../models/search_result.dart';
class Navigation extends StatefulWidget {
Navigation({required Key key}) : super(key: key);
@override
_NavigationState createState() => _NavigationState();
}
class _NavigationState extends State<Navigation> {
int _currentIndex = 0;
final SearchResult _searchResult = SearchResult();
List<PreferredSizeWidget> get _appBars => [
SearchAppBar(
key: GlobalKey(debugLabel: 'search_appbar_ui'),
searchResult: _searchResult,
setSearchResult: (String value) {
//set your string value of the SearchResult class
setState(() => _searchResult.term = value);
}
),
AppBar(title: Text('Saved'))
];
List<Widget> get _pages => [
Search(key: GlobalKey(debugLabel: 'search_ui'), searchResult: _searchResult),
Saved(key: GlobalKey(debugLabel: 'saved_ui')),
];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: widget._appBars[_currentIndex],
body: IndexedStack(
index: _currentIndex,
children: widget._pages,
),
bottomNavigationBar: BottomNavigationBar(
currentIndex: _currentIndex,
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(icon: Icon(Icons.search), label: 'Search'),
BottomNavigationBarItem(icon: Icon(Icons.favorite), label: 'Saved'),
],
onTap: (index) => {
setState(() {
_currentIndex = index;
})
}
),
);
}
}
关于我所做的注释:
_appBars
和_pages
和_searchResult
变量移动到您的 state class 并删除了后期初始化并使它们成为吸气剂。 这是您修改后的SearchAppBar
小部件代码:
import 'package:flutter/material.dart';
import 'package:gifs/models/search_result.dart';
import 'package:appbar_textfield/appbar_textfield.dart';
class SearchAppBar extends StatefulWidget with PreferredSizeWidget {
final SearchResult searchResult;
final ValueChanged<String> setSearchResult;
const SearchAppBar({required Key key, required this.searchResult, required this.setSearchResult}) : super(key: key);
@override
_SearchAppBarState createState() => _SearchAppBarState();
@override
Size get preferredSize => Size.fromHeight(kToolbarHeight);
}
class _SearchAppBarState extends State<SearchAppBar> {
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return AppBarTextField(
title: Text("Enter a search term"),
onBackPressed: _onRestoreAllData,
onClearPressed: _onRestoreAllData,
onChanged: _onSearchChanged,
// Give your string value of the SearchResult class
// as an initial value to your text field.
// If this was a regular TextFormField() widget you would
// have been able to use the initialValue param, but I'm not
// sure if there's a better alternative than using the
// controller for this package
controller: TextEditingController()..text = widget.searchResult.term,
);
}
void _onSearchChanged(String value) {
widget.setSearchResult(value);
}
void _onRestoreAllData() {
_onSearchChanged('');
}
}
关于我所做的注释:
AppBarTextField
的onChanged
参数中调用了widget.setSearchResult
function 来更新父小部件中的值widget.searchResult
的字符串值作为初始值分配给文本字段,这样当您重新访问页面时,它会再次分配给文本字段而不会丢失。如果您想尝试一下,这是我在沙盒应用程序中的代码:(将其放在 dartpad 中并运行它,您应该会看到它在工作)
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
static const String _title = 'Flutter Code Sample';
@override
Widget build(BuildContext context) {
return const MaterialApp(
title: _title,
home: MyStatefulWidget(),
);
}
}
class MyStatefulWidget extends StatefulWidget {
const MyStatefulWidget({Key? key}) : super(key: key);
@override
State<MyStatefulWidget> createState() => _MyStatefulWidgetState();
}
class _MyStatefulWidgetState extends State<MyStatefulWidget> {
String searchResult = '';
List<PreferredSizeWidget> get _appBars => [
SearchAppBar(
setSearchResult: (String value) =>
setState(() => searchResult = value),
searchResult: searchResult,
),
AppBar(title: const Text('Saved')),
];
int _selectedIndex = 0;
static const TextStyle optionStyle =
TextStyle(fontSize: 30, fontWeight: FontWeight.bold);
static const List<Widget> _widgetOptions = <Widget>[
Text(
'Index 0: Home',
style: optionStyle,
),
Text(
'Index 1: Business',
style: optionStyle,
),
];
void _onItemTapped(int index) {
setState(() {
_selectedIndex = index;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: _appBars[_selectedIndex],
body: Center(
child: _widgetOptions.elementAt(_selectedIndex),
),
bottomNavigationBar: BottomNavigationBar(
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: 'Home',
backgroundColor: Colors.red,
),
BottomNavigationBarItem(
icon: Icon(Icons.business),
label: 'Business',
backgroundColor: Colors.green,
),
],
currentIndex: _selectedIndex,
selectedItemColor: Colors.amber[800],
onTap: _onItemTapped,
),
);
}
}
class SearchAppBar extends StatefulWidget with PreferredSizeWidget {
final String searchResult;
final ValueChanged<String> setSearchResult;
const SearchAppBar({required this.setSearchResult, this.searchResult = ''});
@override
_SearchAppBarState createState() => _SearchAppBarState();
@override
Size get preferredSize => const Size.fromHeight(56);
}
class _SearchAppBarState extends State<SearchAppBar> {
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return TextFormField(
onChanged: _onSearchChanged,
controller: TextEditingController()..text = widget.searchResult,
// initialValue: widget.searchResult,
);
}
void _onSearchChanged(String value) {
widget.setSearchResult(value);
}
}
希望这可以帮助!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.