0
1

More than 3 years have passed since last update.

ask me! appのログイン画面の実装

Posted at

1 この記事の内容

ask me! appでのログイン画面の実装方法について記載します。画面レイアウトは下記のとおりです。

quitta①+.jpg

2 ソースコード概要

ソースコードの概要は下記の通りです。

login.dart


  @override
  Widget build(BuildContext context) {
    return
      new GestureDetector(
      onTap:()
      {
        _focusNodePwd.unfocus();
      },
      child:

      new Scaffold(
      appBar: new AppBar(
      centerTitle: true,

        title: new Text('ask me! app',style: TextStyle(fontFamily: 'impact')),
        backgroundColor:Color.fromARGB(255,171 ,232 ,255 ),

      ),

      body:
      KeyboardActions(
      config:_buildConfig(context),
    child:

          _loading?
        bodyProgress:
        new Column(
            children: <Widget>[

              new Padding(
                padding:  EdgeInsets.fromLTRB(24.0*app_size.width/WIDTH,24.0*app_size.height/HEIGHT,24.0*app_size.width/WIDTH,24.0*app_size.height/HEIGHT),
              ),

              new Center(
                child:
                new Text(
                  "H E L L O",
                  style: new TextStyle(fontSize: 56.0*app_size.width*app_size.height/WIDTH/HEIGHT,
                      color: Color.fromARGB(255,171 ,232 ,255 ),
                      fontWeight: FontWeight.w300,
                      fontFamily: 'impact'),
                ),
              ),


              new Center(
                child:
                new Image.asset(
                  'icon/askme.png',
                  width: 230.0*app_size.width/WIDTH,
                  height: 230.0*app_size.width/WIDTH,
                ),
              ),


              new Padding(
                padding:  EdgeInsets.fromLTRB(20.0*app_size.width/WIDTH,10.0*app_size.height/HEIGHT,20.0*app_size.width/WIDTH,10.0*app_size.height/HEIGHT),
              ),


              new Container(
                  width: 300.0*app_size.width/WIDTH,
                  child:new EnsureVisibleWhenFocused(
                    focusNode: _focusNodePwd,
                    child: new TextFormField(
                      controller: passwdcontroller,
                      decoration: const InputDecoration(
                        border: const OutlineInputBorder(),
                        hintText: 'PASSWORD',
                        labelText: 'PASSWORD',
                        hintStyle: TextStyle(fontSize: 20.0,
                            color: const Color(0xFF000000),
                            fontWeight: FontWeight.w200,
                            fontFamily: 'impact'),
                        labelStyle:  TextStyle(fontSize: 20.0,
                            color: const Color(0xFF000000),
                            fontWeight: FontWeight.w200,
                            fontFamily: 'impact'),

                      ),
                      style: new TextStyle(fontSize: 20.0,
                          color: const Color(0xFF000000),
                          fontWeight: FontWeight.w200,
                          fontFamily: 'Roboto'),
                      focusNode: _focusNodePwd,
                      keyboardType: TextInputType.number,
                    ),
                  ),
              ),

              new Padding(
                padding:  EdgeInsets.fromLTRB(20.0*app_size.width/WIDTH,20.0*app_size.height/HEIGHT,20.0*app_size.width/WIDTH,20.0*app_size.height/HEIGHT),
              ),


              new Row(
                  children: <Widget>[

                    new Padding(
                      padding:  EdgeInsets.fromLTRB(app_size.width*0.1,40.0*app_size.height/HEIGHT,0.1*app_size.width,40.0*app_size.height/HEIGHT),
                    ),


                  new Container(

                    width:app_size.width*3/5,
                    child:
                    FlatButton(
                      onPressed: () {

                        buttonPressed();
                      },
                      color: Color.fromARGB(255,171 ,232 ,255 ),
                      child: Text(
                        "    OK    ",
                        style: new TextStyle(fontSize: 50.0,
                            fontWeight: FontWeight.w200,
                            fontFamily: 'impact'
                            ,color: Colors.white
                        ),
                      ),
                      padding: EdgeInsets.symmetric(vertical: 0*app_size.height, horizontal: 0.05*app_size.width),
                     shape:  StadiumBorder()
                    ),
                  ),

                    new Padding(
                      padding:  EdgeInsets.fromLTRB(app_size.width*0.1,40.0*app_size.height/HEIGHT,0.1*app_size.width,40.0*app_size.height/HEIGHT),
                    ),

                  ]
              ),
            ]

        ),
      ),

        bottomNavigationBar: new BottomNavigationBar(
          items: [

            new BottomNavigationBarItem(
              icon: const Icon(Icons.arrow_back),
              title: new Text('back',style: TextStyle(fontFamily: 'impact'),),
            ),


          ],
          onTap:(int index){
            Navigator.of(context).pop();
          },
        ),
      ),
      );
  }

工夫点について個別に説明します。

3 端末のサイズ取得

端末の種類によってレイアウトが変わってしまうのを防ぐために、Container等のwidthには予め取得されたデバイスのサイズを利用します。

サイズ取得に失敗する場合もあるので、その時は再度get_size()を呼び出すようにしています。

ソースコードは下記の通りです。

login.dart

  void get_size(){
    app_size=MediaQuery.of(context).size;
    setState(() {
      width = app_size.width;
      height = app_size.height;
    });

    if(width==0 || height==0) get_size();
  }

  @override
  void initState()  {
    super.initState();
    get_size();
  }

参考サイト:https://qiita.com/najeira/items/c98c5fec9c71104f8263

4 パスワード入力欄 のフォーカス外し

パスワードを入力するために、TextFormFieldをタップするとキーパッドが出ますが、
TextFormField外の箇所をタップするとキーパッドを閉じるようにしました。

実装方法としては、下記の通りです。

login.dart

      new GestureDetector(
      onTap:()
      {
        _focusNodePwd.unfocus();
      },

つまりOnTapイベントでパスワード入力欄に紐づけられたFocusNodeをUnFocusします。

5 TextFormFieldのヘルパーウィジェット

キーバッドが表示されたときに、TextFormFieldが隠れてしまう場合があります。
それを防ぐために下記サイトのヘルパーウィジェットを利用しました。

URL:https://www.didierboelens.com/2018/04/hint-4-ensure-a-textfield-or-textformfield-is-visible-in-the-viewport-when-has-the-focus/

6 キーパッドのDoneボタン

キーパッドでの入力完了後にはDoneボタンを押すことでキーパッドを閉じるようにしました。

Doneボタンの表示には下記のライブラリを使用しました。

Keyboard Actions:https://pub.dev/documentation/keyboard_actions/latest/

7 OKボタン押下時の動作

OKボタン押下時には、入力されたパスワードと予め設定された正解パスワードが合致するかどうか判定しますが、
その際の待ち時間は下記画面のようにCircularProgressIndicatorを使用します。

quitta_②.jpg

ソースコードは下記のとおりです。

login.dart

  var bodyProgress = new Container(
    child: new Stack(
      children: <Widget>[
        //body,
        new Container(
          alignment: AlignmentDirectional.center,
          decoration: new BoxDecoration(
            color: Colors.white70,
          ),
          child: new Container(
            decoration: new BoxDecoration(
                color: Colors.blue[200],
                borderRadius: new BorderRadius.circular(10.0)
            ),
            width: 300.0,
            height: 200.0,
            alignment: AlignmentDirectional.center,
            child: new Column(
              crossAxisAlignment: CrossAxisAlignment.center,
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                new Center(
                  child: new SizedBox(
                    height: 50.0,
                    width: 50.0,
                    child: new CircularProgressIndicator(
                      value: null,
                      strokeWidth: 7.0,
                    ),
                  ),
                ),
                new Container(
                  margin: const EdgeInsets.only(top: 25.0),
                  child: new Center(
                    child: new Text(
                      "please wait...",
                      style: new TextStyle(
                          color: Colors.white
                      ),
                    ),
                  ),
                ),
              ],
            ),
          ),
        ),
      ],
    ),
  );



0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1