颤振-以编程方式更新TextField以显示滚动信息



我想在我的应用程序中显示一些调试信息(例如用户按下按钮A),并考虑使用TextField小部件。

使用下面的代码,我可以从我的手机中记录环境声音,我想在底部添加一个小部件,显示录音开始和停止的时间戳,包括录音的长度。这个想法是使用一个环形缓冲区(package:circular_buffer)来跟踪在TextField中显示的预定义的文本行数。每当发生什么事情时,新的调试信息就会作为一个元素添加到环形缓冲区中,并更新TextField。我是很新的扑动,所以我完全不确定如何实现这一点。我试图使用setState(),但我不知道如何从其他小部件调用它。是否有一种方法可以注册为侦听器,以了解其他小部件的状态变化并相应地更新文本?

import 'dart:async';
import 'dart:io';
// locale, datetime formatting
import 'package:intl/intl.dart';
import 'package:flutter/material.dart';
import 'package:record/record.dart';
import 'package:path_provider/path_provider.dart';
// local imports
import './display_timer.dart';
void main() {
runApp(myApp());
}
class myApp extends StatefulWidget {
@override
myAppState createState() => myAppState();
}
class myAppState extends State<myApp> {
final record = Record();
bool bPressed = false;
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Record',
home: Scaffold(
appBar: AppBar(
title: const Text('Record'),
),
body: Center(
child:
Column(mainAxisAlignment: MainAxisAlignment.center, children: [
ElevatedButton(
child: bPressed ? const Text("Stop") : const Text("Record"),
onPressed: () {
setState(() {
bPressed = !bPressed;
});
action();
},
),
if (bPressed)
ElapsedTime(timestamp: DateTime.now().toString())
else
const Text("")
]),
),
));
}
String getTimestampSec() {
DateTime now = DateTime.now();
var dateString = DateFormat('yyyyMMdd_hhmmss').format(now);
return dateString;
}
Future<void> action() async {
// Get the state of the recorder
bool isRecording = await record.isRecording();
// Check and request permission
if (await record.hasPermission()) {
if (isRecording) {
// Stop recording
await record.stop();
} else {
// get write dir
// TODO: add fnc so dir only has to be initialize once
Directory appDocDir = await getApplicationDocumentsDirectory();
String appDocPath = appDocDir.path;
String outFile =
"$appDocPath/${getTimestampSec()}_ambient_test.m4a";
print("saving audio to: $outFile");
// Start recording
await record.start(
path: outFile,
encoder: AudioEncoder.aacLc, // by default
bitRate: 128000, // by default
samplingRate: 44100, // by default
);
}
}
print('Pressed');
}
}

每次都使用setState()不是很好的做法,而可以使用ValueNotifier。每次你更新字符串值,它通知到你的TextField,它将更新TextField数据。

ValueNotifier<String> logText = ValueNotifier<String>("Welcome");

ValueListenableBuilder(
valueListenable: logText,
builder: (context, logTextUpdate,child) {
return Text(
"${logText.value}",
style: TextStyle(fontSize: 25),
);
}),

当你想更新你的文本,赋值给logText

logText.value = "Happy to see you!"

最新更新