当前位置: 首页 > article >正文

Flutter系列教程之(4)——自定义Widget控件及相关知识

目录

StatelessWidget与StatefulWidget简介

StatelessWidget

创建Widget

使用

StatefulWidget

简单说明

改变页面数据

使用补充

 1.传递参数

2.外层Widget改变当前Widget


StatelessWidget与StatefulWidget简介

我们需要创建我们自定义的 Widget 控件,只需要创建一个类去继承 StatelessWidget StatefulWidget 这两个类即可,这两个类都是 Flutter 提供的基本 Widget 类,不过在使用上有所区别

 StatelessWidget 是静态 Widget ,而 StatefulWidget 则是动态 Widget 

 StatefulWidget StatelessWidget 唯一不同的特点,就是其提供了一个 setState() 的方法,我们可以调用此方法,更新数据,从而会让该 Widget 的内容发生改变(本质上与 MVVM 模式类似)

那什么是静态 Widget 和动态 Widget 分别是什么意思呢?静态 Widget 则是说明其中的内容不会发生改变,如 Button 按钮、文字 Text 等,动态 Widget 则是内容是可变的,如一个列表显示的数据,其数据是通过网络请求来获得的,网络请求返回的数据每次可能有所不一样,之后我们需要增加一个下拉刷新的效果,我们就可以调用 setState 的方法,去更改数据,从而进一步改变列表中显示的数据

综上所述:我们需要创建自定义Widget,需要根据需求来判断是应该使用StatefulWidget还是StatelessWidget,不过实际的需求一般都是动态的多些,比如说两个下拉框需要数据联动,或者是复选框的勾选等...

下面就是分别介绍StatefulWidget和StatelessWidget这两种Widget的用法

StatelessWidget

创建Widget

这种Widget实现比较简单,我们只需要定义一个类,继承StatelessWidget,之后实现StatelessWidget的build接口方法即可

class DemoWidget extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      theme: new ThemeData(
        primaryColor: Colors.blue,
        accentColor: Colors.blueAccent,
      ),
      home: new Scaffold(
        appBar: new AppBar(
          title: new Text('Flutter Bar'),
        ),
        body: new Center(
          child: new Text('Hello World'),
        ),
        floatingActionButton:
        FloatingActionButton(onPressed: () {
          Fluttertoast.showToast(
            msg: "点击添加",
            toastLength: Toast.LENGTH_SHORT,
            gravity: ToastGravity.BOTTOM,
            backgroundColor: Colors.black,
          );
        },
            child: Icon(Icons.add)
        ),
      ),
    );
    
  }

我这里是直接把之前的那个例子拿过来用了,把它封装成了DemoWidget

使用

使用的话就很简单了,我们直接new一个DemoWidget类对象即可

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
	  //new关键字可以省略
    return DemoWidget();
  }
}

StatefulWidget

简单说明

StatefulWidget实现过程稍微复杂一些,需要两个类,一个是Widget,另外一个则是State状态类,如下图所示

还记得之前说到的setState方法吗,其实它是State状态类里的方法

 StatefulWidget与StatelessWidget不一样,StatefulWidget需要实现createState()方法,其方法需要返回一个State对象,而State类与之前的StatelessWidget一样,需要实现build()方法

之后,每当调用setState()方法时候,DemoWidget就会得到一个新的状态,并重新渲染页面(也就是改变了页面显示的内容)

class DemoWidget extends StatefulWidget{
  @override
  State<StatefulWidget> createState() {
    return DemoWidgetState();
  }

}

class DemoWidgetState extends State<DemoWidget>{
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      theme: new ThemeData(
        primaryColor: Colors.blue,
        accentColor: Colors.blueAccent,
      ),
      home: new Scaffold(
        appBar: new AppBar(
          title: new Text('Flutter Bar'),
        ),
        body: new Center(
          child: new Text('Hello World'),
        ),
        floatingActionButton:
        FloatingActionButton(onPressed: () {
          Fluttertoast.showToast(
            msg: "点击添加",
            toastLength: Toast.LENGTH_SHORT,
            gravity: ToastGravity.BOTTOM,
            backgroundColor: Colors.black,
          );
        },
            child: Icon(Icons.add)
        ),
      ),
    );
  }
}

PS:用法和之前一样,直接创建个实例对象即可显示页面

改变页面数据

上面的代码其实与之前的StatelessWidget中的代码效果一致,点击按钮会弹出Toast提示,接下来我们对上面的代码进行部分的改造,实现点击按钮,让页面中间显示的数据发生改变,我们只需要改DemoWidgetState这个类中的代码即可

class DemoWidgetState extends State<DemoWidget> {
  var i = 0;
  var str = "hello";

  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      theme: new ThemeData(
        primaryColor: Colors.blue,
        accentColor: Colors.blueAccent,
      ),
      home: new Scaffold(
        appBar: new AppBar(
          title: new Text('Flutter Bar'),
        ),
        body: new Center(
          child: new Text(str),
        ),
        floatingActionButton: FloatingActionButton(
            onPressed: () {
              setState(() {
                str = "hello$i";
                i++;
              });
            },
            child: Icon(Icons.add)),
      ),
    );
  }
}

 可以看到我们需要的效果,点击添加按钮,中间的文字就会变为hello0,之后第二次就变为hello1

使用补充
 1.传递参数

上面为StatefulWidget的基本用法,接下来补充一下如何传递参数以及获取布局里的数据

传递参数稍微有些繁琐,需要在Widget中写一个变量,同时,也需要在State状态类中写个变量,比如之前的那个布局,我们中间默认显示hello,之后点击按钮会变为hello0

我们想要实现创建的时候直接给定默认显示的数据,可以是hello,或者是其他的数据,就可以写个构造函数,用来传递默认显示的数据即可,代码如下图所示:

可以看到,代码其实没有较大的改动,只是在Widget和State这两个类中添加了对应的成员变量和构造方法

2.外层Widget改变当前Widget

这里可能起的名字不是很好,我们举个例子来说明一下

比如我们有个页面,有个按钮Button的Widget和我们创建的自定义Widget,我们想要实现点击按钮就要获得我们自定义Widget里的数据,这个时候我们有什么办法呢?

我不确定我这是不是正确的解决方法,我的做法是,在Widget类中声明了一个State的变量引用,之后由State类中提供一个方法,用来修改数据

 

之后使用的时候,我们可以直接调用DemoWidget对象实例的state变量,从而在调用setData()

当然,你也可以在DemoWidget中创建一个方法,之后在里面调用state的方法,如:

又或者state不写那个setData方法,直接在Widget中写也可以,如:

 PS:至于获取Widget的数据,与上面也是类似,直接在Widget或者是State中定义个方法,用来返回数据即可

 


http://www.kler.cn/a/565821.html

相关文章:

  • LeetCode 2656 K个元素的最大和
  • 力扣——不同路径
  • 算法日记31:leetcode341整数拆分(DFS->记忆化->DP)
  • deepseek 和chatgpt的论文降重方法有哪些?
  • 大模型最新面试题系列:训练篇之分布式训练
  • go设计模式
  • 【压力测试】
  • 自然语言处理NLP入门 -- 第五节词向量与嵌入
  • Ollama download DeepSeek Local Install
  • 如意玲珑应用构建指南(一):规范体系与配置文件全解析
  • 二、IDE集成DeepSeek保姆级教学(使用篇)
  • 2-1文件描述符
  • DeepSeek如何快速开发PDF转Word软件
  • DeepSeek 开源周(2025/0224-0228)进度全分析:技术亮点、调用与编程及潜在影响
  • WPF高级 | WPF 3D 图形编程基础:创建立体的用户界面元素
  • Uniapp开发微信小程序插件的一些心得
  • CSS—背景属性与盒子模型(border、padding、margin)
  • ipywidgets深度探索:从交互原理到企业级应用
  • /ɪ/音的字母或字母组合的单词
  • 增强for循环