Flattern - Raster dynamischer anzeigen
Ich bin ein bisschen neu in Flutter und neu in der Arbeit mit der Benutzeroberfläche. Ich versuche, eine Reihe von Optionsfeldern für die Wochentage anzuzeigen, und möchte, dass die Felder, die jeden Tag enthalten, zur Länge des Textes passen, ohne den Text zu verkleinern. Dann möchte ich alle Boxen in einem Set zeigen, aber sie passen gut zusammen. Folgendes habe ich jetzt gefolgt von dem, was ich gerne hätte:
Die Kästchen im zweiten Bild sollten unterschiedliche Tage haben und einige von ihnen wären breiter als andere, aber das ist meine grobe Visualisierung davon.
Ich habe verschiedene Kombinationen von großen, angepassten und begrenzten Feldern für die einzelnen Felder und eine Rasteransicht im Vergleich zu einer Spalte mit zwei Zeilen ausprobiert, um den Satz von Feldern anzuzeigen.
Hier ist der Code, den ich derzeit habe. Ich freue mich über Erkenntnisse oder Erklärungen, die jemand für die Arbeit mit Flutter-Layouts haben kann.
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
class TimeRadioModel {
bool isSelected;
String timeText;
TimeRadioModel(this.isSelected, this.timeText);
}
class TimeRadioItem extends StatelessWidget {
final TimeRadioModel item;
TimeRadioItem(this.item);
@override
Widget build(BuildContext context) {
return LimitedBox(
child: Container(
child: Text(
item.timeText,
style: TextStyle(fontSize: 12),
textAlign: TextAlign.center,
),
padding: EdgeInsets.all(4),
decoration: BoxDecoration(
shape: BoxShape.rectangle,
color: Colors.amber,
border: item.isSelected ? Border.all(width: 0.1) : null,
boxShadow: item.isSelected
? [
BoxShadow(
color: Colors.grey.withOpacity(0.3),
spreadRadius: 2,
blurRadius: 3,
offset: Offset(1, 1.5),
),
]
: null,
borderRadius: BorderRadius.all(Radius.circular(7)),
),
),
);
}
}
class CustomTimeRadio extends StatefulWidget {
@override
_CustomTimeRadioState createState() => _CustomTimeRadioState();
}
class _CustomTimeRadioState extends State<CustomTimeRadio> {
List<TimeRadioModel> timeChoices = new List<TimeRadioModel>();
final currTime = DateTime.now().weekday;
// m = 1, t = 2, w = 3, th = 4, f = 5, s = 6, su = 7
@override
void initState() {
super.initState();
if (currTime == 1) {
timeChoices.add(TimeRadioModel(false, 'Today'));
timeChoices.add(TimeRadioModel(false, 'Tomorrow'));
timeChoices.add(TimeRadioModel(false, 'Wednesday'));
timeChoices.add(TimeRadioModel(false, 'Thursday'));
timeChoices.add(TimeRadioModel(false, 'Friday'));
timeChoices.add(TimeRadioModel(false, 'Saturday'));
timeChoices.add(TimeRadioModel(false, 'Sunday'));
} else if (currTime == 2) {
timeChoices.add(TimeRadioModel(false, 'Today'));
timeChoices.add(TimeRadioModel(false, 'Tomorrow'));
timeChoices.add(TimeRadioModel(false, 'Thursday'));
timeChoices.add(TimeRadioModel(false, 'Friday'));
timeChoices.add(TimeRadioModel(false, 'Saturday'));
timeChoices.add(TimeRadioModel(false, 'Sunday'));
timeChoices.add(TimeRadioModel(false, 'Monday'));
} else if (currTime == 3) {
timeChoices.add(TimeRadioModel(false, 'Today'));
timeChoices.add(TimeRadioModel(false, 'Tomorrow'));
timeChoices.add(TimeRadioModel(false, 'Friday'));
timeChoices.add(TimeRadioModel(false, 'Saturday'));
timeChoices.add(TimeRadioModel(false, 'Sunday'));
timeChoices.add(TimeRadioModel(false, 'Monday'));
timeChoices.add(TimeRadioModel(false, 'Tuesday'));
} else if (currTime == 4) {
timeChoices.add(TimeRadioModel(false, 'Today'));
timeChoices.add(TimeRadioModel(false, 'Tomorrow'));
timeChoices.add(TimeRadioModel(false, 'Saturday'));
timeChoices.add(TimeRadioModel(false, 'Sunday'));
timeChoices.add(TimeRadioModel(false, 'Monday'));
timeChoices.add(TimeRadioModel(false, 'Tuesday'));
timeChoices.add(TimeRadioModel(false, 'Wednesday'));
} else if (currTime == 5) {
timeChoices.add(TimeRadioModel(false, 'Today'));
timeChoices.add(TimeRadioModel(false, 'Tomorrow'));
timeChoices.add(TimeRadioModel(false, 'Sunday'));
timeChoices.add(TimeRadioModel(false, 'Monday'));
timeChoices.add(TimeRadioModel(false, 'Tuesday'));
timeChoices.add(TimeRadioModel(false, 'Wednesday'));
timeChoices.add(TimeRadioModel(false, 'Thursday'));
} else if (currTime == 6) {
timeChoices.add(TimeRadioModel(false, 'Today'));
timeChoices.add(TimeRadioModel(false, 'Tomorrow'));
timeChoices.add(TimeRadioModel(false, 'Monday'));
timeChoices.add(TimeRadioModel(false, 'Tuesday'));
timeChoices.add(TimeRadioModel(false, 'Wednesday'));
timeChoices.add(TimeRadioModel(false, 'Thursday'));
timeChoices.add(TimeRadioModel(false, 'Friday'));
} else {
timeChoices.add(TimeRadioModel(false, 'Today'));
timeChoices.add(TimeRadioModel(false, 'Tomorrow'));
timeChoices.add(TimeRadioModel(false, 'Tuesday'));
timeChoices.add(TimeRadioModel(false, 'Wednesday'));
timeChoices.add(TimeRadioModel(false, 'Thursday'));
timeChoices.add(TimeRadioModel(false, 'Friday'));
timeChoices.add(TimeRadioModel(false, 'Saturday'));
}
timeChoices.add(TimeRadioModel(false, 'Anytime'));
}
@override
Widget build(BuildContext context) {
return SizedBox(
height: 100,
width: 200,
child: Column(
children: [
Row(
children: [
for (int i = 0; i < timeChoices.length - 4; i++)
IconButton(
padding: EdgeInsets.fromLTRB(2, 1, 2, 1),
icon: new TimeRadioItem(timeChoices[i]),
onPressed: () {
setState(() {
timeChoices.forEach((element) {
element.isSelected = false;
});
timeChoices[i].isSelected = true;
});
},
),
],
),
Row(
children: [
for (int i = 4; i < timeChoices.length; i++)
IconButton(
padding: EdgeInsets.fromLTRB(2, 1, 2, 1),
icon: new TimeRadioItem(timeChoices[i]),
onPressed: () {
setState(() {
timeChoices.forEach((element) {
element.isSelected = false;
});
timeChoices[i].isSelected = true;
});
},
),
],
)
],
),
);
}
}
Antworten
Sie können es mit einem Wrap anstelle von setzen row
Wrap(
children: [
for (int i = 4; i < timeChoices.length; i++)
IconButton(
padding: EdgeInsets.fromLTRB(2, 1, 2, 1),
icon: new TimeRadioItem(timeChoices[i]),
onPressed: () {
setState(() {
timeChoices.forEach((element) {
element.isSelected = false;
});
timeChoices[i].isSelected = true;
});
},
),
],
)
Lesen Sie hier mehr über das Wrap-Widget https://medium.com/flutter-community/flutter-wrap-widget-e1ee0b005b16
Ich glaube, ich konnte es mit Hilfe früherer Antworten herausfinden. Um die Größe meiner Tagesboxen entsprechend ihrem Text zu bestimmen, habe ich im TimeRadioItem-Widget eine Box mit Größe verwendet, die ihre Breite aus der Länge des Textes berechnet hat:
return SizedBox(
width: item.timeText.length * 9.0,
child: Container(
child: Text(
item.timeText,
style: TextStyle(fontSize: 12),
textAlign: TextAlign.center,
),
padding: EdgeInsets.fromLTRB(0, 4, 0, 4),
decoration: BoxDecoration(
shape: BoxShape.rectangle,
color: Colors.amber,
border: item.isSelected ? Border.all(width: 0.1) : null,
boxShadow: item.isSelected
? [
BoxShadow(
color: Colors.grey.withOpacity(0.3),
spreadRadius: 2,
blurRadius: 3,
offset: Offset(1, 1.5),
),
]
: null,
borderRadius: BorderRadius.all(Radius.circular(7)),
),
),
);
Ich konnte dann die Tage so einstellen, dass sie in meinem CustomTimeRadio-Widget ordnungsgemäß als Satz angezeigt wurden, indem ich Wrap und einen GestureDetector anstelle eines IconButton verwendete:
return SizedBox(
width: 250,
child: Wrap(
children: [
for (int i = 0; i < timeChoices.length; i++)
GestureDetector(
child: Container(
padding: EdgeInsets.fromLTRB(2, 1, 2, 1),
child: new TimeRadioItem(timeChoices[i]),
),
onTap: () {
setState(() {
timeChoices.forEach((element) {
element.isSelected = false;
});
timeChoices[i].isSelected = true;
});
},
),
],
),
);