Я заметил, что мой виджет Dialog прекрасно работает на моем телефоне, но выдает исключение на моем планшете. Как это возможно?
Я попытался установить width
на Dialog
, обернув его Container
, но это не решает проблему.
Вот сообщение об ошибке:
I/flutter (17549): ══╡ EXCEPTION CAUGHT BY RENDERING LIBRARY
╞═════════════════════════════════════════════════════════
I/flutter (17549): The following NoSuchMethodError was thrown during performLayout():
I/flutter (17549): The method 'copyWith' was called on null.
I/flutter (17549): Receiver: null
I/flutter (17549): Tried calling: copyWith(maxWidth: Infinity)
I/flutter (17549):
I/flutter (17549): The relevant error-causing widget was:
I/flutter (17549): AlertDialog
I/flutter (17549): file:///...dialogs/EditTagsDialog.dart:42:41
Вот так выглядит мой диалог:
@override
Widget build(BuildContext context) => AlertDialog(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
title: Container(
alignment: Alignment.center,
child: Text("Select Tags"),
content: ListView.builder(
itemCount: tags.length +1,
itemBuilder: (context, index) {
return GestureDetector(
onTap: () { ... },
child: buildRow(index)
);
},
),
actions: <Widget>[
CancelButton(),
SaveButton()
],
);
Widget _buildRow(int index) {
if(index > 0) {
return Row(
children: <Widget>[
Flexible(
flex: 1,
child: Checkbox( ... ),
),
Flexible(
flex: 3,
child: Text(tags[index-1]))
],
);
} else {
return Row(
children: <Widget>[
SizedBox(
width: 160,
child: TextField(
decoration: InputDecoration(hintText: "Add a tag", hintStyle: TextStyle(color: Theme.of(context).textTheme.display2.color)),
textInputAction: TextInputAction.done,
controller: _textEditingController,
style: TextStyle(color: Theme.of(context).textTheme.display1.color),
),
),
IconButton(
icon: Icon(Icons.check),
onPressed: () { ... };
)
],
);
}
}
Вот полная трассировка стека:
I/flutter (17549): ══╡ EXCEPTION CAUGHT BY RENDERING LIBRARY
╞═════════════════════════════════════════════════════════
I/flutter (17549): The following NoSuchMethodError was thrown during performLayout():
I/flutter (17549): The method 'copyWith' was called on null.
I/flutter (17549): Receiver: null
I/flutter (17549): Tried calling: copyWith(maxWidth: Infinity)
I/flutter (17549):
I/flutter (17549): The relevant error-causing widget was:
I/flutter (17549): AlertDialog
I/flutter (17549): file:///.../dialogs/EditTagsDialog.dart:42:41
I/flutter (17549):
I/flutter (17549): When the exception was thrown, this was the stack:
I/flutter (17549): #0 Object.noSuchMethod (dart:core-patch/object_patch.dart:53:5)
I/flutter (17549): #1 _RenderButtonBarRow.constraints (package:flutter/src/material/button_bar.dart:292:30)
I/flutter (17549): #2 RenderObject.debugFillProperties (package:flutter/src/rendering/object.dart:2791:68)
I/flutter (17549): #3 RenderBox.debugFillProperties (package:flutter/src/rendering/box.dart:2417:11)
I/flutter (17549): #4 RenderFlex.debugFillProperties (package:flutter/src/rendering/flex.dart:1015:11)
I/flutter (17549): #5 DiagnosticableNode.builder (package:flutter/src/foundation/diagnostics.dart:2900:14)
I/flutter (17549): #6 DiagnosticableNode.style (package:flutter/src/foundation/diagnostics.dart:2907:70)
I/flutter (17549): #7 DiagnosticsNode.toString (package:flutter/src/foundation/diagnostics.dart:1629:12)
I/flutter (17549): #8 _StringBase._interpolate (dart:core-patch/string_patch.dart:845:19)
I/flutter (17549): #9 TextTreeRenderer.render.visitor (package:flutter/src/foundation/diagnostics.dart:1140:69)
I/flutter (17549): #10 TextTreeRenderer.render.visitor (package:flutter/src/foundation/diagnostics.dart:1142:22)
I/flutter (17549): #11 TextTreeRenderer.render.visitor (package:flutter/src/foundation/diagnostics.dart:1142:22)
I/flutter (17549): #12 TextTreeRenderer.render.visitor (package:flutter/src/foundation/diagnostics.dart:1142:22)
I/flutter (17549): #13 TextTreeRenderer.render.visitor (package:flutter/src/foundation/diagnostics.dart:1142:22)
I/flutter (17549): #14 TextTreeRenderer.render (package:flutter/src/foundation/diagnostics.dart:1150:14)
I/flutter (17549): #15 TextTreeRenderer.render (package:flutter/src/foundation/diagnostics.dart:1294:39)
I/flutter (17549): #16 FlutterError.dumpErrorToConsole (package:flutter/src/foundation/assertions.dart:652:11)
I/flutter (17549): #17 FlutterError.reportError (package:flutter/src/foundation/assertions.dart:741:14)
I/flutter (17549): #18 RenderObject._debugReportException (package:flutter/src/rendering/object.dart:1270:18)
I/flutter (17549): #19 RenderObject.layout (package:flutter/src/rendering/object.dart:1731:7)
I/flutter (17549): #20 RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
I/flutter (17549): #21 _RenderCustomClip.performLayout (package:flutter/src/rendering/proxy_box.dart:1232:11)
I/flutter (17549): #22 RenderObject.layout (package:flutter/src/rendering/object.dart:1724:7)
I/flutter (17549): #23 RenderConstrainedBox.performLayout (package:flutter/src/rendering/proxy_box.dart:259:13)
I/flutter (17549): #24 RenderObject.layout (package:flutter/src/rendering/object.dart:1724:7)
I/flutter (17549): #25 RenderPositionedBox.performLayout (package:flutter/src/rendering/shifted_box.dart:392:13)
I/flutter (17549): #26 RenderObject.layout (package:flutter/src/rendering/object.dart:1724:7)
I/flutter (17549): #27 RenderPadding.performLayout (package:flutter/src/rendering/shifted_box.dart:206:11)
I/flutter (17549): #28 RenderObject.layout (package:flutter/src/rendering/object.dart:1724:7)
I/flutter (17549): #29 RenderPadding.performLayout (package:flutter/src/rendering/shifted_box.dart:206:11)
I/flutter (17549): #30 RenderObject.layout (package:flutter/src/rendering/object.dart:1724:7)
I/flutter (17549): #31 RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
I/flutter (17549): #32 RenderObject.layout (package:flutter/src/rendering/object.dart:1724:7)
I/flutter (17549): #33 RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
I/flutter (17549): #34 RenderObject.layout (package:flutter/src/rendering/object.dart:1724:7)
I/flutter (17549): #35 RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
I/flutter (17549): #36 RenderObject.layout (package:flutter/src/rendering/object.dart:1724:7)
I/flutter (17549): #37 RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
I/flutter (17549): #38 RenderObject.layout (package:flutter/src/rendering/object.dart:1724:7)
I/flutter (17549): #39 RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
I/flutter (17549): #40 RenderObject.layout (package:flutter/src/rendering/object.dart:1724:7)
I/flutter (17549): #41 RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
I/flutter (17549): #42 RenderObject.layout (package:flutter/src/rendering/object.dart:1724:7)
I/flutter (17549): #43 RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
I/flutter (17549): #44 RenderOffstage.performLayout (package:flutter/src/rendering/proxy_box.dart:3168:13)
I/flutter (17549): #45 RenderObject.layout (package:flutter/src/rendering/object.dart:1724:7)
I/flutter (17549): #46 RenderStack.performLayout (package:flutter/src/rendering/stack.dart:505:15)
I/flutter (17549): #47 RenderObject._layoutWithoutResize (package:flutter/src/rendering/object.dart:1584:7)
I/flutter (17549): #48 PipelineOwner.flushLayout (package:flutter/src/rendering/object.dart:844:18)
I/flutter (17549): #49 RendererBinding.drawFrame (package:flutter/src/rendering/binding.dart:344:19)
I/flutter (17549): #50 WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:774:13)
I/flutter (17549): #51 RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:283:5)
I/flutter (17549): #52 SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1102:15)
I/flutter (17549): #53 SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:1041:9)
I/flutter (17549): #54 SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:957:5)
I/flutter (17549): #58 _invoke (dart:ui/hooks.dart:259:10)
I/flutter (17549): #59 _drawFrame (dart:ui/hooks.dart:217:3)
I/flutter (17549): (elided 3 frames from package dart:async)
I/flutter (17549):
I/flutter (17549): The following RenderObject was being processed when the exception was fired: RenderPhysicalShape#3b374 relayoutBoundary=up2 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE:
I/flutter (17549): needs compositing
I/flutter (17549): creator: PhysicalShape ← _MaterialInterior ← Material ← ConstrainedBox ← Center ← MediaQuery ←
I/flutter (17549): Padding ← AnimatedPadding ← Dialog ← AlertDialog ← EditTagsDialog ← Builder ← ⋯
I/flutter (17549): parentData: <none> (can use size)
I/flutter (17549): constraints: BoxConstraints(280.0<=w<=720.0, 0.0<=h<=1160.0)
I/flutter (17549): size: MISSING
I/flutter (17549): elevation: 24.0
I/flutter (17549): color: Color(0xffffffff)
I/flutter (17549): shadowColor: Color(0xffffffff)
I/flutter (17549): clipper: ShapeBorderClipper
I/flutter (17549): This RenderObject had the following descendants (showing up to depth 5):
I/flutter (17549): child: RenderCustomPaint#a1260 relayoutBoundary=up3 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
I/flutter (17549): child: _RenderInkFeatures#29c07 relayoutBoundary=up4 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
I/flutter (17549): child: RenderIntrinsicWidth#dce05 relayoutBoundary=up5 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
I/flutter (17549): child: RenderFlex#1a3c5 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
I/flutter (17549): child 1: RenderPadding#f4dc8 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
I/flutter (17549): child 2: RenderPadding#45b2a NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
I/flutter (17549): child 3: RenderPadding#8c9cf NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
I/flutter (17549): ════════════════════════════════════════════════════════════════════════════════════════════════════
Вот полный исходный код этого класса:
class EditTagsDialog extends StatefulWidget {
final List<String> tags;
final Function cancelCallback;
final Function(List<String>) saveCallback;
const EditTagsDialog(
{Key key, this.tags, this.saveCallback, this.cancelCallback})
: super(key: key);
@override
State<StatefulWidget> createState() => _EditTagsDialogState();
}
class _EditTagsDialogState extends State<EditTagsDialog> {
TextEditingController _textEditingController;
List<String> _selectedTags;
List<String> _allTags;
TagService _tagService;
@override
void initState() {
super.initState();
_tagService = TagService();
_textEditingController = TextEditingController();
_selectedTags = this.widget.tags;
_allTags = _selectedTags;
_tagService.findAll().then((tags) {
setState(() {
_allTags = tags;
});
});
}
@override
Widget build(BuildContext context) => AlertDialog(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
title: Container(
alignment: Alignment.center,
child: Text(AppLocalizations.of(context).translate("select_tags"),
style: TextStyle(
color: Theme.of(context).textTheme.display1.color))),
content: ListView.builder(
itemCount: _allTags.length +1,
itemBuilder: (context, index) {
return GestureDetector(
onTap: () {
if(index > 0) {
_onRowTap(_allTags[index]);
}
},
child: _buildRow(index)
);
},
),
actions: <Widget>[
CancelButton(),
SaveButton(save: () {
this.widget.saveCallback(_selectedTags);
})
],
);
void _onRowTap(String tag) {
setState(() {
_selectedTags.contains(tag)
? _selectedTags.remove(tag)
: _selectedTags.add(tag);
});
}
Widget _buildRow(int index) {
if(index > 0) {
return Row(
children: <Widget>[
Flexible(
flex: 1,
child: Checkbox(
value: _selectedTags.contains(_allTags[index-1]),
onChanged: (bool selected) {
setState(() {
selected
? _selectedTags.add(_allTags[index-1])
: _selectedTags.remove(_allTags[index-1]);
});
}),
),
Flexible(
flex: 3,
child: Text(_allTags[index-1],
style: TextStyle(
color: Theme.of(context)
.textTheme
.display1
.color)
)
)
],
);
} else {
return Row(
children: <Widget>[
SizedBox(
width: 160,
child: TextField(
decoration: InputDecoration(hintText: AppLocalizations.of(context).translate("add_tag"), hintStyle: TextStyle(color: Theme.of(context).textTheme.display2.color)),
textInputAction: TextInputAction.done,
controller: _textEditingController,
style: TextStyle(color: Theme.of(context).textTheme.display1.color),
),
),
IconButton(
icon: Icon(Icons.check, color: Theme.of(context).buttonColor),
onPressed: (){
setState(() {
_allTags.add(_textEditingController.text);
});
TagService().createTagIfNotExisting(_textEditingController.text);
_textEditingController.clear();
},
)
],
);
}
}
}