- 我使用LongPressDraggable创建了一个小部件。当我执行拖动操作时,流数据(StreamBuilder)从屏幕上消失。附加代码供您参考。*
main.dart
在main.dart中,我定义了一个Stack小部件。在Stack小部件中,我定义了一个BaseWidget。基本小部件将TextStream小部件作为参数
import 'package:example/base_widget.dart';
import 'package:example/text_stream.dart';
import 'package:example/widget_view_model.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
void main() {
runApp(
MultiProvider(providers: [
ChangeNotifierProvider<WidgetViewModel>(
create: (context) => WidgetViewModel(),
),
], child: const MyApp()));
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
WidgetViewModel widgetViewModel = context.read<WidgetViewModel>();
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Stack(
children: <Widget>[
BaseWidget(widgetItem: TextStream(value: widgetViewModel.textStream))
]
),
),
);
}
}
text_stream.dart
在text_stream.dart中,我定义了一个StreamBuilder,它将字符串的Stream作为它的参数。StreamBuilder在找到快照数据时返回TextWidget
import 'package:example/text_widget.dart';
import 'package:flutter/material.dart';
class TextStream extends StatefulWidget {
final Stream<String> value;
const TextStream({Key? key, required this.value}) : super(key: key);
@override
State<TextStream> createState() => _TextStreamState();
}
class _TextStreamState extends State<TextStream> {
@override
Widget build(BuildContext context) {
return StreamBuilder<String>(
stream: widget.value,
builder: (context, snapshot) {
if(snapshot.hasData){
return TextWidget(text: snapshot.data!);
}
else {
return const TextWidget(text: "Unknown");
}
});
}
}
base_widget.dart
base_widget.dart包含LongPressDraggable和Positioned widget的实现。
import 'package:flutter/material.dart';
class BaseWidget extends StatefulWidget {
final Widget widgetItem;
const BaseWidget({Key? key, required this.widgetItem}) : super(key: key);
@override
State<BaseWidget> createState() => _BaseWidgetState();
}
class _BaseWidgetState extends State<BaseWidget> {
double _x = 0.0;
double _y = 0.0;
@override
Widget build(BuildContext context) {
return Positioned(
left: _x,
top: _y,
child: LongPressDraggable(
feedback: widget.widgetItem,
childWhenDragging: const SizedBox(),
onDragEnd: (details) {
setState(() {
_x = details.offset.dx;
_y = details.offset.dy;
});
},
child: widget.widgetItem,
),
);
}
}
widget_view_model.dart
它包含EventChannel(客户端)的实现,它从Android主机获取值。
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:provider/provider.dart';
class WidgetViewModel extends ChangeNotifier {
static const textEvent = EventChannel("com.example.example");
Stream<String> textStream = textEvent.receiveBroadcastStream().distinct().map((event) {
return event as String;
});
}
text_widget.dart
它包含容器和文本小部件的实现。TextStream类将String值作为其输入参数。
import 'package:flutter/material.dart';
class TextWidget extends StatefulWidget {
final String text;
const TextWidget({Key? key, required this.text}) : super(key: key);
@override
State<TextWidget> createState() => _TextWidgetState();
}
class _TextWidgetState extends State<TextWidget> {
@override
Widget build(BuildContext context) {
return Container(
color: Colors.amber,
height: 100.0,
width: 100.0,
child: Text(
widget.text,
style: const TextStyle(fontSize: 20.0),
),
);
}
}
MainActivity.kt
它实现了EventChannel流处理程序和事件接收器,以在Flutter端传递值。
package com.example.example
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.EventChannel
class MainActivity: FlutterActivity() {
private val textEvent = "com.example.example"
private var textEventSink: EventChannel.EventSink? = null
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)
EventChannel(flutterEngine.dartExecutor.binaryMessenger,textEvent).setStreamHandler(
object: EventChannel.StreamHandler {
override fun onListen(arguments: Any?, events: EventChannel.EventSink?) {
textEventSink = events
textEventSink?.success("Harsh")
}
override fun onCancel(arguments: Any?) {
textEventSink?.success("Harsh")
textEventSink = null
}
}
)
}
}
1条答案
按热度按时间dl5txlt91#
流数据(StreamBuilder)没有消失,只是正在重建并等待流的下一个值,但您的textStream在第一次构建后没有发出任何值,如果流继续发出值,您的代码就很好。
//下面是我修改的一些代码,用于存储流值。
main.dart
text_widget.dart
text_stream.dart
base_widget.dart
text_widget.dart
注意!!此方法在onDrag期间仍然无法更新“feedback”参数。