返回按钮在实现ListView Builder Widget Flutter时不工作

9w11ddsr  于 2023-03-24  发布在  Flutter
关注(0)|答案(1)|浏览(79)

我有这样一段代码,它显示一个后退按钮,文本,然后是一个listview构建器小部件。
当我删除listview builder小部件时,后退按钮工作正常,但当我将其添加回来时,后退按钮中断。我不知道为什么会发生这种情况,需要尽快修复此问题。谢谢!
下面是屏幕的代码(一切都很完美,所以不包括其他传入数据的屏幕):

import 'package:flutter/material.dart';
import 'package:workout_app/Screens/Components/Sign_Up_Screens/screen2.dart';

class SingleSelectListViewWithLogo extends StatefulWidget {
  final List<String> items;
  const SingleSelectListViewWithLogo({Key? key, required this.items}) : super(key: key);
  @override
  _SingleSelectListViewWithLogoState createState() =>
      _SingleSelectListViewWithLogoState();
}

class _SingleSelectListViewWithLogoState extends State<SingleSelectListViewWithLogo> {
  int? selectedIndex;

  void returnScreen(context) {
    print('returning');
    Navigator.of(context).pushReplacement(
      MaterialPageRoute(
        fullscreenDialog: true,
        builder: (context) => screen2(),
      ),
    );
  }

  bool nextValid = false;

  @override
  Widget build(BuildContext context) {
    Size size = MediaQuery.of(context).size;
    return Material(
      child: Container (
        decoration: const BoxDecoration(color: Colors.grey),
        height: size.height,
        width: double.infinity,
        child: Stack(
          children: <Widget> [
            Positioned(
              top: size.height * .06,
              left: size.width * .03,
              child: InkWell(
                onTap: () {
                  returnScreen(context);
                },
                child: Image.asset(
                  alignment: Alignment.topLeft,
                  "assets/images/back2.png",
                  width: size.width * .07,
                ),
              ),
            ),
            Positioned(
              top: size.height * .09,
              left: size.width * .4,
              child: const Text(
                style: TextStyle(fontSize: 30, color: Color.fromARGB(255, 4, 3, 3)),
                'Goals'
              )
            ),
            Positioned(
              top: size.height * .15,
              left: size.width * .07,
              child: const Text(
                style: TextStyle(fontSize: 20, color: Color.fromARGB(255, 49, 48, 48)),
                'What body type do you want to get?'
              )
            ),
            Positioned(
              top: size.height * .26,
              left: size.width * .4,
              child: const Text(
                style: TextStyle(fontSize: 15, color: Color.fromARGB(255, 33, 31, 31)),
                'Select 1'
              )
            ),
            ListView.builder(
              itemCount: widget.items.length,
              itemBuilder: (context, index) {
                return GestureDetector(
                  onTap: () {
                    setState(() {
                      selectedIndex = index;
                      nextValid = true;
                    });
                  },
                  child: Container(
                    height: size.height * .15,
                    decoration: BoxDecoration(
                      color: selectedIndex == index ? Color.fromARGB(255, 40, 188, 72) : Color.fromARGB(255, 202, 195, 195),
                      border: Border.all(
                        color: selectedIndex == index ? Color.fromARGB(255, 16, 66, 37) : Colors.transparent,
                        width: 3,
                      ),
                      borderRadius: BorderRadius.circular(10),
                    ),
                    padding: const EdgeInsets.symmetric(horizontal: 10),
                    margin: EdgeInsets.fromLTRB(16, index == 0 ? MediaQuery.of(context).size.height * 0.265 : 0, 16, 8),
                    child: Row(
                      children: [
                        Flexible(
                          child: Text(widget.items[index]),
                        )
                      ],
                    ),
                  ),
                );
              },
            ),
            Positioned(
              top: size.height * .86,
              left: size.width * .1,
              child: SizedBox(
                width: size.width * .8,
                height: size.height * .08,
                child: ElevatedButton(
                  style: ButtonStyle(                  
                    backgroundColor: MaterialStateProperty.all<Color>(!nextValid ? Color.fromRGBO(69, 75, 85, 1) : Color.fromARGB(255, 0, 147, 246)),
                  ),
                  child: const Text('Continue',
                    style: TextStyle(fontSize: 20),
                  ),
                  onPressed: () async {
                  },
                ),
              ),
            ),
          ]
        )
      )
    );
  }
}

谢谢

avwztpqn

avwztpqn1#

这里的问题是你在任何地方都使用Stack小部件,即使你渲染ListView.builder。在这种情况下,ListView.builder覆盖了整个屏幕,特别是当没有给定一个有界的高度/宽度时。在这种情况下,因为所有东西都在Stack中,基于你如何在里面编写小部件,其中一些位于顶部,而另一些位于底部,因此不可点击。如果我重写这个实现,我会使用Column,它会像下面这样:

@override
  Widget build(BuildContext context) {
    Size size = MediaQuery.of(context).size;
    return Material(
        child: SafeArea(
      child: Container(
          decoration: const BoxDecoration(color: Colors.grey),
          height: size.height,
          width: double.infinity,
          child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: <Widget>[
                InkWell(
                  onTap: returnScreen,
                  child: const Icon(Icons.back_hand),
                ),
                const Text(
                    style: TextStyle(
                        fontSize: 30, color: Color.fromARGB(255, 4, 3, 3)),
                    'Goals'),
                const Text(
                    style: TextStyle(
                        fontSize: 20, color: Color.fromARGB(255, 49, 48, 48)),
                    'What body type do you want to get?'),
                const Text(
                    style: TextStyle(
                        fontSize: 15, color: Color.fromARGB(255, 33, 31, 31)),
                    'Select 1'),
                Expanded(
                  child: ListView.builder(
                    itemCount: widget.items.length,
                    itemBuilder: (context, index) {
                      return GestureDetector(
                        onTap: () {
                          setState(() {
                            selectedIndex = index;
                            nextValid = true;
                          });
                        },
                        child: Container(
                          height: size.height * .15,
                          decoration: BoxDecoration(
                            color: selectedIndex == index
                                ? const Color.fromARGB(255, 40, 188, 72)
                                : const Color.fromARGB(255, 202, 195, 195),
                            border: Border.all(
                              color: selectedIndex == index
                                  ? const Color.fromARGB(255, 16, 66, 37)
                                  : Colors.transparent,
                              width: 3,
                            ),
                            borderRadius: BorderRadius.circular(10),
                          ),
                          padding: const EdgeInsets.symmetric(horizontal: 10),
                          margin: EdgeInsets.fromLTRB(
                              16,
                              index == 0
                                  ? MediaQuery.of(context).size.height * 0.265
                                  : 0,
                              16,
                              8),
                          child: Row(
                            children: [
                              Flexible(
                                child: Text(widget.items[index]),
                              )
                            ],
                          ),
                        ),
                      );
                    },
                  ),
                ),
                Positioned(
                  top: size.height * .86,
                  left: size.width * .1,
                  child: SizedBox(
                    width: size.width * .8,
                    height: size.height * .08,
                    child: ElevatedButton(
                      style: ButtonStyle(
                        backgroundColor: MaterialStateProperty.all<Color>(
                            !nextValid
                                ? const Color.fromRGBO(69, 75, 85, 1)
                                : const Color.fromARGB(255, 0, 147, 246)),
                      ),
                      child: const Text(
                        'Continue',
                        style: TextStyle(fontSize: 20),
                      ),
                      onPressed: () async {},
                    ),
                  ),
                ),
              ])),
    ));
  }

但是如果你坚持使用Stack而不是Column,你应该这样做:

@override
  Widget build(BuildContext context) {
    Size size = MediaQuery.of(context).size;
    return Material(
      child: Container(
        decoration: const BoxDecoration(color: Colors.grey),
        height: size.height,
        width: double.infinity,
        child: Stack(
          children: <Widget>[
            Positioned(
                top: size.height * .09,
                left: size.width * .4,
                child: const Text(
                    style: TextStyle(
                        fontSize: 30, color: Color.fromARGB(255, 4, 3, 3)),
                    'Goals')),
            Positioned(
                top: size.height * .15,
                left: size.width * .07,
                child: const Text(
                    style: TextStyle(
                        fontSize: 20, color: Color.fromARGB(255, 49, 48, 48)),
                    'What body type do you want to get?')),
            Positioned(
                top: size.height * .26,
                left: size.width * .4,
                child: const Text(
                    style: TextStyle(
                        fontSize: 15, color: Color.fromARGB(255, 33, 31, 31)),
                    'Select 1')),
            ListView.builder(
              itemCount: widget.items.length,
              itemBuilder: (context, index) {
                return GestureDetector(
                  onTap: () {
                    setState(() {
                      selectedIndex = index;
                      nextValid = true;
                    });
                  },
                  child: Container(
                    height: size.height * .15,
                    decoration: BoxDecoration(
                      color: selectedIndex == index
                          ? const Color.fromARGB(255, 40, 188, 72)
                          : const Color.fromARGB(255, 202, 195, 195),
                      border: Border.all(
                        color: selectedIndex == index
                            ? const Color.fromARGB(255, 16, 66, 37)
                            : Colors.transparent,
                        width: 3,
                      ),
                      borderRadius: BorderRadius.circular(10),
                    ),
                    padding: const EdgeInsets.symmetric(horizontal: 10),
                    margin: EdgeInsets.fromLTRB(
                        16,
                        index == 0
                            ? MediaQuery.of(context).size.height * 0.265
                            : 0,
                        16,
                        8),
                    child: Row(
                      children: [
                        Flexible(
                          child: Text(widget.items[index]),
                        )
                      ],
                    ),
                  ),
                );
              },
            ),
            Positioned(
              top: size.height * .86,
              left: size.width * .1,
              child: SizedBox(
                width: size.width * .8,
                height: size.height * .08,
                child: ElevatedButton(
                  style: ButtonStyle(
                    backgroundColor: MaterialStateProperty.all<Color>(!nextValid
                        ? const Color.fromRGBO(69, 75, 85, 1)
                        : const Color.fromARGB(255, 0, 147, 246)),
                  ),
                  child: const Text(
                    'Continue',
                    style: TextStyle(fontSize: 20),
                  ),
                  onPressed: () async {},
                ),
              ),
            ),
            Positioned(
              top: size.height * .06,
              left: size.width * .03,
              child: InkWell(
                onTap: () {
                  returnScreen(context);
                },
                child: Image.asset(
                  alignment: Alignment.topLeft,
                  "assets/images/back2.png",
                  width: size.width * .07,
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }

请注意我是如何将InkWell作为Stack的最后一个子元素的,因此它位于顶部并可被点击。

相关问题