美文网首页
弹性盒子布局、状态管理、项目搭建

弹性盒子布局、状态管理、项目搭建

作者: 浅墨入画 | 来源:发表于2021-11-21 13:13 被阅读0次

    Stack布局

    继续上篇文章弹性盒子布局进行学习,这一篇我们主要是探索Stack层叠布局

    Stack层叠样式 与 Positioned配合使用

    Stack是多层布局,主轴方向是从内向外。
    Positioned小部件有leftrighttopbottom四个属性定位,参数是像素位置。

    • layout_demo.dart文件添加如下代码
    import 'package:flutter/material.dart';
    
    class LayoutDemo extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return StackDemo();
      }
    }
    
    class StackDemo extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Container(
          color: Colors.yellow,
          alignment: const Alignment(0, -1),
          child: Stack(
            children: [
              //Positioned 绝对定位
              Positioned(
                child: Container(
                  color: Colors.white,
                  width: 200,
                  height: 200,
                  child: const Icon(Icons.add),
                ),
              ),
              Positioned(
                child: Container(
                  color: Colors.red,
                  width: 100,
                  height: 100,
                  child: const Icon(Icons.search_off),
                ),
                left: 0,
              ),
              Positioned(
                child: Container(
                  color: Colors.blue,
                  width: 50,
                  height: 50,
                  child: const Icon(Icons.search),
                  // margin: EdgeInsets.only(right: 20),
                ),
                right: 0,
                // right: 20,
              ),
            ],
          ),
        );
      }
    }
    
    运行效果
    AspectRatio用来影响父部件宽高

    AspectRatio的设置影响的是父布局,当父布局同时有宽度和高度,设置宽高比失效

    • 使用AspectRatio宽高比,只给Container小部件设置height,会按照比例自动生成高度
    import 'package:flutter/material.dart';
    
    class LayoutDemo extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        // TODO: implement build
        return Container(
          color: Colors.yellow,
          width: 300,
          height: 300,
          alignment: const Alignment(0, 0),
          child: Container(
            //属性:child
            color: Colors.blue,
            height: 150,
            child: const AspectRatio(
              aspectRatio: 1 / 1,
            ),
          ),
        );
      }
    }
    
    运行效果
    • Container小部件同时设置widthheight,再设置AspectRatio宽高比将无效
    import 'package:flutter/material.dart';
    
    class LayoutDemo extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        // TODO: implement build
        return Container(
          color: Colors.yellow,
          width: 300,
          height: 300,
          alignment: const Alignment(0, 0),
          child: Container(
            //属性:child
            color: Colors.blue,
            height: 150,
            width: 200,
            child: const AspectRatio(
              aspectRatio: 1 / 1,
            ),
          ),
        );
      }
    }
    
    运行效果

    Flutter的Widget状态管理

    flutter中小部件大都是无状态的,如果小部件有变化,就需要改变其状态,下面自定义一个有状态的小部件
    StatefulWidget有状态小部件,用于对外提供接口,继承自State用来管理状态;需实现build方法访问数据,数据在state中,通过setState设置/改变数据。
    有状态的Widget,需要把渲染逻辑数据逻辑分开,并且保留数据逻辑。

    • 新建state_mag_demo.dart文件
    import 'package:flutter/material.dart';
    
    //渲染逻辑,仍然是不可变的!!
    class StateManagerDemo extends StatefulWidget {
      @override
      // 创建数据管理对象
      State<StatefulWidget> createState() => _SMDState();
    }
    
    //状态管理者,State<StateManagerDemo>表示用于管理StateManagerDemo
    //_SMDState表示私有类,只在当前文件内可用
    class _SMDState extends State<StateManagerDemo> {
      int count = 0;
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          debugShowCheckedModeBanner: false,
          home: Scaffold(
            backgroundColor: Colors.grey[100],
            appBar: AppBar(
              title: const Text('StateDemo'),
            ),
            body: Center(
              // Chip气泡小部件
              child: Chip(
                label: Text('$count'),
              ),
            ),
            // 添加悬浮按钮
            floatingActionButton: FloatingActionButton(
              child: const Icon(Icons.add),
              onPressed: () {
                //实时设置count数据,用于页面刷新。调用一次setState相当于调用一次build方法,因为flutter是增量渲染,所以只会执行Text('$count'),效率会很高
                //setState影响的是build方法内所有与count相关的地方,可能会是多个
                setState(() {
                  count += 1;
                });
                print("count = $count");
              },
            ),
          ),
        );
      }
    }
    
    • main.dart文件中调用StateManagerDemo()
    import 'package:flutter/material.dart';
    import 'package:hello_flutter/state_mag_demo.dart';
    
    void main() => runApp(App());
    
    class App extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        // TODO: implement build
        return StateManagerDemo();
      }
    }
    
    运行效果

    搭建项目

    Flutter基础组件以及用法我们已经学完了,下面我们来搭建一个微信项目,通过这个项目,我们在实战中学习网络多线程

    • 新建一个flutter工程,名称为wechat_demo
    • 创建工程底部BottomNavigationBar
    <!-- main.dart文件 -->
    import 'package:flutter/material.dart';
    
    void main() {
      runApp(App());
    }
    
    class App extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        // TODO: implement build
        return MaterialApp(
          home: MyHomePage(),
        );
      }
    }
    
    class MyHomePage extends StatelessWidget {
    
      int _currentIndex = 0;
    
      @override
      Widget build(BuildContext context) {
        // TODO: implement build
        return Container(
          child: Scaffold(
            bottomNavigationBar: BottomNavigationBar(
              //BottomNavigationBarItem 三个的话,默认选中是蓝色,四个的话变成了白色,所以这里要加type属性修改样式
              type: BottomNavigationBarType.fixed,
              //BottomNavigationBarItem 选中颜色修改
              fixedColor: Colors.green,
              //currentIndex 修改选中的BottomNavigationBarItem 默认是0
              currentIndex: _currentIndex,
              items: const [
                BottomNavigationBarItem(icon: Icon(Icons.chat), label: '微信'),
                BottomNavigationBarItem(icon: Icon(Icons.bookmark), label: '通讯录'),
                BottomNavigationBarItem(icon: Icon(Icons.history), label: '发现'),
                BottomNavigationBarItem(icon: Icon(Icons.person_outline), label: '我的'),
              ],
            ),
          ),
        );
      }
    }
    
    运行效果
    • 新建根页面root_page.dart,并且把main.dart文件中代码迁移过来
    <!-- root_page.dart文件 -->
    import 'package:flutter/material.dart';
    
    class RootPage extends StatefulWidget {
      @override
      _RootPageState createState() => _RootPageState();
    }
    
    class _RootPageState extends State<RootPage> {
      int _currentIndex = 0;
    
      @override
      Widget build(BuildContext context) {
        // TODO: implement build
        return Container(
          child: Scaffold(
            bottomNavigationBar: BottomNavigationBar(
              //BottomBar点击事件
              onTap:(index) {
                setState(() {
                  _currentIndex = index;
                });
              },
    
              //BottomNavigationBarItem 三个的话,默认选中是蓝色,四个的话变成了白色,所以这里要加type属性修改样式
              type: BottomNavigationBarType.fixed,
              //BottomNavigationBarItem 选中颜色修改
              fixedColor: Colors.green,
              //currentIndex 修改选中的BottomNavigationBarItem 默认是0
              currentIndex: _currentIndex,
              items: const [
                BottomNavigationBarItem(icon: Icon(Icons.chat), label: '微信'),
                BottomNavigationBarItem(icon: Icon(Icons.bookmark), label: '通讯录'),
                BottomNavigationBarItem(icon: Icon(Icons.history), label: '发现'),
                BottomNavigationBarItem(icon: Icon(Icons.person_outline), label: '我的'),
              ],
            ),
          ),
        );
      }
    }
    
    <!-- main.dart文件 -->
    import 'package:flutter/material.dart';
    import 'package:wechat_demo/root_page.dart';
    
    void main() {
      runApp(App());
    }
    
    class App extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        // TODO: implement build
        return MaterialApp(
          home: RootPage(),
        );
      }
    }
    
    运行效果
    • 新建 微信 - chat_page.dart、通讯录 - friends_page.dart、发现 - discover_page.dart、我的 - mine_page.dart页面
    <!-- chat_page.dart文件 -->
    import 'package:flutter/material.dart';
    
    class ChatPage extends StatefulWidget {
      @override
      _ChatPageState createState() => _ChatPageState();
    }
    
    class _ChatPageState extends State<ChatPage> {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: const Text('微信页面'),
          ),
          body: const Center(
            child: Text('微信页面'),
          ),
        );
      }
    }
    
    <!-- friends_page.dart文件 -->
    import 'package:flutter/material.dart';
    
    class FriendsPage extends StatefulWidget {
      @override
      _FriendsPageState createState() => _FriendsPageState();
    }
    
    class _FriendsPageState extends State<FriendsPage> {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: const Text('通讯录'),
          ),
          body: const Center(
            child: Text('通讯录'),
          ),
        );
      }
    }
    
    <!-- discover_page.dart文件 -->
    import 'package:flutter/material.dart';
    
    class DiscoverPage extends StatefulWidget {
      @override
      _DiscoverPageState createState() => _DiscoverPageState();
    }
    
    class _DiscoverPageState extends State<DiscoverPage> {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: const Text('发现页面'),
          ),
          body: const Center(
            child: Text('发现页面'),
          ),
        );
      }
    }
    
    <!-- mine_page.dart文件 -->
    import 'package:flutter/material.dart';
    
    class MinePage extends StatefulWidget {
      @override
      _MinePageState createState() => _MinePageState();
    }
    
    class _MinePageState extends State<MinePage> {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: const Text('我的页面'),
          ),
          body: const Center(
            child: Text('我的页面'),
          ),
        );
      }
    }
    
    • root_page.dart中引入上面创建的四个页面
    import 'package:flutter/material.dart';
    import 'package:wechat_demo/chat_page.dart';
    import 'package:wechat_demo/discover_page.dart';
    import 'package:wechat_demo/friends_page.dart';
    import 'package:wechat_demo/mine_page.dart';
    
    class RootPage extends StatefulWidget {
      @override
      _RootPageState createState() => _RootPageState();
    }
    
    class _RootPageState extends State<RootPage> {
      int _currentIndex = 0;
      //配置四个页面
      List <Widget> _pages = [ChatPage(), FriendsPage(), DiscoverPage(), MinePage()];
      @override
      Widget build(BuildContext context) {
        // TODO: implement build
        return Container(
          child: Scaffold(
            // 选中BottomBar配置body页面
            body: _pages[_currentIndex],
            bottomNavigationBar: BottomNavigationBar(
              //BottomBar点击事件
              onTap:(index) {
                setState(() {
                  _currentIndex = index;
                });
              },
    
              //BottomNavigationBarItem 三个的话,默认选中是蓝色,四个的话变成了白色,所以这里要加type属性修改样式
              type: BottomNavigationBarType.fixed,
              //BottomNavigationBarItem 选中颜色修改
              fixedColor: Colors.green,
              //currentIndex 修改选中的BottomNavigationBarItem 默认是0
              currentIndex: _currentIndex,
              items: const [
                BottomNavigationBarItem(icon: Icon(Icons.chat), label: '微信'),
                BottomNavigationBarItem(icon: Icon(Icons.bookmark), label: '通讯录'),
                BottomNavigationBarItem(icon: Icon(Icons.history), label: '发现'),
                BottomNavigationBarItem(icon: Icon(Icons.person_outline), label: '我的'),
              ],
            ),
          ),
        );
      }
    }
    
    运行效果
    水波纹、标题头、选中字体大小属性配置
    • title属性:用于安卓设备 退出后台顶部显示app名称
    • highlightColor属性splashColor属性:用于取消水波纹效果
    • primarySwatch属性:用于设置NaviBar主题色
    <!-- main.dart文件 -->
    class App extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        // TODO: implement build
        // MaterialApp类似于iOS中 UIApplicationMain
        return MaterialApp(
          // title用于安卓设备 退出后台顶部显示app名称
          title: 'WeChatDemo',
          theme: ThemeData(
            // 去掉水波纹效果
            highlightColor: Color.fromRGBO(1, 0, 0, 0.0),
            splashColor: Color.fromRGBO(1, 0, 0, 0.0),
            // 设置NavigationBar主题色,全局有效
            primarySwatch: Colors.grey,
          ),
          home: RootPage(),
        );
      }
    }
    
    • selectedFontSize属性:用于设置BottomBar选中字体大小
    <!-- root_page.dart文件 -->
    class _RootPageState extends State<RootPage> {
      int _currentIndex = 0;
      //配置四个页面
      List <Widget> _pages = [ChatPage(), FriendsPage(), DiscoverPage(), MinePage()];
      @override
      Widget build(BuildContext context) {
        // TODO: implement build
        return Container(
          child: Scaffold(
            body: _pages[_currentIndex],
            bottomNavigationBar: BottomNavigationBar(
              // 设置BottomBar选中字体大小
              selectedFontSize: 22.0,
    
    运行效果

    本地资源文件

    这里主要是学习Android的资源配置,下面图中的label用于展示工程名,icon展示项目图标,ic.lanucher不用添加.png后缀

    安卓资源配置

    Android里面的图片资源没有@2x@3x@4x的概念,安卓里面是mipmap-hdpimipmap-xhdpi等类型。
    其中xhdpi等价于iOS中的@2x图片资源,
    xxhdpi等价于@3x
    xxxhdpi等价于@4x
    mdpi等价于@1.5x
    hdpi等价于@1.0x
    v21等价于@0.75x

    安卓图片资源类型
    安卓icon图片引用

    下面把AppIcon60x60@2x.png资源放入mipmap-xhdpi目录下,注意图片资源不能使用驼峰命名,这里改成了app_icon.png,而且图片资源不能拖入目录,需要复制粘贴到目录

    安卓配置图片资源
    安卓启动图片引用

    安卓启动图片在launch_background.xml文件中配置,需要把<item> <bitmap android:gravity="center" android:src="@mipmap/launch_image" /> </item> 注释放开,推荐把启动图片放入-hdpi目录下,不需要添加.png后缀

    安卓启动图片配置
    项目图片资源引用
    • 把图片资源放入images目录,直接把目录粘贴到flutter项目中

      flutter导入图片资源
    • pubspec.yaml文件中配置,该文件不止可以配置图片资源,引入的三方库也在这里配置。下面三行注释放开

    截屏2021-11-21 下午1.00.50.png

    注意⚠️:注释放开之后,assets一定要与上面uses-material-design: true左对齐,pubspec.yaml文件对格式要求很严格

    image.png
    • flutter工程使用图片资源
    BottomNavigationBarItem(
                    // 默认图标
                    icon:  Image(
                        height: 20,
                        width: 20,
                        image: AssetImage('images/badge.png')
                    ),
                    // 选中图标
                    activeIcon: Image(
                        height: 20,
                        width: 20,
                        image: AssetImage('images/badgeSelect.png')
                    ),
                    label: '微信'),
    
    解决 Gradle 卡住问题

    那么在首次运行的时候, 你会发现卡在如下的地方了, 原因是GradleMaven仓库在国外......然后你就懂了.

    Running Gradle task 'assembleDebug'
    

    解决它比较简单的操作就是镜像, 配置如下:

    1. 修改项目下的build.gradle文件
    • 文件路径: 项目 -> Android -> build.gradle
    • 修改内容: 找到buildscriptallprojects, 将里边 google()jcenter()(新版本是 mavenCentral()) 注释掉, 添加阿里云的镜像
    maven { url 'https://maven.aliyun.com/repository/google' }
    maven { url 'https://maven.aliyun.com/repository/jcenter' }
    maven { url 'http://maven.aliyun.com/nexus/content/groups/public' }
    
    image.png
    1. 修改flutter 安装目录中的 flutter.gradle文件
    • 文件路径: ~/flutter/packages/flutter_tools/gradle/flutter.gradle
    • 修改内容: buildscript 加入阿里镜像
    buildscript {
        repositories {
            //google()
            //mavenCentral()
            maven { url 'https://maven.aliyun.com/repository/google' }
            maven { url 'https://maven.aliyun.com/repository/jcenter' }
            maven { url 'http://maven.aliyun.com/nexus/content/groups/public' }
        }
        dependencies {
            classpath 'com.android.tools.build:gradle:4.1.0'
        }
    }
    

    相关文章

      网友评论

          本文标题:弹性盒子布局、状态管理、项目搭建

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