🔄
FlutterのPull To Refreshで下から上に引っ張って更新できるようにする方法
FlutterのPull To Refreshは、通常は画面を「上から下に」引っ張ることで更新できます。
ListViewで要素を通常通り上から並べる場合はこれで問題ないのですが、
ListViewを上下逆順にし、要素を下から上に並べたときは、Pull To Refreshも「下から上に」引っ張って更新できるようにしたいので、(やや強引な)方法を考えました。
より良い方法がありましたら教えてください。
Pull To Refreshで下から上に引っ張って更新できるようにする方法
RefreshIndicatorウィジェットをTransform.rotate
で半回転させ、
さらにListViewの要素一つ一つもTransform.rotate
で半回転させます。
Transform.rotate(
angle: pi,
child: RefreshIndicator(
onRefresh: () async {
// ここにRefreshしたときの更新処理を入れる
},
child: ListView.builder(
itemCount: _list.length,
itemBuilder: (context, index) {
return ListTile(
title: Transform.rotate(
angle: pi,
child: Center(
child: Text(_list[index]),
),
),
);
},
),
),
),
仕組みとしては、
RefreshIndicatorを上下逆にすることで、下から上にPull To Refreshできるようになります。
ただこのままではListView自体も上下逆になってしまうので、要素一つ一つを上下逆にすることで、要素が正しい向きで、ListViewの下から上に向かって並びます。
Transform.rotate
の回転させる角度はangle: pi
(ラジアン表記)で180度が指定できます。
(import 'dart:math';
が必要です)
これで、ListViewの要素を下から上に並べた状態で、下からスワイプしてリフレッシュインジケーターが出るようになりました。
全体のコード
import 'dart:math';
import 'package:flutter/material.dart';
class ReversePullToRefreshPage extends StatefulWidget {
const ReversePullToRefreshPage({super.key});
State<ReversePullToRefreshPage> createState() =>
_ReversePullToRefreshPageState();
}
class _ReversePullToRefreshPageState extends State<ReversePullToRefreshPage> {
List<String> _list = ['A', 'B', 'C', 'D'];
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Pull To Refresh'),
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
),
body: Transform.rotate(
angle: pi,
child: RefreshIndicator(
onRefresh: () async {
// ここにRefreshしたときの更新処理を入れる
},
child: ListView.builder(
itemCount: _list.length,
itemBuilder: (context, index) {
return ListTile(
title: Transform.rotate(
angle: pi,
child: Center(
child: Text(_list[index]),
),
),
);
},
),
),
),
);
}
}
おまけ:変更前の全体のコード
普通に要素を上から並べるListViewで、上から下にPull To Refreshするコード
import 'dart:math';
import 'package:flutter/material.dart';
class PullToRefreshPage extends StatefulWidget {
const PullToRefreshPage({super.key});
State<PullToRefreshPage> createState() =>
_PullToRefreshPageState();
}
class _PullToRefreshPageState extends State<PullToRefreshPage> {
List<String> _list = ['A', 'B', 'C', 'D'];
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Pull To Refresh'),
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
),
body: RefreshIndicator(
onRefresh: () async {
// ここにRefreshしたときの更新処理を入れる
},
child: ListView.builder(
itemCount: _list.length,
itemBuilder: (context, index) {
return ListTile(
title: Center(
child: Text(_list[index]),
),
);
},
),
),
);
}
}
Discussion