【Flutter】入力フォームの実装【日本語】

Flutterの入力フォームを実装していきます。

入力されたものを画面上に表示するというものを作ってみます。

他のプログラミングに関する記事はこちら

スポンサーリンク

前提

特になし。

なるべく難しい言葉を使わず書いていきます。

尚、以下の順番で説明していきます。

・入力フォームを作成する

・入力したものを表示する

 

スポンサーリンク

作成したものとソースコード

どうやって実装するか説明する前に、どのようなものを作成するのかとソースコードを以下掲載します。

作成したもの

以下のようなものを作成しました。

文字を入力フォームに入力してクリックすることで、画面上に入力した文字を表示させる……というものです。

ソースコード

最終的なソースコードは以下のようになります(詳細は次章から説明)

Flutterを導入してからmain.dartを全文削除し、以下コピペすれば動くはずです。

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget { 
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'otameshi',
      home: Scaffold(
        appBar: AppBar(
          title: Text('InputTest'),
        ),
        body: InputTest(),
      ),
    );
  }
}

class InputTest extends StatefulWidget{
  @override
  _InputTestState createState() => new _InputTestState();
}

class _InputTestState extends State<InputTest>{

  // 入力された内容を保持するコントローラ
  final inputController = TextEditingController();

  // 表示用の変数
  String inputText = "最初の表示";

  // 入力されたときの処理
  void setText (String s){
    setState(() {
      inputText = s;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.start,
      children: <Widget>[
        // Column1
        Container(
          alignment: Alignment.center,
          child: Container(
            width: 300,
            height: 100,
            child: TextField(
              enabled: true, //活性or非活性
              maxLength: 10, //入力最大文字数
              style: TextStyle(color: Colors.red), //入力文字のスタイル
              obscureText: false, //trueでマスク(****表記)にする
              maxLines:1, //入力可能行数
              controller: inputController,
            ),
          )
        ),

        // Column2
        GestureDetector(
          onTap: () {
            setText(inputController.text);
          },
          child: Text("入力が終わったら押してみて"),
        ),

        // Column3
        Text(inputText),

      ],
    );
  }
}

スポンサーリンク

入力フォームを作成する

入力フォームを作成する方法はいくつかあるようですが、今回はTextFieldウィジェットで作成していきます。

作成する方法は簡単で、TextFieldウィジェットを埋め込むだけです。

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget { 
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'otameshi',
      home: Scaffold(
        appBar: AppBar(
          title: Text('InputTest'),
        ),
        body: TextField(
          enabled: true, //活性or非活性
          maxLength: 10, //入力最大文字数
          style: TextStyle(color: Colors.red), //入力文字のスタイル
          obscureText: false, //trueでマスク(****表記)にする
          maxLines:1, //入力可能行数
        ),
      ),
    );
  }
}

 

大事なのはbodyに埋め込んでいるTextField(14~20行目)の内容です。

上記のコードで動かすと以下のような状態となります。

 

TextFieldウィジェットにも色々なプロパティがあるので、それは都度調べて入力すれば問題ないと思います。

よく使うと思われるものとしては、maxLengthで入力文字数を制限したり、styleで入力文字を装飾したり、だと思います。

スポンサーリンク

入力したものを表示する

次に、入力フォームで入力された内容を使い、画面上に表示してみようと思います。

main.dartに何も記載がされていない状態から、作成していきます。

 

1.アプリ起動時にMyAppを呼び出しInputTestクラスの内容を表示させます。

bodyでInputTestクラスを呼び出していますが、現時点ではまだInputTestクラスを作成していないので、動きません。

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget { 
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'otameshi',
      home: Scaffold(
        appBar: AppBar(
          title: Text('InputTest'),
        ),
        body: InputTest(),
      ),
    );
  }
}

 

2.StatefulWidgetを継承して、InputTestクラスを作成します。

InputTestクラスでは_InputTestStateクラスを作成していますが、現時点で_InputTestStateクラスを作成していないので、動きません。

class InputTest extends StatefulWidget{
  @override
  _InputTestState createState() => new _InputTestState();
}

 

ちなみに、個人的には「StatefulWidget」に関する部分がFlutterを使う上での第1関門と感じましたので、以下自分なりの解釈を添えておきます。

既に熟知している方は読み飛ばしてください。


StatefulWidgetについて:ここから

StatefulWidgetを理解するためには、StatelessWidgetとセットで覚える必要があります。

使い分け方としては、

 

StatefulWidget = ユーザーの操作により画面描写を再度行う必要がある場合に適用

StatelessWidget = ユーザーがどんなに操作をしても画面描写が変わらないものに適用

 

といった感じです。

少しややこしい言葉で言うと、

 

Statefulの方は動的な場合に適用

Statelessの方は静的な場合に適用

 

といった感じです。

今回の場合は、InputTestはStatelessWidgetを適用し、MyAppはStatelessWidgetを適用しています。

InputTestは、ユーザー操作によりInputTestの描写を切り替えていく必要があるため、Statelessで行う必要があります。

MyAppは、ユーザー操作によりMyAppクラス内の描写が切り替わらないので、Statelessで問題ありません。

 

「あ、ユーザーの操作によって画面の表示内容が変わったな」

としたい処理が入っているクラスはStatefulWidget

 

「別にユーザーがどんなに操作しても表示内容は変わらんな」

といったものはStatelessWidget

 

でよいのかなぁ、と思います。

StatefulWidgetについて:ここまで


 

3.InputTestのステータスを保持する_InputTestStateクラスを作成します。

このあたりは定型な感じがするので説明が難しいです。

createStateで読んでいるクラス名(今回の場合はInputTestクラス)を、Stateのコレクション(<>内のこと)に指定してあげる必要があります。

class _InputTestState extends State<InputTest>{
}

 

4.(以降は全て_InputTestStateクラス内に記載していきます)buildメソッドで表示させる内容を作成します。

@override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.start,
      children: <Widget>[
        // Column1
        Container(
          alignment: Alignment.center,
          child: Container(
            width: 300,
            height: 100,
            child: TextField(
              enabled: true, //活性or非活性
              maxLength: 10, //入力最大文字数
              style: TextStyle(color: Colors.red), //入力文字のスタイル
              obscureText: false, //trueでマスク(****表記)にする
              maxLines:1, //入力可能行数
              controller: inputController,
            ),
          )
        ),

        // Column2
        GestureDetector(
          onTap: () {
            setText(inputController.text);
          },
          child: Text("入力が終わったら押してみて"),
        ),

        // Column3
        Text(inputText),

      ],
    );
  }

 

長々と書いていますが、興味のない方向けに重要な部分だけをピックアップして説明します。

入力された文字を画面上に表示するために必要な処理は以下の3つだけです。

 

・TextFieldウィジェット内にあるプロパティ「controller」の設定により、入力された内容を「変数:inputController」(未作成)に格納する

・コメントColumn2の内容により、クリックされたときに「メソッド:setText」(未作成)を起動させる

・コメントColumn3の内容により、「変数:inputText」(未作成)を表示させる

 

です。

次から未作成である「変数:inputController」「メソッド:setText」「変数:inputText」を用意していきます。

スポンサーリンク

 

5.「inputController」と「inputText」変数を作成します。

入力された内容を受け取る場合は「TextEditingController()」で変数を作成します。

表示用の変数は特に型はなんでもいいと思いますが、今回は文字列を扱うString型で作成します。

// 入力された内容を保持するコントローラ
final inputController = TextEditingController();

// 表示用の変数
String inputText = "最初の表示";

 

6.「setText」メソッドを作成します。

// 入力されたときの処理
void setText (String s){
  setState(() {
    inputText = s;
  });
}

 

このメソッドはクリックされたときに呼び出されるメソッドです。

引数に文字列sを用意しています。

引数の文字列をinputText変数にコピーするイメージです。

 

更に、StatefulWidgetで使っている変数を更新する場合にsetStateを使ってます。

setStateで処理を指定した場合は、その処理が終了してから画面を再描画してくれます。

inputText変数を更新するだけならsetStateを使う必要がありませんが、今回はinputText変数の内容を書き換えた後に再描写する必要があるため、setStateを使っています。

setStateを使わずに更新した場合は、内部的にはinputText変数が更新されますが画面が再描写されないため、見た目的には何も変わりません。

また、setStateはStatefulWidgetを継承していないと使えません。

 

 

お疲れさまでした。以上で終了です。

最終的には「作成したものとソースコード」の章で述べた通り、以下の通り動きます。

 

他のプログラミングに関する記事

プログラミングまとめ

プログラミングに関する記事です。 言語とかツールごとにまとめています。 スポンサーリンク [adcode] Flutter ・簡単導入~サンプルアプリのデバック起動まで ・文字の表示(重ねて[…]

IMG

スポンサーリンク