flutter problem:how 当我在 flutter 中从另一个页面搜索时反映另一个页面的变化
flutter problem:how to reflect changes in another page when i search from another page in flutter
这是我的“TabTop”搜索 ui 代码。
在此搜索页面中,我有一个搜索功能,该功能将数据存储在
“eventsSearchLists”我还有一个变量“eventsListData”在这个变量中我有以前的数据当我搜索任何东西然后数据将在变量中改变但它不反映另一个页面。
当搜索数据确实进入“eventsListData”时,该时间的数据不会改变,但当我使用“ctrl+s”时,数据会反映出来
这是我的全局变量 eventsListData
import 'dart:async';
import 'package:cwc/ApiManager/api_magager.dart';
import 'package:flutter/material.dart';
import 'constants.dart';
class TabTop extends StatefulWidget {
const TabTop({Key? key}) : super(key: key);
@override
State<TabTop> createState() => _TabTopState();
}
class _TabTopState extends State<TabTop> {
ApiManager apiManager = ApiManager();
@override
void initState() {
super.initState();
}
String query = '';
Timer? debouncer;
void dispose() {
debouncer?.cancel();
super.dispose();
}
void debounce(
VoidCallback callback, {
Duration duration = const Duration(milliseconds: 10),
}) {
if (debouncer != null) {
debouncer!.cancel();
}
debouncer = Timer(duration, callback);
}
Future searchEvent(String query) async => debounce(() async {
// final breanchesLists = await apiManager.topBrancesList(query);
final eventsLists = await apiManager.eventsSearch(query);
if (!mounted) return;
setState(() {
this.query = query;
eventsSearchLists = eventsLists;
print("eventsSearchLists $eventsSearchLists");
setState(() {
eventsListData =[eventsSearchLists];
print("eventsSearchLists111 $eventsListData");
});
});
});
@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.symmetric(vertical: 8),
height: 60,
child: TextField(
onChanged: searchEvent,
textAlignVertical: TextAlignVertical.center,
decoration: InputDecoration(
contentPadding: EdgeInsets.all(10.0),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10.0),
borderSide: BorderSide.none,
),
filled: true,
fillColor: const Color(0xFFFFFFFF),
hintText: 'Search for Events',
suffixIcon: const Icon(
Icons.search_outlined,
color: Color(0xFF444444),
),
),
),
);
}
}
这是我的另一个页面,我在其中调用了“TabTop”和其他东西。
// ignore_for_file: prefer_const_constructors
import 'package:cwc/constants/card_top.dart';
import 'package:cwc/constants/top_card.dart';
import 'package:cwc/ui/Event/components/activities.dart';
import 'package:cwc/ui/Event/components/event_page_changer.dart';
import 'package:cwc/ui/Event/components/event_tab_view.dart';
import 'package:cwc/ui/Home/components/search_components.dart';
import 'package:cwc/ui/Home/home_page.dart';
import 'package:cwc/ui/footer/bottom_nav_bar.dart';
import 'package:cwc/ui/footer/bottom_nav_bar_event.dart';
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
class Event extends StatefulWidget {
const Event({Key? key}) : super(key: key);
@override
_EventState createState() => _EventState();
}
class _EventState extends State<Event> {
@override
void initState() {
// TODO: implement initState
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
// backgroundColor: Color(0xff80CAD7),
body: SafeArea(
child: Stack(
children: [
Container(
width: double.infinity,
height: 210,
decoration: const BoxDecoration(
color: Color(0xff80CAD7),
image: DecorationImage(
image: AssetImage('assets/bg_dummy.png'),
fit: BoxFit.cover,
),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.fromLTRB(18, 12, 0, 0),
child: GestureDetector(
onTap: () {
Navigator.pop(context);
},
child: const CircleAvatar(
radius: 25,
backgroundColor: Colors.white,
child: Icon(Icons.arrow_back_ios_new, color: Colors.black),
),
),
),
],
),
),
Padding(
padding: EdgeInsets.fromLTRB(18, 125, 18, 0),
child: TabTop(),
),
Padding(
padding: EdgeInsets.only(top: 190),
child: Container(
clipBehavior: Clip.hardEdge,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topRight: Radius.circular(24.0),
topLeft: Radius.circular(24.0)),
),
child: Activities()), // here is my list of data in Activities page (Showing data in this page)
)
// EventPageChanger(),
// Expanded(child: Activities()),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
Navigator.pushReplacement(
context, MaterialPageRoute(builder: (context) => HomePage()));
},
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
child: Image.asset('assets/btnavico.png'),
elevation: 5.0,
highlightElevation: 10,
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
bottomNavigationBar: Container(
// height: MediaQuery.of(context).size.height * (10 / 100),
child: BottomNavBarEvent()),
);
}
}
这里发生的事情是,您在加载新数据时调用 TabTop 内的 setState,这只会导致 TabTop 重建,即仅重建 TabTop 内的小部件。但是,显示数据的 Activities() 小部件位于 Event class 内部,它没有得到 rebuilt.So 我们需要一种方法来在数据更新后重建整个 Event class。您可以通过以下方式实现:
在TabTop中定义一个回调函数class,可以在数据更新后调用为:
class TabTop extends StatefulWidget {
const TabTop({Key? key,required this.onDataUpdated}) : super(key: key);
final VoidCallback onDataUpdated;
@override
State<TabTop> createState() => _TabTopState();
}
并在数据更新后调用此回调函数:
Future searchEvent(String query) async => debounce(() async {
// final breanchesLists = await apiManager.topBrancesList(query);
final eventsLists = await apiManager.eventsSearch(query);
if (!mounted) return;
///callback function has been called here
widget.onDataUpdated();
///avoid unnecessary setState
setState(() {
this.query = query;
eventsSearchLists = eventsLists;
eventsListData =[eventsSearchLists];
print("eventsSearchLists111 $eventsListData");
print("eventsSearchLists $eventsSearchLists”);
});
});
On Event class,在调用 TabTop 时,将回调函数作为参数发送为:
Padding(
padding: EdgeInsets.fromLTRB(18, 125, 18, 0),
child: TabTop(
onDataUpdated : () =>setState((){}),
),
),
这是我的“TabTop”搜索 ui 代码。 在此搜索页面中,我有一个搜索功能,该功能将数据存储在 “eventsSearchLists”我还有一个变量“eventsListData”在这个变量中我有以前的数据当我搜索任何东西然后数据将在变量中改变但它不反映另一个页面。
当搜索数据确实进入“eventsListData”时,该时间的数据不会改变,但当我使用“ctrl+s”时,数据会反映出来
这是我的全局变量 eventsListData
import 'dart:async';
import 'package:cwc/ApiManager/api_magager.dart';
import 'package:flutter/material.dart';
import 'constants.dart';
class TabTop extends StatefulWidget {
const TabTop({Key? key}) : super(key: key);
@override
State<TabTop> createState() => _TabTopState();
}
class _TabTopState extends State<TabTop> {
ApiManager apiManager = ApiManager();
@override
void initState() {
super.initState();
}
String query = '';
Timer? debouncer;
void dispose() {
debouncer?.cancel();
super.dispose();
}
void debounce(
VoidCallback callback, {
Duration duration = const Duration(milliseconds: 10),
}) {
if (debouncer != null) {
debouncer!.cancel();
}
debouncer = Timer(duration, callback);
}
Future searchEvent(String query) async => debounce(() async {
// final breanchesLists = await apiManager.topBrancesList(query);
final eventsLists = await apiManager.eventsSearch(query);
if (!mounted) return;
setState(() {
this.query = query;
eventsSearchLists = eventsLists;
print("eventsSearchLists $eventsSearchLists");
setState(() {
eventsListData =[eventsSearchLists];
print("eventsSearchLists111 $eventsListData");
});
});
});
@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.symmetric(vertical: 8),
height: 60,
child: TextField(
onChanged: searchEvent,
textAlignVertical: TextAlignVertical.center,
decoration: InputDecoration(
contentPadding: EdgeInsets.all(10.0),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10.0),
borderSide: BorderSide.none,
),
filled: true,
fillColor: const Color(0xFFFFFFFF),
hintText: 'Search for Events',
suffixIcon: const Icon(
Icons.search_outlined,
color: Color(0xFF444444),
),
),
),
);
}
}
这是我的另一个页面,我在其中调用了“TabTop”和其他东西。
// ignore_for_file: prefer_const_constructors
import 'package:cwc/constants/card_top.dart';
import 'package:cwc/constants/top_card.dart';
import 'package:cwc/ui/Event/components/activities.dart';
import 'package:cwc/ui/Event/components/event_page_changer.dart';
import 'package:cwc/ui/Event/components/event_tab_view.dart';
import 'package:cwc/ui/Home/components/search_components.dart';
import 'package:cwc/ui/Home/home_page.dart';
import 'package:cwc/ui/footer/bottom_nav_bar.dart';
import 'package:cwc/ui/footer/bottom_nav_bar_event.dart';
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
class Event extends StatefulWidget {
const Event({Key? key}) : super(key: key);
@override
_EventState createState() => _EventState();
}
class _EventState extends State<Event> {
@override
void initState() {
// TODO: implement initState
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
// backgroundColor: Color(0xff80CAD7),
body: SafeArea(
child: Stack(
children: [
Container(
width: double.infinity,
height: 210,
decoration: const BoxDecoration(
color: Color(0xff80CAD7),
image: DecorationImage(
image: AssetImage('assets/bg_dummy.png'),
fit: BoxFit.cover,
),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.fromLTRB(18, 12, 0, 0),
child: GestureDetector(
onTap: () {
Navigator.pop(context);
},
child: const CircleAvatar(
radius: 25,
backgroundColor: Colors.white,
child: Icon(Icons.arrow_back_ios_new, color: Colors.black),
),
),
),
],
),
),
Padding(
padding: EdgeInsets.fromLTRB(18, 125, 18, 0),
child: TabTop(),
),
Padding(
padding: EdgeInsets.only(top: 190),
child: Container(
clipBehavior: Clip.hardEdge,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topRight: Radius.circular(24.0),
topLeft: Radius.circular(24.0)),
),
child: Activities()), // here is my list of data in Activities page (Showing data in this page)
)
// EventPageChanger(),
// Expanded(child: Activities()),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
Navigator.pushReplacement(
context, MaterialPageRoute(builder: (context) => HomePage()));
},
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
child: Image.asset('assets/btnavico.png'),
elevation: 5.0,
highlightElevation: 10,
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
bottomNavigationBar: Container(
// height: MediaQuery.of(context).size.height * (10 / 100),
child: BottomNavBarEvent()),
);
}
}
这里发生的事情是,您在加载新数据时调用 TabTop 内的 setState,这只会导致 TabTop 重建,即仅重建 TabTop 内的小部件。但是,显示数据的 Activities() 小部件位于 Event class 内部,它没有得到 rebuilt.So 我们需要一种方法来在数据更新后重建整个 Event class。您可以通过以下方式实现:
在TabTop中定义一个回调函数class,可以在数据更新后调用为:
class TabTop extends StatefulWidget {
const TabTop({Key? key,required this.onDataUpdated}) : super(key: key);
final VoidCallback onDataUpdated;
@override
State<TabTop> createState() => _TabTopState();
}
并在数据更新后调用此回调函数:
Future searchEvent(String query) async => debounce(() async {
// final breanchesLists = await apiManager.topBrancesList(query);
final eventsLists = await apiManager.eventsSearch(query);
if (!mounted) return;
///callback function has been called here
widget.onDataUpdated();
///avoid unnecessary setState
setState(() {
this.query = query;
eventsSearchLists = eventsLists;
eventsListData =[eventsSearchLists];
print("eventsSearchLists111 $eventsListData");
print("eventsSearchLists $eventsSearchLists”);
});
});
On Event class,在调用 TabTop 时,将回调函数作为参数发送为:
Padding(
padding: EdgeInsets.fromLTRB(18, 125, 18, 0),
child: TabTop(
onDataUpdated : () =>setState((){}),
),
),