美文网首页
Flutter踩坑记录01 如何书写界面

Flutter踩坑记录01 如何书写界面

作者: 曾勇浩_7f31 | 来源:发表于2020-05-29 10:24 被阅读0次

万物都是Widget

如同Android中界面都是由View构成一样,Flutter的界面均由Widget构成。

Android使用Activity或者Fragment等进行View的管理,而Flutter更为直接,全部由Widget内部进行管理。所以Flutter并不使用xml进行样式的描述,而是直接使用Dart代码进行一层层的布局嵌套书写,并在其中夹杂状态的管理,数据加载等操作,这一点需要Android开发人员适应。

牢记万物都是Widget

无论是单个的View,或者是掌管排列的Layout,甚至是手势装饰类,都是Widget的一种。

Widget创建之后,是不可变(immutable)的,所以当你试图动态更改一个Textview的style的时候,你会发现这些变量都是final的,改变一个Widget的方法只有重建它,而使用什么方法进行重建呢?这就要谈到State

State

我们将Widget大致分为两种

  • StatelessWidget(无状态的)

如果你所绘制的界面,无须依赖外界数据(就是不会发动态更改),你可以选择继承此Widget,这会让你直接返回一个Widet树,而没有方法进行重绘.

  • StatefulWidget(有状态的)

如果你需要随时刷新界面,则需要继承此类,而后你需要强制重写CreateState函数,返回一个State对象


class LoginPage extends StatefulWidget{

  @override

  State<StatefulWidget> createState() {

    return LoginPageState();

  }

}

这里的State就是我们进行状态管理的一个工具,具体的Widget树将有State进行返回。

如下图


class LoginPageState extends State{

    @override

    Widget build(BuildContext context) {

      return Widget();

      }

继承一个State会让你重写Build方法,以此来返回Widget树。

而这个State对象就掌管了这个Widget

现在我们来看看拥有了State之后,如何通知界面改变。

我们现在有一个需要,显示软件的版本名称,

所以我们需要一个Text()来进行显示,还需要一个变量 String versionName,并将这个变量传入Text,最后我们书写获取版本号的异步方法。


String nameVersion ="";

class LoginPageState extends State{

    @override

    Widget build(BuildContext context) {

      return Text(nameViersion);

      }



  void getVersionAndBuilderNumber () async {

      PackageInfo packageInfo = await PackageInfo.fromPlatform();

      String number = packageInfo.buildNumber;

      String version = packageInfo.version;

      print(version);

      setState(() {

        nameVersion =  "$number($version)";

      });

    }



注意,我们必须设置一个变量,因为我们提到Widget是不可变的,你不能在获取到版本号之后(这个过程是异步)再获取Text进行赋值,我们需要抛弃Android或者iOS开发中的惯性,Flutter是数据驱动的,你只需要更改你的数据,并通知刷新,那些绑定了对应数据的Widget会自动重绘,可能看到这里,使用过Android中数据绑定的同学会会心一笑(虽然机制完全不同)。

最后我们在入口处,比如State的构造方法中,调用getVersion()


LoginPageState(){

      getVersionAndBuilderNumber();

    }

这样只要创建的了State对象,getVersion方法将异步获取版本号(网络请求同理),注意看getVersion()中获取到版本号之后调用的

setState()这个函数的意思就是通知Widget进行刷新,不要担心重复绘制,Flutter会自己决定哪些部分需要刷新。

在setState()中对nameVersion的重新赋值取决你自己的习惯,你也可以在setState()之前进行重新赋值,只要调用了setState(),任何之前的数据改变都将会进行更改。

Widget树

我们已经学会如何单独绘制一个Widget,并且进行动态的数据更新,而这一段我们来继续了解State类中,是如何进行复杂布局的。

继承State之后,我们需要实现Build()方法来返回一个Widget,如同上述代码,我们单单只返回了一个Text,它是一个Wdiget,如同TextView一样,是单个View。

类似Android,Flutter的Widget也提供了一些用来布局的Widget,比如Cloum(),Row(),记住万物都是Widget,只要接收参数是Widget的地方,都可以New这些类来进行布局,包括Cloum(),Row()内部需要的Childs[]也就是Widet数组。


child:Column(children: <Widget>[

                            SizedBox(

                              height:44,

                              child:TextField(

                                keyboardType: TextInputType.number,

                                cursorColor: Color(0x66FFFFFF),

                                style: TextStyle(

                                    color: Colors.white,

                                    fontSize:15

                                ),

                                decoration: InputDecoration(

                                    hintText: 'Phone number',

                                    hintStyle: TextStyle(

                                        color: Color(0x66FFFFFF),

                                        fontSize: 15

                                    ),

                                    border: InputBorder.none

                                ),

                              ),

                            )

这段代码里 最外层是一个Cloum() 表示竖向线性布局,它需要一个Widget的数组(child[])来填充,在child[]数组li,我们New了一个SizeBox()

SizeBox是一个用来描述大小的BoxWidget,Text这类Widget的大小常常需要已Parent来描述尺寸,这是反Android开发习惯的一个地方

SizeBox()中,我们又制造了TextFiled(),这是可编辑的Text(就是EditText)

于是,我们构造了一个可输入的Text,并指明了宽高,如果还没有熟悉的人,可能对着一层层的嵌套感到可怕,然而,通过Idea等编辑器的优化,实际读着没那么费劲,而且这种数据绑定的方式,节省了很多get set程序。

同理 我们一开始生命的LoginPage也是一种Widget,所以,我们也可以在Build()中返回其他的StatefulWidget()

这样,当组合复杂的Widget的时候,将一些带有业务逻辑的Widget进行分离,避免搅作一团.


class LoginPageState extends State{



    @override

    Widget build(BuildContext context) {

        return XXXXPage();********



    }

相关文章

  • Flutter踩坑记录01 如何书写界面

    万物都是Widget 如同Android中界面都是由View构成一样,Flutter的界面均由Widget构成。 ...

  • Flutter 开发记录

    Flutter 开发踩坑记录(干货总结)

  • channel ios framework to Flutter

    今天开发Flutter插件,踩了些坑,记录一下1.Android Studio 新建Flutter 项目,选择pl...

  • flutter 踩坑记录

    参考资料 技术胖在 bilibili 的 flutter 系列视频 坑 1. Android Studio 无法...

  • Flutter踩坑记录

    安卓打包失败 如果遇到failed to respond,如果gradle里配置的是google()和maven(...

  • Flutter踩坑记录

    1 去除Debug 标签 问题:默认创建的Flutter应用运行时,屏幕右上角会带Debug标签解决:在MyApp...

  • Flutter踩坑记录

    如果页面整个空白,说明页内有错误,可以分别注释排查 Textfield不能直接放在Row中,因为不确定Textfi...

  • Flutter踩坑记录

    1.Flutter的UI开发【1+1+0.5=2.5】轮播图和自定义指示器【耗时1天】布局越界问题,布局的宽度高度...

  • Flutter 踩坑记录

    1.问题描述: 一个聊天对话页面,由于对话框形状需要自定义,因此采用了CustomPainter来自定义绘制对话框...

  • Flutter踩坑记录

    1、对于网上下载的开源项目,在使用Xcode运行项目时需要先在Xcode里面指定你本地下载的flutter环境的路...

网友评论

      本文标题:Flutter踩坑记录01 如何书写界面

      本文链接:https://www.haomeiwen.com/subject/wwqxzhtx.html