-1

我试图设计添加到购物车按钮,当用户单击“添加到购物车”时,“添加到购物车”按钮隐藏并且 ListTile 出现在按钮的背面,并且 listtile 有三件事标题,前导和尾随一切都像我想要,但问题是我想要与按钮大小相同的列表图块大小,因此当列表图块出现在屏幕上时它不会增长

这是澄清我的意思的视频

https://youtu.be/Bq2mrc5ao94

这是我的代码

    import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}
class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  int total=0;
  bool cartbuttoncheck=true;
  bool listbool=false;
  IconData delete_icon=Icons.remove;
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text("Button"),

        ),
        body: Center(
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: <Widget>[
                    Visibility(
                      visible: listbool,
                      child: Container(
                        color: Colors.green,
                        child: SizedBox(
                          height: 50.0,
                          width: 160.0,
                          child: ListTile(

                            title: Center(child: Text(total.toString(),style: TextStyle(fontStyle: FontStyle.italic,color: Colors.white),)),
                            leading: IconButton(
                              icon: Icon(delete_icon,color: Colors.white,),
                              onPressed: (){
                                setState(() {
                                  if(total==2)
                                    {
                                      print("i am 2");
                                      delete_icon=Icons.delete;
                                      total--;
                                    }
                                 else if(total==1 && delete_icon==Icons.delete)
                                  {
                                    total=0;
                                    listbool=false;
                                    cartbuttoncheck=true;
                                  }
                               if(total>2)
                                    {
                                   //   delete_icon=Icons.remove;
                                      total--;
                                    }
                                });

                              },
                            ),
                            trailing: IconButton(
                              icon: Icon(Icons.add,color: Colors.white),

                              onPressed: (){
                                setState(() {
                                  if(total==1 && delete_icon==Icons.delete)
                                    {
                                      delete_icon=Icons.remove;
                                    }
                                  total++;

                                });

                              },
                            ),
                          ),
                        ),
                      ),
                    ),
                    Stack(
                      alignment: Alignment.center,
                      children: <Widget>[

                        Visibility(
                          visible: cartbuttoncheck,
                          child: RaisedButton(
                            onPressed: (){
                              setState(() {
                                cartbuttoncheck=false;
                                listbool=true;
                                if(total==0)
                                  {
                                    total++;
                                    delete_icon=Icons.delete;
                                  }
                              });
                            },
              child: Text("Add to Cart",style: TextStyle(color: Colors.white),),
                            color: Colors.green,
                          ),
                        ),
                      ],
                    ),
                  ],
                ),
        ),
      ),
    );
  }
}
4

1 回答 1

0

就像 ListTile 使用具有定义大小的 SizedBox 一样,您可以对 RaisedButton 执行相同的操作

SizedBox(
  height: 50.0,
  width: 160.0,
  child: RaisedButton(
    onPressed: (){
      setState(() {
        cartbuttoncheck=false;
        listbool=true;
        if(total==0){
          total++;
          delete_icon=Icons.delete;
        }
       });
    },
    child: Text("Add to Cart",style: TextStyle(color: Colors.white),),
    color: Colors.green,
  ),
)

话虽如此,我相信最好不要使用您使用的所有小部件(列、堆栈、可见性),而只是根据布尔值在 ListTile 和 RaisedButton 之间进行更改(例如 listbool)

class _MyAppState extends State<MyApp> {
  int total = 0;
  bool listbool = false;
  IconData delete_icon = Icons.remove;
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text("Button"),
        ),
        body: Center(
          child: Container(
            color: Colors.green,
            height: 50.0,
            width: 160.0,
            child: listbool
                ? ListTile(
                    title: Center(
                        child: Text(
                      total.toString(),
                      style: TextStyle(
                          fontStyle: FontStyle.italic, color: Colors.white),
                    )),
                    leading: IconButton(
                      icon: Icon(
                        delete_icon,
                        color: Colors.white,
                      ),
                      onPressed: () {
                        setState(() {
                          if (total == 2) {
                            print("i am 2");
                            delete_icon = Icons.delete;
                            total--;
                          } else if (total == 1 &&
                              delete_icon == Icons.delete) {
                            total = 0;
                            listbool = false;
                          }
                          if (total > 2) {
                            //   delete_icon=Icons.remove;
                            total--;
                          }
                        });
                      },
                    ),
                    trailing: IconButton(
                      icon: Icon(Icons.add, color: Colors.white),
                      onPressed: () {
                        setState(() {
                          if (total == 1 && delete_icon == Icons.delete) {
                            delete_icon = Icons.remove;
                          }
                          total++;
                        });
                      },
                    ),
                  )
                : RaisedButton(
                    onPressed: () {
                      setState(() {
                        listbool = true;
                        if (total == 0) {
                          total++;
                          delete_icon = Icons.delete;
                        }
                      });
                    },
                    child: Text(
                      "Add to Cart",
                      style: TextStyle(color: Colors.white),
                    ),
                    color: Colors.green,
                  ),
          ),
        ),
      ),
    );
  }
}

现在您在中心有一个特定大小的绿色容器,并根据 listbool 的值将其子项更改为 ListTile 和 RaisedButton

更新

class _MyAppState extends State<MyApp> {
  double width; //the width of the RaisedButton based on the text
  double height; //the heightof the RaisedButton based on the text
  EdgeInsets myPadding = EdgeInsets.all(8); //a known padding to use in the RaisedButton
  
  @override
  void initState(){
    super.initState();
    TextSpan longestParagraphTest = TextSpan(
      text: "Add to Cart",
      style: TextStyle(color: Colors.white, fontSize: 14),
    );
    TextPainter _textPainter = TextPainter(text: longestParagraphTest, textDirection: TextDirection.ltr, maxLines: 1)..layout(minWidth: 0.0, maxWidth: double.infinity);
    width = _textPainter.width + 16; //this is the padding
    height = _textPainter.height + 16; //this is the padding
  }
  
  int total = 0;
  bool listbool = false;
  IconData delete_icon = Icons.remove;
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text("Button"),
        ),
        body: Center(
          child: Container(
            duration: const Duration(milliseconds: 300),
            color: Colors.green,
            height: height,
            width: width, //now you know the size of the RaisedButton and use it in both the ListTile and RaisedButton
            child: listbool
                ? ListTile(
                    title: Center(
                        child: Text(
                      total.toString(),
                      style: TextStyle(
                          fontStyle: FontStyle.italic, color: Colors.white),
                    )),
                    leading: IconButton(
                      icon: Icon(
                        delete_icon,
                        color: Colors.white,
                      ),
                      onPressed: () {
                        setState(() {
                          if (total == 2) {
                            print("i am 2");
                            delete_icon = Icons.delete;
                            total--;
                          } else if (total == 1 &&
                              delete_icon == Icons.delete) {
                            total = 0;
                            listbool = false;
                          }
                          if (total > 2) {
                            //   delete_icon=Icons.remove;
                            total--;
                          }
                        });
                      },
                    ),
                    trailing: IconButton(
                      icon: Icon(Icons.add, color: Colors.white),
                      onPressed: () {
                        setState(() {
                          if (total == 1 && delete_icon == Icons.delete) {
                            delete_icon = Icons.remove;
                          }
                          total++;
                        });
                      },
                    ),
                  )
                : RaisedButton(
                  padding: myPadding,
                    onPressed: () {
                      setState(() {
                        listbool = true;
                        if (total == 0) {
                          total++;
                          delete_icon = Icons.delete;
                        }
                      });
                    },
                    child: Text(
                      "Add to Cart",
                      maxLines: 1,
                      style: TextStyle(color: Colors.white, fontSize: 14),
                    ),
                    color: Colors.green,
                  ),
          ),
        ),
      ),
    );
  }
}

你会得到这样的东西,因为按钮尺寸太小,ListTile 无法显示 2 个图标和一个文本

在此处输入图像描述 在此处输入图像描述

如果你想保持这种方式,我有 2 条建议,在 initState 中将 minWidth 更改layout(minWidth: 0.0, maxWidth: double.infinity);为更大的值(比如说 100.0),以确保万一你的 minWidth 太小,它会更改为 100 以适应 ListTile。我的第二个建议是使用 AnimatedContainer 并根据显示的小部件更改大小

AnimatedContainer(
  duration: const Duration(milliseconds: 300),
  color: Colors.green,
  height: listbool ? 50.0 : height, //it animates to a a better size to fit the listTile
  width: listbool ? 200.0 : width, //it animates to a a better size to fit the listTile
  child: listbool ? ListTile(...) : RaisedButton(...),
),

其中高度和宽度是在 initState 中计算的值。它将在 2 种尺寸之间制作流畅的动画(就像您的视频一样,但更流畅、更清晰)

于 2020-06-29T03:27:03.757 回答