一个Flutter的Demo

作者: 仕明同学 | 来源:发表于2018-09-10 20:12 被阅读65次
    ezgif-2-c954a6dd5e.gif
    ezgif-2-f3661cf95e.gif

    App的页面详情

    HomePage;里面嵌套了四个页面,使用的是TabBarTabBarView的组合,比如安卓中的Fragment Viewpager

    • 1、首页的第一页使用豆瓣电影的接口,请求数据,并且展示出来了,工程中如何代码中如何使用依赖?如下代码所示
       flutter:
       sdk: flutter
     # The following adds the Cupertino Icons font to your application.
     # Use with the CupertinoIcons class for iOS style icons.
     cupertino_icons: ^0.1.0
     fluttertoast: ^2.0.7 #"Packages get" 要去主动的 get 一次依赖
      dio: ^v1.0.3
     # 添加网络依赖
    
    • 2、演示了图片控件摆放
    • 3、综合列表的展示
    • 4、其他控件的使用Demo
    首页.jpg 一些控件.jpg
     * 首页的关键代码
    ```
     //为给定的[子]控件创建默认选项卡控制器。
    return new DefaultTabController(
        length: 5,
        child: new Scaffold(
          appBar: new AppBar(
            backgroundColor: Colors.black45,
           // title: titleWidget(),
            title: new Text("首页",style: new TextStyle(color: Colors.white,fontSize: 22.00),),
            actions: <Widget>[
              new IconButton(
                  icon: new Icon(Icons.add_a_photo), onPressed: () {
                Navigator
                    .of(context)
                    .push(new MaterialPageRoute(builder: (context) {
                  return new OtherPage();
                }));
              })
            ],
            bottom: new TabBar(
                isScrollable: true,
                labelStyle: new TextStyle(fontSize: 22.00,color: Colors.red),
                indicatorPadding:EdgeInsets.zero,
                labelColor: Colors.white,
                indicatorWeight:4.0,
                unselectedLabelColor: Colors.blueAccent,
                tabs: [
                  new Tab(
                    text: "豆瓣电影",
                  ),
                  new Tab(
                    text: "控件摆放",
                  ),
                  new Tab(
                    text: "列表展示",
                  ),
                  new Tab(
                    text: "其他控件展示",
                  ),
                ]),
          ),
          body: new TabBarView(children: [new TabOne(), new TabTwo(),new TabThree(),new TabFroth()]),
        ));
    ```
    

    SimilarWordsPage寻找近义词Demo,就是一个点击按钮,然后请求网络,刷新页面的流程。

    • 1、使用了TextField相当于安卓中的Edittext,只不过获取值的时候有些变化
         new Expanded(
               child: new TextField(
                 //不要主动弹起来
                 autofocus: false,
                 controller: _textController,
                 decoration: new InputDecoration.collapsed(
                     hintText: "请输入要查找的词",
                     hintStyle: new TextStyle(color: Colors.red)),
               ),
      
    • 2、如何退出页面Navigator.of(context).pop();
    • 3、如何使用Toast,这里我是使用了三方的依赖!底层原理是使用了反射,具体实现的方法,有兴趣的同学可以看看String res = await _channel.invokeMethod('showToast', params);
         Fluttertoast.showToast(
                          msg: "输入为空,请重新输入",
                          timeInSecForIos: 1,
                          bgcolor: "#e74c3c",
                          textcolor: '#ffffff');
      
      • 4、带框的Button的使用,具体请看实现的代码。
      • 5、具体页面如下
    近义词页面.jpg
    • 6、代码如下
               import 'dart:convert';
    import 'dart:io';
    import 'package:flutter/material.dart';
    import 'package:flutter_app/bean/DataBean.dart';
    import 'package:fluttertoast/fluttertoast.dart';
    
    class SimilarWordsPage extends StatefulWidget {
    @override
    State<StatefulWidget> createState() {
      return new SimilarWordsPageState();
    }
    }
    
    class SimilarWordsPageState extends State<SimilarWordsPage> {
    List<DataBean> datas = [];
    static int i=0;
    final TextEditingController _textController = new TextEditingController();
    
    @override
    Widget build(BuildContext context) {
      return new Scaffold(
        appBar: findAppBar(),
        backgroundColor: Colors.black12,
        body: findBody(),
      );
    }
    
    findBody() {
      return new Container(
          child: new Scaffold(
        body: new ListView.builder(
          itemCount: datas.length,
          itemBuilder: (BuildContext context, int position) {
            i=position;
            return getRow(position);
          },
        ),
      ));
    }
    
    Widget findAppBar() {
      return new AppBar(
          title: new Container(
        child: new Row(
          children: <Widget>[
            new Container(
              child: new FlatButton.icon(
                onPressed: () {
                  // 本来就在栈顶,退出会有显示的问题
                  Navigator.of(context).pop();
                },
                icon: new Icon(Icons.close, color: Colors.white30),
                label: new Text(""),
              ),
              width: 60.0,
            ),
            new Expanded(
              child: new TextField(
                //不要主动弹起来
                autofocus: false,
                controller: _textController,
                decoration: new InputDecoration.collapsed(
                    hintText: "请输入要查找的词",
                    hintStyle: new TextStyle(color: Colors.red)),
              ),
            ),
            //点击事件的第一种实现的方式  我觉得不太好
            //  new GestureDetector(child: new Icon(Icons.find_in_page),onTap: (){print("dd");})
            // 这种点击时间有点效果
            new IconButton(
                icon: new Icon(Icons.find_in_page),
                onPressed: () {
                  print(_textController.text);
                  if (_textController.text.isEmpty) {
                    Fluttertoast.showToast(
                        msg: "输入为空,请重新输入",
                        timeInSecForIos: 1,
                        bgcolor: "#e74c3c",
                        textcolor: '#ffffff');
                  } else {
                    FocusNode focusNode = new FocusNode();
                    FocusScope.of(context).requestFocus(new FocusNode());
                    Fluttertoast.showToast(
                        msg: "查找值为:" + _textController.text,
                        timeInSecForIos: 1,
                        bgcolor: "#e74c3c",
                        textcolor: '#ffffff');
                    getApiData(_textController.text);
                    focusNode.unfocus();
                  }
                })
          ],
        ),
        decoration: new BoxDecoration(
            borderRadius: const BorderRadius.all(const Radius.circular(4.0)),
            color: Colors.white10),
      ));
    }
    
    Widget getRow(int i) {
      return new Padding(
        padding: new EdgeInsets.all(10.0),
        // child: new Text("Row ${datas[i].key}",style: new TextStyle(color: Colors.orange,fontSize: 18.00),)
        //  Column 相当于 相对布局  Row 线性布局
        child: new Column(
          children: <Widget>[
            new Padding(
              padding: new EdgeInsets.fromLTRB(0.0, 5.0, 0.0, 5.0),
              child: new Row(
                children: <Widget>[
                  new Expanded(
                      child: new OutlineButton(
                        borderSide:new BorderSide(color: Theme.of(context).primaryColor),
                        child: new Text('条目 = '+i.toString(),style: new TextStyle(color: Theme.of(context).primaryColor),),
                        onPressed: (){},
                      )
                  ),
                ],
              ),
            ),
    
            new Container(
              child: new Text(
                "联想到的词:" + datas[i].key,
                style: new TextStyle(color: Colors.purple, fontSize: 12.00),
              ),
              padding: new EdgeInsets.all(10.0),
            ),
            new Container(
              child: new Text("联想到词的翻译信息:" + datas[i].message,
                  style: new TextStyle(color: Colors.cyan, fontSize: 15.00)),
              padding: new EdgeInsets.all(10.0),
            )
          ],
        ),
      );
    }
    
    @override
    void initState() {
      super.initState();
      // 网络请求
      //http://dict-mobile.iciba.com/interface/index.php?c=word&m=getsuggest&nums=10&client=6&is_need_mean=1&word=sm
      //我的 Api的地址
      getApiData("sm");
    }
    
    // 网络请求
    void getApiData(String tag) async {
      // 注意导入的包的地方是  import 'dart:io';
      var httpClient = new HttpClient();
      var url =
          "http://dict-mobile.iciba.com/interface/index.php?c=word&m=getsuggest&nums=20&client=6&is_need_mean=1&word=" +
              tag;
      var request = await httpClient.getUrl(Uri.parse(url));
      var response = await request.close();
      if (response.statusCode == HttpStatus.OK) {
        var jsonData = await response.transform(utf8.decoder).join();
        setState(() {
          datas = DataBean.decodeData(jsonData);
        });
        for (int i = 0; i < datas.length; i++) {
          print(datas[i].key);
          print(datas[i].message);
        }
      }
    }
    }
    

    官方Demo

    官方Demo.jpg

    关于我

    关于我.jpg

    一些总结

    • widget相当于ViewWidget的实例仅仅存在每一帧之间,并且每一帧之间 Flutter都会主动的创建一颗Widget树用于下一帧的渲染。
    • AndroidView 是可变的,在 Flutter 中的 Widget 是不可变的。这种特性使得 Flutter 中的 Widget 变得十分轻量级
    • 一个 Widget会变化,那么它就是有状态的。但是如果一个子Widget是有状态的,但是其父Widget是不可变的话父Widget也可以是 StatelessWidget
    • TatelessWidgetStatefulWidget 的核心内容是一致的,它们都会在每一帧中被重构,不同之处在于StatefulWidget 有一个 State 对象,它可以为 StatefulWidget 在不同帧之间存储数据。
    • FlutterUI的布局是通过在dart 文件中构建 Widget 树来实现的。
    • Android中,使用 LinearLayout 使你的部件垂直或水平放置。在 Flutter中,你可以使用Row 或者 Co​​lumn 来实现相同的效果。
    • Flutter 中,最简单的方法是使用ListView 。在Flutter 中,ListView 既是ScrollView 又是Android中的ListView
    • 通过使用ColumnRowStackWidget 的组合来实现 RelativeLayout 的效果
    • Flutter 中,添加触摸监听器有两种方法
    • 如果Widget支持事件检测,则可以将一个函数传递给它并进行处理。例如,RaisedButton 有一个onPressed 参数
    • 如果 Widget不支持事件检测,则可以将该 Widget 包装到 GestureDetector中,并将函数传递给onTap 参数。
    • GestureDetector 我们可以监听广泛的手势
    • 要充分利用应用程序中的 Material风格的组件的话,可以把顶级部件 MaterialApp作为应用程序的入口。MaterialApp作为一个比较方便的部件,包装了许多实现了 Material 风格所需要的部件(如 Scaffold)。MaterialApp是在 WidgetsApp 的基础上进行实现的
    • Flutter不会自动导入包
    • Column相当于 相对布局Row线性布局
    • 首页的数据结构展示
    • HttpClient导入的包是 io里面的
    • DEBUG 包要不正式包大很多 Built build\app\outputs\apk\debug\app-debug.apk (31.9MB).而正式包才8.4M.
    • 解决的Bug的时候太痛苦了,Flutter使用 ide ,太痛苦了
    • 在脑袋要构思出 这个布局的整体的结构
    • 关闭系统自带的防火墙,重启OK 由于需要出差,就是用的是笔记本开发,导致自己笔记本的防火墙没有被关闭,真的是日了狗了,解决防火墙
    • MediaQuery.of(context).size.width / 4分之一的屏幕
    • MaterialApp 带有 Debug的标记

    感谢以下资料给与我的帮助

    求赞或者求星星 FlutterApp

    相关文章

      网友评论

        本文标题:一个Flutter的Demo

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