我构建了一个具有多个页面的应用程序,并且这些应用程序之间具有导航功能。 我想在单击URL时打开特定页面。
我将代码放在起始页面上以侦听URI链接流,并在用户仍在该起始页面上的情况下设法打开所需页面。
如果用户导航到另一个页面,则流将不再拦截呼叫,并且不会打开url链接的页面。
我是否需要在每个页面上放置流侦听器?
是否有一种方法可以使该应用在全球范围内使用,以便无论我在哪个屏幕上,我都可以拦截并重定向到另一个页面?
谢谢
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:myapp/app.config.dart';
import 'package:myapp/mobile/screens/login.dart';
import 'package:myapp/mobile/screens/inviteView.dart';
import 'package:uni_links/uni_links.dart';
/// The goal of this splash screen is to give time to the app
/// to retrieve the current database or redirect to the login page.
/// We may want to add a different splash screen natively to avoid
/// having a white screen when the user launches the app
class SplashScreen extends StatefulWidget {
const SplashScreen({Key key}) : super(key: key);
@override
_SplashScreenState createState() => _SplashScreenState();
}
class _SplashScreenState extends State<SplashScreen> {
Future<bool> ready;
Uri _latestUri;
StreamSubscription _sub;
@override
void initState() {
super.initState();
SystemChannels.textInput.invokeMethod('TextInput.hide');
ready = initPlatformStateForUriUniLinks();
}
@override
void dispose() {
if (_sub != null) _sub.cancel();
super.dispose();
}
/// An implementation using the [Uri] convenience helpers
Future<bool> initPlatformStateForUriUniLinks() async {
// Attach a listener to the Uri links stream
_sub = getUriLinksStream().listen((Uri uri) {
if (!mounted) return true;
setState(() {
_latestUri = uri;
});
}, onError: (err) {
if (!mounted) return true;
setState(() {
_latestUri = null;
});
});
// Attach a second listener to the stream
getUriLinksStream().listen((Uri uri) {
print('got uri: ${uri?.path} ${uri?.queryParameters}');
}, onError: (err) {
print('got err: $err');
});
// Get the latest Uri
Uri initialUri;
// Platform messages may fail, so we use a try/catch PlatformException.
try {
initialUri = await getInitialUri();
} on PlatformException {
initialUri = null;
} on FormatException {
initialUri = null;
}
// If the widget was removed from the tree while the asynchronous platform
// message was in flight, we want to discard the reply rather than calling
// setState to update our non-existent appearance.
if (!mounted) return true;
setState(() {
_latestUri = initialUri;
});
return true;
}
@override
Widget build(BuildContext context) {
return FutureBuilder(
future: ready,
builder: (context, AsyncSnapshot<bool> snapshot) {
if (snapshot.hasError) return Center(child: Text('Error validating invitation'));
if (!snapshot.hasData) return Center(child: Text('Loading'));
if (_latestUri != null) {
final queryParams = _latestUri?.queryParameters;
final config = AppConfig.of(context);
final baseUrl = config.apiBaseUrl;
switch (_latestUri.path) {
case '/acceptInvite/':
final token = queryParams['token'];
return AcceptInviteView(baseUrl, token);
break;
default:
break;
}
}
return LoginScreen();
},
);
}
}