Button is not changing background color on click in ListView

46 Views Asked by At

In a flutter app, I have a FilledButton in a ListView widget and one outside the ListView. Both these Buttons are identical in terms of their code, they just live inside different parents:

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        useMaterial3: true,
      ),
      home: const MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key});

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        children: [
          SizedBox(
            height: 100,
            child: ListView(
              children: [
                FilledButton(
                    onPressed: () { },
                    style: ButtonStyle(
                        backgroundColor: MaterialStateProperty.resolveWith<Color>((Set<MaterialState> states) {
                          if (states.contains(MaterialState.pressed)) {
                            return Colors.black;
                          }
                          return Colors.white;
                        }),
                        foregroundColor: MaterialStateProperty.resolveWith((states) {
                          if (states.contains(MaterialState.pressed)) {
                            return Colors.white;
                          }
                          return Colors.black;
                        }),
                        shape: MaterialStateProperty.resolveWith((states) {
                          return const ContinuousRectangleBorder(side: BorderSide(color: Colors.black));
                        }),
                        animationDuration: const Duration(milliseconds: 1),
                        alignment: Alignment.centerLeft,
                        padding: MaterialStateProperty.resolveWith((states) {
                          return const EdgeInsets.symmetric(horizontal: 20, vertical: 10);
                        })
                    ),
                    child: Text("Button Text")
                )
              ],
            ),
          ),
          FilledButton(
              onPressed: () { },
              style: ButtonStyle(
                  backgroundColor: MaterialStateProperty.resolveWith<Color>((Set<MaterialState> states) {
                    if (states.contains(MaterialState.pressed)) {
                      return Colors.black;
                    }
                    return Colors.white;
                  }),
                  foregroundColor: MaterialStateProperty.resolveWith((states) {
                    if (states.contains(MaterialState.pressed)) {
                      return Colors.white;
                    }
                    return Colors.black;
                  }),
                  shape: MaterialStateProperty.resolveWith((states) {
                    return const ContinuousRectangleBorder(side: BorderSide(color: Colors.black));
                  }),
                  animationDuration: const Duration(milliseconds: 1),
                  alignment: Alignment.centerLeft,
                  padding: MaterialStateProperty.resolveWith((states) {
                    return const EdgeInsets.symmetric(horizontal: 20, vertical: 10);
                  })
              ),
              child: Text("Button Text")
          )
        ],
      )
    );
  }
}

However, they somehow behave differently when clicked: GIF showing the issue.

The one outside the ListView changes (background-)color as expected. Yet the button inside the ListView widget does only change its (background-)color when it is pressed for a little longer time: GIF also showing the longer button press.

I already looked for other questions regarding similar issues, yet I couldn't find any so far. Also the flutter documentation did not help me as I simply don't know where to even start looking for a possible solution. I am quite new to Flutter, so I also don't know if this is intended behaviour for ListView or not. In the case it is, what would be an alternative to ListView that renders the first button just like the second one?

1

There are 1 best solutions below

2
On

This probably has to do with ListView. When you set physics to NeverScrollableScrollPhysics(), everything seems to be normal. I think maybe the scroll priority of ListView is higher than the click event of FilledButton, so it only changes its background color when it is pressed for a longer time.