長さの異なるデータの 3 つのリストを処理する 1 つの PageView があります。リスト 1 には 1 つの項目があり、リスト 2 には 2 つの項目があり、リスト 3 には 3 つの項目があります。これが何が起こっているかです。
- PageView は、リスト 1 itemCount = 1 およびページ 0 で構築されます。
- PageView は、リスト 2 itemCount = 2 およびページ 0 で構築されます。
- PageView は、リスト 3 itemCount = 3 およびページ 2 で構築されます。
- PageController.jumpToPage(2) が呼び出されます。
- ページ 2 が表示され、自動的にページ 1 にスクロールします。
PageController が古い itemCount = 2 の値をどこかで読み取っていると考えて、ビルド メソッドで WidgetsBinding.instance.addPostFrameCallback(...) を使用して PageView がビルドされた後に jumpToPage(2) を呼び出してみました。それはうまくいきませんでした。
新しい PageView itemCount = 3 に基づいて jumpToPage(2) を機能させるにはどうすればよいですか?
これが私のコードです。できるだけシンプルにしようとしました。
import 'package:flutter/material.dart';
class HomePage2 extends StatefulWidget {
@override
_HomePage2State createState() => _HomePage2State();
}
class _HomePage2State extends State<HomePage2> {
List<Map<String, dynamic>> following = [
{'title': 'Page 1 of 1 following', 'color': Colors.purple.value},
];
List<Map<String, dynamic>> suggested = [
{'title': 'Page 1 of 2 suggested', 'color': Colors.purple.value},
{'title': 'Page 2 of 2 suggested', 'color': Colors.red.value},
];
List<Map<String, dynamic>> trending = [
{'title': 'Page 1 of 3 trending', 'color': Colors.purple.value},
{'title': 'Page 2 of 3 trending', 'color': Colors.red.value},
{'title': 'Page 3 of 3 trending', 'color': Colors.orange.value},
];
String currentFeed = 'suggested';
int followingCurrentPosition = 0;
int suggestedCurrentPosition = 0;
int trendingCurrentPosition = 0;
PageController _pageController;
@override
void initState() {
super.initState();
_pageController = PageController();
}
@override
void dispose() {
_pageController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
print('build');
WidgetsBinding.instance.addPostFrameCallback(
(_) => _pageController.jumpToPage(getCurrentFeedPosition()));
return Scaffold(
body: PageView.builder(
itemCount: getCurrentFeed().length,
scrollDirection: Axis.vertical,
controller: _pageController = PageController(viewportFraction: 1),
itemBuilder: (context, index) {
print('PageView itemBuilder');
return Container(
color: Color(getCurrentFeed()[index]['color']),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Center(
child: Text(getCurrentFeed()[index]['title']),
),
Center(
child: RaisedButton(
onPressed: () => changeCurrentFeed(),
child: Text('Change Feed'),
),
),
],
),
);
},
),
);
}
void changeCurrentFeed() {
setState(
() {
if (currentFeed == 'following') {
followingCurrentPosition = _pageController.page.floor();
currentFeed = 'suggested';
} else if (currentFeed == 'suggested') {
suggestedCurrentPosition = _pageController.page.floor();
currentFeed = 'trending';
} else {
trendingCurrentPosition = _pageController.page.floor();
currentFeed = 'following';
}
},
);
}
List<Map<String, dynamic>> getCurrentFeed() {
if (currentFeed == 'following') {
return following;
} else if (currentFeed == 'suggested') {
return suggested;
} else {
return trending;
}
}
int getCurrentFeedPosition() {
if (currentFeed == 'following') {
return followingCurrentPosition;
} else if (currentFeed == 'suggested') {
return suggestedCurrentPosition;
} else {
return trendingCurrentPosition;
}
}
}