从未来获取权限流
Get a stream of permissions from a future
我正在尝试流式传输两种类型的基于位置包的数据:
final _location = Location();
runApp(
MultiProvider(
providers: [
StreamProvider<PermissionStatus>(create: (_) => _location.hasPermission().asStream()),
StreamProvider<bool>(create: (_) => _location.serviceEnabled().asStream()),
],
child: MaterialApp();
)
)
当我 'stream' 数据时,它加载初始值并流式传输。它不是不断地倾听变化,而这正是我想要做的。我已经尝试将两个期货抽象成它们自己的 class 并创建一个产生当前状态的异步*流,这两个都给出了同样的问题。
我的用例涉及持续监听权限状态和位置 on/off 并在任务之间修改这些部分时关闭 UI 的某些部分。
简化用法:
class LocationWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Consumer2<PermissionStatus, bool>(
builder: (_, permission, isLocationEnabled, __) => _LocationWidget(
permission: permission, isLocationEnabled: isLocationEnabled));
}
}
class _LocationWidget extends StatelessWidget {
const _LocationWidget({this.permission, this.isLocationEnabled})
: assert(permission != null);
final PermissionStatus permission;
final bool isLocationEnabled;
@override
Widget build(BuildContext context) {
return Container(
child: Center(
child: (() {
if (!isLocationEnabled) // Check Bool and show different text
return Text(
"Off",
);
else
return Text("On");
}())));
}
}
将 updateShouldNotify: (_, __) => true
添加到您的 StreamProvider
By default, StreamProvider considers that the Stream listened uses immutable data. As such, it will not rebuild dependents if the previous and the new value are ==. To change this behavior, pass a custom updateShouldNotify.
ikerfah 是对的,您正在从 Future 创建 Stream,这意味着当 Future 完成时 Stream 将只包含一个事件(基本上,它不是真正意义上的真正“流” ).
FutureBuilder 也不会工作,因为 Future 只会完成一次,所以它也只会触发一次状态更改。
如果this is the plugin you're using,作者似乎没有实现任何东西来为权限更改事件公开一个“真实的”流。我也不会为此屏住呼吸,因为据我所知,iOS 和 Android 都没有广播事件 if/when 权限已更改。
如果您需要disable/enable一些基于权限是否改变的东西,您只需要在 StatefulWidget 中设置一个定期定时器来轮询变化。
class _LocationWidget extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return _LocationWidgetState();
}
}
class _LocationWidgetState extends State<_LocationWidget> {
PermissionStatus permission;
bool isLocationEnabled = false;
Timer _timer;
@override
void initState() {
_timer = Timer.periodic(Duration(seconds:5), (_) {
var permission = await _location.hasPermission();
var isLocationEnabled = await _location.serviceEnabled();
if(permission != this.permission || isLocationEnabled != this.isLocationEnabled)
setState(() {});
});
}
@override
void dispose() {
_timer.cancel();
}
@override
Widget build(BuildContext context) {
return Container(
child: Center(
child: (() {
if (!isLocationEnabled) // Check Bool and show different text
return Text(
"Off",
);
else
return Text("On");
}())));
}
5 秒是否合适由您决定。 initState() 也应该在状态初始化时设置初始 isLocationEnabled/permission 值,而不是等待 5 秒让计时器启动。
我正在尝试流式传输两种类型的基于位置包的数据:
final _location = Location();
runApp(
MultiProvider(
providers: [
StreamProvider<PermissionStatus>(create: (_) => _location.hasPermission().asStream()),
StreamProvider<bool>(create: (_) => _location.serviceEnabled().asStream()),
],
child: MaterialApp();
)
)
当我 'stream' 数据时,它加载初始值并流式传输。它不是不断地倾听变化,而这正是我想要做的。我已经尝试将两个期货抽象成它们自己的 class 并创建一个产生当前状态的异步*流,这两个都给出了同样的问题。
我的用例涉及持续监听权限状态和位置 on/off 并在任务之间修改这些部分时关闭 UI 的某些部分。
简化用法:
class LocationWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Consumer2<PermissionStatus, bool>(
builder: (_, permission, isLocationEnabled, __) => _LocationWidget(
permission: permission, isLocationEnabled: isLocationEnabled));
}
}
class _LocationWidget extends StatelessWidget {
const _LocationWidget({this.permission, this.isLocationEnabled})
: assert(permission != null);
final PermissionStatus permission;
final bool isLocationEnabled;
@override
Widget build(BuildContext context) {
return Container(
child: Center(
child: (() {
if (!isLocationEnabled) // Check Bool and show different text
return Text(
"Off",
);
else
return Text("On");
}())));
}
}
将 updateShouldNotify: (_, __) => true
添加到您的 StreamProvider
By default, StreamProvider considers that the Stream listened uses immutable data. As such, it will not rebuild dependents if the previous and the new value are ==. To change this behavior, pass a custom updateShouldNotify.
ikerfah 是对的,您正在从 Future 创建 Stream,这意味着当 Future 完成时 Stream 将只包含一个事件(基本上,它不是真正意义上的真正“流” ).
FutureBuilder 也不会工作,因为 Future 只会完成一次,所以它也只会触发一次状态更改。
如果this is the plugin you're using,作者似乎没有实现任何东西来为权限更改事件公开一个“真实的”流。我也不会为此屏住呼吸,因为据我所知,iOS 和 Android 都没有广播事件 if/when 权限已更改。
如果您需要disable/enable一些基于权限是否改变的东西,您只需要在 StatefulWidget 中设置一个定期定时器来轮询变化。
class _LocationWidget extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return _LocationWidgetState();
}
}
class _LocationWidgetState extends State<_LocationWidget> {
PermissionStatus permission;
bool isLocationEnabled = false;
Timer _timer;
@override
void initState() {
_timer = Timer.periodic(Duration(seconds:5), (_) {
var permission = await _location.hasPermission();
var isLocationEnabled = await _location.serviceEnabled();
if(permission != this.permission || isLocationEnabled != this.isLocationEnabled)
setState(() {});
});
}
@override
void dispose() {
_timer.cancel();
}
@override
Widget build(BuildContext context) {
return Container(
child: Center(
child: (() {
if (!isLocationEnabled) // Check Bool and show different text
return Text(
"Off",
);
else
return Text("On");
}())));
}
5 秒是否合适由您决定。 initState() 也应该在状态初始化时设置初始 isLocationEnabled/permission 值,而不是等待 5 秒让计时器启动。