【发布时间】:2019-08-26 08:05:06
【问题描述】:
我创建了一个用于绘制图形的 CustomPaint。我需要一个滑块来处理要显示的数据数量。我在构建 CustomPaint 小部件的同一页面上放置了一个滑块和一个按钮,单击按钮或滑块上的幻灯片将触发 CustomPaint 的paint & shouldRepaint 方法,即使按钮和滑块的 onPressed 和onChanged 为空。
我基于 https://github.com/MSzalek-Mobile/weight_tracker 构建我的小部件,
他使用 Redux 进行状态管理,而我更喜欢使用 Provider。我的结构几乎和他的一样——在显示它的页面上用消费者包装我的小部件,但无济于事。
图表小部件
import 'package:flowy/models/data_entry.dart';
import 'package:flowy/models/XDataPositionOnGraph.dart';
import 'package:flowy/models/YDataPositionOnGraph.dart';
import 'package:flutter/material.dart';
import 'dart:ui' as ui;
class GraphWidget extends CustomPainter {
double leftOffsetStart;
double topOffsetEnd;
double drawingWidth;
double drawingHeight;
///Sorts Max Min Value and Difference
///Y Axis max min : (double) dataValue
///X Axis max min : (DateTime) dataTime
void sortMaxAndMinValue(List<DataEntry> dataEntry) {
yMax = dataEntry[0].dataValue;
yMin = dataEntry[0].dataValue;
xMax = dataEntry[0].dataTime;
xMin = dataEntry[0].dataTime;
for (int i = 0; i < dataEntry.length; i++) {
if (yMax <= dataEntry[i].dataValue) {
yMax = dataEntry[i].dataValue;
//print('yMax now is $yMax');
} else if (yMin >= dataEntry[i].dataValue) {
yMin = dataEntry[i].dataValue;
//print('yMmin now is $yMin');
}
}
//
for (int i = 0; i < dataEntry.length; i++) {
if ((dataEntry[i].dataTime).isAfter(xMax)) {
xMax = dataEntry[i].dataTime;
//print('dataEntryValue is ${dataEntry[i].dataTime} xMax now is $xMax');
}
if ((dataEntry[i].dataTime).isBefore(xMin)) {
xMin = dataEntry[i].dataTime;
//print('dataEntryValue is ${dataEntry[i].dataTime} xMin now is $xMin');
}
}
//print('xMax is $xMax');
//print('xMin is $xMin');
yDifference = yDifferenceBetweenMaxAndMin(yMax, yMin);
xDifference = xDifferenceBetweenMaxAndMin(xMax, xMin);
//print('xDifference is ${xDifference.inDays}');
//print('yDifference is $yDifference');
holder = dataEntry[2].dataTime.millisecondsSinceEpoch;
int holder1 = dataEntry[3].dataTime.millisecondsSinceEpoch;
DateTime.fromMillisecondsSinceEpoch(holder).toUtc();
int diffHolder = holder - holder1;
print(
'dataEntryList ${dataEntry[2].dataTime} convert to epoch: ${dataEntry[2].dataTime.millisecondsSinceEpoch}');
print(
'dataEntryList ${dataEntry[3].dataTime} convert to epoch: ${dataEntry[3].dataTime.millisecondsSinceEpoch}');
Duration nonEpoch = dataEntry[2].dataTime.difference(dataEntry[3].dataTime);
print(
'holder ${DateTime.fromMillisecondsSinceEpoch(diffHolder).toUtc().day}');
print('nonEpoch = ${nonEpoch.inDays}');
// //print('xDifference is ${DateTime.fromMicrosecondsSinceEpoch(xDifference)}');
}
///Draw Horizontal lines and labels
///change Offset(singleWidth) to change line offset
///Plots Data
void drawHorizontalLinesAndLabels(List<DataEntry> dataEntryList, Size size,
Canvas canvas, xDifference, yDifference, yMax, yMin, xMax, xMin) {
double singleHeight = size.height / 11;
double singleWidth = size.width / 6;
var paint = Paint();
paint.color = Colors.grey[200];
paint.strokeWidth = 3;
List<double> yAxisNewList =
stepDifferenceYAxis(dataEntryList, yDifference, yMax, yMin);
List<DateTime> xAxisNewList =
stepDifferenceXAxis(size, dataEntryList, xDifference, xMax, xMin);
drawYAxisLabel(yAxisNewList, size, canvas);
for (int i = 1; i < 12; i++) {
if (i.isOdd) {
//drawing label and line if odd
// //print('i is $i');
canvas.drawLine(
Offset(singleWidth, singleHeight * i),
Offset(size.width, singleHeight * i),
paint,
);
}
}
drawXAxisLabelFixed(xAxisNewList, size, canvas, xDifference);
plotData(dataEntryList, canvas, size, yDifference, xDifference, singleWidth,
singleHeight, yMax);
}
///Draw X Axis Label Fixed
///Fixes 10 labels
///stepWidth is defined by plotSize/ 10
///size.width - (stepWidth): Drawing from the right side
/// [0] is latest, xAxisIntLabelList.length oldest
///
/// Because the first label might have a difference value difference, hence,
/// xMinDifference is calculated to find the deviation on the canvas from it
void drawXAxisLabelFixed(List<DateTime> xAxisIntLabelList, Size size,
Canvas canvas, Duration difference) {
double singleHeight = size.height / 11;
double singleWidth = size.width / 6;
Size plotSize;
plotSize = Size(size.width - singleWidth, size.height + singleHeight * 0.2);
ui.Paragraph paragraph;
print(
'difference between [9][8] and [8][7] xData ${xAxisIntLabelList[9].difference(xAxisIntLabelList[8]) == xAxisIntLabelList[8].difference(xAxisIntLabelList[7])}');
double stepWidth = plotSize.width / 10;
print(
'singlewidth is $singleWidth original size is $size plotsize is $plotSize \n stepwidth is $stepWidth datalength is ${xAxisIntLabelList.length} ');
for (int j = 0; j < 10; j++) {
paragraph = _buildXAxisLabel(xAxisIntLabelList,
Size(stepWidth, size.height), canvas, difference, j);
canvas.drawParagraph(
paragraph,
Offset(size.width - size.width * 0.02 - (stepWidth * j),
plotSize.height));
xDataLabelsPosition.add(XDataPositionOnGraph(
xAxisIntLabelList[j], size.width - (stepWidth * j)));
}
//In DateTime
// print(' xData Position = ${xDataLabelsPosition[9].position}');
xLineDifference = (xDataLabelsPosition[0].position -
xDataLabelsPosition[1].position) /
((xDataLabelsPosition[0].value.difference(xDataLabelsPosition[1].value))
.inMinutes);
xMinLineDifference = (xDataLabelsPosition[9].position -
xDataLabelsPosition[8].position) /
((xDataLabelsPosition[9].value.difference(xDataLabelsPosition[8].value))
.inMinutes);
print(
'xLineDifference is $xLineDifference ,\n xMinLineDifference $xMinLineDifference \n difference in minutes is ${(xDataLabelsPosition[0].value.difference(xDataLabelsPosition[1].value)).inMinutes} ');
}
///Builds XAxisLabel with DateTime List calc from stepDifferenceXAxis
ui.Paragraph _buildXAxisLabel(List<DateTime> xAxisIntLabelList, Size size,
Canvas canvas, difference, j) {
//print('xAxisIntLabelList is $xAxisIntLabelList');
//difference is duration
print(xAxisIntLabelList[0]);
double leftOffsetStart = size.width;
ui.ParagraphBuilder builder;
builder = ui.ParagraphBuilder(
new ui.ParagraphStyle(
fontSize: 10.0,
textAlign: TextAlign.start,
),
);
builder
..pushStyle(new ui.TextStyle(color: Colors.black))
..addText(xAxisIntLabelList[j].minute.toString());
final ui.Paragraph paragraph = builder.build()
..layout(new ui.ParagraphConstraints(width: leftOffsetStart));
return paragraph;
}
///XAxis Step Difference
///Difference divide by 5 for 5 labels
///Return a new List<int> with max = max-xDiff;
///Build according to data.length : Build 6
List<DateTime> stepDifferenceXAxis(Size size, List<DataEntry> dataEntryList,
Duration xDifference, DateTime max, DateTime min) {
// dataEntryList.add(_buildCurrentWaitingData());
// max = DateTime.now();
// Duration difference = max.difference(min);
print(
'xDIff in stepDiffXAxis is ${xDifference.inMinutes}, diff is ${xDifference.inMinutes}');
xDifferenceAddedDateTimeNow = int.parse((xDifference.inMinutes.toString()));
double stepValue = xDifference.inMinutes / 10;
print('stepValue is ${stepValue}');
//print('\n/////////////////' 'xMax is $max and xDiff is $xDiff dataEntryList.length ${dataEntryList.length}' '\n//////////////////////');
List<DateTime> newList = [];
for (int i = 0; i < 9; i++) {
newList.add(max);
xDateTime.add(max);
print('i is $i max is $max ${dataEntryList[0].dataTime} ');
max = max.subtract(Duration(minutes: stepValue.ceil()));
print('xAxisCummulative is ${max} maxDay is ${dataEntryList.length}');
}
if (min.isBefore(newList[8])) {
newList.add(min);
} else {
newList.add(max.subtract(Duration(minutes: stepValue.ceil())));
}
print('newList is $newList');
return newList;
}
/// Draw YAxis label,
/// Build 6 Paragraphs(1,3,5,7,9,11) with _buildXAxisLabel()
/// Draw Paragraphs at XLine
/// Collect Data Value and Y Position of the lines
/// Calculate difference of the lines and find out relative position of each value
void drawYAxisLabel(List<double> yAxisIntList, Size size, Canvas canvas) {
double singleHeight = size.height / 11;
double singleWidth = size.width / 6;
ui.Paragraph paragraph1 = _buildYAxisLabel(yAxisIntList, size, canvas, 0);
ui.Paragraph paragraph3 = _buildYAxisLabel(yAxisIntList, size, canvas, 1);
ui.Paragraph paragraph5 = _buildYAxisLabel(yAxisIntList, size, canvas, 2);
ui.Paragraph paragraph7 = _buildYAxisLabel(yAxisIntList, size, canvas, 3);
ui.Paragraph paragraph9 = _buildYAxisLabel(yAxisIntList, size, canvas, 4);
ui.Paragraph paragraph11 = _buildYAxisLabel(yAxisIntList, size, canvas, 5);
canvas.drawParagraph(
paragraph1, Offset(singleWidth - 20, singleHeight * 1));
if (!yDataLabelsPosition
.contains(YDataPositionOnGraph(yAxisIntList[0], singleHeight * 1))) {
yDataLabelsPosition
.add(YDataPositionOnGraph(yAxisIntList[0], singleHeight * 1));
}
canvas.drawParagraph(
paragraph3, Offset(singleWidth - 20, singleHeight * 3));
if (!yDataLabelsPosition
.contains(YDataPositionOnGraph(yAxisIntList[1], singleHeight * 3))) {
yDataLabelsPosition
.add(YDataPositionOnGraph(yAxisIntList[1], singleHeight * 3));
}
canvas.drawParagraph(
paragraph5, Offset(singleWidth - 20, singleHeight * 5));
if (!yDataLabelsPosition
.contains(YDataPositionOnGraph(yAxisIntList[2], singleHeight * 5))) {
yDataLabelsPosition
.add(YDataPositionOnGraph(yAxisIntList[2], singleHeight * 5));
}
canvas.drawParagraph(
paragraph7, Offset(singleWidth - 20, singleHeight * 7));
if (!yDataLabelsPosition
.contains(YDataPositionOnGraph(yAxisIntList[3], singleHeight * 7))) {
yDataLabelsPosition
.add(YDataPositionOnGraph(yAxisIntList[3], singleHeight * 7));
}
canvas.drawParagraph(
paragraph9, Offset(singleWidth - 20, singleHeight * 9));
if (!yDataLabelsPosition
.contains(YDataPositionOnGraph(yAxisIntList[4], singleHeight * 9))) {
yDataLabelsPosition
.add(YDataPositionOnGraph(yAxisIntList[4], singleHeight * 9));
}
canvas.drawParagraph(
paragraph11, Offset(singleWidth - 20, singleHeight * 11));
if (!yDataLabelsPosition
.contains(YDataPositionOnGraph(yAxisIntList[5], singleHeight * 11))) {
yDataLabelsPosition
.add(YDataPositionOnGraph(yAxisIntList[5], singleHeight * 11));
}
yLineDifference =
(yDataLabelsPosition[1].position - yDataLabelsPosition[0].position) /
(yDataLabelsPosition[0].value - yDataLabelsPosition[1].value);
print('yLineDifference is $yLineDifference');
}
///Build YAxisLabel Paragraph
ui.Paragraph _buildYAxisLabel(
List<double> yLineLabelList, Size size, Canvas canvas, j) {
double leftOffsetStart = size.width * 0.11;
ui.ParagraphBuilder builder;
builder = ui.ParagraphBuilder(
new ui.ParagraphStyle(
fontSize: 10.0,
textAlign: TextAlign.start,
),
);
builder
..pushStyle(new ui.TextStyle(color: Colors.black))
..addText(yLineLabelList[j].toString());
final ui.Paragraph paragraph = builder.build()
..layout(new ui.ParagraphConstraints(width: leftOffsetStart));
return paragraph;
}
///YAxis Step Difference
///Difference divide by 5 for 5 labels
///Return a new List<int> for Labelling with max = max-xLineDiff;
List<double> stepDifferenceYAxis(List<DataEntry> dataEntryList,
double yDifference, double max, double min) {
double stepDiff = yDifference / 5;
print('ydifference is $yDifference');
List<double> newList = [];
for (int i = 0; i <= 6; i++) {
//print('max is $max');
print(
'max ceil is ${max.ceil()} max round is ${max.round()} max floor is ${max.floor()}');
newList.add(double.parse(max.floor().toStringAsFixed(2)));
max = max - stepDiff;
}
//print('instantiate newlist[0] as max ${newList[0]}');
return newList;
}
///Get Difference between Max And Min
double yDifferenceBetweenMaxAndMin(max, min) {
return max - min;
}
Duration xDifferenceBetweenMaxAndMin(DateTime max, DateTime min) {
return max.difference(min);
}
///Build Current Data point
DataEntry _buildCurrentWaitingData() {
return DataEntry(null, DateTime.now());
}
//TODO Work on representing X region with step
///Plot Data
/// Put all x and y values in a list of their own type
/// Define dataPlotSize
/// Calls checkDataAndPlot()
/// DrawLine for all plots
void plotData(
List<DataEntry> dataEntryList,
Canvas canvas,
Size size,
double yDifference,
Duration xDifference,
singleWidth,
singleHeight,
max) {
//dataPlotSize is the Data Plotting region
for (int j = 0; j < yDataLabelsPosition.length; j++) {
if (!yLabelsInDouble.contains(yDataLabelsPosition[j].value)) {
yLabelsInDouble.add(yDataLabelsPosition[j].value);
}
}
for (int j = 0; j < xDataLabelsPosition.length; j++) {
if (!xLabelInDateTime.contains(xDataLabelsPosition[j].value)) {
xLabelInDateTime.add(xDataLabelsPosition[j].value);
}
}
print('xlabels in int $xLabelInDateTime');
print('xlabels[0] = ${xDataLabelsPosition[0].position}');
Size dataPlotSize =
Size(size.width - singleWidth, size.height - singleHeight);
var paint = Paint();
paint.color = Colors.blueGrey[500];
paint.strokeWidth = 3;
print('yDiff is $yDifference');
//dataPlotSizeheight / difference, meaning representing each step by its plotting height
double singlePlotHeight = dataPlotSize.height / yDifference;
double stepWidth = dataPlotSize.width / dataEntryList.length;
print(
'singlePlotHeight is $singlePlotHeight size is $size dataPlotSize is $dataPlotSize singleHeight is $singleHeight');
print('max is $max');
print(
'data value is ${dataEntryList[2].dataValue} , max - datavalue is ${max - dataEntryList[2].dataValue}');
print('xDiffAddedDTNow $xDifferenceAddedDateTimeNow');
for (int i = 0; i < dataEntryList.length; i++) {
print('\n////////////////\nPLOTTING GRAPH\n////////////////\n');
print('dataEntry Value is ${dataEntryList[i].dataValue}');
checkDataPositionAndPlot(dataEntryList, canvas, i);
print('all YData ${yDataPosition.length} ');
}
print('ydataposition ${yDataPosition.length}');
print('xdataposition ${xDataPosition.length}');
print('xlabelsposition ${xDataLabelsPosition.length}');
for (int i = 0; i < yDataPosition.length - 1; i++) {
canvas.drawLine(
Offset(xDataPosition[i].position, yDataPosition[i].position),
Offset(xDataPosition[i + 1].position, yDataPosition[i + 1].position),
paint);
}
}
/// CheckDataPositionAndPlot
/// 1. Check if dataEntry should be plotted on line (exists in yLabelsInDouble)
/// a. If exists, forEach dataLabelPosition that is == to dataEntry
/// add data to yDataPosition with the position
/// b. Else, check if dataEntry is null, --> do nothing
/// c. Else, dataEntry should not be plotted on line,
/// for loop to check dataEntry falls in which region by subtracting
/// dataEntry with the label value, If negative, then take the previous
/// line and find the difference in value and position then add to yDataPosition
/// 2. Note : a. first label value on X Axis is assigned directly depending on whether it is < the
/// consecutive label value
/// b. Checks if falls between the first label [9] and second label [8]
/// c. Use xLineDifference and xMinLineDifference accordingly
void checkDataPositionAndPlot(
List<DataEntry> dataEntryList, Canvas canvas, i) {
print('yDatalabel Length ${yDataLabelsPosition.length}');
if (yLabelsInDouble.contains(dataEntryList[i].dataValue)) {
print(' ${dataEntryList[i].dataValue} y is online');
yDataLabelsPosition.forEach((f) {
print("${f.value} is fvalue ");
if (f.value == dataEntryList[i].dataValue) {
print("${f.value} value added ");
yDataPosition.add(YDataPositionOnGraph(f.value, f.position));
}
});
} else {
if (dataEntryList[i].dataValue == null) {
} else {
print('!!!! ${dataEntryList[i].dataValue}not online !!!!');
double sign;
for (int j = yLabelsInDouble.length - 1; j >= 0; j--) {
sign = 0;
sign = dataEntryList[i].dataValue - yDataLabelsPosition[j - 1].value;
// print('iteration $j ydatalabel ${yDataLabelsPosition[j].value}');
if (sign.isNegative) {
double deviation =
dataEntryList[i].dataValue - yDataLabelsPosition[j].value;
print(
' datavalue = ${dataEntryList[i].dataValue}, ydatalabel [j]${yDataLabelsPosition[j].value} deviation ${deviation}');
yDataPosition.add(YDataPositionOnGraph(dataEntryList[i].dataValue,
yDataLabelsPosition[j].position - deviation * yLineDifference));
print('not on graph added ');
break;
}
}
}
}
print(
'xlabel in int [0] ${xLabelInDateTime.length} dataTime[0] ${dataEntryList[i].dataTime.day}');
///////////////////////////////////////////////////////////////////////////////////////////////////
if (xLabelInDateTime.contains(dataEntryList[i].dataTime)) {
print(' ${dataEntryList[i].dataTime} x is online');
xDataLabelsPosition.forEach((f) {
print("${f.value} is fvalue ");
if (f.value == dataEntryList[i].dataTime) {
print("${f.value} X value added ");
xDataPosition.add(XDataPositionOnGraph(f.value, f.position));
}
});
} else {
if (dataEntryList[i].dataValue == null) {
} else {
print('datalabelpost length ${xDataLabelsPosition.length}');
print('dataentry length ${dataEntryList.length}');
print('xlabelint ${xLabelInDateTime[0]}');
print('!!!! ${dataEntryList[i].dataTime.minute}not online !!!!');
for (int j = xLabelInDateTime.length - 1; j >= 0; j--) {
//
//
print('X,iteration $j xdatalabel ${xDataLabelsPosition[j].value}');
if (dataEntryList[i].dataTime.isAfter(xDataLabelsPosition[j].value) &&
dataEntryList[i]
.dataTime
.isBefore(xDataLabelsPosition[j - 1].value)) {
int deviation = dataEntryList[i]
.dataTime
.difference(xDataLabelsPosition[j].value)
.inMinutes;
print(
' datavalue = ${dataEntryList[i].dataTime.day}, xdatalabel [j]${xDataLabelsPosition[j].value} deviation ${deviation}');
if (j == xLabelInDateTime.length - 1) {
xDataPosition.add(XDataPositionOnGraph(
dataEntryList[i].dataTime,
xDataLabelsPosition[j].position +
deviation * xMinLineDifference));
} else {
xDataPosition.add(XDataPositionOnGraph(
dataEntryList[i].dataTime,
xDataLabelsPosition[j].position +
deviation * xLineDifference));
print('not on graph added ');
break;
}
}
}
print('Y Not on graph');
}
}
}
/// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// ///
/// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// ///
/// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// ///
List<XDataPositionOnGraph> xDataLabelsPosition = [];
List<YDataPositionOnGraph> yDataLabelsPosition = [];
List<DateTime> xDateTime = [];
double yMax =0 , yMin=0, yDifference=0;
DateTime xMax, xMin;
Duration xDifference;
int xDifferenceAddedDateTimeNow=0;
double yLineDifference, xLineDifference, xMinLineDifference=0;
List<YDataPositionOnGraph> yDataPosition = [];
List<XDataPositionOnGraph> xDataPosition = [];
List<double> yLabelsInDouble = [];
List<DateTime> xLabelInDateTime = [];
int holder;
double stepDifference;
List<DataEntry> dataEntryList = [];
@override
void paint(Canvas canvas, Size size) {
leftOffsetStart = size.width * 0.07;
topOffsetEnd = size.height * 0.9;
drawingWidth = size.width * 0.93;
drawingHeight = topOffsetEnd;
sortMaxAndMinValue(dataEntryList);
int sinceEpoch1 = dataEntryList[3].dataTime.millisecondsSinceEpoch;
int sinceEpoch0 = dataEntryList[0].dataTime.millisecondsSinceEpoch;
int diffEpoch = sinceEpoch1 - sinceEpoch0;
print(
'from Epoch ${DateTime.fromMillisecondsSinceEpoch(diffEpoch).minute} duration is ${dataEntryList[3].dataTime.difference(dataEntryList[0].dataTime).inMinutes}');
//print('after sortMaxMinValue diff is $yDifference');
drawHorizontalLinesAndLabels(dataEntryList, size, canvas, xDifference,
yDifference, yMax, yMin, xMax, xMin);
}
@override
bool shouldRepaint(GraphWidget old) => true;
GraphWidget(this.dataEntryList);
}
GraphCardWidget -- 基本上是用卡片包裹它
import 'package:flowy/models/data_entry.dart';
import 'package:flowy/state_management/main.dart';
import 'package:flowy/widget/graph_widget.dart';
import 'package:flowy/widget/graph_widget_without_labels.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class GraphCardWidget extends StatefulWidget {
double height, width;
List dataEntryList;
bool withLabel;
GraphCardWidget(this.height, this.width, this.dataEntryList,
{this.withLabel = true});
@override
State<StatefulWidget> createState() {
return GraphCardWidgetState();
}
}
class GraphCardWidgetState extends State<GraphCardWidget> {
double _value = 0.0;
void _setvalue(double value) => setState(() => _value = value);
@override
Widget build(BuildContext context) {
return
widget.withLabel == true ? Column(
children: <Widget>[ Card(
child: Column(
children: <Widget>[
Container(
padding: EdgeInsets.only(bottom: widget.height * 0.03,
right: widget.width * 0.05)
,
height: widget.height * 0.4,
width: widget.width * 0.94,
child:
CustomPaint(
size: Size(widget.height * 0.1, widget.width * 0.01),
painter: GraphWidget(widget.dataEntryList),
)
),
new Slider(value: _value, onChanged: _setvalue)
],
)),
]
) : Card(
child: Container(
padding: EdgeInsets.only(
bottom: widget.height * 0.03, right: widget.width * 0.05),
height: widget.height * 0.4,
width: widget.width * 0.94,
// child: GestureDetector(
child: CustomPaint(
size: Size(widget.height * 0.1, widget.width * 0.01),
painter: GraphWidgetWithoutLabels(widget.dataEntryList),
),
),
);
}
}
我构建 GraphCardWidget 的页面
import 'package:flutter/material.dart';
//Third party library import
import 'package:provider/provider.dart';
//Local import
import 'package:flowy/widget/drawer_widget.dart';
import 'package:flowy/state_management/main.dart';
import 'package:flowy/models/data_entry.dart';
import 'package:flowy/utils/dummy_data.dart';
import 'package:flowy/widget/graph_card_widget.dart';
/// Pressure = Volume for Petroleum
class PressurePage extends StatefulWidget {
MainStateManager manager;
PressurePage(this.manager);
@override
State<StatefulWidget> createState() {
return _PressurePageState();
}
}
class _PressurePageState extends State<PressurePage> {
List<String> _RTUList;
List<DataEntry> _dataEntryList;
int _index;
String _dropDownBtnSelectedVal;
@override
void initState() {
if (widget.manager.dataIndex == null) {
_index = 0;
} else {
_index = widget.manager.dataIndex;
}
_RTUList = DummyData('Volume').RTUList;
_dataEntryList = DummyData('Volume').buildDataEntry()[_index];
_dropDownBtnSelectedVal = _RTUList[_index];
print('RTUList is $_RTUList');
print('dropdownValue is $_dropDownBtnSelectedVal');
super.initState();
}
DropdownButton _buildDropDownButton() {
final List<DropdownMenuItem<String>> _dropDownMenuItems = _RTUList.map(
(String value) => DropdownMenuItem<String>(
value: value,
child: Text(value),
),
).toList();
return DropdownButton<String>(
value: _dropDownBtnSelectedVal,
onChanged: ((String newValue) {
setState(() {
_dropDownBtnSelectedVal = newValue;
_dataEntryList = DummyData('Volume')
.buildDataEntry()[_RTUList.indexOf(_dropDownBtnSelectedVal)];
});
}),
items: _dropDownMenuItems,
);
}
@override
Widget build(BuildContext context) {
print('dataEntryList is $_dataEntryList');
final double width = MediaQuery.of(context).size.width;
final double height = MediaQuery.of(context).size.height;
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).accentColor,
title: Text('Volume'),
),
body: Stack(
children: <Widget>[
Container(
color: Theme.of(context).primaryColor,
),
Container(
alignment: Alignment.center,
child: Consumer<MainStateManager>(builder:
(BuildContext context, MainStateManager manager, Widget child) {
return Center(
child: Column(
children: <Widget>[
ListTile(
title: _buildDropDownButton(),
),
Consumer<MainStateManager>(builder: (BuildContext context,
MainStateManager manager, child) {
return GraphCardWidget(
height, width, manager.handleInputDateTime());
}),
Expanded(
child: Container(
child: Card(
child: RaisedButton(
child: Text('hehe '),
onPressed: () {
})),
))
],
),
);
}),
)
],
),
);
}
}
期望 CustomPaint 小部件不会在没有实际 onPressed 回调的情况下为每个按钮点击进行绘制
【问题讨论】:
标签: canvas flutter triggers widget paint