Closed38

FlutterのMaterial Widgetを使ってみる

薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

StatefulWidget

https://api.flutter.dev/flutter/widgets/StatefulWidget-class.html

コード

import 'package:flutter/material.dart';

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

class MyApp extends StatefulWidget {
  const MyApp({super.key});
  
  
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  int count = 0;

  
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Center(
          child: Text("Count $count"),
        ),
        floatingActionButton: FloatingActionButton(
          child: const Text("+"),
          onPressed: () {
            setState(() {
              count += 1;
            });
          },
        ),
      ),
    );
  }
}

実行結果

薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

MaterialApp

https://api.flutter.dev/flutter/material/MaterialApp-class.html

コード

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});
  
  
  Widget build(BuildContext context){
    return MaterialApp(
      routes: {
        "/": (context) => Scaffold(
          appBar: AppBar(title: const Text("Home")),
          body: Center(
            child: TextButton(
              child: const Text("Go to A"),
              onPressed: () {
                Navigator.pushNamed(context, "/a");
              },
            ),
          ),
        ),
        "/a": (context) => Scaffold(
          appBar: AppBar(title: const Text("A")),
        ),
      }
    );
  }
}

実行結果

薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

Scaffold

https://api.flutter.dev/flutter/material/Scaffold-class.html

コード

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  const MyApp();

  
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text("App Bar Tilte")),
        body: const Center(
          child: Text("Body"),
        ),
        bottomNavigationBar: const BottomAppBar(
          shape: CircularNotchedRectangle(),
          child: SizedBox(
            height: 50.0,
            child: Center(
              child: Text("Bottom App Bar"),
            ),
          ),
        ),
        floatingActionButton: FloatingActionButton(
          child: const Text("+"),
          onPressed: () {},
        ),
        floatingActionButtonLocation: FloatingActionButtonLocation.endDocked,
      ),
    );
  }
}

実行結果

薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

Container

https://api.flutter.dev/flutter/widgets/Container-class.html

コード

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({ super.key });
  
  
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Center(
          child: Container(
            alignment: Alignment.center,
            color: Colors.amber,
            width: 50.0,
            height: 50.0,
            transform: Matrix4.rotationZ(0.1),
            child: const Text("Text"),
          ),
        ),
      ),
    );
  }
}

実行結果

薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

Row

https://api.flutter.dev/flutter/widgets/Row-class.html

コード

import 'package:flutter/material.dart';

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

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

  
  Widget build(BuildContext context) {
    const style = TextStyle(fontSize: 50);
    return MaterialApp(
      home: Scaffold(
        body: Center(
          child: Row(
            children: const [
              Expanded(
                child: Text("1", style: style),
              ),
              Expanded(
                child: Text("2", style: style),
              ),
              Expanded(
                child: Text("3", style: style),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

実行結果

薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

Column

https://api.flutter.dev/flutter/widgets/Column-class.html

コード

import 'package:flutter/material.dart';

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

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

  
  Widget build(BuildContext context) {
    const style = TextStyle(fontSize: 50);
    return MaterialApp(
      home: Scaffold(
        body: Center(
          child: Column(
            children: const [
              Expanded(
                child: Text("1", style: style),
              ),
              Expanded(
                child: Text("2", style: style),
              ),
              Expanded(
                child: Text("3", style: style),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

実行結果

薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

Stack

https://api.flutter.dev/flutter/widgets/Stack-class.html

コード

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({ super.key });
  
  
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Stack(
          children: [
            Container(
              width: 100,
              height: 100,
              color: Colors.red,
            ),
            Container(
              width: 75,
              height: 75,
              color: Colors.green,
            ),
            Container(
              width: 50,
              height: 50,
              color: Colors.blue,
            ),
          ],
        ),
      ),
    );
  }
}

実行結果

薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

Wrap

https://api.flutter.dev/flutter/widgets/Wrap-class.html

コード

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({ super.key });
  
  
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Wrap(
          spacing: 8.0,
          runSpacing: 4.0,
          children: <Widget>[
            Chip(
              avatar: CircleAvatar(backgroundColor: Colors.blue.shade900, child: const Text('AH')),
              label: const Text('Hamilton Hamilton'),
            ),
            Chip(
              avatar: CircleAvatar(backgroundColor: Colors.blue.shade900, child: const Text('ML')),
              label: const Text('Lafayette Lafayette'),
            ),
            Chip(
              avatar: CircleAvatar(backgroundColor: Colors.blue.shade900, child: const Text('HM')),
              label: const Text('Mulligan Mulligan'),
            ),
            Chip(
              avatar: CircleAvatar(backgroundColor: Colors.blue.shade900, child: const Text('JL')),
              label: const Text('Laurens Laurens'),
            ),
          ],
        ),
      ),
    );
  }
}

実行結果

薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

Expanded

https://api.flutter.dev/flutter/widgets/Expanded-class.html

コード

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({ super.key });
  
  
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Center(
          child: Column(
            children: [
              Container(
                width: 100,
                height: 100,
                color: Colors.blue,
              ),
              Expanded(
                child: Container(
                  width: 100,
                  color: Colors.yellow,
                ),
              ),
              Container(
                width: 100,
                height: 100,
                color: Colors.blue,
              ),
            ],
          ),
        ),
      ),
    );
  }
}

実行結果

薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

Flexible

https://api.flutter.dev/flutter/widgets/Flexible-class.html

コード

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({ super.key });
  
  
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Column(
          children: [
            Flexible(
              flex: 1,
              child: Container(
                color: Colors.blue,
              ),
            ),
            Flexible(
              flex: 2,
              child: Container(
                color: Colors.yellow,
              ),
            ),
            Flexible(
              flex: 1,
              child: Container(
                color: Colors.blue,
              ),
            ),
          ],
        ),
      ),
    );
  }
}

実行結果

薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

LayoutBuilder

https://api.flutter.dev/flutter/widgets/LayoutBuilder-class.html

コード

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({ super.key });
  
  
  Widget build(BuildContext context) {
    final children = [
      Flexible(
        flex: 1,
        child: Container(color: Colors.blue),
      ),
      Flexible(
        flex: 1,
        child: Container(color: Colors.yellow),
      ),
    ];
    
    return MaterialApp(
      home: Scaffold(
        body: LayoutBuilder(
          builder: (context, constraints) {
            if (constraints.maxWidth > 500) {
              return Row(children: children);
            } else {
              return Column(children: children);
            }
          },
        )
      ),
    );
  }
}

実行結果

薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

Center

https://api.flutter.dev/flutter/widgets/Center-class.html

コード

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({ super.key });
  
  
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Center(
          widthFactor: 2.0,
          heightFactor: 2.0,
          child: Container(
            width: 100,
            height: 100,
            color: Colors.blue,
          ),
        ),
      ),
    );
  }
}

実行結果

薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

Align

https://api.flutter.dev/flutter/widgets/Align-class.html

コード

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({ super.key });
  
  
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Align(
          alignment: Alignment(-0.9, -0.9),
          child: Container(
            width: 100,
            height: 100,
            color: Colors.blue,
          ),
        ),
      ),
    );
  }
}

実行結果

薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

Padding

https://api.flutter.dev/flutter/widgets/Padding-class.html

コード

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({ super.key });
  
  
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Column(
          children: [
            Expanded(
              child: Container(
                color: Colors.blue,
              ),
            ),
            Expanded(
              child: Padding(
                padding: const EdgeInsets.fromLTRB(0, 20, 0, 20),
                child: Container(
                  color: Colors.yellow,
                ),
              )
            ),
            Expanded(
              child: Container(
                color: Colors.blue,
              ),
            ),
          ],
        )
      ),
    );
  }
}

実行結果

薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

AppBar

https://api.flutter.dev/flutter/material/AppBar-class.html

コード

import 'package:flutter/material.dart';

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

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

  
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text("AppBar Title"),
          actions: [
            IconButton(
              icon: const Icon(Icons.add_alert),
              tooltip: "Show Snackbar",
              onPressed: () {},
            ),
            IconButton(
              icon: const Icon(Icons.navigate_next),
              tooltip: "Go to the Next Page",
              onPressed: () {},
            ),
          ],
        ),
        body: const Center(
          child: Text(
            "Body",
            style: TextStyle(fontSize: 50),
          ),
        ),
      ),
    );
  }
}

実行結果

薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

BottomNavigationBar

https://api.flutter.dev/flutter/material/BottomNavigationBar-class.html

コード

import 'package:flutter/material.dart';

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

class MyApp extends StatefulWidget {
  const MyApp({ super.key });
  
  
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  int _selectedIndex = 0;

  
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text("AppBar Title"),
        ),
        body: const Center(
          child: Text(
            "Body",
            style: TextStyle(fontSize: 50),
          ),
        ),
        bottomNavigationBar: BottomNavigationBar(
          items: const [
            BottomNavigationBarItem(
              icon: Icon(Icons.home),
              label: "Home",
            ),
            BottomNavigationBarItem(
              icon: Icon(Icons.business),
              label: "Business",
            ),
            BottomNavigationBarItem(
              icon: Icon(Icons.school),
              label: "School",
            ),
          ],
          currentIndex: _selectedIndex,
          selectedItemColor: Colors.amber,
          onTap: (index) {
            setState(() {
              _selectedIndex = index;
            });
          },
        ),
      ),
    );
  }
}

実行結果

薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

Drawer

https://api.flutter.dev/flutter/material/Drawer-class.html

コード

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({ super.key });
  
  
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text("AppBar Title"),
        ),
        drawer: Drawer(
          child: ListView(
            padding: EdgeInsets.zero,
            children: const [
              DrawerHeader(
                child: Text("DrawerHeader"),
              ),
              ListTile(
                leading: Icon(Icons.message),
                title: Text("Messages"),
              ),
              ListTile(
                leading: Icon(Icons.account_circle),
                title: Text("Profile"),
              ),
              ListTile(
                leading: Icon(Icons.settings),
                title: Text("Settings"),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

実行結果

薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

Routes

https://docs.flutter.dev/development/ui/navigation

https://docs.flutter.dev/cookbook/navigation/navigate-with-arguments

コード

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({ super.key });
  
  
  Widget build(BuildContext context) {
    return MaterialApp(
      routes: {
        "/": (context) => const HomeScreen(),
        "/details": (context) => const DetailScreen(),
      },
    );
  }
}

class HomeScreen extends StatelessWidget {
  const HomeScreen({ super.key });
  
  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("Home")),
      body: Padding(
        padding: const EdgeInsets.all(10),
        child: Column(
          children: [
            SizedBox(
              width: double.infinity,
              child: ElevatedButton(
                onPressed: () {
                  Navigator.pushNamed(
                    context,
                    "/details",
                    arguments: const DetailScreenArguments(1),
                  );
                },
                child: const Text("Details 1"),
              ),
            ),
            const SizedBox(height: 5),
            SizedBox(
              width: double.infinity,
              child: ElevatedButton(
                onPressed: () {
                  Navigator.pushNamed(
                    context,
                    "/details",
                    arguments: const DetailScreenArguments(2),
                  );
                },
                child: const Text("Details 2"),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

class DetailScreen extends StatelessWidget {
  const DetailScreen({ super.key });
  
  
  Widget build(BuildContext context) {
    final args = ModalRoute.of(context)!.settings.arguments as DetailScreenArguments;
    
    return Scaffold(
      appBar: AppBar(title: const Text("Details")),
      body: Center(
        child: Text("Details of #${args.id}"),
      ),
    );
  }
}

class DetailScreenArguments {
  final int id;

  const DetailScreenArguments(this.id);
}

実行結果

薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

Dialogs

https://api.flutter.dev/flutter/material/AboutDialog-class.html

https://api.flutter.dev/flutter/material/AlertDialog-class.html

コード

import 'package:flutter/material.dart';

void main() {
  runApp(
    const MaterialApp(
      home: MyApp(),
    ),
  );
}

class MyApp extends StatelessWidget {
  const MyApp({ super.key });
  
  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("AppBar Title")),
      body: Padding(
        padding: const EdgeInsets.all(20),
        child: Column(
          children: [
            SizedBox(
              width: double.infinity,
              child: ElevatedButton(
                onPressed: () => _showAboutDialog(context),
                child: const Text("About Dialog"),
              ),
            ),
            const SizedBox(height: 10),
            SizedBox(
              width: double.infinity,
              child: ElevatedButton(
                onPressed: () => _showAlertDialog(context),
                child: const Text("Alert Dialog"),
              ),
            ),
          ]
        ),
      ),
    );
  }
  
  void _showAboutDialog(BuildContext context) {
    showAboutDialog(
      context: context,
      applicationName: "MyApp",
      applicationVersion: "0.0.0",
    );
  }

  Future<void> _showAlertDialog(BuildContext context) async {
    final answer = await showDialog(
      context: context,
      builder: (context) => AlertDialog(
        title: const Text("AlertDialog Title"),
        content: const Text("AlertDialog Content"),
        actions: [
          TextButton(
            onPressed: () => Navigator.pop(context, "Cancel"),
            child: const Text("Cancel"),
          ),
          TextButton(
            onPressed: () => Navigator.pop(context, "OK"),
            child: const Text("OK"),
          ),
        ],
      ),
    );
    
    print(answer);
  }
}

実行結果

薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

Buttons

https://api.flutter.dev/flutter/material/DropdownButton-class.html

https://api.flutter.dev/flutter/material/ElevatedButton-class.html

https://api.flutter.dev/flutter/material/IconButton-class.html

https://api.flutter.dev/flutter/material/OutlinedButton-class.html

https://api.flutter.dev/flutter/material/PopupMenuButton-class.html

https://api.flutter.dev/flutter/material/TextButton-class.html

コード

import 'package:flutter/material.dart';

void main() {
  runApp(
    const MaterialApp(
      debugShowCheckedModeBanner: false,
      home: MyApp(),
    ),
  );
}

class MyApp extends StatelessWidget {
  const MyApp({ super.key });
  
  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("AppBar Title"),
        actions: [
          PopupMenuButton<String>(
            itemBuilder: (context) => const [
              PopupMenuItem(
                value: "1",
                child: Text("1"),
              ),
              PopupMenuItem(
                value: "2",
                child: Text("2"),
              ),
              PopupMenuItem(
                value: "3",
                child: Text("3"),
              ),
            ],
          ),
        ],
      ),
      body: Padding(
        padding: const EdgeInsets.all(20),
        child: Wrap(
          crossAxisAlignment: WrapCrossAlignment.center,
          spacing: 10,
          children: [
            DropdownButton<String>(
              value: "1",
              onChanged: (String? value) {},
              items: const [
                DropdownMenuItem(value: "1", child: Text("1")),
                DropdownMenuItem(value: "2", child: Text("2")),
                DropdownMenuItem(value: "3", child: Text("3")),
              ],
            ),
            ElevatedButton(
              onPressed: () {},
              child: const Text("ElevatedButton"),
            ),
            IconButton(
              onPressed: () {},
              icon: const Icon(Icons.favorite),
            ),
            OutlinedButton(
              onPressed: () {},
              child: const Text("OutlinedButton"),
            ),
            TextButton(
              onPressed: () {},
              child: const Text("TextButton"),
            ),
          ],
        ),
      ),
    );
  }
}

実行結果

薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

TextField

https://api.flutter.dev/flutter/material/TextField-class.html

コード

import 'package:flutter/material.dart';

void main() {
  runApp(
    const MaterialApp(
      home: MyApp(),
    ),
  );
}

class MyApp extends StatelessWidget {
  const MyApp({ super.key });
  
  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("AppBar Title")),
      body: Padding(
        padding: const EdgeInsets.all(20),
        child: Column(
          children: const [
            TextField(
              decoration: InputDecoration(
                border: OutlineInputBorder(),
                labelText: "Label",
              ),
            ),
          ],
        ),
      ),
    );
  }
}

実行結果

薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

Switch

https://api.flutter.dev/flutter/material/Switch-class.html

import 'package:flutter/material.dart';

void main() {
  runApp(
    const MaterialApp(
      home: MyApp(),
    ),
  );
}

class MyApp extends StatefulWidget {
  const MyApp({ super.key });
  
  
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  bool enabled1 = true;
  bool enabled2 = true;
  
  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("AppBar Title")),
      body: Padding(
        padding: const EdgeInsets.all(20),
        child: Column(
          children: [
            Switch(
              value: enabled1,
              onChanged: (value) {
                setState(() {
                  enabled1 = !enabled1;
                });
              },
            ),
            SwitchListTile(
              title: const Text("SwitchListTile Tilte"),
              value: enabled2,
              onChanged: (value) {
                setState(() {
                  enabled2 = !enabled2;
                });
              },
            ),
          ],
        ),
      ),
    );
  }
}

実行結果

薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

Text

https://api.flutter.dev/flutter/widgets/Text-class.html

コード

import 'package:flutter/material.dart';

void main() {
  runApp(const MaterialApp(
    home: MyApp(),
  ));
}

class MyApp extends StatelessWidget {
  const MyApp({ super.key });
  
  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("AppBar Title")),
      body: Padding(
        padding: const EdgeInsets.all(20),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: const [
            Text(
              "Hello, Ruth! How are you? "
              "Hello, Ruth! How are you? "
              "Hello, Ruth! How are you? "
              "Hello, Ruth! How are you? "
              "Hello, Ruth! How are you?",
              overflow: TextOverflow.ellipsis,
              style: TextStyle(fontWeight: FontWeight.bold),
            ),
            SizedBox(height: 20),
            Text.rich(
              TextSpan(
                text: "Hello",
                children: <TextSpan>[
                  TextSpan(
                    text: " beautiful ",
                    style: TextStyle(fontStyle: FontStyle.italic),
                  ),
                  TextSpan(
                    text: "world",
                    style: TextStyle(fontWeight: FontWeight.bold),
                  ),
                ],
              ),
            ),
          ],
        )
      )
    );
  }
}

実行結果

薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

Icon

https://api.flutter.dev/flutter/widgets/Icon-class.html

コード

import 'package:flutter/material.dart';

void main() {
  runApp(const MaterialApp(
    home: MyApp(),
  ));
}

class MyApp extends StatelessWidget {
  const MyApp({ super.key });
  
  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("AppBar Title")),
      body: Padding(
        padding: const EdgeInsets.all(20),
        child: Row(
          children: const [
            Icon(
              Icons.favorite,
              color: Colors.pink,
              size: 24.0,
              semanticLabel: "Text to announce in accessibility modes",
            ),
            SizedBox(width: 20),
            Icon(
              Icons.audiotrack,
              color: Colors.green,
              size: 24.0,
            ),
            SizedBox(width: 20),
            Icon(
              Icons.beach_access,
              color: Colors.blue,
              size: 24.0,
            ),
          ],
        )
      )
    );
  }
}

実行結果

薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

Image

https://api.flutter.dev/flutter/widgets/Image-class.html

コード

import 'package:flutter/material.dart';

void main() {
  runApp(const MaterialApp(
    home: MyApp(),
  ));
}

class MyApp extends StatelessWidget {
  const MyApp({ super.key });
  
  
  Widget build(BuildContext context) {
    const imageUrl = "https://flutter.github.io/assets-for-api-docs/assets/widgets/owl.jpg";

    return Scaffold(
      appBar: AppBar(title: const Text("AppBar Title")),
      body: const Center(
        child: Image(
          width: 400,
          height: 400,
          fit: BoxFit.cover,
          image: NetworkImage(imageUrl),
        ),
      ),
    );
  }
}

実行結果

薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

ListView

https://api.flutter.dev/flutter/widgets/ListView-class.html

コード

import 'package:flutter/material.dart';

void main() {
  runApp(const MaterialApp(
    home: MyApp(),
  ));
}

class MyApp extends StatelessWidget {
  const MyApp({ super.key });
  
  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("AppBar Title")),
      body: ListView.builder(
        padding: const EdgeInsets.all(20),
        itemBuilder: (context, index) {
          if (index % 2 == 0) {
            return Container(
              height: 50,
              color: index % 4 == 0 ? Colors.yellow : Colors.blue,
            );
          } else {
            return const Divider();
          }
        },
      ),
    );
  }
}

実行結果

薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

SingleChildScrollView

https://api.flutter.dev/flutter/widgets/SingleChildScrollView-class.html

コード

import 'package:flutter/material.dart';

void main() {
  runApp(const MaterialApp(
    home: MyApp(),
  ));
}

class MyApp extends StatelessWidget {
  const MyApp({ super.key });
  
  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("AppBar Title")),
      body: SingleChildScrollView(
        child: Container(
          width: double.infinity,
          height: 1000,
          color: Colors.yellow,
          alignment: Alignment.center,
          child: const Text(
            "Center",
            style: TextStyle(fontSize: 20),
          ),
        ),
      ),
    );
  }
}

実行結果

薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

GridView

https://api.flutter.dev/flutter/widgets/GridView-class.html

コード

import 'package:flutter/material.dart';

void main() {
  runApp(const MaterialApp(
    home: MyApp(),
  ));
}

class MyApp extends StatelessWidget {
  const MyApp({ super.key });
  
  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("AppBar Title")),
      body: GridView.builder(
        gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
          crossAxisCount: 4,
        ),
        itemBuilder: (context, index) {
          return Container(
            color: _getColor(index),
          );
        },
      ),
    );
  }
  
  _getColor(int index) {
    switch (index % 8) {
      case 0: return Colors.amber;
      case 1: return Colors.blue;
      case 2: return Colors.cyan;
      case 3: return Colors.deepPurple;
      case 4: return Colors.green;
      case 5: return Colors.indigo;
      case 6: return Colors.lime;
      case 7: return Colors.orange;
    }
  }
}

実行結果

薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

画像アセット

https://docs.flutter.dev/development/ui/assets-and-images

コマンド

flutter create hello_image_assets
mkdir -p assets/images
curl https://storage.googleapis.com/cms-storage-bucket/c823e53b3a1a7b0d36a9.png > assets/images/flutter_logo.png

ソースコード

import 'package:flutter/material.dart';

void main() {
  runApp(const MaterialApp(
    home: MyApp(),
  ));
}

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

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("AppBar Title")),
      body: const Center(
        child: Image(image: AssetImage("assets/images/flutter_logo.png")),
      ),
    );
  }
}

実行結果

薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

CircularProgressIndicator

https://api.flutter.dev/flutter/material/CircularProgressIndicator-class.html

コード

import 'package:flutter/material.dart';

void main() {
  runApp(const MaterialApp(
    home: MyApp(),
  ));
}

class MyApp extends StatelessWidget {
  const MyApp({ super.key });
  
  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("AppBar Title")),
      body: const Center(
        child: CircularProgressIndicator(
          strokeWidth: 2,
          color: Colors.amber,
        ),
      ),
    );
  }
}

実行結果

薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

LinearProgressIndicator

https://api.flutter.dev/flutter/material/LinearProgressIndicator-class.html

コード

import 'package:flutter/material.dart';

void main() {
  runApp(const MaterialApp(
    home: MyApp(),
  ));
}

class MyApp extends StatefulWidget {
  const MyApp({ super.key });
  
  
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp>
  with TickerProviderStateMixin {
  late AnimationController controller;
  
  
  void initState() {
    controller = AnimationController(
      vsync: this,
      duration: const Duration(seconds: 5),
    )
      ..addListener(() => setState(() {}))
      ..repeat();

    super.initState();
  }
  
  
  void dispose() {
    controller.dispose();
    super.dispose();
  }
  
  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("AppBar Title")),
      body: Center(
        child: LinearProgressIndicator(
          value: controller.value,
        ),
      ),
    );
  }
}

実行結果

薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

RefreshIndicator

https://api.flutter.dev/flutter/material/RefreshIndicator-class.html

コード

import 'package:flutter/material.dart';

void main() {
  runApp(MaterialApp(
    home: MyApp(),
  ));
}

class MyApp extends StatelessWidget {
  final GlobalKey<RefreshIndicatorState> _key = GlobalKey<RefreshIndicatorState>();

  MyApp({ super.key });
  
  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("AppBar Title")),
      body: RefreshIndicator(
        key: _key,
        onRefresh: () {
          return Future.delayed(const Duration(seconds: 3));
        },
        child: ListView(
          children: List<Widget>.generate(30, (i) {
            return const ListTile(
              title: Text("ListTile Title"),
            );
          }),
        ),
      ),
      floatingActionButton: FloatingActionButton.extended(
        onPressed: () {
          _key.currentState?.show();
        },
        icon: const Icon(Icons.refresh),
        label: const Text("Reload"),
      ),
    );
  }
}

実行結果

薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

TextTheme

https://api.flutter.dev/flutter/material/TextTheme-class.html

コード

import 'package:flutter/material.dart';

void main() {
  runApp(const MaterialApp(
    home: MyApp(),
  ));
}

class MyApp extends StatelessWidget {
  const MyApp({ super.key });
  
  
  Widget build(BuildContext context) {
    final theme = Theme.of(context);

    return Scaffold(
      appBar: AppBar(title: const Text("AppBar Title")),
      body: Center(
        child: Text(
          "Display Large",
          style: theme.textTheme.displayLarge,
        ),
      ),
    );
  }
}

実行結果

薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

ButtonTheme

https://docs.flutter.dev/cookbook/design/themes

コード例

import 'package:flutter/material.dart';

void main() {
  runApp(MaterialApp(
    theme: ThemeData(
      elevatedButtonTheme: ElevatedButtonThemeData(
        style: ElevatedButton.styleFrom(
          backgroundColor: Colors.amber,
          foregroundColor: Colors.black,
        ),
      ),
    ),
    home: const MyApp(),
  ));
}

class MyApp extends StatelessWidget {
  const MyApp({ super.key });
  
  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("AppBar Title")),
      body: Center(
        child: ElevatedButton(
          onPressed: () {},
          child:  const Text("ElevatedButton"),
        ),
      ),
    );
  }
}

実行結果

このスクラップは2023/01/10にクローズされました