android+flutter开发笔记(一)

android+flutter开发笔记(一)

android+flutter开发笔记(一)_第1张图片

    对flutter的详细解惑答案:https://blog.csdn.net/zhangxiangliang2/article/details/75675693

    flutter的基础组件使用,参考大神整理:https://blog.csdn.net/sinat_17775997/article/details/82180605

********************************************************************    

   flutter项目的入口

        void main() {
             runApp(new MaterialApp(
             title: 'My app', // used by the OS task switcher
             home: new MyScaffold(),
           ));
        }
    
    或
    
         void main() => runApp(AppSplashPage());

 ********************************************************************      

1、首先是flutter的环境配置和开发环境配置

    整理地址:https://blog.csdn.net/u010326875/article/details/88865345
    
2、然后对于新的语言形式,面向对象的,就会涉及到声明周期:

    官方文档介绍:https://book.flutterchina.club/chapter3/flutter_widget_intro.html


    1》、android的里面的声明周期存在的类有:
    
        Activity、Fragment、view、service等等;  (这里不再赘述了)

    2》、flutter里也有声明周期,对应的控件有:
    
        StatelessWidget、StatefulWidget

        参考:https://www.imooc.com/article/details/id/68585

        
        一、StatelessWidget的声明周期: (  构造方法、build   )比如:
        
                class MyApp extends StatelessWidget {

                  //构造函数
                  MyApp({Key key}) : super(key: key);

                  // This widget is the root of your application.
                  @override
                  Widget build(BuildContext context) {
                    return MaterialApp(
                      title: 'Flutter Demo',
                      theme: ThemeData(
                        primarySwatch: Colors.blue,
                      ),
                      home: MyHomePage(title: 'Flutter Demo Home Page'),
                    );
                  }
                }
            
            当然,StatelessWidget类里面的方法有:
            
                abstract class StatelessWidget extends Widget {

                  const StatelessWidget({ Key key }) : super(key: key);

                  @override
                  StatelessElement createElement() => StatelessElement(this);

                  @protected
                  Widget build(BuildContext context);
                  
                }
                
        二、StatefulWidget的声明周期:(构造方法、initState()、build()、setState()、didUpdateWidget()、build())
        
                class MyHomePage extends StatefulWidget {
                
                  //构造函数
                  MyHomePage({Key key, this.title}) : super(key: key);

                  //定义变量
                  final String title;

                  //生命周期函数
                  @override
                  _MyHomePageState createState() => _MyHomePageState();

                }
            
                class _MyHomePageState extends State {

                  @override
                  Widget build(BuildContext context) {
                
                }
        
3、flutter里有一个类似于gradle的文件     pubspec.yaml :

    官方文档介绍:https://book.flutterchina.club/chapter2/flutter_package_mgr.html?h=pubspec.yaml
    
    一个完整的应用程序往往会依赖很多第三方包,正如在原生开发中,Android使用Gradle来管理依赖,iOS用Cocoapods或Carthage来管理依赖,而Flutter也有自己的依赖管理工具,本节我们主要介绍一下flutter如何使用配置文件pubspec.yaml(位于项目根目录)来管理第三方依赖包。

    YAML是一种直观、可读性高并且容易被人类阅读的文件格式,它和xml或Json相比,它语法简单并非常容易解析,所以YAML常用于配置文件,Flutter也是用yaml文件作为其配置文件,Flutter项目默认的配置文件是pubspec.yaml
        
    需要注意的几个点:(pubspec.yaml)
    
        //依赖的第三方的包,等等,按照下面的格式来写;
    1》、dependencies:
          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.2
          
          ## 实现页面加载的loading库
          flutter_spinkit: "^3.1.0"
          
    2》、Flutter里面的依赖资源
        flutter:

          # The following line ensures that the Material Icons font is
          # included with your application, so that you can use the icons in
          # the material Icons class.
          uses-material-design: true

          # To add assets to your application, add an assets section, like this:
          # assets:
          #  - images/a_dot_burr.jpeg
          #  - images/a_dot_ham.jpeg

          assets:
            - images/beijing_log.png ##背景logo图
            - images/beijing.jpg ##背景图

        
    3》、在pubspec.yaml添加依赖包后,需要执行 get package 来获取依赖包资源
        
4、第一个页面,设置整个页面的背景图片:

    官方文档介绍图片添加:https://book.flutterchina.club/chapter3/img_and_icon.html
    
    1》、在工程的“根目录下”创建images文件夹里面放上要展示的图片:
    
              android--------------
              lib------------------
              ios------------------
              images---------------
                bg.jpg

    2》、首先在这里遇到一个坑,flutter加载图片时需要在: pubspec.yaml中声明图片的列表的比如:
    
            参考:https://www.jianshu.com/p/c6135bc044e4
    
              # To add assets to your application, add an assets section, like this:
              # assets:
              #  - images/a_dot_burr.jpeg
              #  - images/a_dot_ham.jpeg

              assets:
                - images/bg.jpg   #这个位置格式和图片全名称不能错

    3》、Scaffold(
      body: Container(
        decoration: BoxDecoration(
          image: DecorationImage(
            image: AssetImage("images/bg.jpg"),
            fit: BoxFit.cover,
          ),
        ),
        child: Center(
          child: Text('Hello Wolrd', style: TextStyle(fontSize: 22.0, color: Colors.white),),
        ),
      ),
    );

    参考:https://www.jianshu.com/p/69aaaa9ffe08
        
        
        
5、主题颜色的使用:

    1》、使用Dart的Color类里提供的颜色和对应的透明度值:
    
        new MaterialApp(
          title: title,
          theme: new ThemeData(
            brightness: Brightness.dark,
            primaryColor: Colors.lightBlue[800],//颜色值
            accentColor: Colors.cyan[600],//颜色值

          ),
        );
    
    2》、使用自定义的ARGB的格式:
    
        参考:https://blog.csdn.net/mengks1987/article/details/84819431 
    
        Color c = const Color(0xFF42A5F5);//16进制的ARGB
        Color c = const Color.fromARGB(0xFF, 0x42, 0xA5, 0xF5);
        Color c = const Color.fromARGB(255, 66, 165, 245);
        Color c = const Color.fromRGBO(66, 165, 245, 1.0);//opacity:不透明度

        new MaterialApp(
          title: title,
          theme: new ThemeData(
            brightness: Brightness.dark,
            primaryColor: const Color(0xFF42A5F5),//自定义颜色值
            accentColor: const Color(0xFF42A5F5),//自定义颜色值

          ),
        );

6、组件设置padding:

    https://book.flutterchina.club/chapter5/container.html

    child: Column(
        mainAxisAlignment: MainAxisAlignment.start,//内容从最上面开始
        children: [
          Padding(
            //顶部添加50像素补白
            padding: const EdgeInsets.only(top: 50.0),//left、top、right、bottom
            
            //图片组件
            child:  Image(
              image: AssetImage("images/beijing_log.png"),
              width: 300,
              height: 300,
            ),
          ),
          Text(
            'You have pushed the button this many times:',
          ),
        ],
      ),
      
      
7、容器添加margin的使用:

    https://book.flutterchina.club/chapter5/container.html

      body: Container(
        // 相当于直接制定了该Container的宽和高,且它的优先级要高于width和height
        constraints: new BoxConstraints.expand(width: 250.0, height: 150.0),
        margin: const EdgeInsets.all(10.0),//设置整个页面的margin边距值
        margin: const EdgeInsets.only(top: 50.0),//left、top、right、bottom  设置margin的边距值
      }
    
8、使用组件TextFiled软键盘弹出导致的bug

    【flutter 溢出BUG】 bottom overflowed by 113 PIXELS
    
    解决办法参考:https://blog.csdn.net/u012280292/article/details/81988886
    
    一开始直接使用Scaffold布局,body:new Column  然后结果调出键盘的时候就报这个错了,解决办法是使用SingleChildScrollView包装一下:
    
     body: Container(
        alignment: Alignment.topCenter,
        //设置登录页面背景图片
        decoration: BoxDecoration(
          image: DecorationImage(
            image: AssetImage("images/beijing.jpg"),
            fit: BoxFit.cover,
          ),),
        child: Center(
          child: new SingleChildScrollView(
            child: new ConstrainedBox(
              //约束布局
              constraints: new BoxConstraints(
                minHeight: 1000.0,//这个最小的高度一定要设置偏大一些,否则页面内容只有居中不能从顶部罗列组件布局
              ),

              child: new Column(
                mainAxisAlignment: MainAxisAlignment.start, //内容从最上面开始
                children: [
                  Padding(
                    //左边添加8像素补白
                    padding: const EdgeInsets.only(top: 10.0),
                    child: Image(
                      image: AssetImage("images/beijing_log.png"),
                      width: 280,
                      height: 280,
                      alignment: Alignment.topCenter,
                    ),
                  ),
                ],
              ),
            ),
          ),
        ),
      ),
9、flutter动态改变变量的内容,而改变VIEW Text的内容值,比如:

    StatefulWidget------------------------------------------------

      String  resultInfoShowText='111';//声明变量

      Text(resultInfoShowText),//使用变量
      
      OutlineButton(//点击按钮,改变变量的值,需要在setState里改变
        splashColor: const Color(0xFFFFFFFF),
        child: Text('按钮'),
        onPressed: () {
          
          setState(() {
            resultInfoShowText = '漠天';
          });

        },
      ),

10、页面StatefulWidget下的组件,抽出一部分单独处理,为了防止内容太多不好管理:

    //页面加载器,作为主页面
    class LoginPage extends StatefulWidget {
      //生命周期函数
      @override
      LoginPageState createState() => LoginPageState();
    }
    
    
    //主页面(就是类似于activity)
    class LoginPageState extends State {
      //密码控制器,设置监听用
      static TextEditingController pwdController=new TextEditingController();
      //账号控制器,设置监听用
      static TextEditingController nameController=new TextEditingController();
      //密码和账号的Container内容
      MainContentContainer _mainContentContainer = new MainContentContainer(nameController,pwdController);
      //账号密码结果
      String  resultName = '',resultPwd = '',resultInfoShowText='';

      @override
      void initState() {
        // TODO: implement initState
        super.initState();
        //设置账号监听(获取TextFiled的内容)
        nameController.addListener((){
          resultName = nameController.text;
          print(resultName);
        });

        //设置密码监听(获取TextFiled的内容)
        pwdController.addListener((){
          resultPwd = pwdController.text;
          print(resultPwd);
        });

      }

      @override
      Widget build(BuildContext context) {
        return Scaffold(
    //      appBar: new AppBar(
    //        title: Text('登录页面'),
    //      ),
          body: Container(
            alignment: Alignment.topCenter,
            //设置登录页面背景图片
            decoration: BoxDecoration(
              image: DecorationImage(
                image: AssetImage("images/beijing.jpg"),
                fit: BoxFit.cover,
              ),),
            child: Center(
              child: new SingleChildScrollView(
                child: new ConstrainedBox(
                  //约束布局
                  constraints: new BoxConstraints(
                    minHeight: 1000.0,//这个最小的高度一定要设置偏大一些,否则页面内容只有居中不能从顶部罗列组件布局
                  ),
                  child: new Column(
                    mainAxisAlignment: MainAxisAlignment.start, //内容从最上面开始
                    children: [
                      
                      _mainContentContainer,
                     
                    ],
                  ),
                ),
              ),
            ),
          ),
        );
      }
    }
    
    
    //抽出登录页面的账号密码部分(输入框内容的展示)
    class MainContentContainer extends Container {

      static TextEditingController nameController,pwdController;

       MainContentContainer(TextEditingController nameControllerFrom,TextEditingController pwdControllerFrom){
        nameController = nameControllerFrom;
        pwdController = pwdControllerFrom;
      }

      @override
      // TODO: implement margin
      EdgeInsetsGeometry get margin => new EdgeInsets.fromLTRB(50.0, 0, 50.0, 10.0);

      @override
      // TODO: implement child
      Widget get child =>
          new SingleChildScrollView(
              child: new ConstrainedBox(
                //约束布局
                  constraints: new BoxConstraints(
                    minHeight: 0.0,
                  ),
                  child: new Column(
                      children: [
                        TextField(
                          controller: nameController,
                          autofocus: true,
                          decoration: InputDecoration(
                              labelText: "用户名",
                              hintText: "用户名或邮箱",
                              prefixIcon: Icon(Icons.person),
                          ),
                          obscureText: true,
                          style: TextStyle(color: const Color(0xFFFFFFFF)) ,
                          cursorColor: const Color(0xFFFFFFFF),
                        ),
                        TextField(
                          controller: pwdController,
                          decoration: InputDecoration(
                              labelText: "密码",
                              hintText: "您的登录密码",
                              prefixIcon: Icon(Icons.lock),
                          ),
                          obscureText: true,
                          style: TextStyle(color: const Color(0xFFFFFFFF)) ,
                          cursorColor: const Color(0xFFFFFFFF),
                        ),
                      ])
              )
          );
    }

11、flutter设置控件组件的宽度全屏:

    由于flutter的button不支持直接设置width和height所以可以通过Container来实现,也可以通过padding来实现,参考:https://juejin.im/post/5b85f1de6fb9a01a0f24a233

    width: double.infinity,
    height: double.infinity
    
    //登录按钮
      new Container(
        height: 40.0,
        width: double.infinity,
        margin:EdgeInsets.only(left: 50.0,top: 20.0,right: 50.0,bottom: 0.0),
        child: OutlineButton(
          borderSide: BorderSide(color: const Color(0xFFFFFFFF),width: 1.0,style: BorderStyle.solid),
          child: Text('登录'),
          onPressed: () {
    
          },
        ),
      ),
    
12、flutter的TextFiled组件的基本使用:

    参考:https://book.flutterchina.club/chapter3/input_and_form.html
    
    
    TextField(
      controller: nameController,
      focusNode: nameFocusNode,
      autofocus: true,
      maxLength: 11,
      keyboardType: TextInputType.phone,
      decoration: InputDecoration(
        labelText: "用户名",
        hintText: "用户名或邮箱",
        prefixIcon: Icon(Icons.person),
        hintStyle: TextStyle(color: Colors.green, fontSize: 13.0),
        border: InputBorder.none,//隐藏下划线
      ),
      obscureText: true,
    ),

13、android studio,使用flutter开发,冷启动优化的处理:

    1》、flutter工程,对android studio已经做过处理的;在style.xml里:
    
    
        
        
            

        
        
    2》、在对应的 launch_background.xml里:
    
        
        
        
            
            
        

    3》、在纯android原生的项目里,对冷启动的优化:
        
        https://blog.csdn.net/u010326875/article/details/88852940
        
14、flutter里,Map键值对的使用:

     Map paramsMap = {"username":name,"password":pwd};
     
     
15、flutter里面loading的实现:

    参考提供的库:https://pub.flutter-io.cn/packages/flutter_spinkit
    
    
    1》、Installing 
          dependencies://在pubspec.yawl文件添加
          flutter_spinkit: "^3.1.0"
          
          eg:dependencies:
                  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.2
                  
                  ## 实现页面加载的loading库
                  flutter_spinkit: "^3.1.0"
            
          
    2》、Import
        import 'package:flutter_spinkit/flutter_spinkit.dart';
        
    3》、使用
        SpinKitRotatingCircle(
          color: Colors.white,
          size: 50.0,
        );
        
        
    我这边的使用:
    
        https://blog.csdn.net/u010326875/article/details/88976789
        
16、flutter让组件在最上层展示,比如:loading弹框

    flutter有提供stack布局来管理展示层级:
    
    child: Center(
          child:new Stack(
            children: [
                Image,//背景图片
                new SpinKitHourGlass(color: Colors.blueAccent, size: 30.0,),//loading控件
            ]
          )
        )
    
17、请求接口,访问网络:

    1》、以登录接口为例,测试:
    
        参考官方文档:https://book.flutterchina.club/chapter10/http.html    使用基础的HttpClient实现post请求接口:
        
          //+++++++++++++++++++++++++++++++++++  请求登录接口  +++++++++++++++++++++++++++++++++++++++++++++++++++++

          try {
            //创建一个HttpClient
            HttpClient httpClient = new HttpClient();
            Uri uri=Uri(scheme: "https", host: "www.zgjdy.cn", path: "/entrance/mobile_login");
            //打开Http连接
            HttpClientRequest request = await httpClient.postUrl(uri);
            Map paramsMap = {
              "username":name,
              "password":pwd
            };
            request.add(utf8.encode(json.encode(paramsMap)));
            //等待连接服务器(会将请求信息发送给服务器)
            HttpClientResponse response = await request.close();
            //读取响应内容
            String result = await response.transform(utf8.decoder).join();
            setState(() {
              resultInfoShowText = result;
            });
            //关闭client后,通过该client发起的所有请求都会中止。
            httpClient.close();
          } catch (e) {
            resultInfoShowText = "请求失败:$e";
          } finally {
            setState(() {
              isShowLoading=false;
            });
          }

          //++++++++++++++++++++++++++++++++++  请求登录接口 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
        
    2》、Flutter 网络请求的三种简单实现,

参考:https://blog.csdn.net/weixin_33955681/article/details/88294968  (这篇帖子比较详细,也挺简单)
    
       

 

第一个登录页面+HttpClient调用登录接口demo源码:https://download.csdn.net/download/u010326875/11082948

 

 

你可能感兴趣的:(flutter)