#flutter #dart #controller #flutter-alertdialog
Вопрос:
В моем проекте flutter я хочу сделать экран, на котором пользователь вводит количество для нескольких продуктов. Я хочу управлять текстовыми контроллерами для нескольких строк данных в таблице данных.
Мой код таблицы данных таков:
TextEditingController textController = TextEditingController();
AlertDialog(
content: Container(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.height,
margin: EdgeInsets.all(0),
child: ListView(
padding: EdgeInsets.all(0),
primary: true,
scrollDirection: Axis.vertical,
shrinkWrap: true,
children: [
DataTable(
columns: [
DataColumn(
label: Text(
"Product",
softWrap: true,
),
),
DataColumn(
label: Text(
"Qty",
),
),
DataColumn(
label: Text(
"Rs",
)),
DataColumn(
label: SizedBox(
width: 40,
child: Text(
'BalQty',
),
),
),
DataColumn(
label: SizedBox(
width: 40,
child: Text(
'Stock',
),
),
),
],
rows: listOfProduct!
.map(
((element) => DataRow(
cells: <DataCell>[
DataCell(Text(
element.name,
)),
DataCell(
TextField(
controller: textEditingController,
maxLength: 4,
decoration: InputDecoration(
labelText: 'Qty',
labelStyle: TextStyle(fontSize: 9.sp),
counterText: "",
),
),
),
DataCell(
Text(
(element.pTR ?? 0).toStringAsFixed(2),
),
),
DataCell(Text(
element.text!.printDashIfEmpty(),
)),
DataCell(Text(
(element.balQty ?? 0).toStringAsFixed(2),
)),
],
)),
)
.toList(),
),
],
),
),
actions: <Widget>[
OutlinedButton(
onPressed: () {
Navigator.pop(context);
},
child: Text(
"Cancel",
)),
SizedBox(
width: 10,
),
OutlinedButton(
onPressed: () async {
print("QUANTITY : $textEditingController");
listSearchProductMaster!.forEach((e) {
return print("TEXT CONTROLLER: ${e.textEditingController}");
});
},
child: Text(
"Add",
))
],
)
Вывод, который я вижу, заключается в том, что количество, которое вставляет пользователь, должно быть добавлено к конкретному продукту.
В настоящее время вывод моего приложения выглядит следующим образом
Кто-нибудь помогает?
Ответ №1:
Ну, в моем случае мой подход был:
- Когда пользователь нажимает элемент для редактирования, отображается модальный с начальным значением
- Пользователь вводит данные и нажимает кнопку Подтверждения вкладки
- после действительного ввода примените
Он включает в себя узел фокусировки и контроллер, поэтому прост в использовании.
Но это заставляет пользователя копаться еще на 1 уровне пользовательского интерфейса, так что, возможно, есть лучшие способы, но это все равно работает.
Я сделал виджет TextEditModal и функцию, чтобы показать это.
Future<String> showSingleTextEditDialog({
@required BuildContext context,
String initText = '',
}) async {
String text = initText;
bool submit = false;
await showDialog(
context: context,
builder: (_) {
return _SingleTextEditDialog(
text: text,
textChanged: (value) => text = value,
onSubmit: () => submit = true,
);
},
);
return submit ? text : null;
}
class _SingleTextEditDialog extends StatefulWidget {
_SingleTextEditDialog({
Key key,
@required this.text,
@required this.textChanged,
this.onSubmit,
}) : super(key: key);
final String text;
final ValueChanged<String> textChanged;
final VoidCallback onSubmit;
@override
_SingleTextEditDialogState createState() => _SingleTextEditDialogState();
}
class _SingleTextEditDialogState extends State<_SingleTextEditDialog> {
TextEditingController textController;
@override
void initState() {
super.initState();
textController = TextEditingController(text: widget.text);
}
@override
void dispose() {
textController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return SimpleDialog(
children: [
DecoInput(
controller: textController,
onChanged: widget.textChanged,
),
VSpace.md,
StyledInterfaceButton(
onTap: () {
setState(() => widget.onSubmit());
Navigator.of(context).pop();
},
text: 'Confirm',
),
// VSpace.md,
],
);
}
}
и использовать как
onTap: () async {
HapticFeedback.mediumImpact();
final input = await showSingleTextEditDialog(
context: context,
initText: text,
);
if (input == null) return;
// valid user input here
valueChanged(input); // apply user input
},
Это не полный код. Я свернул код для удобства чтения. Так что игнорируйте, если есть какие-либо ошибки.
Ответ №2:
Добавьте свой код таблицы в SingleChildScrollView() с scrollDirection: Axis.horizontal
приведенным ниже кодом, надеюсь, это поможет вам
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Column(
children: <Widget>[
Container(
margin: EdgeInsets.all(20),
child: Table(
defaultColumnWidth: FixedColumnWidth(80.0),
border: TableBorder.all(
color: Colors.black,
style: BorderStyle.solid,
width: 2),
children: [
TableRow(
children: [
Column(
children: [
Text(
'Website',
style: TextStyle(fontSize: 20.0),
),
],
),
Column(
children: [
Text(
'Tutorial',
style: TextStyle(fontSize: 20.0),
),
],
),
Column(
children: [
Text(
'Review',
style: TextStyle(fontSize: 20.0),
),
],
),
Column(children: [
Text(
'Review',
style: TextStyle(fontSize: 20.0),
),
]),
Column(
children: [
Text(
'Review',
style: TextStyle(fontSize: 20.0),
),
],
),
],
),
TableRow(children: [
Column(
children: [
Text('Javatpoint'),
],
),
Column(
children: [
Text('Flutter'),
],
),
Column(
children: [
Text('5*'),
],
),
Column(
children: [
Text('5*'),
],
),
Column(
children: [
Text('5*'),
],
),
]),
TableRow(
children: [
Column(children: [
Text('Javatpoint'),
]),
Column(
children: [
Text('MySQL'),
],
),
Column(
children: [
Text('5*'),
],
),
Column(children: [
Text('5*'),
]),
Column(children: [
Text('5*'),
]),
],
),
],
),
),
],
),
),
Прокрутите таблицу по горизонтали