Flutterメモ: 逆引き編

# 👆はじめに

**2021/09/24** 勉強中

本記事はサンプルコードを読んで使えそうな部分だけを切り取った記事です。
また、メモとして記しているため説明(理解した部分)は全て省いています。
「こんなWidgetがあるんだな〜🤔」くらいの気持ちで読んでいただければ幸いです。

# 📖参考

[Flutterでスクロールを検知し、ある位置までスクロールしたらWidgetを表示するには]
(https://kwmt27.net/2018/09/03/flutter-scroll/)
[Flutter - Dart API docs]
(https://api.flutter.dev/)

# 無限スクロールのGridView

```dart:State
final ScrollController _scrollController = ScrollController();

@override
void initState() {
  // スクロールを検知するListenerのセット
  _scrollController.addListener(() {
    // イベントハンドラ
    setState(() {});
  });
  super.initState();
}

@override
void dispose() {
  // Listenerの解放
  _scrollController.dispose();
  super.dispose();
}

// Widget生成時
GridView.builder(
  controller: _scrollController,
  gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
    crossAxisCount: 3,  //@required(列数)
  ),  //@required(SliverGridDelegate)
  itemBuilder: (context, index) {
    return Widget();  // Grid表示するWidget
  },  //@required(IndexedWidgetBuilder)
),
```

## 一番上まで自動スクロールするFAB

```dart
FloatingActionButton(
  onPressed: () {
    _scrollController.animateTo(
      0,  //offset
      duration: const Duration(milliseconds: 600),  //@required(アニメーション時間)
      curve: Curves.easeInQuint,  //@required(アニメーション効果)
    )
  },  //@required(タップ検知時の処理)
),
```

# 背景色に応じた文字色の変更

```dart:(int_index)
import 'dart:math' as math;

// ランダムな色の生成(後述)
final itemColor = 
  Color(
    (math.Random(index).nextDouble() * 0x00FFFFFF).toInt()
  ).withOpacity(1);

// 輝度の取得
final itemBrightness = itemColor.computeLuminance();

// Text
Text(
  index.toString(),
  style: TextStyle(
    // 文字色の分岐
    color: itemBrightness > 0.5 ? Colors.black : Colors.white,
  ),
),
```

## ランダムな色の生成

```dart:(int_index)
import 'dart:math' as math;

// シード値を指定して0以上1未満の小数乱数を生成
final d = math.Random(index).nextDouble();

// 小数乱数を用いた色(int型)の生成
// 0x .. 16進数, 00 .. 不透明度(Opacity), FFFFFF .. 色の最大値
final i = (d * 0x00FFFFFF).toInt();

// 不透明度が1である色(Color型)の生成
final Color c = Color(i).withOpacity(1);
```

# スクロールに応じて変化するSliverAppBar

```dart
CustomScrollView(
  slivers: [
    // AppBar
    SliverAppBar(
      flexibleSpace: FlexibleSpaceBar(
        title: Text('FlexibleSpaceBar.title'),
        background: Stack(
          children: <Widget>[
            SizedBox(
              child: Image.network(
                'https://~.jpg',  //@required(画像URL)
              ),
            ),
            Container(
              decoration: BoxDecoration(
                gradient: LinearGradient(
                  begin: FractionalOffset.topCenter,
                  end: FractionalOffset.bottomCenter,
                  colors: [
                    Color(0xffee0000),  // グラデーション開始色
                    Color(0xffeeee00),  // グラデーション終了色
                  ],  //@required(グラデーション色)
                ),
              ),
            ),
          ],
        ),
      ),
    ),

    // Content
    SliverList(
      delegate: SliverChildListDelegate(
        <Widget>[
          Widget()  // スクロール表示するWidget
        ],
      ),  //@required(SliverChildDelegate)
    ),
  ],
),
```

# 画面遷移(プッシュ遷移)するボタン

```dart:(BuilderContext_context)
ElevatedButton(
  onPressed: () => Navigator.of(context).push(
    MaterialPageRoute(
      builder: (context) => Widget(),  //@required(遷移先Widget)
    ),
  ),
  child: const Text('Push Navigation'),
),
```

# Widgetのぼかし

```dart:
Stack(
  children: [
    BackgroundWidget(),  // 背景となる(=一部がぼかされる)Widget
    BackdropFilter(
      filter: ImageFilter.blur(sigmaX: 5, sigmaY: 5),  //@required(ImageFilter, ぼかし部分)
      child: Container(
        decoration: BoxDecoration(
          color: Colors.white.withOpacity(0.5),  // ぼかし部分の背景色
        ),
        child: WidgetOnBlur(),  // ぼかし部分の上に設置するWidget
      ),
    ),  // 
  ],
),
```