Scenario个
我有一个创建5个项目的ListView.Builder.每个磁贴都有一个文本和一个图标.当图标被点击时,它需要在粗体和普通之间切换文本的字体,以及将图标从已读切换到未读.
我正在使用BLOC进行国家管理.
Code个
tile_state.dart个
abstract class TileState {}
class UnreadState extends TileState {
final bool isUnread;
UnreadState({
required this.isUnread,
});
}
class ReadState extends TileState {
final bool isUnread;
ReadState({
required this.isUnread,
});
}
tile_event.dart个
abstract class TileEvent {}
class UnreadEvent extends TileEvent {
final bool unreadStatus;
UnreadEvent(this.unreadStatus);
}
class ReadEvent extends TileEvent {
final bool unreadStatus;
ReadEvent(this.unreadStatus);
}
tile_bloc.dart个
class TileBloc extends Bloc<TileEvent, TileState> {
TileBloc() : super(UnreadState(isUnread: true)) {
on<UnreadEvent>((event, emit) => emit(UnreadState(isUnread: true)));
on<ReadEvent>((event, emit) => emit(ReadState(isUnread: false)));
}
}
tile.dart个
class CustomTile extends StatelessWidget {
CustomTile({
Key? key,
required this.text,
required this.isUnread,
required this.onTap,
}) : super(key: key);
final String text;
bool isUnread;
final VoidCallback onTap;
@override
Widget build(BuildContext context) {
return Container(
padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 7.5),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
text,
style: TextStyle(
fontWeight: isUnread ? FontWeight.w600 : FontWeight.w200,
),
),
InkWell(
onTap: onTap,
child: Icon(
isUnread ? Icons.mail_rounded : Icons.mail_outline_rounded,
),
),
],
),
);
}
}
tile_page.dart个
class TilesPage extends StatefulWidget {
const TilesPage({Key? key}) : super(key: key);
@override
State<TilesPage> createState() => _TilesPageState();
}
class _TilesPageState extends State<TilesPage> {
@override
Widget build(BuildContext context) {
final TileBloc bloc = context.read<TileBloc>();
return Scaffold(
appBar: AppBar(
title: const Text("Tile Screen"),
),
body: Center(
child: Column(
children: [
Expanded(
child: ListView.builder(
itemCount: 5,
itemBuilder: (context, index) {
return BlocBuilder<TileBloc, TileState>(
builder: (context, state) {
if (state is UnreadState) {
return CustomTile(
text: "Message $index",
isUnread: state.isUnread,
onTap: () {
bloc.add(ReadEvent(false));
},
);
} else if (state is ReadState) {
return CustomTile(
text: "Message $index",
isUnread: state.isUnread,
onTap: () {
bloc.add(UnreadEvent(true));
},
);
} else {
return const SizedBox();
}
},
);
},
),
),
],
),
),
);
}
}
Problem个
当我点击一个特定的磁贴,而不是切换该磁贴的字体宽度和图标,所有的磁贴都会同时切换它们的字体宽度和图标,也就是说,整个ListView正在重建.
Request个
我想知道我的代码中有什么错误导致了这一点,以及如何只重建单个磁贴而不是整个列表.