美文网首页
Flutter记录

Flutter记录

作者: Ocean_e553 | 来源:发表于2020-09-27 17:16 被阅读0次

一.导航
1.导航栏按钮设置

    Scaffold(
      appBar: AppBar(
        title: Text("导航栏标题"),
        centerTitle: true, // 设置多个actions时, 标题会靠左边, 设置此熟悉标题会居中
        actions: [ // 设置右边的 items
          IconButton(icon: Icon(Icons.near_me), onPressed: null),
          IconButton(icon: Icon(Icons.near_me), onPressed: null),
        ],
        automaticallyImplyLeading: false, // 默认是系统自动实现左边的item实现导航跳转, 当页面需要手动控制时, 使用下面3个熟悉来调整
        leadingWidth: 60,
        leading: Icon(Icons.arrow_back),
      ),
      body: Center(
        child: Text("内容")
      ),
    )

2.怎么present一个界面
使用fullscreenDialog实现

Navigator.of(context).push(MaterialPageRoute(fullscreenDialog: true, builder: (context){
   return ThePresentedPage(); // 需要present出来的界面
}));

二.布局
1. 使用ListView时使用ListTile, 但是title和leading默认的距离太大, 调整他们之间的距离
使用transform属性调整leading的位置. 另外可以自定义cell

ListTile(
 title: Transform(transform: Matrix4.translationValues(-20, 0, 0), child: Text("退出")),
 leading: Icon(Icons.exit_to_app),
 trailing: Icon(Icons.navigate_next),
 onTap: (){print("logout")},
)

2. alignment实现(垂直居中, 水平左对齐)

alignment.png

来源: https://www.jianshu.com/p/a675b4d66a93

3.根据传入的动态数组创建一组widget

  _buildStatusRow(String type, String status, List<String> infos) {
    List<Widget> infoWidgets = [];
    for (var info in infos) {
      var oneInfoW = Container(
          margin: EdgeInsets.only(left: 5),
          padding: EdgeInsets.only(left: 5, right: 5),
          decoration: BoxDecoration(
              border: Border.all(color: Colors.black12, width: 0.5),
              borderRadius: BorderRadius.circular(4)),
          child: Text(
            "$info",
            style: TextStyle(fontSize: 12),
          ));
      infoWidgets.add(oneInfoW);
    }

    List<Widget> rowChildren = [
      Text("$type:"),
      Container(width: 5),
      ClipRRect(
          borderRadius: BorderRadius.only(
              topLeft: Radius.circular(6), bottomRight: Radius.circular(6)),
          child: Container(
              padding: EdgeInsets.only(left: 5, right: 5),
              color: Colors.orangeAccent,
              child: Text(
                status,
                style: TextStyle(color: Colors.white, fontSize: 13, height: 1.5),
              ))),
    ];

    rowChildren.addAll(infoWidgets);

    return Container(
        margin: EdgeInsets.only(bottom: 3), child: Row(children: rowChildren));
  }

4.兄弟widget有重叠时,使用Stack布局

5.ListView显示scroll indicator
将ListView包裹在Scrollbar里面

  @override
  Widget build(BuildContext context) {
    return Scrollbar(
          child: ListView.builder(
            itemCount: 50,
            itemBuilder: (context, index) {
                return ListTile();
          })
        );
  }

6.监听app的生命周期
生命周期共4种, 分别是: resumed(从后台进入前台)、inactive(即将进入后台和进入前台之前, 例如iOS app在前台, 双击home键时的状态)、paused(进入后台)、detached
如果还需要其它事件,则可以用EventChannel实现

class _HomePageState extends State<HomePage> with WidgetsBindingObserver {
 
  @override
  void dispose() {
    super.dispose();
    WidgetsBinding.instance.removeObserver(this);
  }
 
  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addObserver(this);
  }
 
  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    print(state);
  }
 
}

7.flutter键盘弹出,遮挡界面
问题:在登录注册界面会有输入框, 键盘弹出时会遮挡输入框.
解决:在原生iOS开发中, 会监听键盘弹出和隐藏事件, 然后改变界面布局. 我们使用相同的处理方法在flutter中进行处理

class _LoginPageState extends State<LoginPage> with WidgetsBindingObserver {

  var _username = "";
  var _pwd = "";

  var _keyboardH = 0.0;

  // 1.监听键盘事件
  @override
  void initState() {
    super.initState();
    
    _username = LoginInfoMgr.sharedMgr.username;
    _pwd = LoginInfoMgr.sharedMgr.pwd;

    WidgetsBinding.instance.addObserver(this);
  }

  @override
  void dispose() {
    // TODO: implement dispose
    super.dispose();

    WidgetsBinding.instance.removeObserver(this);
  }

  @override
  void didChangeMetrics() {
    // TODO: implement didChangeMetrics
    print("did changemetrics");
    super.didChangeMetrics();
    WidgetsBinding.instance.addPostFrameCallback((_) {
      double bottom = MediaQuery.of(context).viewInsets.bottom;
      if(bottom == 0){
        //关闭键盘
        print("close");
        setState(() {
          _keyboardH = 0.0;
        });
      }else{
        //显示键盘
        print("show - $bottom");
        setState(() {
          _keyboardH = bottom;
        });
      }
    });
  }


  // 2.根据键盘高度调整布局
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      resizeToAvoidBottomPadding: false, // 需要设置为false, 保证widget不变形
      appBar: AppBar(
        title: Text("登录"),
      ),
      backgroundColor: Colors.lightBlueAccent,
      body: Stack(
        children: [
          _buildTopContainer(),
          _buildBottomContainer()
        ]
      ),
    );
  }

  _buildTopContainer() {
    return GestureDetector(
      onTap: () {FocusScope.of(context).requestFocus(FocusNode());},
      child: Container(
        width: MediaQuery.of(context).size.width,
        height: 200,
        color: Colors.lightBlueAccent,
        child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            crossAxisAlignment: CrossAxisAlignment.center,
            children: [
              Icon(Icons.settings_bluetooth, size: 55, color: Colors.white70),
              Container(
                  margin: EdgeInsets.only(top: 15),
                  child: Text(
                    "app名字",
                    style: TextStyle(color: Colors.white70, fontSize: 16),
                  )),
            ]),
      ),
    );
  }

  
  // 根据键盘高度, 调整下面container的位置
  _buildBottomContainer() {
    var marginTop = 200 - _keyboardH/6;
    marginTop = marginTop < 0 ? 0 : marginTop;
    return Container(
        margin: EdgeInsets.only(top: marginTop),
        height: MediaQuery.of(context).size.height - 200,
        child: ClipRRect(
      borderRadius: BorderRadius.only(topLeft: Radius.circular(30), topRight: Radius.circular(30)),
      child: Container(
        color: Colors.white,
        child: Column(children: [
          Container(
              margin: EdgeInsets.only(left: 20, right: 20, top: 35),
              child: TextField(
                controller: TextEditingController(text: _username),
                decoration: InputDecoration(
                    hintText: "用户名", icon: Icon(Icons.account_balance)),
                onChanged: (value) {
                  _username = value;
                },
              )),
          Container(
              margin: EdgeInsets.only(left: 20, right: 20, top: 10),
              child: TextField(
                controller: TextEditingController(text: _pwd),
                obscureText: true,
                decoration: InputDecoration(hintText: "密码", icon: Icon(Icons.security),),
                onChanged: (value){
                  _pwd = value;
                },
              )),
          Expanded(
              child: Center(
                  child: Container(
                      width: MediaQuery.of(context).size.width * 0.7,
                      height: 45,
                      child: ClipRRect(
                        borderRadius: BorderRadius.all(Radius.circular(22.5)),
                        child: RaisedButton(
                          color: Colors.lightBlueAccent,
                          textColor: Colors.white,
                          child: Text("登录"), 
                          onPressed: _doLogin
                        )
                      )
          ))),
        ]),
      ),
    ));
  }
}

8.flutter Tab搭建

import 'package:flutter/material.dart';

class TabCtlPage extends StatefulWidget {

  @override
  State<StatefulWidget> createState() => _TabCtlPageState();

}

class _TabCtlPageState extends State<TabCtlPage> {

  var _pageController = PageController();
  var _currentIdx = 0;

  _changedIndex(index) {
    print("index = $index");
    if (_currentIdx == index) {
      print("return");
      return;
    }
    _pageController.jumpToPage(index);
    setState(() {
      _currentIdx = index;
    });
  }

  var _pages = List<Widget>();

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    _pages = [
      HomePage(),
      MinePage()
    ];
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: PageView(
        physics: NeverScrollableScrollPhysics(),
        controller: _pageController,
        children: _pages,
      ),
      bottomNavigationBar: BottomNavigationBar(
        items: [
          BottomNavigationBarItem(icon: Icon(Icons.hearing), title: Text("首页")),
          BottomNavigationBarItem(icon: Icon(Icons.settings), title: Text("我的")),
        ],
        onTap: _changedIndex,
        currentIndex: _currentIdx,
      ),
    );
  }
  
}

相关文章

网友评论

      本文标题:Flutter记录

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