[Flutter]バーコードスキャナーで読んだ値をユーザーがフォーカスしているテキストボックスにセットする

## 状況

Fluttterで、バーコードスキャナーで読み込んだバーコードの値を、
ユーザーが選択しているテキストボックスにセットしたい。

## まずはバーコードスキャナーを実装する

### pubspec.yamlに追加

```pubspec.yaml
  flutter_barcode_scanner: ^1.0.1
```

### viewにカメラボタンと、バーコードスキャナーの処理を実装する

```dart:view.dart
  // カメラ起動ボタンの実装
  RaisedButton(
    child: Text("バーコードスキャン"),
    onPressed: () async {
      var barcode = await scanBarcode();
  }),

  // バーコードスキャナーの処理
  Future<String> scanBarcode() async {
    String barcode;
    try {
      barcode = await FlutterBarcodeScanner.scanBarcode(
          "#ff6666", "Cancel", true, ScanMode.BARCODE);
    } on PlatformException {
      barcode = 'Failed to get platform version.';
    }

    // キャンセルボタンを押下された時の処理
    if (barcode == "-1") {
      return null;
    }
    return barcode;
  }
```

## テキストフォームを実装する

```dart:view.dart
  FocusNode _focus = new FocusNode();
  bool _isFocusPassword = false;  //focusがpasswordのテキストフォームにあっているか
  final _formKey = GlobalKey<FormState>();
  var actNmController = TextEditingController();
  var passwordController = TextEditingController();

  @override
  void initState() {
    super.initState();
    _focus.addListener(_onFocusChange); //focusを監視する
  }

  @override
  Widget build(BuildContext context) {
    return Form(
      key: _formKey,
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.center,
        children: [
          TextFormField(
            controller: actNmController,
                  decoration: const InputDecoration(
                    labelText: 'アカウント名',
                    border: OutlineInputBorder(),
                  ),
                  validator: (String value) {
                    if (value.trim().isEmpty) {
                      return 'アカウント名を入力してください';
                    }
                    return null;
                  },
                  onSaved: (String value) {
                    setState(() {
                      _actNm = value;
                    });
                  },
                ),
                SizedBox(height: 16),
                TextFormField(
                  controller: passwordController,
                  focusNode: _focus,
                  obscureText: true,
                  decoration: const InputDecoration(
                    labelText: 'パスワード',
                    border: OutlineInputBorder(),
                  ),
                  validator: (String value) {
                    if (value.trim().isEmpty) {
                      return 'パスワードを入力してください';
                    }
                    return null;
                  },
                  onSaved: (String value) {
                    setState(() {
                      _password = value;
                    });
                  },
                ),
        ],
      ),
    );
  }

  void _onFocusChange() {
    debugPrint("Focus: " + _focus.hasFocus.toString());
    setState(() {
      _isFocusPassword = _focus.hasFocus;
    });
  }

```

## バーコードスキャナーにフォーカスの条件分岐を実装

```dart:view.dart
  RaisedButton(
      child: Text("バーコードスキャン"),
      onPressed: () async {
        var barcode = await model.scanBarcode();
        // パスワードにフォーカスが当たっていたら、パスワードのテキストボックスに値をセットする
        if (_isFocusPassword) {
          setState(() {
            _password = barcode;
            passwordController.text = barcode;
          });
       // パスワードにフォーカスが当たっていなければ、アカウント名にセット
        } else {
          setState(() {
            _actNm = barcode;
            actNmController.text = barcode;
          });
        }
      }),