我有一个Home类,其中一个PageView作为正文,一个BottomNavigationBar。
在此类中,将加载当前用户和用户的当前位置。
当用户和位置已知时,全局变量设置为true

在BottomNavigationBar的第一个标签图标上,有一个附近位置的提要,该位置以Feed类编码

现在的问题。
当我第一次启动该应用程序或进行热重载时,geoQuery()返回圆形微调框。加载当前用户后,它将返回文本“No Data”,而不显示事件。用户需要将BottomNavigationBar的选项卡从提要更改为其他内容,然后再返回提要以刷新streambuilder。之后,它会按预期工作。

当我不使用条件(currentLocationloaded && currentUserloaded == true)使用streambuilder时,它会按预期工作,但有时会由于用户加载速度不够而引发错误。

我该怎么做才能使其与条件配合使用?

更新

工作流程已登录:
RootPage->登录? ->首页

根页

enum AuthStatus {
  NOT_DETERMINED,
  NOT_LOGGED_IN,
  LOGGED_IN,
}

class RootPage extends StatefulWidget {
  RootPage({this.auth});

  final BaseAuth auth;

  @override
  State<StatefulWidget> createState() => new _RootPageState();
}

class _RootPageState extends State<RootPage> {
  AuthStatus authStatus = AuthStatus.NOT_DETERMINED;
  String _userID = "";

  @override
  void initState() {
    super.initState();
    widget.auth.getCurrentUser().then((user) {
      setState(() {
        if (user != null) {
          _userID = user?.uid;
        }
        authStatus =
            user?.uid == null ? AuthStatus.NOT_LOGGED_IN : AuthStatus.LOGGED_IN;
      });
    });
  }

  void loginCallback() {
    widget.auth.getCurrentUser().then((user) {
      setState(() {
        _userID = user.uid.toString();
      });
    });
    setState(() {
      authStatus = AuthStatus.LOGGED_IN;
    });
  }

  void logoutCallback() {
    setState(() {
      authStatus = AuthStatus.NOT_LOGGED_IN;
      _userID = "";
    });
  }

  Widget buildWaitingScreen() {
    return Scaffold(
      body: Container(
        alignment: Alignment.center,
        child: CircularProgressIndicator(),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    switch (authStatus) {
      case AuthStatus.NOT_DETERMINED:
        return buildWaitingScreen();
        break;
      case AuthStatus.NOT_LOGGED_IN:
        return new StartPage(
          auth: widget.auth,
          loginCallback: loginCallback,
        );
        break;
      case AuthStatus.LOGGED_IN:
        if (_userID.length > 0 && _userID != null) {
          return new Home(
            userID: _userID,
            auth: widget.auth,
            logoutCallback: logoutCallback,
          );
        } else
          return buildWaitingScreen();
        break;
      default:
        return buildWaitingScreen();
    }
  }
}


User currentUser;
bool currentUserloaded = false;
bool currentLocationloaded = false;

class Home extends StatefulWidget {
  final BaseAuth auth;
  final VoidCallback logoutCallback;
  final String userID;

  const Home({Key key, this.auth, this.logoutCallback, this.userID})
      : super(key: key);

  @override
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<Home> {
  final _scaffoldKey = GlobalKey<ScaffoldState>();
  PageController pageController;
  int pageIndex = 0;
  double longitude;
  double latitude;

  //INIT
  @override
  void initState() {
    super.initState();
    loadCurrentUser();
    getCurrentLocation();
    pageController = PageController();
  }


  //LOAD current user
  loadCurrentUser() async {
    print("Current User ${widget.userID}");
    DocumentSnapshot doc = await userRef.document(widget.userID).get();
    currentUser = User.fromDocument(doc);
    setState(() {
      currentUserloaded = true;
      print("User loaded $currentUserloaded");
    });
  }

  //get current location
  getCurrentLocation() async {
    var currentLocationCoordinates = await Geolocator()
        .getCurrentPosition(desiredAccuracy: LocationAccuracy.high);
    List<Placemark> place = await Geolocator().placemarkFromCoordinates(
        currentLocationCoordinates.latitude,
        currentLocationCoordinates.longitude);
    latitude = currentLocationCoordinates.latitude;
    longitude = currentLocationCoordinates.longitude;
    setState(() {
      currentLocationloaded = true;
      print("Got location $currentLocationloaded");
    });
  }

  //DISPOSE
  @override
  void dispose() {
    pageController.dispose();
    super.dispose();
  }

  //Pageview
  onPageChanged(int pageIndex) {
    setState(() {
      this.pageIndex = pageIndex;
    });
  }

  //On Tap of ButtomTabbar => Jump to next Page
  onTap(int pageIndex) {
    if (currentUserloaded && currentLocationloaded) {
      pageController.jumpToPage(pageIndex);
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      key: _scaffoldKey,
      body: PageView(
        children: <Widget>[
          Feed(userID: widget.userID, latitude: latitude, longitude: longitude),
          SearchView(),
          ChatHome(),
          Profile(
              uid: currentUser?.uid,
              auth: widget.auth,
              logoutCallback: widget.logoutCallback),
        ],
        controller: pageController,
        onPageChanged: onPageChanged,
        physics: NeverScrollableScrollPhysics(),
      ),
      bottomNavigationBar: CupertinoTabBar(
          currentIndex: pageIndex,
          inactiveColor: Colors.white,
          backgroundColor: Colors.blue,
          activeColor: Colors.orange,
          onTap: onTap,
          items: [
            BottomNavigationBarItem(
              icon: Icon(Icons.home, size: 20),
              title: Text("Home"),
            ),
            BottomNavigationBarItem(
              icon: Icon(Icons.search, size: 20),
              title: Text("Search"),
            ),
            BottomNavigationBarItem(
              icon: Icon(Icons.chat, size: 20),
              title: Text("chat"),
            ),
            BottomNavigationBarItem(
              icon: Icon(Icons.profil, size: 20),
              title: Text("Profil"),
            ),
          ]),
    );
  }
}

饲料
class Feed extends StatefulWidget {
  final String userID;
  final double latitude;
  final double longitude;

  const Feed({Key key, this.userID, this.latitude, this.longitude})
      : super(key: key);

  @override
  _FeedState createState() => _FeedState();
}

class _FeedState extends State<Feed> {
  final _scaffoldKey = GlobalKey<ScaffoldState>();
  List<Event> events = [];

  var radius = BehaviorSubject<double>.seeded(50.0);
  Stream<List<DocumentSnapshot>> stream;
  Geoflutterfire geo;

  @override
  void initState() {
    super.initState();
    geo = Geoflutterfire();
    GeoFirePoint center = geo.point(
        latitude: widget.latitude,
        longitude: widget
            .longitude);
    stream = radius.switchMap((rad) {
      var collectionReference =
          eventRef.where("event", isEqualTo: "festival");
      return geo.collection(collectionRef: collectionReference).within(
          center: center, radius: rad, field: 'position', strictMode: true);
    });
  }

  //GEOQUERY

  Widget geoQuery() {
    if (currentLocationloaded && currentUserloaded) {
      return Column(
        children: <Widget>[
          StreamBuilder(
            stream: stream,
            builder: (BuildContext context,
                AsyncSnapshot<List<DocumentSnapshot>> snapshot) {
              if (!snapshot.hasData) {
                Text("No data");
              }
              events =
                  snapshot.data.map((doc) => Event.fromDocument(doc)).toList();
              events.sort((a, b) {
                var aDate = a.timestamp;
                var bDate = b.timestamp;
                return aDate.compareTo(bDate);
              });
              if (events.isEmpty) {
                return Text("No events");
              }
              return Flexible(
                child: ListView.builder(
                  itemCount: snapshot.data.length,
                  itemBuilder: (context, index) {
                    return buildEvent(index);
                  },
                ),
              );
            },
          )
        ],
      );
    } else {
      return circularProgress();
    }
  }


  @override
  Widget build(BuildContext context) {
    SizeConfig().init(context);
    return Scaffold(
        key: _scaffoldKey,
        appBar: AppBar(
          centerTitle: true,
          title: Text("Feed"),
          backgroundColor: Colors.blue,
        ),
        body: geoQuery(),
        );
  }
}

更新2

如果我使用硬编码的纬度和经度GeoFirePoint center = geo.point(latitude: 37.773972, longitude: -122.431297);有用!
传递当前用户位置似乎是一个问题。
有什么建议么?

最佳答案

问题是当前用户的位置未按时传递。
刚放

GeoFirePoint center = geo.point(
        latitude: widget.latitude,
        longitude: widget
            .longitude);
    stream = radius.switchMap((rad) {
      var collectionReference =
          eventRef.where("event", isEqualTo: "festival");
      return geo.collection(collectionRef: collectionReference).within(
          center: center, radius: rad, field: 'position', strictMode: true);
    });

从initState到geoQuery()

关于flutter - 满足条件后,Streambuilder的Flutter Snapshot没有数据,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/59697260/

10-11 19:23