Open15

Flutterの整理

YHYH

FutureBuilderとStreamBuilderの違い

  • FutureBuilderはデータを1度取得し、その取得の中でのウィジェットの変化を表す

  • StreamBuilderはデータを常に監視(常に取得)し、その取得の中でのウィジェットの変化を表す

YHYH

VerticalDividerが消えることがある

Rowでラップしているだけなら表示されるが、更にColumnでラップするとVerticalDividerは表示されなくなる。

理由:
VerticalDividerは親ウィジェットから高さの制約を受ける必要がある。
Rowの場合には自身の高さを子ウィジェットに制約として伝えるが、ColumnでRowをラップした場合に、Columnが垂直方向に可能な限りスペースを取る仕様によりRowの高さの制約がなくなり、それを受けたVerticalDividerが高さの制約がなくなり表示されなくなる。

対応策:
RowにSizedBoxやContainerなどを用いて高さの制約を与え、その上からColumnでラップする

YHYH

StatefulBuilderってなに?

簡潔に言うと、setStateをDialogやBottomSheetで使えるようにするもの

以下簡単な例

import 'package:flutter/material.dart';

void main() {
 runApp(MaterialApp(
    home: MyApp(),
  ));
}

class MyApp extends StatelessWidget {
  
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('StatefulBuilder Example'),
        ),
        body: Center(
          child: ElevatedButton(
            child: Text('Show Dialog'),
            onPressed: () {
              showDialog(
                context: context,
                builder: (BuildContext context) {
                  int selectedValue = 1;
                  return StatefulBuilder(
                    builder: (BuildContext context, StateSetter setState) {
                      return AlertDialog(
                        title: Text('StatefulBuilder Example'),
                        content: Text('Selected Value: $selectedValue'),
                        actions: <Widget>[
                          TextButton(
                            child: Text('Increment'),
                            onPressed: () {
                              setState(() {
                                selectedValue++;
                              });
                            },
                          ),
                        ],
                      );
                    },
                  );
                },
              );
            },
          ),
        ),
      ),
    );
  }
}
YHYH

ダイアログ内の状態管理でConsumerで囲うこと忘れてたせいでリアルタイム反映がされなかった。。

1時間ぐらい費やした、、、(戒め)

YHYH

トランザクションでの処理はawait要らないのか

YHYH

Freezedの内容を拡張するとき

  • プライベートコンストラクタを定義
  • 継承して拡張
extension AClassX on AClass {
    Map<String, dynamic> toFirestore() {}
}
YHYH

WillPopScopeの代わりにPopScopeでダイアログを閉じたい場合

PopScope(
    canPop: false,
    onPopInvoked: (bool didPop) {
        if (didPop) return;
        Navigator.of(context).pop();
},
YHYH

UIで文字を複数表示

Text("*" * 10)

普通に思いつかなかったわ

YHYH

UIで文字をリストで表示

Column(
    children: [
        ...List.generate(
            10,
            (index) => Text("*")
)
    ]
)

YHYH
class UIWidget<T extends AutoDisposeNotifier<S>,
    S extends IState> extends ConsumerWidget {
    ...
    }
UIWidget<UIProvider,
    State>() {
}

これの意味するところは、

UIWidget<監視しているprovider, 監視対象>
class UIWidget<監視しているprovider extends AutoDisposeNotifier<監視対象>,
    監視対象 extends IState> extends ConsumerWidget {
    ...
    }
YHYH

Chipの枠線を消す方法

Chip(
    label: Text("テキスト"),
    shape: const StadiumBorder(
        side: BorderSide(
            color: Colors.transparent,
            width: 0,
        ),
    )
)

shapeで適当に合った形のボーダーを選択し、そこからBorderSideでcolorとwidthを設定か

YHYH

AsyncValueでの値の書き換え

state = AsyncValue.data(state.value!.copyWith(selectedDate: date));

YHYH

状態更新のタイミング:

await ref.watch(provider(id).future) を使用することで、データが取得されるまで待機します。
データ取得後に状態を作成し返すため、不完全な状態や中間状態を避けられます。

YHYH

画面描画後に行いたい処理

WidgetsBinding.instance.addPostFrameCallback((_) {
      print(' PostFrameCallback from build');
    });

initStateとbuildメソッドの両方でWidgetsBinding.instance.addPostFrameCallbackを実行する場合は
initState->buildの順で行われる

YHYH
query = query
      .where('playerName', isGreaterThanOrEqualTo: playerName.trim())
      .where('playerName', isLessThan: playerName.trim() + '\uf8ff');

日本語での前方一致