Skip to content

Instantly share code, notes, and snippets.

@vabym8
Created February 18, 2021 07:58
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vabym8/d4ed0aae5e9d9db308718f6d0c3d093d to your computer and use it in GitHub Desktop.
Save vabym8/d4ed0aae5e9d9db308718f6d0c3d093d to your computer and use it in GitHub Desktop.
Creating a custom Flutter DropDown button as a separate widget
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