美文网首页APP & programFlutter
flutter学习笔记-02-官方demo my_friendl

flutter学习笔记-02-官方demo my_friendl

作者: 牵手生活 | 来源:发表于2022-05-31 17:48 被阅读0次

    codelabs demo功能、官方步骤

    1:模拟聊天界面
    2:根据学习dart代码是的布局、事件绑定
    3:构建组件
    4: 简单的动画展示
    5:根据ios、或android 显示界面
    6:flutter 在android studio中调试

    使用 Flutter 构建精美的界面 (flutter-io.cn)

    debug其实类似Android 、java

    函数上设置断点来练习使用调试程序,然后运行和调试应用。您可以检查堆栈框架以查看您的应用的函数调用历史记录。


    image.png

    demo截屏

    image.png image.png

    flutter的界面布局-使用代码

    原生android 默认使用xml方式进行布局
    flutter使用代码组件进行布局,类似vue、微信小程序

    new Container 提法提醒

    main.dart -step03 在添加动画前

    import 'package:flutter/foundation.dart';
    import 'package:flutter/material.dart';
    
    void main() {
      runApp(new FriendlychatApp());
    }
    
    
    final ThemeData kIOSTheme = new ThemeData(//采用 iOS 颜色(浅灰色,强调色为橙色)
     primarySwatch: Colors.orange,
      primaryColor:Colors.grey[100],
      primaryColorBrightness: Brightness.light,
    
    );
    final ThemeData kDefaultTheme = new ThemeData(//采用 Android 颜色(紫色,强调色为橙色)
      primarySwatch: Colors.purple,
      accentColor: Colors.orangeAccent[400],
    
    );
    
    class FriendlychatApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return new MaterialApp(
          title: "Friendlychat2",
          theme: defaultTargetPlatform == TargetPlatform.iOS  //根据iso平台、或android平台,使用不同的主题
          ? kIOSTheme:kDefaultTheme,
          home: new ChatScreen(),
        );
      }
    }
    
    class ChatScreen extends StatefulWidget {
    
    
      @override
      State createState()=>new ChatScreenState();
    }
    class ChatScreenState extends State<ChatScreen> with TickerProviderStateMixin{//创建AnimationController对象后,您需要向其传递一个vsync参数。vsync可防止处于屏幕之外的动画消耗不必要的资源。要使用ChatScreenState作为vsync,请在ChatScreenState类定义中添加一个TickerProviderStateMixin mixin。
      final List<ChatMessage> _messages = <ChatMessage>[]; //用于存放消息list,发生消息是_handleSubmitted会将新消息添加进来
      final TextEditingController _textController = new TextEditingController();//用它来读取输入字段的内容,并在发送文本消息后清除字段。
      bool _isComposing = false; //是否有输入文字,决定是否启用send 按钮
    
      @override
      void dispose(){
        for (ChatMessage message in _messages){
          message.animationController.dispose(); //释放动画资源
          super.dispose();
        }
    
    
      }
      @override
      Widget build(BuildContext context) {
        return new Scaffold(
          appBar: new AppBar(
              title: new Text("Friendlychat")
          ) ,
          body:new Column(//可以占用多个子微件,包括滚动列表和输入字段的行。
            children: [
              new Flexible(//消息list的父容器,这将指示框架允许已接收的消息列表进行扩展以填充Column高度
                  child: new ListView.builder(
                    padding: new EdgeInsets.all(8.0),
                    reverse: true,//可使ListView从屏幕底部开始
                    itemBuilder: (_,int index)=>_messages[index],
                    itemCount: _messages.length,
    
                  )
              ),
              new Divider(height: 1.0,) ,//分割线
              new Container(//输入框+发送 Container可作为文本合成器的父微件,其可用于定义背景图片、内边距、外边距和其他常见的布局细节
                decoration: new BoxDecoration(
                  color: Theme.of(context).cardColor
                ),
                child: _buildTextComposer(),
              ),
    
    
    
            ],
    
          ),
          //body: _buildTextComposer(),
        );
      }
    
      Widget _buildTextComposer(){
        return new IconTheme(//应用一个不同的主题背景。  图标的颜色、不透明度和大小
            data: new IconThemeData(color: Theme.of(context).accentColor),//data属性指定当前主题背景的ThemeData对象
            child: new Container(
                margin: const EdgeInsets.symmetric(horizontal: 8.0),
                child: new Row( //水平行方向创建子组件 Creates a horizontal array of children.
                  children: [
                    new Flexible(
                      child: new TextField(
                        controller: _textController,  //构造函数提供一个 TextEditingController。此控制器还可用于清除字段或读取字段的值。
                        onChanged: (String text){
                          setState(() {
                            _isComposing = text.length>0;
                          });
                        },
    
                        onSubmitted: _handleSubmitted,
                        decoration: new InputDecoration.collapsed(hintText: "send a message"),
                      ),
                    ),
    
                    new Container(
                      margin: new EdgeInsets.symmetric(horizontal:4.0),
                      child: new IconButton(
                        icon: new Icon(Icons.send),
                        onPressed:_isComposing? ()=> _handleSubmitted(_textController.text):null //粗箭头函数声明 => expression 是 { return expression; } 的简写形式。
                      ),
                    ),
    
                  ],
    
                )
    
            )
        );
    
      }
      
    
      void _handleSubmitted(String value) {
        _textController.clear();
        setState(() {
          _isComposing = false;
        });
    
        ChatMessage message = new ChatMessage(
          text: value,
          animationController:new AnimationController(//实例化一个AnimationController对象用于控制动画
              duration: new Duration(milliseconds: 700),
                vsync: this
            ),
        );
        setState(() { //并让框架了解此部分微件树已发生变化,且需要重新构建界面
          _messages.insert(0, message);
        });
        message.animationController.forward();
      }
    }
    const String _name = "牵手生活";
    class ChatMessage extends StatelessWidget{
      ChatMessage({required this.text,required this.animationController});  //???为何需要keyword
      final String text;
    
      final AnimationController animationController; //存储动画控制器,在 _handleSubmitted()函数初始化 All final variables must be initialized, but 'animationController' isn't.  animationController由构造函数传入
    
      @override
      Widget build(BuildContext context) {
        return new SizeTransition(//CurvedAnimation对象与SizeTransition类结合使用可生成一个缓出动画效果。缓出动画效果可使消息在动画开始时快速滑入,然后慢下来,直至停止
          sizeFactor: new CurvedAnimation(
                parent: animationController,
                curve: Curves.easeOut
            ),
          axisAlignment: 0.0,
          child: new Container(
            margin: const EdgeInsets.symmetric(vertical: 10.0),
            child: new Row(
              crossAxisAlignment: CrossAxisAlignment.start,  //以确定头像和消息相对于其父微件的位置
              children: <Widget>[
                new Container(
                  margin: const EdgeInsets.only(right: 16.0),
                  child: new CircleAvatar(child: new Text(_name[0]),),  //头像部分:可使用用户的姓名首字母大写作为其标签
                ),
                new Column(
                  crossAxisAlignment: CrossAxisAlignment.start,//消息,父微件是一个Column微件,其主轴是垂直的,因此CrossAxisAlignment.start将沿水平轴的最左侧位置对齐文本。
                  children: <Widget>[
                    new Text(_name, style: Theme.of(context).textTheme.subtitle2), //主题 .subhead 风格已经没有了
                    new Container(
                      margin: const EdgeInsets.only(top:5.0),
                      child: new Text(text),
                    ),
                  ],
    
                ),
    
              ],
    
            ),
          ),
        );
      }
      
    }
    
    

    相关文章

      网友评论

        本文标题:flutter学习笔记-02-官方demo my_friendl

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