【flutter】ナビゲーションとルーティング

Navigation widgetを使用すると、新たなwidgetの作成が不要

移動先をpush
Navigator.push(,)
Navigator.pop()

import 'package:flutter/material.dart';

void main() {
  runApp(new MyApp());
}
class MyApp extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Generated App',
      theme: new ThemeData(
        primarySwatch: Colors.blue,
        primaryColor: const Color(0xFF2196f3),
        canvasColor: const Color(0xFFfafafa),
      ),
      home: FirstScreen(),
    );
  }
}

class FirstScreen extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("Home"),
      ),
      body: Center(
        child: Container (
          child: const Text("Home Screen",
            style: const TextStyle(fontSize:32.0)),
        ),
      ),
      bottomNavigationBar: BottomNavigationBar(
        currentIndex: 1,
        items: <BottomNavigationBarItem>[
          const BottomNavigationBarItem(
            label: 'Home',
            icon: const Icon(Icons.home, size:32),
          ),
          const BottomNavigationBarItem(
            label: 'next',
            icon: const Icon(Icons.navigate_next, size:32),
          ),
        ],
        onTap: (int value) {
          if (value == 1)
            Navigator.push(
              context,
              MaterialPageRoute(builder:
              (context)=> SecondScreen()),
            );
        }
      )
    );
  }
}

class SecondScreen extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: const Text("Next"),
        ),
        body: Center(
          child: Container (
            child: const Text("Next Screen",
                style: const TextStyle(fontSize:32.0)),
          ),
        ),
        bottomNavigationBar: BottomNavigationBar(
            currentIndex: 0,
            items: <BottomNavigationBarItem>[
              const BottomNavigationBarItem(
                label: 'prev',
                icon: const Icon(Icons.navigate_before, size:32),
              ),
              const BottomNavigationBarItem(
                label: '?',
                icon: const Icon(Icons.android, size:32),
              ),
            ],
            onTap: (int value) {
              if (value == 0)
                Navigator.pop(
                  context
                );
            }
        )
    );
  }
}

表示間での値の引き渡しは、値を引数に指定してインスタンスを作成

class FirstScreen extends StatefulWidget {
  FirstScreen({Key? key}) : super(key: key);

  @override
  _FirstScreenState createState() => _FirstScreenState();
}


class _FirstScreenState extends State<FirstScreen> {
  static final _controller = TextEditingController();
  static var _input = "";

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("Home"),
      ),
      body: Column(
        children: <Widget>[
          const Text('Home Screen',
          style: const TextStyle(fontSize: 32.0)),
          Padding(
            padding: const EdgeInsets.all(20.0),
            child: TextField(
              controller: _controller,
              style: const TextStyle(fontSize: 28.0),
              onChanged: changeField,
            ),
          ),
        ],
      ),
      bottomNavigationBar: BottomNavigationBar(
        currentIndex: 1,
        items: <BottomNavigationBarItem>[
          const BottomNavigationBarItem(
            label: 'Home',
            icon: const Icon(Icons.home, size:32),
          ),
          const BottomNavigationBarItem(
            label: 'next',
            icon: const Icon(Icons.navigate_next, size:32),
          ),
        ],
        onTap: (int value) {
          if (value == 1)
            Navigator.push(
              context,
              MaterialPageRoute(builder:
              (context)=> SecondScreen(_input)),
            );
        }
      )
    );
  }

  void changeField(String val) => _input = val;
}

class SecondScreen extends StatelessWidget {

  final String _value;

  SecondScreen(this._value);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: const Text("Next"),
        ),
        body: Center(
          child: Text(
            'you typed: "$_value".',
            style: const TextStyle(fontSize: 32.0),
          ),
        ),
        bottomNavigationBar: BottomNavigationBar(
            currentIndex: 0,
            items: <BottomNavigationBarItem>[
              const BottomNavigationBarItem(
                label: 'prev',
                icon: const Icon(Icons.navigate_before, size:32),
              ),
              const BottomNavigationBarItem(
                label: '?',
                icon: const Icon(Icons.android, size:32),
              ),
            ],
            onTap: (int value) {
              if (value == 0)
                Navigator.pop(
                  context
                );
            }
        )
    );
  }
}

routesによるルーティング

import 'package:flutter/material.dart';

void main() {
  runApp(new MyApp());
}
class MyApp extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Generated App',
      theme: new ThemeData(
        primarySwatch: Colors.blue,
        primaryColor: const Color(0xFF2196f3),
        canvasColor: const Color(0xFFfafafa),
      ),
      initialRoute: '/',
      routes: {
        '/': (context) => FirstScreen(),
        '/second': (context) => SecondScreen('Second'),
        '/third': (context) => SecondScreen('Third'),
      }
    );
  }
}

class FirstScreen extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("Home"),
      ),
      body: Center(
        child:const Text("Home Screen",
          style: const TextStyle(fontSize: 32.0),
        ),
      ),
      bottomNavigationBar: BottomNavigationBar(
        currentIndex: 1,
        items: <BottomNavigationBarItem>[
          const BottomNavigationBarItem(
            label: 'Home',
            icon: const Icon(Icons.home, size:32),
          ),
          const BottomNavigationBarItem(
            label: 'next',
            icon: const Icon(Icons.navigate_next, size:32),
          ),
        ],
        onTap: (int value) {
          if (value == 1)
            Navigator.pushNamed(context, '/second');
        }
      )
    );
  }
}

class SecondScreen extends StatelessWidget {

  final String _value;
  SecondScreen(this._value);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: const Text("Next"),
        ),
        body: Center(
          child: Text(
            '$_value Screen',
            style: const TextStyle(fontSize: 32.0),
          ),
        ),
        bottomNavigationBar: BottomNavigationBar(
            currentIndex: 0,
            items: <BottomNavigationBarItem>[
              const BottomNavigationBarItem(
                label: 'prev',
                icon: const Icon(Icons.navigate_before, size:32),
              ),
              const BottomNavigationBarItem(
                label: '?',
                icon: const Icon(Icons.android, size:32),
              ),
            ],
            onTap: (int value) {
              if (value == 0)
                Navigator.pop(
                  context
                );
              if (value == 1)
                Navigator.pushNamed(context, '/third');
            }
        )
    );
  }
}

【flutter】複雑な構造のウィジェット

class _MyHomePageState extends State<MyHomePage> {

  static var _message = "ok.";
  static var _stars = '★★★★★';
  static var _star = 0;

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text('App Name'),
        leading: BackButton(
          color: Colors.white,
        ),


      actions: <Widget>[
        IconButton(
          icon: Icon(Icons.android),
          tooltip: 'add star...',
          onPressed: iconPressedA,
        ),
        IconButton(
          icon: Icon(Icons.favorite),
          tooltip: 'subtract star...',
          onPressed: iconPressedB,
        )
      ],
      bottom: PreferredSize(
        preferredSize: const Size.fromHeight(30.0),
        child: Center(
          child: Text(_stars,
          style: TextStyle(
            fontSize: 22.0,
            color:Colors.white,
          ),),
        ),
      ),
    ),
    body:
      new Center(
        child: Text(
          _message,
          style: const TextStyle(
            fontSize: 28.0,
          ),
        )

      ),

    );
  }

  void iconPressedA(){
    _message = 'tap "Android".';
    _star++;
    update();
  }

  void iconPressedB(){
    _message = 'tap "favorite".';
    _star--;
    update();
  }

  void update(){
    _star = _star < 0 ? 0 : _star > 5 ? 5 : _star;
    setState((){
      _stars = '★★★★★☆☆☆☆☆'.substring(5 - _star, 5 - _star + 5);
      _message = _message + '[$_star]';
    });
  }
}

BottomNavigationBar

class _MyHomePageState extends State<MyHomePage> {
  static var _message = "ok.";
  static var _index = 0;

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text('App Name'),
      ),
      body:
      new Center(
        child: Text(
          _message,
          style: const TextStyle(
            fontSize: 28.0,
          ),
        ),
      ),
      bottomNavigationBar: BottomNavigationBar(
        currentIndex: _index,
        backgroundColor: Colors.lightBlueAccent,
        items: <BottomNavigationBarItem>[
          BottomNavigationBarItem(
            label: 'Android',
            icon: Icon(Icons.android, color: Colors.black, size: 50),
          ),
          BottomNavigationBarItem(
            label: 'Favorite',
            icon: Icon(Icons.android, color: Colors.red, size: 50),
          ),
          BottomNavigationBarItem(
            label: 'Home',
            icon: Icon(Icons.android, color: Colors.white, size: 50),
          ),
        ],
        onTap: tapBottomIcon,
      ),
    );
  }

  void tapBottomIcon(int value) {
    var items = ['Android', 'Heart', 'Home'];
    setState((){
      _index = value;
      _message = 'you tapped: "' + items[_index] + '".';
    });
  }
}

List View

【flutter】UIその2

class _MyHomePageState extends State<MyHomePage> {

  static var _message = "ok.";
  static var _value = 0.0;

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text('App Name'),
      ),
      body:
      new Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.start,
          mainAxisSize: MainAxisSize.max,
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: <Widget>[
            Padding(
              padding: EdgeInsets.all(20.0),
              child: Text(
                _message,
                style: TextStyle(
                  fontSize: 32.0,
                  fontWeight: FontWeight.w400,
                  fontFamily:"Robot"),
              ),
            ),
            Padding(
              padding: EdgeInsets.all(10.0),
            ),
            Slider (
              onChanged: sliderChanged,
              min: 0.0,
              max: 100.0,
              divisions: 20,
              value:_value,
            ),
          ],
        ),

      ),

    );
  }

  void sliderChanged(double value){
    setState((){
      _value = value.floorToDouble();
      _message = 'set value: $_value';
    });
  }
}
class _MyHomePageState extends State<MyHomePage> {

  static var _message = "ok.";

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text('App Name'),
      ),
      body:
      new Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.start,
          mainAxisSize: MainAxisSize.max,
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: <Widget>[
            Padding(
              padding: EdgeInsets.all(20.0),
              child: Text(
                _message,
                style: TextStyle(
                  fontSize: 32.0,
                  fontWeight: FontWeight.w400,
                  fontFamily:"Robot"),
              ),
            ),
            Padding(
              padding: EdgeInsets.all(10.0),
            ),
            Padding(
              padding: EdgeInsets.all(10.0),
              child: ElevatedButton(
                onPressed:buttonPressed,
                child: Text(
                  "tap me!",
                  style: TextStyle(fontSize:32.0,
                  color: const Color(0xff000000),
                  fontWeight: FontWeight.w400,
                  fontFamily: "Roboto"),
                )
              )
            )
          ],
        ),

      ),

    );
  }

  void buttonPressed(){
    showDialog(
      context: context,
      builder: (BuildContext context) => AlertDialog(
        title: Text("Hello!"),
        content: Text("This is sample."),
        actions: <Widget>[
          TextButton(
              child: const Text('Cancel'),
              onPressed: () => Navigator.pop<String>(context, 'Cancel')
          ),
          TextButton(
              child: const Text('OK'),
              onPressed: () => Navigator.pop<String>(context, 'OK')
          ),
        ]
      ),
    ).then<void>((value)=> resultAlert(value));
  }

  void resultAlert(String value){
    setState((){
      _message = 'selected: $value';
    });
  }
}
class _MyHomePageState extends State<MyHomePage> {
  static var _message = "ok.";

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text('App Name'),
      ),
      body:
      new Column(
        children: <Widget>[
          Text(
            _message,
            style: TextStyle(
              fontSize: 32.0,
            ),
          ),

          ListView(
            shrinkWrap: true,
            padding: const EdgeInsets.all(20.0),

            children: <Widget>[

              Text('First item',
              style: TextStyle(fontSize: 24.0),
              ),
              Text('Second item',
                style: TextStyle(fontSize: 24.0),
              ),
              Text('Third item',
                style: TextStyle(fontSize: 24.0),
              ),
            ],
          ),
        ],
      ),

    );
  }
}
class _MyHomePageState extends State<MyHomePage> {
  static var _message = "ok.";
  static var _index = 0;

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text('App Name'),
      ),
      body:
      new Column(
        children: <Widget>[
          Text(
            _message,
            style: TextStyle(
              fontSize: 32.0,
            ),
          ),

          ListView(
            shrinkWrap: true,
            padding: const EdgeInsets.all(20.0),

            children: <Widget>[

              ListTile(
                leading: const Icon(Icons.android, size:32),
                title: const Text('first item',
                  style: TextStyle(fontSize: 28)),
                selected: _index == 1,
                onTap:() {
                  _index = 1;
                  tapTile();
                },
              ),
              ListTile(
                leading: const Icon(Icons.favorite, size:32),
                title: const Text('second item',
                    style: TextStyle(fontSize: 28)),
                selected: _index == 2,
                onTap:() {
                  _index = 2;
                  tapTile();
                },
              ),
              ListTile(
                leading: const Icon(Icons.home, size:32),
                title: const Text('third item',
                    style: TextStyle(fontSize: 28)),
                selected: _index == 3,
                onTap:() {
                  _index = 3;
                  tapTile();
                },
              ),

            ],
          ),
        ],
      ),

    );
  }

  void tapTile() {
    setState(() {
      _message = 'you tapped: No, $_index.';
    });
  }
}

SingleChildScrollView

class _MyHomePageState extends State<MyHomePage> {

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text('App Name'),
      ),
      body: SingleChildScrollView(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          mainAxisAlignment: MainAxisAlignment.spaceAround,
          children: <Widget>[
            Container(
              color: Colors.blue,
              height: 120.0,
              child: const Center(
                child: Text('one',
                style: const TextStyle(fontSize:32.0)),
              ),
            ),
            Container(
              color: Colors.white,
              height: 120.0,
              child: const Center(
                child: Text('two',
                    style: const TextStyle(fontSize:32.0)),
              ),
            ),
            Container(
              color: Colors.blue,
              height: 120.0,
              child: const Center(
                child: Text('three',
                    style: const TextStyle(fontSize:32.0)),
              ),
            ),
            Container(
              color: Colors.white,
              height: 120.0,
              child: const Center(
                child: Text('four',
                    style: const TextStyle(fontSize:32.0)),
              ),
            ),
            Container(
              color: Colors.blue,
              height: 120.0,
              child: const Center(
                child: Text('five',
                    style: const TextStyle(fontSize:32.0)),
              ),
            ),
          ],
        ),
      )
    );
  }
}

【flutter】TextFieldなどのUI

class _MyHomePageState extends State<MyHomePage> {

  static var _message = "ok.";
  static final _controller = TextEditingController();

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text('App Name'),
      ),
      body:
      new Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.start,
          mainAxisSize: MainAxisSize.max,
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: <Widget>[
            Padding(
              padding: EdgeInsets.all(20.0),
              child: Text(
                _message,
                style: TextStyle(
                  fontSize: 32.0,
                  fontWeight: FontWeight.w400,
                  fontFamily:"Robot"),
              ),
            ),
            Padding(
              padding: EdgeInsets.all(10.0),
              child: TextField(
                controller: _controller,
                style: TextStyle(
                    fontSize: 28.0,
                    color: const Color(0xffFF0000),
                    fontWeight: FontWeight.w400,
                    fontFamily:"Robot"),
              ),
            ),
              ElevatedButton(
                onPressed: buttonPressed,
                child: Text(
                  "Push me!",
                  style: TextStyle(
                    fontSize: 32.0,
                    color: const Color(0xff000000),
                    fontWeight: FontWeight.w400,
                    fontFamily: "Robot"),
              ),
            )
          ]
        ),

      ),

    );
  }

  void buttonPressed(){
    setState((){
      _message = "you said : " + _controller.text;
    });
  }
}
class _MyHomePageState extends State<MyHomePage> {

  static var _message = "ok.";
  static final _controller = TextEditingController();

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text('App Name'),
      ),
      body:
      new Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.start,
          mainAxisSize: MainAxisSize.max,
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: <Widget>[
            Padding(
              padding: EdgeInsets.all(20.0),
              child: Text(
                _message,
                style: TextStyle(
                  fontSize: 32.0,
                  fontWeight: FontWeight.w400,
                  fontFamily:"Robot"),
              ),
            ),
            Padding(
              padding: EdgeInsets.all(10.0),
              child: TextField(
                onChanged: textChanged,
                controller: _controller,
                style: TextStyle(
                    fontSize: 28.0,
                    color: const Color(0xffFF0000),
                    fontWeight: FontWeight.w400,
                    fontFamily:"Robot"),
              ),
            ),
          ]
        ),

      ),

    );
  }

  void textChanged(String val){
    setState((){
      _message = val.toUpperCase();
    });
  }
}

checkbox

class _MyHomePageState extends State<MyHomePage> {

  static var _message = "ok.";
  static var _checked = false;

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text('App Name'),
      ),
      body:
      new Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.start,
          mainAxisSize: MainAxisSize.max,
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: <Widget>[
            Padding(
              padding: EdgeInsets.all(20.0),
              child: Text(
                _message,
                style: TextStyle(
                  fontSize: 32.0,
                  fontWeight: FontWeight.w400,
                  fontFamily:"Robot"),
              ),
            ),
            Padding(
              padding: EdgeInsets.all(10.0),
              child: Row(
                mainAxisAlignment: MainAxisAlignment.start,
                mainAxisSize: MainAxisSize.max,
                crossAxisAlignment: CrossAxisAlignment.end,
                children: <Widget> [
                  Checkbox(
                    value:_checked,
                    onChanged: checkChanged,
                  ),
                  Text(
                    "Checkbox",
                    style: TextStyle(fontSize:28.0,
                    fontWeight: FontWeight.w400,
                    fontFamily: "Roboto"),
                  )
                ]
              )
            ),
          ]
        ),

      ),

    );
  }

  void checkChanged(bool? value){
    setState((){
      _checked = value!;
      _message = value ? 'checked!' : 'not checked...';
    });
  }
}

Radio

class _MyHomePageState extends State<MyHomePage> {

  static var _message = "ok.";
  static var _selected = 'A';

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text('App Name'),
      ),
      body:
      new Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.start,
          mainAxisSize: MainAxisSize.max,
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: <Widget>[
            Padding(
              padding: EdgeInsets.all(20.0),
              child: Text(
                _message,
                style: TextStyle(
                  fontSize: 32.0,
                  fontWeight: FontWeight.w400,
                  fontFamily:"Robot"),
              ),
            ),
            Padding(
              padding: EdgeInsets.all(10.0),
            ),
            Row(
              mainAxisAlignment: MainAxisAlignment.start,
              mainAxisSize: MainAxisSize.max,
              crossAxisAlignment:CrossAxisAlignment.center,
              children: <Widget>[
                Radio<String>(
                  value: 'A',
                  groupValue: _selected,
                  onChanged: checkChanged,
                ),
                Text(
                  "radio A",
                  style: TextStyle(fontSize:28.0,
                  fontWeight: FontWeight.w400,
                  fontFamily: "Roboto"),
                )
              ]
            ),
            Row(
                mainAxisAlignment: MainAxisAlignment.start,
                mainAxisSize: MainAxisSize.max,
                crossAxisAlignment:CrossAxisAlignment.center,
                children: <Widget>[
                  Radio<String>(
                    value: 'B',
                    groupValue: _selected,
                    onChanged: checkChanged,
                  ),
                  Text(
                    "radio B",
                    style: TextStyle(fontSize:28.0,
                        fontWeight: FontWeight.w400,
                        fontFamily: "Roboto"),
                  )
                ]
            )
          ]
        ),

      ),

    );
  }

  void checkChanged(String? value){
    setState((){
      _selected = value ?? 'nodata';
      _message = 'select: $_selected';
    });
  }
}

DropdownButton

class _MyHomePageState extends State<MyHomePage> {

  static var _message = "ok.";
  static var _selected = 'One';

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text('App Name'),
      ),
      body:
      new Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.start,
          mainAxisSize: MainAxisSize.max,
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: <Widget>[
            Padding(
              padding: EdgeInsets.all(20.0),
              child: Text(
                _message,
                style: TextStyle(
                  fontSize: 32.0,
                  fontWeight: FontWeight.w400,
                  fontFamily:"Robot"),
              ),
            ),
            Padding(
              padding: EdgeInsets.all(10.0),
            ),
            DropdownButton<String>(
              onChanged: popupSelected,
              value: _selected,
              style: TextStyle(color:Colors.black,
                fontSize:28.0,
                fontWeight:FontWeight.w400,
                fontFamily: 'Robot'),

              items: <DropdownMenuItem<String>>[
                const DropdownMenuItem<String>(value: 'One', child: const Text('One')),
                const DropdownMenuItem<String>(value: 'Two', child: const Text('Two')),
                const DropdownMenuItem<String>(value: 'Three', child: const Text('Three')),
              ]
            )
          ]
        ),

      ),

    );
  }

  void popupSelected(String? value){
    setState((){
      _selected = value ?? 'not selected...';
      _message = 'select: $_selected';
    });
  }
}class _MyHomePageState extends State<MyHomePage> {

  static var _message = "ok.";
  static var _selected = 'One';

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text('App Name'),
      ),
      body:
      new Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.start,
          mainAxisSize: MainAxisSize.max,
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: <Widget>[
            Padding(
              padding: EdgeInsets.all(20.0),
              child: Text(
                _message,
                style: TextStyle(
                  fontSize: 32.0,
                  fontWeight: FontWeight.w400,
                  fontFamily:"Robot"),
              ),
            ),
            Padding(
              padding: EdgeInsets.all(10.0),
            ),
            DropdownButton<String>(
              onChanged: popupSelected,
              value: _selected,
              style: TextStyle(color:Colors.black,
                fontSize:28.0,
                fontWeight:FontWeight.w400,
                fontFamily: 'Robot'),

              items: <DropdownMenuItem<String>>[
                const DropdownMenuItem<String>(value: 'One', child: const Text('One')),
                const DropdownMenuItem<String>(value: 'Two', child: const Text('Two')),
                const DropdownMenuItem<String>(value: 'Three', child: const Text('Three')),
              ]
            )
          ]
        ),

      ),

    );
  }

  void popupSelected(String? value){
    setState((){
      _selected = value ?? 'not selected...';
      _message = 'select: $_selected';
    });
  }
}

【flutter】ボタンウィジェット

class _MyHomePageState extends State<MyHomePage> {

  static var _message = "ok.";
  static var _janken = <String>['グー','チョキ','パー'];
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text('App Name'),
      ),
      body:
      new Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.start,
          mainAxisSize: MainAxisSize.max,
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: <Widget>[
            Padding(
              padding: EdgeInsets.all(20.0),
              child: Text(
                _message,
                style: TextStyle(
                  fontSize: 32.0,
                  fontWeight: FontWeight.w400,
                  fontFamily:"Robot"
                ),
              ),
            ),
              TextButton(
                onPressed: buttonPressed,
                child: Padding(
                  padding: EdgeInsets.all(10.0),
                  child: Text(
                    "Push me!",
                    style: TextStyle(
                      fontSize: 32.0,
                      color: const Color(0xff000000),
                      fontWeight: FontWeight.w400, fontFamily: "Robot"),
                )
              )
            )
          ]
        ),

      ),

    );
  }

  void buttonPressed(){
    setState((){
      _message = (_janken..shuffle()).first;
    });
  }
}
              TextButton(
                onPressed: buttonPressed,
                child: Padding(
                  padding: EdgeInsets.all(10.0),
                  child: Icon(
                    Icons.android,
                    size: 50.0,
                )
              )
            )

elevatedbutton, iconButtonなどがある

【Flutter】Dart入門

void main() {
  print("Hello!");
}
void main() {
  const a = 12;
  const int b = 34;
  int c = 56;
  var x = a * b ~/ c;
  print(x);
}
void main() {
  var arr = <int>[1,2,3];
  arr[0] = arr[1] + arr[2];
  print(arr);
}
void main() {
  var map = {"A":1, "B":2, "C":3};
  map["total"] = map["A"]! + map["B"]! + map["C"]!;
  print(map);
}

setterとgetter

void main() {
  Person me = Person("Taro", 39);
  me.say();
  me.birth = 1999;
  me.say();
}

class Person {
  String _name;
  int _age;
  
  int get birth => 2022 - _age;
  set birth(int n) => _age = 2022 - n;
  
  Person(this._name, this._age);
  
  void say() {
    print("Hi, I'm $_name. I was born in $birth ($_age years old).");
  }

setterとgetter

void main() {
  Exchange salary = Exchange(1000000, 144.5);
  salary.say();
  salary.dollar = 10000;
  salary.say();
}

class Exchange {
  double _yen;
  double _rate;
  
  double get dollar => _yen / _rate;
  set dollar(double n) => _yen = n * _rate; 
  
  Exchange(this._yen, this._rate);
  
  void say() {
    print("1ドル $_rate の時、$_yen 円は $dollar ドルです。");
  } 
}

1ドル 144.5 の時、1000000 円は 6920.415224913495 ドルです。
1ドル 144.5 の時、1445000 円は 10000 ドルです。

### 継承
継承の元となるclassをスーパークラスという

void main() {
  Person me = Person("Taro", 39);
  me.say();
  Student you = Student("Hanako", 16, 2);
  you.say();
}

class Person {
  String _name;
  int _age;
  
  Person(this._name, this._age);
  
  void say() {
    print("Hi, I'm $_name. I'm $_age years old.");
  }
}

class Student extends Person {
  int _grade;
  
  Student(name, age, this._grade):super(name, age);
  
  @override
  void say() {
    print("Hi, I'm $_name. I'm $_age years old. I'm $_grade grade student.");
  }
}
void main() {
  Company jr = Company("東日本旅客鉄道","渋谷区");
  jr.say();
  Airline ana = Airline("全日本空輸","港区","スターアライアンス");
  ana.say();
}

class Company {
  String _name;
  String _address;
  
  Company(this._name, this._address);
  
  void say() {
    print("$_name : 所在地 $_address");
  }
}

class Airline extends Company {
  String _alliance;
  
  Airline(name, address, this._alliance):super(name, address);
  
  @override
  void say() {
    print("$_name : 所在地 $_address $_alliance");
  }
}

東日本旅客鉄道 : 所在地 渋谷区
全日本空輸 : 所在地 港区 スターアライアンス

void main() {
  const data = [12, 34, 566, 78, 90, 100];
  var total = 0;
  data.forEach((n){
    total += n;
  });
  print("total is $total.");
}

【Flutter】ウィジェットの基本レイアウトを考える

flutter studioを利用する
https://flutterstudio.app/

source codeに変換する

import 'package:flutter/material.dart';

void main() {
  runApp(new MyApp());
}
class MyApp extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Generated App',
      theme: new ThemeData(
        primarySwatch: Colors.blue,
        primaryColor: const Color(0xFF2196f3),
        accentColor: const Color(0xFF2196f3),
        canvasColor: const Color(0xFFfafafa),
      ),
      home: new MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key}) : super(key: key);
  @override
  _MyHomePageState createState() => new _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
    @override
    Widget build(BuildContext context) {
      return new Scaffold(
        appBar: new AppBar(
          title: new Text('App Name'),
          ),
        body:
          new Text(
          "Hello Flutter!",
            style: new TextStyle(fontSize:32.0,
            color: const Color(0xFF000000),
            fontWeight: FontWeight.w700,
            fontFamily: "Roboto"),
          ),
    
      );
    }
}

Center

import 'package:flutter/material.dart';

void main() {
  runApp(new MyApp());
}
class MyApp extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Generated App',
      theme: new ThemeData(
        primarySwatch: Colors.blue,
        primaryColor: const Color(0xFF2196f3),
        accentColor: const Color(0xFF2196f3),
        canvasColor: const Color(0xFFfafafa),
      ),
      home: new MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key}) : super(key: key);
  @override
  _MyHomePageState createState() => new _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
    @override
    Widget build(BuildContext context) {
      return new Scaffold(
        appBar: new AppBar(
          title: new Text('App Name'),
          ),
        body:
          new Center(
            child:
              new Text(
              "qWerty1",
                style: new TextStyle(fontSize:12.0,
                color: const Color(0xFF000000),
                fontWeight: FontWeight.w200,
                fontFamily: "Roboto"),
              ),
    
          ),
    
      );
    }
}

Column

class _MyHomePageState extends State<MyHomePage> {
    @override
    Widget build(BuildContext context) {
      return new Scaffold(
        appBar: new AppBar(
          title: new Text('App Name'),
          ),
        body:
          new Column(
            mainAxisAlignment: MainAxisAlignment.start,
            mainAxisSize: MainAxisSize.max,
            crossAxisAlignment: CrossAxisAlignment.center,
            children: <Widget>[
              new Text(
              "one",
                style: new TextStyle(fontSize:12.0,
                color: const Color(0xFF000000),
                fontWeight: FontWeight.w200,
                fontFamily: "Roboto"),
              )
            ]
    
          ),
    
      );
    }
}

【Flutter】StatefulWidget 複雑な値の利用

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);
  final title = 'Flutterサンプル';

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      home: MyHomePage(
        title: this.title,
      ),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({
    title ='Flutter Demo'
}): super();

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class Data {
  int _price;
  String _name;
  Data(this._name, this._price): super();

  @override
  String toString() {
    return _name + ':' + _price.toString() + '円';
  }
}

class _MyHomePageState extends State<MyHomePage> {
  static final _data = [
    Data('Apple',200),
    Data('Orange',150),
    Data('Peach',300)
  ];
  Data _item = _data[0];

  void _setData(){
    setState((){
      _item = (_data..shuffle()).first;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold (
      appBar: AppBar(
        title: Text('Set data'),
      ),
      body: Text(
        _item.toString(),
        style: TextStyle(fontSize:32.0),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _setData,
        tooltip: 'set message',
        child: Icon(Icons.star),
      ),
    );
  }
}

【Flutter】StatefulWidgetについて

class ${widgetClass} extends StatefulWidget {
	
	@override
	ステートクラス createState() => ステートクラス();
}

stateクラスの場合は、Widget build(BuildContent context) だった

main.dart

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);
  final title = 'Flutterサンプル';
  final message = 'サンプルメッセージ';

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      home: MyHomePage(
        title: this.title,
        message: this.message
      ),
    );
  }
}

class MyHomePage extends StatefulWidget {
  final String title;
  final String message;
  const MyHomePage({
    Key? key,
    required this.title,
    required this.message
}): super(key: key);

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {

  @override
  Widget build(BuildContext context) {
    return Scaffold (
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Text(
        widget.message,
        style: TextStyle(fontSize:32.0),
      )
    );
  }
}

_MyHomePageState createState() => _MyHomePageState(); のところをステートの処理に従って変化するよに処理を作成すれば良い

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);
  final title = 'Flutterサンプル';

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      home: MyHomePage(
        title: this.title,
      ),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({
    required this.title,
}): super();
  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  String _message = 'Hello!';

  void _setMessage(){
    setState((){
      _message = 'タップしました!';
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold (
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Text(
        _message,
        style: TextStyle(fontSize:32.0),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _setMessage,
        tooltip: 'set message',
        child: Icon(Icons.star),
      ),
    );
  }
}

Flutterとは

### Flutterの特徴
Flutterはマルチプラットフォームのための開発環境
SDKにより専用のAPIを提供している
Androidで採用されているマテリアルデザインをベースに設計しているが、iOS用のクパティーノというUIフレームワークを用意している
開発言語はDart
プログラムをプラットフォームごとにネイティブコードにコンパイルする
IntelliJ(Android Studio)/Visual Studio Codeに対応

### Flutter開発に必要なもの
JDK
Dart
Flutter SDK
IntelliJ(Android Studio)/Visual Studio Code
Visual Studio
Xcode

$ java -version
openjdk version “18.0.2.1” 2022-08-18
OpenJDK Runtime Environment Homebrew (build 18.0.2.1+0)
OpenJDK 64-Bit Server VM Homebrew (build 18.0.2.1+0, mixed mode, sharing)

flutterをdownload
https://docs.flutter.dev/get-started/install

パスを通す
$ vi ~/.bash_profile
export PATH=$PATH:/Users/mac/flutter/flutter/bin
$ source ~/.bash_profile
$ flutter upgrade

intelliJ からdownload
https://www.jetbrains.com/ja-jp/idea/

main.dart

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  // const MyApp({super.key});

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      title: 'Flutter Demo',
      home: Text(
        'hello, Flutter world!!',
        style: TextStyle(fontSize:32.0),
      ),
    );
  }
}

Flutterはwidgetという部品の組み合わせによって作成される
widget treeによって記述する

ウィジェットによって記述
mainはアプリ起動時に呼び出される関数

void main() {
  runApp(MyApp());
}

StatelessWidgetはステート(状態を表す値)を持たないwidgetのベースとなるクラス
StatelessWidgetかStatefulWidgetのいずれかを継承して作成する
MaterialAppというインスタンスが返されている

class ${className} extends StatelessWidget {
	
	@override
	Widget build(BuildContext context) {
		return MaterialApp(...略...),
	}
}

titleはアプリケーションのタイトル、homeがwidget
Textウィジェットを指定

    return const MaterialApp(
      title: 'Flutter Demo',
      home: Text(
        'hello, Flutter world!!',
        style: TextStyle(fontSize:32.0),
      ),
    );

### アプリの構造
– アプリケーションはmain関数として定義
– runApp関数では、StatelessWidget継承クラスのインスタンスを引数に指定
– StatelessWidget継承クラスにはbuildメソッドを用意する
– MaterialAppの引数homeに、実際にアプリ内に表示するwidgetを設定する

標準的なwidgetはwidget.dartというパッケージにまとめられている
material.dartとcupertino.dartが用意されている

ScaffoldとAppBar

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      home: Scaffold(
        appBar: AppBar(
          title: Text("Hello Flutter!"),
        ),
        body: Text(
          'hello, Flutter world!!',
          style: TextStyle(fontSize:32.0),
        ),
      ),
    );

Scaffoldは建築現場の足場
Scaffoldには基本的なデザインとレイアウトが組み込まれている
Scaffoldでは Scaffold(appBar:, body:)としてインスタンスを作成する

空白エリアの表示を担当するのがbody