我有一个列表,其中包含许多 Draggables 和 DragTargets 小部件。当 Draggable 小部件的状态发生变化时,我想更改 DragTargets 的颜色。
我正在尝试使用 flutter_bloc 来实现它,但出现以下错误:Error: Could not find the correct Provider<MyBloc> above this _InheritedProviderScope<MyBloc> Widget
。
这是一个最小的例子:
class ListItemBloc extends Bloc<ListItemEvent, ListItemState> {
ListItemBloc() : super(ListItemInitial());
@override
Stream<ListItemState> mapEventToState(
ListItemEvent event,
) async* {
if (event is OnDragStarted) {
yield ListItemUpdated(true, false, false);
} else if (event is OnDragCompleted) {
yield ListItemUpdated(false, true, false);
} else if (event is OnDraggableCanceled) {
yield ListItemUpdated(false, false, true);
}
}
}
abstract class ListItemState extends Equatable {
@override
List<Object?> get props => [];
}
class ListItemInitial extends ListItemState {}
class ListItemUpdated extends ListItemState {
final bool isOnDragStarted;
final bool isOnDragCompleted;
final bool isOnDraggableCanceled;
ListItemUpdated(
this.isOnDragStarted,
this.isOnDragCompleted,
this.isOnDraggableCanceled,
);
@override
List<Object?> get props => [
isOnDragStarted,
isOnDragCompleted,
isOnDraggableCanceled,
];
}
abstract class ListItemEvent extends Equatable {
@override
List<Object?> get props => [];
}
class OnDragStarted extends ListItemEvent {}
class OnDragCompleted extends ListItemEvent {}
class OnDraggableCanceled extends ListItemEvent {}
...
List<String> folders = ['folderA', 'folderB'];
List<String> images = [
'https://images.unsplash.com/photo-1622495805731-eefd22e836f4?ixid=MnwxMjA3fDF8MHxlZGl0b3JpYWwtZmVlZHwxfHx8ZW58MHx8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=900&q=60',
'https://images.unsplash.com/photo-1622472263439-28f6e98d05b7?ixid=MnwxMjA3fDB8MHxlZGl0b3JpYWwtZmVlZHw0fHx8ZW58MHx8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=900&q=60',
'https://images.unsplash.com/photo-1622497274862-2dd4cd0ddaac?ixid=MnwxMjA3fDB8MHxlZGl0b3JpYWwtZmVlZHw1fHx8ZW58MHx8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=900&q=60',
'https://images.unsplash.com/photo-1622506614848-65988f1f6b33?ixid=MnwxMjA3fDB8MHxlZGl0b3JpYWwtZmVlZHwyfHx8ZW58MHx8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=900&q=60',
];
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
...
@override
Widget build(BuildContext context) {
final _length = folders.length + images.length;
return BlocProvider<ListItemBloc>(
create: (context) => context.read<ListItemBloc>(),
child: MaterialApp(
...
home: ListView.builder(
itemCount: _length,
itemBuilder: (context, index) {
if (index < folders.length) {
return MyDragTargetCard(folderName: folders[index]);
}
return MyDraggableCard(
index: index - 2,
imageUrl: images[index - 2],
);
},
),
),
);
}
}
class MyDraggableCard extends StatelessWidget {
final int index;
final String imageUrl;
...
@override
Widget build(BuildContext context) {
print(context.read<ListItemBloc>().state); // error while trying to know the current state
final GlobalKey _draggableKey = GlobalKey();
Image _image = Image.network(imageUrl);
return Draggable<Image>(
dragAnchorStrategy: pointerDragAnchorStrategy,
data: Image.network(imageUrl),
feedback: DraggingCard(
key: Key('_draggingCard$index'),
dragKey: _draggableKey,
image: _image,
),
child: Card(
...
child: _image,
),
onDragStarted: () => print('onDragStarted'),
onDragCompleted: () => print('onDragCompleted'),
onDraggableCanceled: (Velocity velocity, Offset offset) {
print('onDraggableCanceled');
},
);
}
}
class DraggingCard extends StatelessWidget {
final GlobalKey dragKey;
final Image image;
...
@override
Widget build(BuildContext context) {
final GlobalKey _draggableKey = GlobalKey();
return FractionalTranslation(
translation: const Offset(-0.5, -0.5),
child: ClipRRect(
key: _draggableKey,
...
child: SizedBox(
height: 150,
width: 150,
child: Opacity(
opacity: 0.85,
child: image,
),
),
),
);
}
}
class _MyDragTargetCardState extends State<MyDragTargetCard> {
late Color _folderColor;
@override
void initState() {
_folderColor = Colors.grey;
super.initState();
}
@override
Widget build(BuildContext context) {
print(context.read<ListItemBloc>().state); // error while trying to know the current state
return DragTarget<Image>(
builder: (context, candidateData, rejectedData) {
return Card(
color: _folderColor,
child: Center(child: Text(widget.folderName)),
);
},
onWillAccept: (item) => true,
onAccept: (item) => print('onAccept'),
onLeave: (item) => setState(() {
_folderColor = Colors.green;
}),
onMove: (item) => setState(() {
_folderColor = Colors.red;
}),
);
}
}
关于如何在不出现上述错误的情况下获取集团当前状态的任何建议?