スクロールできるリスト
ListView/SingleChildScrollView
1. はじめに
リスト表示、それも画面からスクロールできるヴィジェットを2つ。ListView
とSingleChildScrollView
。
今回扱うファイルは下記ディレクトリである。
プロジェクトディレクトリ
│
│── lib
│ │──main
│ │── first_page.dart
│ │── main.dart
│ │── second_page.dart
│
2. ListView
直線的に配置された、スクロール可能なリストが作成出来るヴィジェット
body: Center(
child: ListView(
reverse: true, //要素を逆にすることも可
children: <Widget>[
const Text('こんにちは'),
const Text('こんばんは'),
Container(width: 200, height: 1000, color: Colors.red)
],
),
),
■ ListView.builder
表示したい要素が動的な場合はListView.builder
ヴィジェットを使うと良い
body: Center(
child: ListView.builder(
itemCount: 10,
itemBuilder: (context, index) {
return Container(
child: Text('$index'),
alignment: Alignment.center,
width: 200,
height: 100,
color: Colors.red,
margin: const EdgeInsets.symmetric(vertical: 10));
},
),
),
■ ListView.separated
1行ごとに何かしらの要素を加えたい場合
body: Center(
child: ListView.separated(
separatorBuilder: (context, item) {
return Container(color: Colors.blue, height: 20);
},
itemCount: 10,
itemBuilder: (context, index) {
return Container(
child: Text('$index'),
alignment: Alignment.center,
width: 200,
height: 100,
color: Colors.red,
margin: const EdgeInsets.symmetric(vertical: 10));
},
),
),
2. SingleChildScrollView
子ヴィジェットでColumnやRowと一緒に用いられる。例えば、SingleChildScrollView
の中にColumn
の子ヴィジェットがあれば、縦にはみ出すときに上下スクロールが出来るようになる。Row
の場合は左右スクロールが可能になる。
body: Center(
child: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text('こんにちは'),
const Text('こんばんは'),
Container(
width: 200,
height: 1000,
color: Colors.red,
)
],
))
),
3. とりあえず、練習でこんなやつを。
べたーとはるだけ。
■ main.dart
ここはとくに。
import 'package:flutter/material.dart';
import 'first_page.dart';
//アプリの起動
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.lightGreen,
),
home: FirstPage(),
);
}
}
■ first_page.dart
スクロールできるように無駄にテキストが長い。
import 'package:flutter/material.dart';
import 'package:flutter_sample/second_page.dart';
class FirstPage extends StatelessWidget {
FirstPage({Key? key}) : super(key: key);
String description = '';
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text("Page1")),
body: Center(
child: ListView(
reverse: false, //要素を逆にすることも可
children: <Widget>[
const Padding(
padding: EdgeInsets.all(8.0),
child: Text(
'List Viewのいろいろ',
textAlign: TextAlign.center,
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20),
),
),
SizedBox(
width: 200,
height: 200,
child: Image.network('https://picsum.photos/250?image=9'),
),
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: const [
Text('List Viewは'),
Text('直線的に配置されたスクロール可能な'),
Text('リストが作れる。'),
Text('表示する要素が動的な場合'),
Text('ListView.builderを使うと良い'),
Text('表示する要素が事前に把握しており、'),
Text('且つ一行ごとに何か要素を差し込みたい場合は'),
Text('ListView.separated'),
Text('を使うと良い'),
Text('もう一度言います(再放送)'),
Text('List Viewは'),
Text('直線的に配置されたスクロール可能な'),
Text('リストが作れる。'),
Text('表示する要素が動的な場合'),
Text('ListView.builderを使うと良い'),
Text('表示する要素が事前に把握しており、'),
Text('且つ一行ごとに何か要素を差し込みたい場合は'),
Text('ListView.separated'),
Text('を使うと良い'),
Text('もう一度言います(再々放送)'),
Text('List Viewは'),
Text('直線的に配置されたスクロール可能な'),
Text('リストが作れる。'),
Text('表示する要素が動的な場合'),
Text('ListView.builderを使うと良い'),
Text('表示する要素が事前に把握しており、'),
Text('且つ一行ごとに何か要素を差し込みたい場合は'),
Text('ListView.separated'),
Text('を使うと良い'),
],
),
ElevatedButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => SecondPage(),
fullscreenDialog: true),
);
},
child: const Text("Go to Page2"),
),
],
),
),
);
}
}
■ second_page.dart
リストの項目間で separatorBuilder
で見られるように戻るボタンを挟む(珍)。
import 'package:flutter/material.dart';
class SecondPage extends StatelessWidget {
const SecondPage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text("Page2")),
body: SizedBox(
child: ListView.separated(
separatorBuilder: (context, item) {
return ElevatedButton(
onPressed: () {
Navigator.pop(context);
},
child: const Text("Back"),
);
},
itemCount: 10,
itemBuilder: (context, index) {
return Container(
alignment: Alignment.center,
width: 200,
height: 100,
color: Colors.lime,
margin: const EdgeInsets.symmetric(vertical: 10),
child: Text('$index'));
},
),
),
);
}
}
4. おわりに
UdemyのFlutterラボの講座に依存しつつ、公式ドキュメントを含めた肉付けをしようとしたが、案外さっぱり目。
参考↓