【问题标题】:How to add a widget when a button is pressed flutter按下按钮时如何添加小部件颤动
【发布时间】:2019-06-27 19:30:17
【问题描述】:

对于我的颤振应用程序,我需要一个可以在按下添加按钮时添加的容器。因此,我查看了其他 Stack Overflow 问题,例如:Flutter - Render new Widgets on click 和 Flutter - Add new Widget on click。之后,这就是我想出的。

class Body extends StatelessWidget {

  @override
  Widget build(BuildContext context) {

    var tPadding= MediaQuery.of(context).size.width  * 0.08; 
    var bPadding= MediaQuery.of(context).size.width  * 0.15; 
    var vPadding = MediaQuery.of(context).size.height  * 0.015;

    return Expanded (
      child: Container (
        child: NotificationListener<OverscrollIndicatorNotification> (
          onNotification: (OverscrollIndicatorNotification overscroll) {
            overscroll.disallowGlow();
          },
          child: PageView.builder(
            pageSnapping: false,
            controller: PageController(viewportFraction: 0.85),
            itemCount: container.length,
            itemBuilder: (context, i) {
              return Padding (
                padding: EdgeInsets.only(
                  left: vPadding,
                  right: vPadding,
                  top: tPadding,
                  bottom: bPadding
                ),
                child: container[i]
              );
            },
          )
        )
      )
    );
  }

}

 int _count = 1;

List container = [
  List.generate(_count, (int i) => ContainerCard),
  AddContainer()
];

class ContainerCard extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return Material (
      borderRadius: BorderRadius.circular(50.0),
      color: Colors.white,
      elevation: 8.0,
    );
  }

}

class AddContainer extends StatefulWidget {

  @override
  AddContainerState createState() => AddContainerState();

}

class AddContainerState extends State<AddContainer> {

  @override
  Widget build(BuildContext context) {
    return Material(
      borderRadius: BorderRadius.circular(50.0),
      color: Colors.white,
      elevation: 8.0,
      child: InkWell (
        onTap: _addContainer,
        splashColor: Colors.transparent,
        highlightColor: Colors.transparent,
        child: Column (
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Icon (
              Icons.add,
              size: 50.0,
            )
          ]
        ),
      )
    );
  }
  void _addContainer() {
    setState(() {
      _count = _count + 1;
    });
  }

}

但由于某种原因,这不起作用。出了什么问题,我该如何解决?

完整代码:

import 'package:flutter/material.dart';

class MainPage extends StatelessWidget {

  @override
    Widget build(BuildContext context) {

      return MaterialApp (
        debugShowCheckedModeBanner: false,
        home: Scaffold (
          backgroundColor: Colors.white,
          body: Column (
            children: <Widget> [
              AppBar(),
              Body(),
            ]
          )
        )
      );
    }

}

class AppBar extends StatelessWidget {

  @override
  Widget build(BuildContext context) {

    var abHeight = MediaQuery.of(context).size.height  * 0.2;

    var vPadding = MediaQuery.of(context).size.height  * 0.07;

    return Container (
      height: abHeight,
      child:  Column (
        mainAxisAlignment: MainAxisAlignment.end,
        children: <Widget> [
          Row (
            mainAxisAlignment: MainAxisAlignment.start,
            children: <Widget>[
              Padding(
                padding: EdgeInsets.only(left: vPadding),
                child: PoppinsText (
                  text: "App",
                  fontSize: 40.0,
                  fontWeight: FontWeight.bold,
                  color: Colors.black,
                ),
              )
            ]
          )
        ]
      )
    );
  }

}

class Body extends StatelessWidget {

  @override
  Widget build(BuildContext context) {

    var tPadding= MediaQuery.of(context).size.width  * 0.08; 
    var bPadding= MediaQuery.of(context).size.width  * 0.15; 
    var vPadding = MediaQuery.of(context).size.height  * 0.015;

    return Expanded (
      child: Container (
        child: NotificationListener<OverscrollIndicatorNotification> (
          onNotification: (OverscrollIndicatorNotification overscroll) {
            overscroll.disallowGlow();
          },
          child: PageView.builder(
            pageSnapping: false,
            controller: PageController(viewportFraction: 0.85),
            itemCount: container.length,
            itemBuilder: (context, i) {
              return Padding (
                padding: EdgeInsets.only(
                  left: vPadding,
                  right: vPadding,
                  top: tPadding,
                  bottom: bPadding
                ),
                child: container[i]
              );
            },
          )
        )
      )
    );
  }

}

 int _count = 1;

List container = [
  List.generate(_count, (int i) => ContainerCard),
  AddContainer()
];

class ContainerCard extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return Material (
      borderRadius: BorderRadius.circular(50.0),
      color: Colors.white,
      elevation: 8.0,
    );
  }

}

class AddContainer extends StatefulWidget {

  @override
  AddContainerState createState() => AddContainerState();

}

class AddContainerState extends State<AddContainer> {

  @override
  Widget build(BuildContext context) {
    return Material(
      borderRadius: BorderRadius.circular(50.0),
      color: Colors.white,
      elevation: 8.0,
      child: InkWell (
        onTap: _addContainer,
        splashColor: Colors.transparent,
        highlightColor: Colors.transparent,
        child: Column (
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Icon (
              Icons.add,
              size: 50.0,
            )
          ]
        ),
      )
    );
  }
  void _addContainer() {
    setState(() {
      _count = _count + 1;
    });
  }

}

class PoppinsText extends StatelessWidget {

  PoppinsText ({Key key, 
    this.text, 
    this.fontSize, 
    this.fontWeight,
    this.color}) : super(key: key);

  final String text;
  final double fontSize;
  final FontWeight fontWeight;
  final Color color;

  @override
  Widget build(BuildContext context) {
    return Text (
      text,
      style: TextStyle (
        fontFamily: 'Poppins',
        fontWeight: fontWeight,
        fontSize: fontSize,
        color: color
      ),
    );
  }

}

【问题讨论】:

    标签: dart flutter


    【解决方案1】:

    您正在使用无状态小部件。切换到 有状态小部件

    编辑

    根据要求更新。 这里的诀窍是使用 pageview 的 reverse 属性。

    class Body extends StatefulWidget {
      @override
      _BodyState createState() => _BodyState();
    }
    
    class _BodyState extends State<Body> {
      int count = 1;
      @override
      Widget build(BuildContext context) {
        return Expanded(
            child: Container(
                child: NotificationListener<OverscrollIndicatorNotification>(
                    onNotification: (OverscrollIndicatorNotification overscroll) {
                      overscroll.disallowGlow();
                    },
                    child: PageView.builder(
                        reverse: true,
                        pageSnapping: false,
                        controller: PageController(viewportFraction: 0.85),
                        itemCount: count,
                        itemBuilder: (context, i) {
                          print(i);
                          if (i == 0) {
                            return Padding(
                                padding: EdgeInsets.only(
                                    left:
                                        MediaQuery.of(context).size.height * 0.015,
                                    right:
                                        MediaQuery.of(context).size.height * 0.015,
                                    top: MediaQuery.of(context).size.width * 0.08,
                                    bottom:
                                        MediaQuery.of(context).size.width * 0.15),
                                child: Material(
                                    borderRadius: BorderRadius.circular(50.0),
                                    color: Colors.white,
                                    elevation: 8.0,
                                    child: InkWell(
                                      onTap: () {
                                        setState(() {
                                          count++;
                                        });
                                      },
                                      splashColor: Colors.transparent,
                                      highlightColor: Colors.transparent,
                                      child: Column(
                                          mainAxisAlignment:
                                              MainAxisAlignment.center,
                                          children: <Widget>[
                                            Icon(
                                              Icons.add,
                                              size: 50.0,
                                            )
                                          ]),
                                    )));
                          } else {
                            return Padding(
                                padding: EdgeInsets.only(
                                    left:
                                        MediaQuery.of(context).size.height * 0.015,
                                    right:
                                        MediaQuery.of(context).size.height * 0.015,
                                    top: MediaQuery.of(context).size.width * 0.08,
                                    bottom:
                                        MediaQuery.of(context).size.width * 0.15),
                                child: Material(
                                  borderRadius: BorderRadius.circular(50.0),
                                  color: Colors.white,
                                  elevation: 8.0,
                                ));
                          }
                        }))));
      }
    

    【讨论】:

    • 抱歉回复晚了。即使我将类 Body 更改为 Stateful 小部件,它也会给我一个错误提示 'List&lt;Type&gt;' is not a subtype of type 'Widget'
    • @Extra 您的代码有很多错误。您能否详细说明您的布局,以便我为您提供更好的解决方案?
    • 我正在尝试创建一个网页浏览,其中只有一个页面有一个加号按钮,可以将其他页面(容器卡)添加到我的网页浏览中。另外,我不想将容器添加到左侧而不是右侧。非常感谢所有这些帮助。
    • @Extra 当然。它很容易解决。只需在网页浏览中使用 reverse: true 并返回您想要的小部件。我又更新了答案
    【解决方案2】:

    我不知道您是否找到了解决方案。这是我的代码:

    import 'package:flutter/material.dart';
    
    void main() => runApp(MyApp());
    const double paddingInset = 5;
    Color tileColor = Colors.grey[350];
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          debugShowCheckedModeBanner: false,
          title: 'Test App',
          theme: ThemeData(
            primarySwatch: Colors.deepPurple,
          ),
          home: MyHomePage(),
        );
      }
    }
    
    class MyHomePage extends StatefulWidget {
      @override
      _MyHomePageState createState() => _MyHomePageState();
    }
    
    List<Widget> bodyElements = [];
    int num = 0;
    
    void addBodyElement() {
      bodyElements.add(
        Padding(
          padding: const EdgeInsets.all(paddingInset),
          child: Container(
            height: 500,
            width: double.infinity,
            child: Center(child: Text('This is section $num')),
            decoration: BoxDecoration(
              color: tileColor,
              borderRadius: BorderRadius.circular(10),
            ),
          ),
        ),
      );
    }
    
    class _MyHomePageState extends State<MyHomePage> {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          backgroundColor: Colors.white,
          appBar: AppBar(
            title: Center(child: Text('Home')),
            brightness: Brightness.dark,
            leading: IconButton(
              icon: Icon(Icons.refresh),
              onPressed: () {
                setState(() {
                  bodyElements.clear();
                  num = 0;
                });
              },
            ),
          ),
          body: ListView(
            children: <Widget>[
              Column(
                children: bodyElements,
              ),
            ],
          ),
          floatingActionButton: FloatingActionButton.extended(
            icon: Icon(Icons.add),
            label: Text('Add'),
            onPressed: () {
              num++;
              setState(() {
                addBodyElement();
              });
            },
          ),
        );
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-07-20
      • 2021-01-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多