uniquejava / blog

My notes regarding the vibrating frontend :boom and the plain old java :rofl.
Creative Commons Zero v1.0 Universal
11 stars 5 forks source link

flutter notes #291

Open uniquejava opened 4 years ago

uniquejava commented 4 years ago

Column

高度是 max available height

ListView

ListView 是 Column 的 scrollable 版本, 他的高度是 infinite

不能把 ListView 直接放进 Column

必须给 ListView 限制高度, 比如包裹一层 height=300 的 container

  1. ListView(children:[])
  2. ListView.builder()

注册需要传参的函数

// TextField 需要传参, 但是不用
onSubmitted: (_) => submitData()

// Button 不需要传参
onPressed: submitData

保留两位小数

double.toStringAsFixed(2)

actionSheet

// 包装一层GestureDector的原因是阻止 sheet 点击时 自动 隐藏
showModalBottomSheet(context: ctx, builder: (bCtx)=>
  GestureDetector(onTap: (){}, child: Widget, behavior: HitTestBehavior.opaque))

FittedBox(child: Text('long text'))

缩小文字以避免折行

FractionallySizedBox(heightFactor: 0.7)

大小为父容器的 70%

Expanded / Flexible

作为 Column、Row 的子元素

Flexible(fit: FlexFit.loose) 默认值

Flexible(fit: FlexFit.tight) tight 表示此元素不能占用或挤压兄弟元素的空间

Expanded(flex:1) = Flexible(fit: FlexFit.tight, flex: 1)

Expanded: 按照 flex 的值(默认=1) 占用尽可能多的剩余空间

Responsive

screen 的高度: MediaQuery.of(context).size.height statusBar 的高度 MediaQuery.of(context).padding.top appBar 的高度:appBar.preferredSize.height (或 kToolbarHeight)

parent 的高度:LayoutBuilder(build:(ctx, constraints)=>Widget(height: constraint.maxHeight))

键盘弹出时不要向上推屏幕

Scaffold(
  backgroundColor: Colors.transparent,
  resizeToAvoidBottomPadding: false,

移除 TextField 默认的 padding

InputDecoration(
  isDense: true,
  contentPadding: EdgeInsets.symmetric(horizontal: 24, vertical: 12),

椭圆形 button

MaterialButton(
  onPressed: _submit,
  shape: StadiumBorder()
)

去掉 tabview 的侧滑切屏功能

TabBarView(
 physics: NeverScrollableScrollPhysics(),
 controller: tabcontroler,
 children: <Widget>[]
)

向 ListView.builder 里添加固定项

https://stackoverflow.com/a/59517826/2497876

在出现键盘的页面慎用 MediaQuery

在 build 方法中 final mq = MediaQuery.of(context);

此时键盘的 show/hide 都会导致 build 方法被重复调用!

见:https://github.com/flutter/flutter/issues/37878

解决办法: 在首屏的 build 方法中将 screen size 提前保存下来。 可以借助 flutter_screenutil 插件

flutter_screenutil 插件

  1. 在首屏 login 的 build 方法中初始化 ScreenUtil.init(context);
  2. ScreenUtil.screenHeightDp 对应 mq.size.height
  3. ScreenUtil.statusBarHeight 对应 mq.padding.top
  4. 示例:

    final tabsPanelHeight = ScreenUtil.screenHeightDp - ScreenUtil.statusBarHeight - kToolbarHeight - 58;

Stack 中也可以使用 Align 对齐, 不用 Positioned

Stack(
  children: <Widget>[
    Align(alignment:, child:)
  ]
)

监听 swipe right 事件

GestureDetector(onPanUpdate: (details) {
  if (details.delta.dx > 0) {
    // swiping in right direction
  }
});

以编程的方式打开 drawer

GlobalKey<ScaffoldState> _drawerKey = GlobalKey();

@override
Widget build(BuildContext context) {
  return Scaffold(
    key: _drawerKey,
    drawer: Drawer(),

    //
    onPanUpdate: () {
      if (!_drawerKey.currentState.isDrawerOpen) {
        // open drawer if this value is true
        _drawerKey.currentState.openDrawer();
      }
    },
  );
}

不传context 怎么打开dialog

https://stackoverflow.com/questions/56280736/alertdialog-without-context-in-flutter

https://www.reddit.com/r/Flutter/comments/fiky2t/show_alert_without_context/

The reason an Alert needs the BuildContext in order to display is that the alert is a generalized dialog box that is essentially another Route that is displayed in the Navigation Stack. You can potentially get around this by having a direct reference to the Navigator itself. However, a

uniquejava commented 4 years ago

风格

null

According to the Dart style guide, you should avoid explicitly assigning objects to null (see http://mng.bz/om52).

comment

 // Inline comments

/*
Blocks of comments. It's not convention to use block comments in Dart. 
*/

/// Documentation
///
/// This is what you should use to document your classes.

Null-aware operator

dart中没有基本类型, 所有类型的默认值都是null

image

this.userAge = user?.age;  // 如果user为null, 则userAge也赋值为null
this.userAge = user.age ?? 18  // 如果user.age为null, 则userAge赋值为18
int x = 5
x ??= 3;  // 如果x的值为null, 则给他赋值为3, 如果不为null, 则保持原值不变
uniquejava commented 4 years ago

setState() or markNeedsBuild() called during build

https://stackoverflow.com/questions/51493737/adding-overlayentry-in-flutter