我正在使用 Flutter 开发移动应用程序。我正在使用颤振块包https://pub.dev/packages/flutter_bloc来管理和设置块。但是当状态改变时,它不会更新小部件或视图。
我有一个名为 home_bloc.dart 的 bloc 类文件,具有以下实现。
class HomeEvent {
static const int FETCH_ARTICLES = 1;
static const int TOGGLE_IS_FILTERING = 2;
int _event = 0;
String _filterKeyword = "";
int get event => _event;
void set event(int event) {
this._event = event;
}
String get filterKeyword => _filterKeyword;
void set filterKeyword(String filterKeyword) {
this._filterKeyword = filterKeyword;
}
}
class HomeBloc extends Bloc<HomeEvent, HomeState> {
Repository _repository = Repository();
HomeState state = HomeState();
@override
HomeState get initialState => state;
@override
Stream<HomeState> mapEventToState(HomeEvent event) async* {
switch (event.event) {
case HomeEvent.FETCH_ARTICLES:
{
List<dynamic> articles = List<dynamic>();
fetchArticles(filter: event.filterKeyword).listen((dynamic article) {
articles.add(article);
});
state = state.copyWith(articles: articles);
break;
}
case HomeEvent.TOGGLE_IS_FILTERING:
{
state.isFiltering = ! state.isFiltering;
state = state.copyWith();
break;
}
default:
{
state = state.initial();
break;
}
}
yield state;
}
Stream<dynamic> fetchArticles({String filter = ""}) async* {
List<dynamic> list = (this.state.articles.length > 0)
? this.state.articles
: await _repository.getArticles();
if (filter.isNotEmpty) {
for (var article in list) {
if (article is String) {
yield article;
} else if (article.title.contains(filter)) {
yield article;
}
}
} else {
for (var article in list) {
yield article;
}
}
}
}
class HomeState {
bool _isFiltering = false;
List<dynamic> _articles = List<dynamic>();
bool get isFiltering => _isFiltering;
void set isFiltering(bool isFiltering) {
this._isFiltering = isFiltering;
}
List<dynamic> get articles => _articles;
void set articles(List<dynamic> list) {
this._articles = list;
}
HomeState initial() {
HomeState state = HomeState();
state.isFiltering = false;
state.articles = List<dynamic>();
return state;
}
HomeState copyWith({ bool isFiltering, List<dynamic> articles }) {
HomeState state = HomeState();
state.isFiltering = isFiltering != null? isFiltering: this._isFiltering;
state.articles = articles!=null && articles.length > 0? articles: this._articles;
return state;
}
}
这是我的存储库类返回虚拟数据。
class Repository {
Future<List<dynamic>> getArticles() async {
List<dynamic> list = List<dynamic>();
list.add("A");
Article article1 = Article();
article1.id = 1;
article1.title = "A start is born";
list.add(article1);
Article article2 = Article();
article2.id = 2;
article2.title = "Asking for help";
list.add(article2);
Article article3 = Article();
article3.id = 3;
article3.title = "Angel is comming";
list.add(article3);
list.add("B");
Article article4 = Article();
article4.id = 4;
article4.title = "Baby Boss";
list.add(article4);
Article article5 = Article();
article5.id = 5;
article5.title = "Beginner guide to Staying at Home";
list.add(article5);
list.add("C");
Article article6 = Article();
article6.id = 6;
article6.title = "Care each other";
list.add(article6);
Article article7 = Article();
article7.id = 7;
article7.title = "Controlling the world";
list.add(article7);
Article article8 = Article();
article8.id = 8;
article8.title = "Chasing the dream";
list.add(article8);
return list;
}
}
这是我的主页小部件
class HomePage extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return _HomePageState();
}
}
class _HomePageState extends State<HomePage> {
IconData _searchIcon = Icons.search;
Widget _appBarTitle;
HomeBloc _homeBloc;
@override
void initState() {
super.initState();
this._homeBloc = BlocProvider.of(context);
WidgetsBinding.instance.addPostFrameCallback((_) => this.fetchArticles());
WidgetsBinding.instance
.addPostFrameCallback((_) => this.buildAppBarTitle());
}
@override
Widget build(BuildContext context) {
return BlocBuilder<HomeBloc, HomeState>(
builder: (context, state) {
return Scaffold(
appBar: AppBar(title: Text("Home"),),
body: Container(
child: buildListView(context, state),
),
);
},
);
}
@override
void dispose() {
super.dispose();
}
void buildAppBarTitle() {
this.setState(() {
if (_searchIcon == Icons.search) {
this._appBarTitle = Text("Home");
} else {
this._appBarTitle = TextField(
onChanged: (String inputValue) {
debugPrint("Search term has changed $inputValue");
//homeBloc.fetchArticles(filter: inputValue);
},
style: TextStyle(
color: Colors.white,
),
decoration: InputDecoration(
hintText: "Search",
),
);
}
});
}
Widget buildAppBarSearchIcon() {
return IconButton(
icon: Icon(
_searchIcon,
color: Colors.white,
),
onPressed: () {
if (this._searchIcon == Icons.search) {
//display the search text field and close icons
this.setState(() {
this._searchIcon = Icons.close;
this.buildAppBarTitle();
//homeBloc.toggleFiltering();
});
} else {
this.fetchArticles();
this.setState(() {
this._searchIcon = Icons.search;
this.buildAppBarTitle();
//homeBloc.toggleFiltering();
});
}
});
}
Widget buildListView(
BuildContext context, HomeState state) {
if (state.articles.length > 0) {
var listView = ListView.builder(
itemCount: state.articles.length,
itemBuilder: (context, index) {
var item = state.articles[index];
if (item is String) {
return buildListFirstInitialView(item);
}
Article article = item as Article;
return buildListArticleView(article);
});
return listView;
} else {
return Center(
child: Text("No resources found."),
);
}
}
Widget buildListFirstInitialView(String initial) {
return ListTile(
title: Text(initial),
);
}
Widget buildListArticleView(Article article) {
return ListTile(
title: Text(article.title),
);
}
Widget buildBottomNavigationBar() {
return BottomNavigationBar(
currentIndex: 0,
onTap: (int position) {},
items: [
BottomNavigationBarItem(
icon: Icon(Icons.home),
title: Text('Home'),
),
BottomNavigationBarItem(
icon: Icon(Icons.settings),
title: Text('Settings'),
),
]);
}
void fetchArticles({String filter = ""}) {
HomeEvent event = HomeEvent();
event.event = HomeEvent.FETCH_ARTICLES;
_homeBloc.add(event);
}
}
如您所见,这是我的 HomePage 小部件正在做的事情。构建小部件后,它将获取文章。然后列表视图将使用虚拟数据进行更新。
这是我的 main.dart 文件。
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
theme: ThemeData(
// This is the theme of your application.
//
// Try running your application with "flutter run". You'll see the
// application has a blue toolbar. Then, without quitting the app, try
// changing the primarySwatch below to Colors.green and then invoke
// "hot reload" (press "r" in the console where you ran "flutter run",
// or simply save your changes to "hot reload" in a Flutter IDE).
// Notice that the counter didn't reset back to zero; the application
// is not restarted.
primarySwatch: Colors.blue,
),
home: BlocProvider(
create: (context) => HomeBloc(),
child: HomePage(),
),
);
}
}
当我运行我的应用程序时,它不会使用虚拟数据更新列表视图。相反,它总是显示未找到记录的消息。
为什么它不起作用?