Created
February 18, 2021 07:58
-
-
Save vabym8/d4ed0aae5e9d9db308718f6d0c3d093d to your computer and use it in GitHub Desktop.
Creating a custom Flutter DropDown button as a separate widget
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'package:flutter/material.dart'; | |
class TestPage extends StatefulWidget { | |
@override | |
_TestPageState createState() => _TestPageState(); | |
} | |
class _TestPageState extends State<TestPage> { | |
List<Activities> _activities = [ | |
Activities(id: 1, icon: Icons.place, title: 'Travel'), | |
Activities(id: 2, icon: Icons.food_bank, title: 'Eat'), | |
]; | |
List<DropdownMenuItem<Activities>> activityListDropDownItems = []; | |
Activities selectedActivity; | |
int selectedActivityId = 0; | |
String selectedActivityTitle = ''; | |
IconData selectedActivityIcon = Icons.addchart; | |
List<DropdownMenuItem<Activities>> buildActivityList(List activities) { | |
List<DropdownMenuItem<Activities>> items = []; | |
for (Activities activity in activities) { | |
items.add( | |
DropdownMenuItem( | |
value: activity, | |
child: Row( | |
children: [ | |
Text( | |
'${activity.title}', | |
style: TextStyle( | |
color: Colors.red, | |
), | |
), | |
], | |
), | |
), | |
); | |
} | |
return items; | |
} | |
// VOID | |
void onChangeActivityListDropDownItem(Activities selected) { | |
setState(() { | |
selectedActivity = selected; | |
selectedActivityId = selected.id; | |
selectedActivityTitle = selected.title; | |
selectedActivityIcon = selected.icon; | |
}); | |
} | |
@override | |
void initState() { | |
activityListDropDownItems = buildActivityList(_activities); | |
super.initState(); | |
} | |
@override | |
Widget build(BuildContext context) { | |
return Scaffold( | |
appBar: AppBar( | |
title: Text('Custom DropDown'), | |
), | |
body: Padding( | |
padding: const EdgeInsets.all(16.0), | |
child: Column( | |
mainAxisAlignment: MainAxisAlignment.center, | |
children: [ | |
Text('$selectedActivityTitle'), | |
SizedBox(height: 20.0), | |
// pass the class | |
MyDropDown<Activities>( | |
hintText: 'Activites', | |
icon: selectedActivityIcon, | |
value: selectedActivity, | |
items: activityListDropDownItems, | |
onChanged: onChangeActivityListDropDownItem, | |
), | |
], | |
), | |
), | |
); | |
} | |
} | |
// class that can accept type T | |
class MyDropDown<T> extends StatelessWidget { | |
final List<DropdownMenuItem> items; | |
final IconData icon; | |
final T value; | |
final String hintText; | |
// ValueChanged with the passed type | |
final ValueChanged<T> onChanged; | |
const MyDropDown( | |
{Key key, | |
@required this.items, | |
this.icon, | |
this.value, | |
this.hintText, | |
this.onChanged}) | |
: super(key: key); | |
@override | |
Widget build(BuildContext context) { | |
return Container( | |
padding: EdgeInsets.symmetric(horizontal: 10.0), | |
decoration: BoxDecoration( | |
color: Colors.white, | |
border: Border.all( | |
color: Colors.grey, | |
width: 0.3, | |
), | |
borderRadius: BorderRadius.all( | |
Radius.circular( | |
30.0, | |
), | |
), | |
), | |
child: Row( | |
children: [ | |
SizedBox(width: 10.0), | |
Icon( | |
icon, | |
color: Colors.red.withOpacity(0.7), | |
), | |
SizedBox(width: 10.0), | |
Expanded( | |
// T | |
child: DropdownButton<T>( | |
hint: Text( | |
hintText, | |
style: TextStyle(), | |
), | |
isExpanded: true, | |
value: value, | |
items: items, | |
onChanged: onChanged, | |
underline: Container(), | |
), | |
) | |
], | |
), | |
); | |
} | |
} | |
class Activities { | |
final int id; | |
final IconData icon; | |
final String title; | |
Activities({@required this.id, @required this.icon, @required this.title}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment