状態管理のProviderを利用している際に以下のようなPickerを実装する方法を書き記します
↓
実装方法
フォルダ構成
lib
┗ models
┗profile_model.dart
┗ pickers
┗location.dart
┗ providers
┗profile_provider.dart
┗ screens
┗my_profile_screen.dart
main.dart
コード
main.dart
import 'package:flutter/material.dart';
import 'package:matchingappweb/providers/profile_provider.dart';
import 'package:matchingappweb/screens/my_profile_screen.dart';
import 'package:provider/provider.dart';
void main() {
runApp(
MultiProvider(
providers: [
ChangeNotifierProvider(create: (_) => ProfileProvider()),
],
child: const MyApp(),
),
);
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
home: MyProfileScreen(),
routes: <String, WidgetBuilder>{
'/my-profile': (BuildContext context) => MyProfileScreen(),
},
);
}
}
location_picker.dart
final Map<String, String> locationPicker = {
'hokkaido' : '北海道',
'tohoku' : '東北',
'kanto' : '関東',
'hokuriku' : '北陸',
'chubu' : '中部',
'chugoku' : '中国',
'shikoku' : '四国',
'kyushu' : '九州',
};
profile_model.dart
class ProfileModel {
late String? location = '';
ProfileModel({
this.location,
});
}
profile_provider.dart
import 'package:flutter/material.dart';
import '../models/profile_model.dart';
class ProfileProvider with ChangeNotifier {
ProfileModel myProfile = ProfileModel(
location: null,
);
}
my_profile_screen.dart
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:matchingappweb/providers/profile_provider.dart';
import 'package:provider/provider.dart';
import '../pickers/location_picker.dart';
class MyProfileScreen extends StatelessWidget {
const MyProfileScreen({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('マイプロフィール'),
),
body: Consumer<ProfileProvider>(
builder: (context, profileProvider, _) {
return Padding(
padding: const EdgeInsets.all(32.0),
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Row(
children: [
const Text('居住エリア ',),
Text(locationPicker[profileProvider.myProfile.location] ?? '', style: const TextStyle(fontWeight: FontWeight.bold)),
TextButton(
child: const Text('選択'),
onPressed: () {
showModalBottomSheet(
context: context,
builder: (BuildContext context) {
return Container(
height: MediaQuery.of(context).size.height / 2,
child: Column(
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
TextButton(
child: const Text('戻る'),
onPressed: () => Navigator.pop(context),
),
TextButton(
child: const Text('決定'),
onPressed: () {
profileProvider.notifyListeners();
Navigator.pop(context);
},
),
],
),
Container(
height: MediaQuery.of(context).size.height / 3,
child: CupertinoPicker(
itemExtent: 40,
children: [
for (String key in locationPicker.keys) ... {
Text(locationPicker[key] ?? '住所不定')
},
],
onSelectedItemChanged: (int index) => profileProvider.myProfile.location = locationPicker.keys.elementAt(index),
),
)
],
),
);
}
);
},
),
],
),
],
),
),
);
},
),
);
}
}
以上です