I am getting below exception while running flutter code in android studio.
I/flutter ( 5360): ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY
╞═══════════════════════════════════════════════════════════ I/flutter
( 5360): The following assertion was thrown building Text("xyz"): I/flutter ( 5360): No Directionality widget found. I/flutter
( 5360): RichText widgets require a Directionality widget ancestor.
I/flutter ( 5360): The specific widget that could not find a
Directionality ancestor was: I/flutter ( 5360): RichText(softWrap:
wrapping at box width, maxLines: unlimited, text: "xyz")
I/flutter ( 5360): The ownership chain for the affected widget is:
I/flutter ( 5360): RichText ← Text ← Center ← Container ← [root]
I/flutter ( 5360): Typically, the Directionality widget is introduced
by the MaterialApp or WidgetsApp widget at the I/flutter ( 5360): top
of your application widget tree. It determines the ambient reading
direction and is used, for I/flutter ( 5360): example, to determine
how to lay out text, how to interpret "start" and "end" values, and to
resolve I/flutter ( 5360): EdgeInsetsDirectional,
AlignmentDirectional, and other *Directional objects.
Code snippet:
import 'package:flutter/material.dart';
void main() {
runApp(
Container(child: Center(child: Text("xyz"))),
);
}
I am not sure why this exception says
I/flutter ( 5360): Typically, the Directionality widget is introduced by the MaterialApp or WidgetsApp widget at the ...
Because in flutter everything is a widget, so any widget should work for us.
If you are using a material widget component, like Scaffold, Material, you don't need to specify textDirection in your Text widget because Directionality is implicitly provided in these cases. So, a good solution would be to use:
Scaffold(body: Text("xyz"))
But if you don't use it, you will have to
Text(
'xyz',
textDirection: TextDirection.ltr,
)
If you are using Directionality constructor your problem will resolve
Widget build(BuildContext context) {
return Directionality(
textDirection: TextDirection.ltr,
child: Container(
color: myColor,
child: Center(
child: RaisedButton(
onPressed: () {
print('You pressed me');
changeColor();
},
child: Text('Click', textDirection: TextDirection.ltr)
),
),
),
);
}
Text widget needs to know whether it should display text left to right or right to left. There is no default. This information can be provided in 2 ways:
by nesting it in Directionality widget (as mentioned in the error message, typically MaterialApp or WidgetsApp)
explicitly, as an argument to the constructor:
Text(
'Hello World',
textDirection: TextDirection.ltr,
)
Second approach clearly is unmanageable in the long run.
late but I hope it can help.
I don't use any predefined root widget too. So I wrapped my App in Directionality widget in main function and flutter stopped complaining:
my code:
void main() {
runApp(
new Directionality(textDirection: TextDirection.ltr, child: MyApp())
);
}
A little more elaboration on what's happening internally.
When a Text widget is used without the specified style, it tries to inherit the style from the parents automatically. Here's the first few lines of the build method of Text Widget.
#override
Widget build(BuildContext context) {
final DefaultTextStyle defaultTextStyle = DefaultTextStyle.of(context);
TextStyle? effectiveTextStyle = style;
if (style == null || style!.inherit)
effectiveTextStyle = defaultTextStyle.style.merge(style);
if (MediaQuery.boldTextOverride(context))
effectiveTextStyle = effectiveTextStyle!.merge(const TextStyle(fontWeight: FontWeight.bold));
Look at the line - final DefaultTextStyle defaultTextStyle = DefaultTextStyle.of(context);
Now if a material widget is used in the widget tree before the Text Widget appears, they would have already set the default text style which Text widget automatically inherits from the Build Context. If none of the material widgets were used before Text, then we would need to specify the text style explicitly.
Related
I am using the PrimaryScrollController to in a custom stateful widget which is basically a ListView with code to load items from the server as the user scrolls. I need the PrimaryScrollController so that tapping the top of the app bar on iOS scrolls back to the top.
I am using this same widget in multiple pages, which are controlled by a BottomNavigationBar. I am also trying to persist state, so that when the user scrolls, then changes to another tab in the bottom nav bar, and then returns to the first tab, the scroll position and all the items loaded from the server will still be there.
To persist the state of the pages I'm using an IndexedStack. However, since both pages are using the PrimaryScrollController at the same time I'm getting a long chain of the same error message in the console: flutter: Another exception was thrown: ScrollController attached to multiple scroll views.
I'm understanding that this is telling me that I shouldn't use the same ScrollController in multiple views. The simple solution would be to just create a new instance for each view. However, I must use the same ScrollController because I need the PrimaryScrollController for the tap the app bar on iOS to work.
If I just ignore the errors, the actual code works the way I want it to, each page retains its own state.
Actually, it doesn't work the way I want it to. The listeners don't work when they are on sperate pages.
I created a sample app to show the problem:
import 'package:flutter/material.dart';
import 'dart:math';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
List<Widget> _pages = [
BodyWidget(key: PageStorageKey(1)),
BodyWidget(key: PageStorageKey(2)),
];
class _MyHomePageState extends State<MyHomePage> {
int _currentPage = 0;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: IndexedStack(
index: _currentPage,
children: _pages,
),
bottomNavigationBar: BottomNavigationBar(
currentIndex: _currentPage,
onTap: (int index) {
setState(() {
_currentPage = index;
});
},
items: [
BottomNavigationBarItem(
icon: Icon(Icons.star_border), title: Text('page 1')),
BottomNavigationBarItem(
icon: Icon(Icons.crop_square), title: Text('page 2'))
]),
);
}
}
class BodyWidget extends StatefulWidget {
BodyWidget({Key key}) : super(key: key);
#override
_BodyWidgetState createState() => _BodyWidgetState();
}
class _BodyWidgetState extends State<BodyWidget> {
ScrollController _scrollController;
List<int> numbers = [];
void dataGenerator() {
// simulate loading items from server
var rng = new Random();
for (var i = 0; i < 100; i++) {
if (this.mounted) {
setState(() {
numbers.add(rng.nextInt(100));
});
}
}
print('loaded more items');
}
#override
void initState() {
super.initState();
// This delay is required to get the build context
Future.delayed(
Duration.zero,
() {
_scrollController = PrimaryScrollController.of(context);
_scrollController.addListener(() {
if (_scrollController.position.pixels >=
(_scrollController.position.maxScrollExtent - 50)) {
dataGenerator();
}
});
dataGenerator();
},
);
}
#override
Widget build(BuildContext context) {
return ListView.builder(
itemCount: numbers.length,
controller: _scrollController,
itemBuilder: (BuildContext context, int index) {
return Container(
child: Card(
child: Column(
children: <Widget>[
SizedBox(
height: 15,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Text('Random number: ' + numbers[index].toString()),
Text('Index: ' + index.toString())
],
),
SizedBox(
height: 15,
),
],
),
),
);
},
);
}
}
This is the error that is thrown:
flutter: ══╡ EXCEPTION CAUGHT BY FOUNDATION LIBRARY ╞════════════════════════════════════════════════════════
flutter: The following assertion was thrown while dispatching notifications for ScrollController:
flutter: ScrollController attached to multiple scroll views.
flutter: 'package:flutter/src/widgets/scroll_controller.dart': Failed assertion: line 111 pos 12:
flutter: '_positions.length == 1'
flutter:
flutter: Either the assertion indicates an error in the framework itself, or we should provide substantially
flutter: more information in this error message to help you determine and fix the underlying cause.
flutter: In either case, please report this assertion by filing a bug on GitHub:
flutter: https://github.com/flutter/flutter/issues/new?template=BUG.md
flutter:
flutter: When the exception was thrown, this was the stack:
flutter: #2 ScrollController.position
package:flutter/…/widgets/scroll_controller.dart:111
flutter: #3 _BodyWidgetState.initState.<anonymous closure>.<anonymous closure>
package:primaryscrollcontroller_test/main.dart:97
flutter: #4 ChangeNotifier.notifyListeners
package:flutter/…/foundation/change_notifier.dart:206
flutter: #5 ChangeNotifier.notifyListeners
package:flutter/…/foundation/change_notifier.dart:206
flutter: #6 ScrollPosition.notifyListeners
package:flutter/…/widgets/scroll_position.dart:696
flutter: #7 ScrollPosition.setPixels
package:flutter/…/widgets/scroll_position.dart:218
flutter: #8 ScrollPositionWithSingleContext.setPixels
package:flutter/…/widgets/scroll_position_with_single_context.dart:84
flutter: #9 ScrollPositionWithSingleContext.applyUserOffset
package:flutter/…/widgets/scroll_position_with_single_context.dart:127
flutter: #10 ScrollDragController.update
package:flutter/…/widgets/scroll_activity.dart:372
flutter: #11 ScrollableState._handleDragUpdate
package:flutter/…/widgets/scrollable.dart:496
flutter: #12 DragGestureRecognizer.handleEvent.<anonymous closure>
flutter: #13 GestureRecognizer.invokeCallback
package:flutter/…/gestures/recognizer.dart:166
flutter: #14 DragGestureRecognizer.handleEvent
package:flutter/…/gestures/monodrag.dart:182
flutter: #15 PointerRouter._dispatch
package:flutter/…/gestures/pointer_router.dart:73
flutter: #16 PointerRouter.route
package:flutter/…/gestures/pointer_router.dart:101
flutter: #17 _WidgetsFlutterBinding&BindingBase&GestureBinding.handleEvent
package:flutter/…/gestures/binding.dart:221
flutter: #18 _WidgetsFlutterBinding&BindingBase&GestureBinding.dispatchEvent
package:flutter/…/gestures/binding.dart:199
flutter: #19 _WidgetsFlutterBinding&BindingBase&GestureBinding._handlePointerEvent
package:flutter/…/gestures/binding.dart:156
flutter: #20 _WidgetsFlutterBinding&BindingBase&GestureBinding._flushPointerEventQueue
package:flutter/…/gestures/binding.dart:102
flutter: #21 _WidgetsFlutterBinding&BindingBase&GestureBinding._handlePointerDataPacket
package:flutter/…/gestures/binding.dart:86
flutter: #25 _invoke1 (dart:ui/hooks.dart:233:10)
flutter: #26 _dispatchPointerDataPacket (dart:ui/hooks.dart:154:5)
flutter: (elided 5 frames from class _AssertionError and package dart:async)
flutter:
flutter: The ScrollController sending notification was:
flutter: ScrollController#be798(2 clients)
flutter: ════════════════════════════════════════════════════════════════════════════════════════════════════
flutter: Another exception was thrown: ScrollController attached to multiple scroll views.
flutter: Another exception was thrown: ScrollController attached to multiple scroll views.
flutter: Another exception was thrown: ScrollController attached to multiple scroll views.
flutter: Another exception was thrown: ScrollController attached to multiple scroll views.
The line flutter: Another exception was thrown: ScrollController attached to multiple scroll views. just keeps repeating many more times
How do I fix this issue?
Old, and there are lots of answers out there. I had similar issue, a few months ago:
The problem as the issue states, you have multiple positions (several scrollable views).
Declare as usual:
ScrollController scrollController;
//Note, Position, contains the información regarding the scroll offset, physics etc, this "positions" is an iterable., you might guess, here its where all scrolls "position" are stored (one for each scrollable view attached for this #scrollController" .
final scrollPositions = scrollController.positions;
//given the positions length I grabbed the latest one, which in my use case was always the last one (going back and forward doing new lists), you can adapt it to grab the position information depending on your needs.
final scrollPositionImInterested = scrollPositions
.elementAt(scrollController.positions.length - 1);
hope this helps someone in the same needs
I am placing the following in column like this
Widget _getDropDownCombo()
{
Widget combo = new DropdownButton(
value: _currentItem,
items:_dropDownMenuItems,
onChanged: _changedDropDownItem
);
return Flexible(child:combo);
}
and _getDropDownCombo is being called from a row somewhere like this
child: new Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
_getDropDownCombo(),
getIcon(),
],)
This gives me the error
flutter: ══╡ EXCEPTION CAUGHT BY RENDERING LIBRARY ╞═════════════════════════════════════════════════════════
flutter: The following assertion was thrown during performLayout():
flutter: RenderIndexedStack object was given an infinite size during layout.
flutter: This probably means that it is a render object that tries to be as big as possible, but it was put
flutter: inside another render object that allows its children to pick their own size.
flutter: The nearest ancestor providing an unbounded width constraint is:
flutter: RenderFlex#dfcbf relayoutBoundary=up17 NEEDS-LAYOUT NEEDS-PAINT
Why am I getting this error with DropDownButton ? Any suggestions ?
Their might be problem because of the items inside your DropdownButton.
I've tried using this in items and it works just fine:
items: ['Foo', 'Bar'].map((String value) {
return new DropdownMenuItem(
value: value,
child: new Text(value),
);
}).toList(),
here is the code. what I want is showing progress when requesting result, and display the result as a list when requesting completed.
I choose the AnimatedCrossFade cause it had convinient transition animation;
Widget SearchResultPage() {
return AnimatedCrossFade(
firstChild: Center(
child: CircularProgressIndicator(),
),
secondChild: ListView.builder(
itemCount: _searchResult.length,
itemBuilder: (BuildContext context, int index) {
return SearchListItem(_searchResult[index]);
}),
crossFadeState: _searchResult.isEmpty
? CrossFadeState.showFirst
: CrossFadeState.showSecond,
duration: Duration(milliseconds: 500));
}
Widget SearchListItem(BookFuzzySearchDetail detail) {
return Container(
decoration:
BoxDecoration(border: Border(bottom: BorderSide(color: Colors.grey))),
child: ListTile(
contentPadding: EdgeInsets.symmetric(vertical: 5.0, horizontal: 4.0),
leading: Image.network(
detail.cover,
width: 50.0,
height: 50.0,
),
title: Text(
detail.title,
),
),
);
}
and I got the error:
I/flutter ( 6281): ══╡ EXCEPTION CAUGHT BY RENDERING LIBRARY ╞═════════════════════════════════════════════════════════
I/flutter ( 6281): The following assertion was thrown during performResize():
I/flutter ( 6281): Vertical viewport was given unbounded height.
I/flutter ( 6281): Viewports expand in the scrolling direction to fill their container.In this case, a vertical
I/flutter ( 6281): viewport was given an unlimited amount of vertical space in which to expand. This situation
I/flutter ( 6281): typically happens when a scrollable widget is nested inside another scrollable widget.
I/flutter ( 6281): If this widget is always nested in a scrollable widget there is no need to use a viewport because
I/flutter ( 6281): there will always be enough vertical space for the children. In this case, consider using a Column
I/flutter ( 6281): instead. Otherwise, consider using the "shrinkWrap" property (or a ShrinkWrappingViewport) to size
I/flutter ( 6281): the height of the viewport to the sum of the heights of its children.
New to flutter and stucked here for a few days, appreciate for any advice please.
Try adding the property shrinkWrap to your ListView.builder
ListView.builder(
shrinkWrap: true,
itemCount: _searchResult.length,
itemBuilder: (BuildContext context, int index) {
return SearchListItem(_searchResult[index]);
}),
AnimatedCrossFade not only animates the opacity change of both widgets, but also the size transition; since the size of the list is unknown at build time (I mean build lifecycle method, not building the project) without shrinkWrap: true it throws an exception.
As #nickolay-savchenko pointed out in the comment to the accepted answer, shrinkWrap: true may cause significant performance issues and is definitely an unnecessary overkill for this case.
I'd advise using AnimatedSwitcher instead of AnimatedCrossFade, which will only do the opacity change (default behaviour).
Arguably, you don't need to animate the size change between a large possibly screen-overflowing list and "empty search results" widget.
Here is how I used it in one of my projects to animate transition between the list and "loading" widget:
AnimatedSwitcher(
duration: const Duration(milliseconds: 500),
child: items.isEmpty
? const LoadingWidget()
: ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) => ...
),
),
I am trying to add an image that covers the top 20% of the screen and the other 80% should be a grid of cards. The image needs to be in the body and not on the Appbar. I made the grid of cards, and then I tried to put the image and the grid in a column. The implementation is the following.
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
primary: true,
appBar: AppBar(
elevation: 4.0,
backgroundColor: Color(0xfff8f8f8),
title: Center(child: titleLogo,),
),
//------------ PROBLEM BELOW ----------------
body: new Column(
children: <Widget>[
titleLogo, //Image object
TheGridView().build() //Returns a GridView object
],
),
),
);
}
I am getting the following error
I/flutter (21751): The following assertion was thrown during performResize():
I/flutter (21751): Vertical viewport was given unbounded height.
I/flutter (21751): Viewports expand in the scrolling direction to fill their container.In this case, a vertical
I/flutter (21751): viewport was given an unlimited amount of vertical space in which to expand. This situation
I/flutter (21751): typically happens when a scrollable widget is nested inside another scrollable widget.
I/flutter (21751): If this widget is always nested in a scrollable widget there is no need to use a viewport because
I/flutter (21751): there will always be enough vertical space for the children. In this case, consider using a Column
I/flutter (21751): instead. Otherwise, consider using the "shrinkWrap" property (or a ShrinkWrappingViewport) to size
I/flutter (21751): the height of the viewport to the sum of the heights of its children.
Any suggestion is highly appreciated. Thank you in advance.
for distributing space between multiple items you should use the Expanded widget like this:
return new Column(
children: <Widget>[
new Expanded(
flex: 2,
child: new Container(
color: Colors.red,
),
),
new Expanded(
flex: 8,
child: new Container(//use your Gridview instead
color: Colors.green,
)
)
],
);
This question already has answers here:
Can't add a ListView in Flutter
(3 answers)
Closed 4 years ago.
I recently started learning Flutter and have been going through the documentation. I am working on this small app, where the screen has a button on the top of the screen and a list below it.
Whenever I pass RaisedButton with a ListView widget into another ListView or Column Widget, its throwing error.
I/flutter ( 4734): ══╡ EXCEPTION CAUGHT BY RENDERING LIBRARY ╞═════════════════════════════════════════════════════════
I/flutter ( 4734): The following assertion was thrown during performResize():
I/flutter ( 4734): Vertical viewport was given unbounded height.
I/flutter ( 4734): Viewports expand in the scrolling direction to fill their container.
////MORE LINES OF ERRORS/////
Here's the code I have been working on:
import 'package:flutter/material.dart';
void main() {
runApp(ListDemo(
items: new List<ListItem>.generate(
100,
(i) => i % 6 == 0
? new HeadingItem("Heading $i")
: new MessageItem("Sender $i", "Message body $i"),
),
));
}
// The base class for the different types of items the List can contain
abstract class ListItem {}
// A ListItem that contains data to display a heading
class HeadingItem implements ListItem {
final String heading;
HeadingItem(this.heading);
}
// A ListItem that contains data to display a message
class MessageItem implements ListItem {
final String sender;
final String body;
MessageItem(this.sender, this.body);
}
class ListDemo extends StatelessWidget {
final List<ListItem> items;
ListDemo({Key key, #required this.items}) : super(key: key);
#override
Widget build(BuildContext context) {
final ListView listView = ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) {
final item = items[index];
if (item is HeadingItem) {
return new ListTile(
title: new Text(
item.heading,
style: Theme.of(context).textTheme.headline,
),
);
} else if (item is MessageItem) {
return new ListTile(
title: new Text(item.sender),
subtitle: new Text(item.body),
);
}
},
);
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Lists'),
),
body: ListView( //Tried using ListView, Column.. None of them help solving the issue
children: <Widget>[
RaisedButton(
onPressed: null,
child: Text('Sample Button'),
),
Container(
child: listView,
)
]
)
)
);
}
}
Please help me solve this issue of letting know, how to pass multiple children, and also please make understand the concept as well.
EDITED
One of the possible solutions suggested wrapping ListView with Expanded class. When I did it threw me an error as below:
I/flutter ( 4190): ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
I/flutter ( 4190): The following assertion was thrown building NotificationListener<KeepAliveNotification>:
I/flutter ( 4190): Incorrect use of ParentDataWidget.
I/flutter ( 4190): Expanded widgets must be placed inside Flex widgets.
I/flutter ( 4190): Expanded(no depth, flex: 1, dirty) has no Flex ancestor at all.
So I wrapped the entire Widget code in Flex as below:
Flex(
direction: Axis.vertical,
children: <Widget>[
ListView(
children: <Widget>[
RaisedButton(
onPressed: null,
child: Text('Snackbar'),
),
Expanded(
child: listView
)
],
)
],
)
but then it threw me this error:
I/flutter ( 4388): ══╡ EXCEPTION CAUGHT BY RENDERING LIBRARY ╞═════════════════════════════════════════════════════════
I/flutter ( 4388): The following assertion was thrown during performResize():
I/flutter ( 4388): Vertical viewport was given unbounded height.
I/flutter ( 4388): Viewports expand in the scrolling direction to fill their container.In this case, a vertical
I/flutter ( 4388): viewport was given an unlimited amount of vertical space in which to expand. This situation
I/flutter ( 4388): typically happens when a scrollable widget is nested inside another scrollable widget.
This question is already answered here
Can't add a ListView in Flutter
If you use a scrollable view(Listview) inside another scrollable view, the inner scrollable view doesn't know how much height it should occupy. You can tell the inner scrollable view about how much height it should take using an Expanded widget.