Reputation: 175
In flutter I'm trying to have one of the columns of a DataTable be a DropdownButton, where the user can select from the DropdownButton and it changes that cells value (and not any other cells, so don't change values in the 1st column at all).
See below for example code (DropdownButton doesn't change cell value), also in DartPad.
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: DataTableDemo(),
);
}
}
class User {
String firstName;
String lastName;
User({this.firstName, this.lastName});
static List<User> getUsers() {
return <User>[
User(firstName: "Paul", lastName: "Rudd"),
User(firstName: "Owen", lastName: "Wilson"),
User(firstName: "Jonah", lastName: "Hill"),
];
}
}
class DataTableDemo extends StatefulWidget {
DataTableDemo() : super();
final String title = "Data Table Flutter Demo";
@override
DataTableDemoState createState() => DataTableDemoState();
}
class DataTableDemoState extends State<DataTableDemo> {
List<User> users;
@override
void initState() {
users = User.getUsers();
super.initState();
}
List<String> lastNamesList = <String>[
'Rudd',
'Wilson',
'Hill',
];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('DropdownButton in DataTable'),
),
body: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: DataTable(
columns: [
DataColumn(
label: Text("FIRST NAME"),
numeric: false,
tooltip: "This is First Name",
),
DataColumn(
label: Text("LAST NAME"),
numeric: false,
tooltip: "This is Last Name",
),
],
rows: users
.map(
(user) => DataRow(cells: [
DataCell(
Text(user.firstName),
onTap: () {
print('Selected firstName: ${user.firstName}');
},
),
DataCell(DropdownButton<String>(
value: user.lastName,
onChanged: (String newValue) {
setState(() {
//help!
});
},
items: lastNamesList
.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
))
]),
)
.toList(),
),
));
}
}
Upvotes: 3
Views: 3514
Reputation: 54377
You can copy paste run full code below
Step 1: You can use a List
selectedUser
to record each selection
Step 2: Use selectedUser.asMap().entries.map
to get index
code snippet
List<User> selectedUser;
...
rows: selectedUser.asMap().entries.map((user) {
int idx = user.key;
print(idx);
return DataRow(cells: [
DataCell(
Text(selectedUser[idx].firstName),
onTap: () {
print('Selected firstName: ${selectedUser[idx].firstName}');
},
),
DataCell(DropdownButton<User>(
value: selectedUser[idx],
onChanged: (User newUser) {
setState(() {
selectedUser[idx] = newUser;
});
},
items: users.map<DropdownMenuItem<User>>((User value) {
return DropdownMenuItem<User>(
value: value,
child: Text(value.lastName),
);
}).toList(),
))
]);
}).toList(),
working demo
full code
import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: DataTableDemo(),
);
}
}
class User {
String firstName;
String lastName;
User({this.firstName, this.lastName});
static List<User> getUsers() {
return <User>[
User(firstName: "Paul", lastName: "Rudd"),
User(firstName: "Owen", lastName: "Wilson"),
User(firstName: "Jonah", lastName: "Hill"),
];
}
}
class DataTableDemo extends StatefulWidget {
DataTableDemo() : super();
final String title = "Data Table Flutter Demo";
@override
DataTableDemoState createState() => DataTableDemoState();
}
class DataTableDemoState extends State<DataTableDemo> {
List<User> users;
List<User> selectedUser;
@override
void initState() {
users = User.getUsers();
selectedUser = List.from(users);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('DropdownButton in DataTable'),
),
body: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: DataTable(
columns: [
DataColumn(
label: Text("FIRST NAME"),
numeric: false,
tooltip: "This is First Name",
),
DataColumn(
label: Text("LAST NAME"),
numeric: false,
tooltip: "This is Last Name",
),
],
rows: selectedUser.asMap().entries.map((user) {
int idx = user.key;
print(idx);
return DataRow(cells: [
DataCell(
Text(selectedUser[idx].firstName),
onTap: () {
print('Selected firstName: ${selectedUser[idx].firstName}');
},
),
DataCell(DropdownButton<User>(
value: selectedUser[idx],
onChanged: (User newUser) {
setState(() {
selectedUser[idx] = newUser;
});
},
items: users.map<DropdownMenuItem<User>>((User value) {
return DropdownMenuItem<User>(
value: value,
child: Text(value.lastName),
);
}).toList(),
))
]);
}).toList(),
),
));
}
}
full code 2, first column value not change
import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: DataTableDemo(),
);
}
}
class User {
String firstName;
String lastName;
User({this.firstName, this.lastName});
static List<User> getUsers() {
return <User>[
User(firstName: "Paul", lastName: "Rudd"),
User(firstName: "Owen", lastName: "Wilson"),
User(firstName: "Jonah", lastName: "Hill"),
];
}
}
class DataTableDemo extends StatefulWidget {
DataTableDemo() : super();
final String title = "Data Table Flutter Demo";
@override
DataTableDemoState createState() => DataTableDemoState();
}
class DataTableDemoState extends State<DataTableDemo> {
List<User> users;
List<User> selectedUser;
@override
void initState() {
users = User.getUsers();
selectedUser = List.from(users);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('DropdownButton in DataTable'),
),
body: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: DataTable(
columns: [
DataColumn(
label: Text("FIRST NAME"),
numeric: false,
tooltip: "This is First Name",
),
DataColumn(
label: Text("LAST NAME"),
numeric: false,
tooltip: "This is Last Name",
),
],
rows: users.asMap().entries.map((user) {
int idx = user.key;
print(idx);
return DataRow(cells: [
/*DataCell(
Text(selectedUser[idx].firstName),
onTap: () {
print('Selected firstName: ${selectedUser[idx].firstName}');
},
),*/
DataCell(
Text(user.value.firstName),
onTap: () {
print('Selected firstName: ${user.value.firstName}');
},
),
DataCell(DropdownButton<User>(
value: selectedUser[idx],
onChanged: (User newUser) {
setState(() {
selectedUser[idx] = newUser;
});
},
items: users.map<DropdownMenuItem<User>>((User value) {
return DropdownMenuItem<User>(
value: value,
child: Text(value.lastName),
);
}).toList(),
))
]);
}).toList(),
),
));
}
}
Upvotes: 4