我在设计ListTile时遇到了问题

时间:2020-06-29 00:59:05

标签: flutter flutter-layout

当用户单击“添加到购物车”时,试图设计“添加到购物车”按钮,“添加到购物车”按钮隐藏,ListTile出现在按钮和Listtile的背面,其中三件事分别是title,前导和尾随就像我想要的一样工作,但问题是我想要列表图块的大小与按钮大小相同,因此当列表项出现在屏幕上时不会增长

这是清楚我意思的视频

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,
                          ),
                        ),
                      ],
                    ),
                  ],
                ),
        ),
      ),
    );
  }
}

1 个答案:

答案 0 :(得分: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,
  ),
)

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

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,
                  ),
          ),
        ),
      ),
    );
  }
}

现在,您在中间有一个特定大小的绿色容器,根据列表布尔值,它将其子级更改为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个图标和一个文本

enter image description here enter image description here

如果要保持这种方式,我有2条建议,请在initState中将layout(minWidth: 0.0, maxWidth: double.infinity);中的minWidth更改为更大的值(例如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中计算的值。它将在两种尺寸之间做一个平滑的动画(就像您的视频一样,但更平滑和更干净)