0

I have added a TabBar to my flutter app. It was pretty easy. I have created a new page for tab 1 and moved an existing page to tab 2. Both of these pages should display data from a Firestore QuerySnapshot but I don't know how to do this.

I have a screen, AgentDashBoardScreen, that creates a QuerySnapshot and builds a ListView with the data retrieved by the query.

In the onTap property of each ListTile the user is taken to the TransactionHomeScreen which has the TabBar widget in it. Also, I want to pass the QuerySnapshot to this page. Below is the code for AgentDashBoardScreen.

class AgentDashboardScreen extends StatefulWidget {
  static const String id = 'agent_dashboard_screen';

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

class _AgentDashboardScreenState extends State<AgentDashboardScreen> {
  bool showSpinner = false;
  //int _selectedIndex = 0;

  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        home: Scaffold(
          appBar: AppBar(
            title: Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                Image.asset('assets/images/Appbar_logo.png',
                    fit: BoxFit.cover, height: 56),
              ],
            ),
          ),
          drawer: Drawer(
            child: ListView(
              children: <Widget>[
                ListTile(
                  title: Text("Agent Profile"),
                  onTap: () {
                    MainScreen.of(context)?.setIndex(3);  // Added this for BottomNavigationBar sync
                    Navigator.of(context).push(MaterialPageRoute(
                      builder: (context) => AgentProfileScreen()));
                    },
                ),
  ],
            ),
          ),
          body: SafeArea(
            child: Container(
              child: StreamBuilder(
                stream: FirestoreService().getAgencyTrxns(context),
                builder: (context, snapshot) {
                  if (!snapshot.hasData)
                    return Center(
                        child: const Text(
                          'Loading...',
                          style: TextStyle(
                              fontSize: 20, fontWeight: FontWeight.bold),
                        ));
                  return new ListView.builder(
                      itemCount: (snapshot.data! as QuerySnapshot).docs.length,
                      itemBuilder: (BuildContext context, int index) {
                        Trxns trxns = Trxns.fromFirestore(
                            (snapshot.data! as QuerySnapshot).docs[index]
                                .data() as Map<String, dynamic>);

                        return ListTile(
                          isThreeLine: true,
                          title: Text(
                            'Client: ${trxns.clientFName ?? 'n/a'} ${trxns
                                .clientLName ?? 'n/a'}',
                            style: TextStyle(
                                fontWeight: FontWeight.w900,
                                color: Colors.blueAccent),
                          ),
                          subtitle: Text.rich(TextSpan(
                              text:
                              '${trxns.propertyAddress ?? 'n/a'}, ${trxns
                                  .propertyCity ?? 'n/a'}, ${trxns
                                  .propertyState ?? 'n/a'}',
                              children: <TextSpan>[
                                TextSpan(
                                  text:
                                  '\nPrice: ${trxns!.contractPrice == null ? 'n/a' : NumberFormat.simpleCurrency().format(trxns.contractPrice)}\nStatus: ${trxns.trxnStatus ?? 'n/a'}',
                                  style: TextStyle(
                                      fontWeight: FontWeight.w900,
                                      color: Colors.blueGrey),
                                )
                              ])),
                          trailing: Text('MLS#: ${trxns.mlsNumber ?? 'n/a'}\n${trxns.clientType}'),
                          onTap: () {
                            MainScreen.of(context)?.setIndex(2);  // Added this for BottomNavigationBar sync
                            globals.newTrxn = false;
                            Navigator.of(context).push(MaterialPageRoute(
                                builder: (context) =>
                                **TrxnHomeScreen(
                                        (snapshot.data! as QuerySnapshot).docs[index])));**
                          },
                        );
                      });
                },
              ),
            ),
          ),
        ));
  }
}

Here is the code for the TrxnHomeScreen.

    class TrxnHomeScreen extends StatefulWidget {
      static const String id = 'trxn_home_screen';
      final QueryDocumentSnapshot? trxns;
    
      TrxnHomeScreen([this.trxns]);
    
      @override
      _TrxnHomeScreenState createState() => _TrxnHomeScreenState();
    }
    
    class _TrxnHomeScreenState extends State<TrxnHomeScreen> with SingleTickerProviderStateMixin {
      bool showSpinner = false;
      TabController? _trxnTabController;
    
      @override
      void initState() {
        super.initState();
    
        _trxnTabController = TabController(length: 3, vsync: this);
    
      }
    
      @override
      Widget build(BuildContext context) {
        return DefaultTabController(
          length: 3,
          child: MaterialApp(
              home: Scaffold(
                appBar: AppBar(
                  title: Row(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: [
                      Image.asset('assets/images/Appbar_logo.png',
                          fit: BoxFit.cover, height: 56),
                    ],
                  ),
                  bottom: TabBar(
                    indicatorWeight: 5,
                    indicatorColor: Colors.orange,
                    controller: _trxnTabController,
                    tabs: [
                        Tab(
                          text: "STATUS"
                        ),
                        Tab(
                          text: "DETAILS",
                        ),
                        Tab(
                          text: "TASKS",
                        ),
                    ],
                  ),
                ),
                body: SafeArea(
                  child: Container(
                    child: TabBarView(
                      controller: _trxnTabController,
                        children: <Widget>[
                          TransactionStatusScreen(widget.trxns),
                          TransactionDetailScreen(widget.trxns),
                          Text('Tasks'),
                        ])
                  ),
                ),
              )),
        );
      }
    }

Here is the code for the TransactionDetailScreen.
class TransactionDetailScreen extends StatefulWidget {
  static const String id = 'transaction_detail_screen';
  final QueryDocumentSnapshot? trxns;

  TransactionDetailScreen([this.trxns]);

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

class _TransactionDetailScreenState extends State<TransactionDetailScreen> {
getTrxn() async {
    final DocumentSnapshot _mlsId =
      await mlsRef.doc(globals.mlsId).get();
    _mlsSearchLink = _mlsId.get('mlsNbrSearch');


    if (widget.trxns == null) {
      globals.newTrxn = true;
    } else {
      globals.newTrxn = false;
    }

  @override
  void initState() {
    getTrxn();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {

  }
}
LostTexan
  • 431
  • 5
  • 18
  • Can you include the code for the tab bar and its pages? – Victor Eronmosele Jul 26 '21 at 21:17
  • I added more code. I hope you can follow my logic. – LostTexan Jul 26 '21 at 21:50
  • "How do I pass and access the QuerySnapshot in the tab pages?". Looks like the code is already doing that. Where exactly is the issue with the code? – Victor Eronmosele Jul 26 '21 at 22:03
  • When I get to the page with the TabBar the QuerySnapshot is null. I don't get any errors but when I evaluate "widget.trxns" in the TabBarView code it is null. Maybe I am trying to pass the snapshot to the tabs in the wrong way? – LostTexan Jul 26 '21 at 22:18
  • Okay, so the null error is in the `TrxnHomeScreen` widget. Include the code that sends the data to `TrxnHomeScreen`, it could be the way you're passing it. Also, you can edit your question with the screen names instead of "page 1", "page 2" as that's hard to follow. – Victor Eronmosele Jul 26 '21 at 22:27
  • Thanks, I cleaned up the question and so I hope it is more clear. – LostTexan Jul 26 '21 at 22:50
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/235326/discussion-between-victor-eronmosele-and-losttexan). – Victor Eronmosele Jul 27 '21 at 07:45

1 Answers1

0

From the code, you are passing the QueryDocumentSnapshot to TransactionHomeScreen but the code you provided for the tab bar is TrxnHomeScreen.

Victor Eronmosele
  • 7,040
  • 2
  • 10
  • 33