Home > other >  UI is responding only after Hot reload or restart in Flutter
UI is responding only after Hot reload or restart in Flutter

Time:05-04

I like to hide the floatingActionButton on scroll down and to show it when scrolling up. But it only works after hot restart or reload.

transaction.dart

class Transaction extends StatefulWidget {
  const Transaction({Key? key}) : super(key: key);

  @override
  State<Transaction> createState() => _TransactionState();
}

bool isFab = false;

class _TransactionState extends State<Transaction> {
  @override
  Widget build(BuildContext context) {
    return DefaultTabController(
      length: 2,
      child: Scaffold(
        body: SafeArea(
            child: NestedScrollView(
                floatHeaderSlivers: true,
                headerSliverBuilder: (context, innerBoxIsScrolled) => [
                      SliverAppBar(
                        pinned: true,
                        floating: true,
                        snap: true,
                        centerTitle: true,
                        title: Text(
                          "Money Manager",
                          style: TextStyle(letterSpacing: 1.5),
                          strutStyle: StrutStyle(
                              fontSize: 20, fontStyle: FontStyle.normal),
                        ),
                        bottom: TabBar(tabs: [
                          Tab(
                            child: Text(
                              "Income",
                              style:
                                  TextStyle(fontSize: 18, letterSpacing: 1.5),
                            ),
                          ),
                          Tab(
                            child: Text(
                              "Expense",
                              style:
                                  TextStyle(fontSize: 18, letterSpacing: 1.5),
                            ),
                          )
                        ]),
                      )
                    ],
                body: TabBarView(children: [Income(), Expense()]))),
        floatingActionButton: isFab ? Fab() : null,
      ),
    );
  }
}

expense.dart

class Expense extends StatefulWidget {
  const Expense({Key? key}) : super(key: key);

  @override
  State<Expense> createState() => _ExpenseState();
}

class _ExpenseState extends State<Expense> {
  @override
  Widget build(BuildContext context) {
    return NotificationListener<UserScrollNotification>(
      onNotification: (notification) {
        if (notification.direction == ScrollDirection.forward) {
          setState(() => isFab = true);
        } else if (notification.direction == ScrollDirection.reverse) {
          setState(() => isFab = false);
        }
        return true;
      },
      child: ListView.separated(
          itemBuilder: (context, index) {
            return ListTile(
              leading: CircleAvatar(),
              trailing: Text("- ₹2000"),
              title: Text("category"),
              subtitle: Text(formatter),
            );
          },
          separatorBuilder: (context, index) {
            return Divider();
          },
          itemCount: 30),
    );
  }
}

CodePudding user response:

In your code, isFab is declared false as a global variable, so it won't be changed by a setState call. I don't exactly know why it starts to work after a hot reload or restart though.

To make it work you have to make it part of _TransactionState, and you also have to make it accessible from ExpenseState since you put the NotificationListener there.

But probably the simplest solution is to move the NotificationListener in Transaction as the body of the Scaffold, then declare the isFab variable as part of the _TransactionState. You can see it here: I had to change something (like using the default FAB) to make the dartpad run, but now the FAB appears only when on top.

  • Related