Это еще один подход к решению проблемы.
Идея состоит в том, чтобы использовать переменную _loading и изначально установить ее в значение true. Теперь, после использования функции inputData (), вы можете установить ее в false, как только получите dbref. Сохраните dbref, как я хранил _myFuture в приведенном ниже коде, т. Е. Глобально в классе.
Используйте вашу переменную _loading, чтобы вернуть индикатор выполнения, если ее true возвращает FutureBuilder с вашим dbref.once () на месте. Теперь, когда вы загрузили его, он должен быть доступен в этот момент.
class MyWidget extends StatefulWidget {
@override
createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget> {
// Is the future being loaded?
bool _loading;
// This is the future we will be using in our FutureBuilder.
// It is currently null and we will assign it in _loadMyFuture function.
// Until assigned, we will keep the _loading variable as true.
Future<String> _myFuture;
// Load the _myFuture with the future we are going to use in FutureBuilder
Future<void> _loadMyFuture() async {
// Fake the wait for 2 seconds
await Future.delayed(const Duration(seconds: 2));
// Our fake future that will take 2 seconds to return "Hello"
_myFuture = Future(() async {
await Future.delayed(const Duration(seconds: 2));
return "Hello";
});
}
// We initialize stuff here. Remember, initState is called once in the beginning so hot-reload wont make flutter call it again
@override
initState() {
super.initState();
_loading = true; // Start loading
_loadMyFuture().then((x) => setState(() => _loading = false)); // Set loading = false when the future is loaded
}
@override
Widget build(BuildContext context) {
// If loading, show loading bar
return _loading?_loader():FutureBuilder<String>(
future: _myFuture,
builder: (context, snapshot) {
if(!snapshot.hasData) return _loader(); // still loading but now it's due to the delay in _myFuture
else return Text(snapshot.data);
},
);
}
// A simple loading widget
Widget _loader() {
return Container(
child: CircularProgressIndicator(),
width: 30,
height: 30
);
}
}
Вот результат этого подхода
![Output](https://i.stack.imgur.com/MTb6d.gif)
Это делает работу, но вам, возможно, придется делать это для каждого класса, где вам требуется ваш идентификатор.
==================== ====================
Вот подход, который я описал в комментариях.
// Create a User Manager like this
class UserManager {
static String _uid;
static String get uid => _uid;
static Future<void> loadUID() async {
// Your loading code
await Future.delayed(const Duration(seconds: 5));
_uid = '1234'; // Let's assign it directly for the sake of this example
}
}
На экране приветствия:
class MyWidget extends StatefulWidget {
@override
createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget> {
bool _loading = true;
@override
void initState() {
super.initState();
UserManager.loadUID().then((x) => setState(() => _loading = false));
}
@override
Widget build(BuildContext context) {
return _loading ? _loader() : Text('Welcome User ${UserManager.uid}!');
}
// A simple loading widget
Widget _loader() {
return Container(child: CircularProgressIndicator(), width: 30, height: 30);
}
}
Преимущество этого метода заключается в том, что после загрузки uid вы можете напрямую получить к нему доступ следующим образом:
String uid = UserManager.uid;
, что исключает использование фьючерсов.
Надеюсь, это поможет!