Я новичок в флаттере и дарте, начал учиться около двух недель назад. Мое первое приложение, которое я пытаюсь создать в качестве начального проекта, представляет собой простой калькулятор дозировки для расчета количества анестетика, которое необходимо добавить, в зависимости от количества и веса мышей.
Итак, к моей проблеме: мне удалось создать самые основные элементы пользовательского интерфейса и создать выпадающее меню для протокола анестезии, который хочет использовать пользователь. На основе выбранного элемента я хотел бы отображать различные текстовые элементы в столбце, представляющие различные лекарства, из которых состоит протокол. Например, если пользователь выбирает ММФ, он будет отображать медетомидин, мидазолам и фентанил.
Я везде искал условное создание виджетов и пока не нашел решения, подходящего для моей проблемы. Может быть, я просто плохо ищу. Поскольку я немного знаком с Python, я подумал, что должно быть довольно просто настроить что-то подобное, используя операторы if, основанные на переменной, которая создается при изменении selectedItem. Однако я не нашел, как создать эти переменные, чтобы затем использовать их для реализации в столбце.
Извините за стену текста, надеюсь, вы сможете мне помочь, заранее спасибо!
Вот мой код:
import 'package:flutter/material.dart';
import 'package:flutter_spinbox/flutter_spinbox.dart';
void main() => runApp(MyApp());
/// This is the main application widget.
class MyApp extends StatelessWidget {
static const String _title = 'Dosierungsrechner';
Color c = const Color.fromRGBO(17, 29, 78, 1.0);
Color b = const Color.fromRGBO(223, 240, 250, 1.0);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: _title,
home: Scaffold(
appBar: AppBar(title: const Text(_title),
centerTitle:true,
backgroundColor: c,
),
body: Column(
children: [
Align(
alignment: Alignment.topCenter,
child: Column(
children: <Widget> [
Padding(
padding:const EdgeInsets.all(8.0),
child: Container(
height:60,
decoration:BoxDecoration(
color: b,
borderRadius: BorderRadius.circular(10.0)
),
child: Align(
alignment:Alignment.bottomCenter,
child:MyStatefulWidget(),
),
),
),
Padding(
padding:const EdgeInsets.all(8.0),
child:Container(
height:40,
decoration:BoxDecoration(
color: b,
borderRadius: BorderRadius.circular(10.0)
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Flexible(
child: Text('Anzahl der Mäuse:',
textAlign: TextAlign.center,
style: TextStyle(fontWeight: FontWeight.bold),
),
),
Flexible(
child: SpinBox(
min: 0,
max: 100,
value: 0,
onChanged: (value) => print(value),
),
),
],
),
),
),
Padding(
padding:const EdgeInsets.all(8.0),
child:Container(
height:40,
decoration:BoxDecoration(
color: b,
borderRadius: BorderRadius.circular(10.0)
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Flexible(
child: Text('Gewicht/Maus in g:',
textAlign: TextAlign.center,
style: TextStyle(fontWeight: FontWeight.bold),
),
),
Flexible(
child: SpinBox(
min: 0,
max: 50,
value: 0,
onChanged: (value) => print(value),
),
),
],
),
),
),
],
),
),
Text('Anzumischende Bestandteile',
style: TextStyle(fontWeight: FontWeight.bold),
textAlign: TextAlign.center,
),
Padding(
padding:const EdgeInsets.all(8.0),
child: Container(
height:200,
decoration:BoxDecoration(
color: b,
borderRadius: BorderRadius.circular(10.0)
),
child: Align(
alignment: Alignment.center,
child: Column(
children:[
Text('Midazolam 5mg/ml'),
Text('Medetomidin 5mg/ml'),
Text('Fentanyl 1mg/ml'),
],
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
),
),
),
),
Padding(
padding:const EdgeInsets.all(8.0),
child: Container(
height:200,
decoration:BoxDecoration(
color: b,
borderRadius: BorderRadius.circular(10.0)
),
child: Align(
alignment: Alignment.center,
child: Text('Testausgabe2'),
),
),
),
],
),
),
);
}
}
/// This is the stateful widget that the main application instantiates.
class MyStatefulWidget extends StatefulWidget {
MyStatefulWidget({Key key}) : super(key: key);
@override
_MyStatefulWidgetState createState() => _MyStatefulWidgetState();
}
/// This is the private State class that goes with MyStatefulWidget.
class _MyStatefulWidgetState extends State<MyStatefulWidget> {
final List<String> items = <String>['Protokoll auswählen', 'MMF', 'MM','MMB','AA','AAN'];
String selectedItem = 'Protokoll auswählen';
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 12.0),
child:DropdownButtonHideUnderline(
child: DropdownButton<String>(
value: selectedItem,
onChanged: (String string) => setState(() => selectedItem = string),
selectedItemBuilder: (BuildContext context) {
return items.map<Widget>((String item) {
return Text(item,
style: TextStyle(fontWeight: FontWeight.bold),
textAlign: TextAlign.right,
);
}).toList();
},
items: items.map((String item) {
return DropdownMenuItem<String>(
child: Text('$item',
style: TextStyle(fontWeight: FontWeight.bold),
textAlign: TextAlign.right,
),
value: item,
);
}).toList(),
),
),
);
}
}
Вы ищете государственное управление.
Это тот момент в путешествии по флаттеру, когда все может стать довольно сложным по сравнению с тем, насколько легко и быстро можно создать пользовательский интерфейс.
Вот хороший туториал по управлению состоянием: https://thewikihow.com/video_jdUBV7AWL2U
Я обновил ваш код простейшей формой управления состоянием (streamBuilder).
import 'package:flutter/material.dart';
import 'package:flutter_spinbox/flutter_spinbox.dart';
void main() => runApp(MyApp());
StreamController streamController = StreamController();
/// This is the main application widget.
class MyApp extends StatelessWidget {
static const String _title = 'Dosierungsrechner';
Color c = const Color.fromRGBO(17, 29, 78, 1.0);
Color b = const Color.fromRGBO(223, 240, 250, 1.0);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: _title,
home: Scaffold(
appBar: AppBar(title: const Text(_title),
centerTitle: true,
backgroundColor: c,
),
body: Column(
children: [
Align(
alignment: Alignment.topCenter,
child: Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
height: 60,
decoration: BoxDecoration(
color: b,
borderRadius: BorderRadius.circular(10.0)
),
child: Align(
alignment: Alignment.bottomCenter,
child: MyStatefulWidget(),
),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
height: 40,
decoration: BoxDecoration(
color: b,
borderRadius: BorderRadius.circular(10.0)
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Flexible(
child: Text('Anzahl der Mäuse:',
textAlign: TextAlign.center,
style: TextStyle(fontWeight: FontWeight.bold),
),
),
Flexible(
child: SpinBox(
min: 0,
max: 100,
value: 0,
onChanged: (value) => print(value),
),
),
],
),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
height: 40,
decoration: BoxDecoration(
color: b,
borderRadius: BorderRadius.circular(10.0)
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Flexible(
child: Text('Gewicht/Maus in g:',
textAlign: TextAlign.center,
style: TextStyle(fontWeight: FontWeight.bold),
),
),
Flexible(
child: SpinBox(
min: 0,
max: 50,
value: 0,
onChanged: (value) => print(value),
),
),
],
),
),
),
],
),
),
Text('Anzumischende Bestandteile',
style: TextStyle(fontWeight: FontWeight.bold),
textAlign: TextAlign.center,
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
height: 200,
decoration: BoxDecoration(
color: b,
borderRadius: BorderRadius.circular(10.0)
),
child: Align(
alignment: Alignment.center,
child: StreamBuilder(
stream: streamController.stream,
builder: (context, snapshot) {
return updateBestandteile(snapshot.data);
},
),
),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
height: 200,
decoration: BoxDecoration(
color: b,
borderRadius: BorderRadius.circular(10.0)
),
child: Align(
alignment: Alignment.center,
child: Text('Testausgabe2'),
),
),
),
],
),
),
);
}
Column updateBestandteile(String i) {
switch (i) {
case "MMF":
{
return Column(
children: [
Text('Midazolam 5mg/ml'),
Text('Medetomidin 5mg/ml'),
Text('Fentanyl 1mg/ml'),
],
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
);
}
break;
case "MM":
{
return Column(
children: [
Text('MM'),
Text('MM'),
Text('MM'),
],
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
);
}
break;
case "MMB":
{
return Column(
children: [
Text('MMB'),
Text('MMB'),
Text('MMB'),
],
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
);
}
break;
case "AA":
{
return Column(
children: [
Text('AA'),
Text('AA'),
Text('AA'),
],
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
);
}
break;
case "AAN":
{
return Column(
children: [
Text('AAN'),
Text('AAN'),
Text('AAN'),
],
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
);
}
break;
default: { return Column(
children: [
Text('No choice made'),
Text(''),
Text(''),
],
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
);}
break;
}
}
}
/// This is the stateful widget that the main application instantiates.
class MyStatefulWidget extends StatefulWidget {
MyStatefulWidget({Key key}) : super(key: key);
@override
_MyStatefulWidgetState createState() => _MyStatefulWidgetState();
}
/// This is the private State class that goes with MyStatefulWidget.
class _MyStatefulWidgetState extends State<MyStatefulWidget> {
final List<String> items = <String>['Protokoll auswählen', 'MMF', 'MM','MMB','AA','AAN'];
String selectedItem = 'Protokoll auswählen';
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 12.0),
child:DropdownButtonHideUnderline(
child: DropdownButton<String>(
value: selectedItem,
onChanged: (String string) => setState(() {
streamController.sink.add(string);
return selectedItem = string;
}),
selectedItemBuilder: (BuildContext context) {
return items.map<Widget>((String item) {
return Text(item,
style: TextStyle(fontWeight: FontWeight.bold),
textAlign: TextAlign.right,
);
}).toList();
},
items: items.map((String item) {
return DropdownMenuItem<String>(
child: Text('$item',
style: TextStyle(fontWeight: FontWeight.bold),
textAlign: TextAlign.right,
),
value: item,
);
}).toList(),
),
),
);
}
}
Спасибо за ответ и код! Теперь я наконец знаю, что мне нужно искать! Ты восхитителен :)