#flutter #dart
Вопрос:
Я пытаюсь создать приложение для рисования, в котором теперь у вас может быть несколько кистей, когда вы добавляете кисть в список, она добавляется в список, но когда я пытаюсь показать listview.builder
, как она отображается strokeWidth
, она включается null
.
класс поставщика,
import 'package:flutter/material.dart';
import 'package:paint_app/models/brush.dart';
class BrushProvider extends ChangeNotifier {
Map<String, Brush> _brush = {};
Map<String, Brush> get brush => _brush;
int get brushCount => _brush.length;
void addBrush(double strokeWidth, Color color, String id) {
if (_brush.containsKey(strokeWidth)) {
_brush.update(
id,
(value) => Brush(color: color, id: id, strokeWidth: strokeWidth),
);
notifyListeners();
} else {
_brush.putIfAbsent(
id,
() => Brush(
strokeWidth: strokeWidth,
id: DateTime.now().toString(),
color: color),
);
notifyListeners();
}
notifyListeners();
}
}
место, где я пытаюсь это показать,
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> with TickerProviderStateMixin {
List<Offset> _points = <Offset>[];
AnimationController _controller;
double value = 1;
Color pickerColor = Color(0xff443a49);
Color currentColor = Color(0xff443a49);
@override
void initState() {
super.initState();
_controller = AnimationController(
vsync: this,
duration: Duration(milliseconds: 500),
);
}
@override
Widget build(BuildContext context) {
final brushes = Provider.of<BrushProvider>(context);
return Scaffold(
key: _scaffoldKey,
drawer: Drawer(
child: Column(
children: [
SizedBox(
height: 100,
),
Text(
'Add Stroke width',
style: TextStyle(fontSize: 20),
),
SliderTheme(
data: SliderTheme.of(context).copyWith(
activeTrackColor: Colors.red[700],
inactiveTrackColor: Colors.red[100],
trackShape: RoundedRectSliderTrackShape(),
trackHeight: 4.0,
thumbShape: RoundSliderThumbShape(enabledThumbRadius: 12.0),
thumbColor: Colors.redAccent,
overlayColor: Colors.red.withAlpha(32),
overlayShape: RoundSliderOverlayShape(overlayRadius: 28.0),
tickMarkShape: RoundSliderTickMarkShape(),
activeTickMarkColor: Colors.red[700],
inactiveTickMarkColor: Colors.red[100],
valueIndicatorShape: PaddleSliderValueIndicatorShape(),
valueIndicatorColor: Colors.redAccent,
valueIndicatorTextStyle: TextStyle(
color: Colors.white,
),
),
child: Slider(
value: value,
min: 1,
max: 30,
divisions: 30,
label: '${value.round()}',
onChanged: (v) {
setState(
() {
value = v;
},
);
},
),
),
ElevatedButton(
onPressed: () {
brushes.addBrush(
value, currentColor, DateTime.now().toString()); //<-- adding to the list
},
child: Icon(Icons.add),
style: ElevatedButton.styleFrom(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
),
primary: Colors.blueGrey),
),
Divider(
thickness: 2,
),
SizedBox(
height: 50,
),
ListView.builder(
shrinkWrap: true,
itemCount:
brushes.brush.length,
itemBuilder: (context, index) {
if (brushes.brush.length == null ) {
return Text('No Brushes');
}
return Container(
height: 50,
width: double.infinity,
child: Text(
'Stroke Width: ${brushes.brush[index].strokeWidth}'), // <-- here trying to show
color: brushes.brush[index].color,
);
}),
],
),
),
body:(rest of the code...)
класс модели,
import 'package:flutter/cupertino.dart';
class Brush{
final Color color;
final double strokeWidth;
final String id;
Brush({this.strokeWidth,this.color,this.id});
}
кто-нибудь может сказать мне, что я здесь делаю не так?
Ответ №1:
Проблема в том , что вы работаете с картой brushes.brush
, которая зависит от 'key':'value'
пар, но вы рассматриваете ее как список, который зависит от [index]
.
Вы можете преобразовать свою карту в список, а затем работать с ней ListView.builder
.
Попробуйте это:
Widget build(BuildContext context) {
final brushes = Provider.of<BrushProvider>(context, listen:true);
List<Brush> brushList = brushes.brush.entries.map((entry) => entry.value).toList();
и в вашем ListView.builder
, измените его на этот:
ListView.builder(
shrinkWrap: true,
itemCount:
brushList.length,
itemBuilder: (context, index) {
if (brushList.isEmpty ) {
return Text('No Brushes');
}
return Container(
height: 50,
width: double.infinity,
child: Text(
'Stroke Width: ${brushList[index].strokeWidth}'), // <-- should work now
color: brushList[index].color,
);
}),
Комментарии:
1. хорошо, большое вам спасибо, это работает как шарм, но есть ли лучший способ сделать это, или у меня все в порядке?
2. Пожалуйста, я не эксперт, но я думаю, что у вас все в порядке. Я смог понять, что должен делать ваш код и управление состоянием, потому что вы используете имена, которые имеют смысл. Возможно, вам не хватало простой концепции, но все выглядит нормально. Я сменил вашего провайдера на
listen: true
, чтобы ваш список мог обновляться, если что-то будет удалено или добавлено. Продолжай идти!