-
Notifications
You must be signed in to change notification settings - Fork 27.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Exception while scrolling through TabBar navigation #18756
Comments
Please add your flutter doctor -v output seems to be the same as #18763 |
I have the same issue. Heres my flutter doctor output:
|
Please add your |
|
|
import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart';
import 'bottom_navigation.dart';
import 'theme.dart';
import 'register.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return new MaterialApp(
debugShowCheckedModeBanner: false,
title: 'GabHub',
theme: defaultTargetPlatform == TargetPlatform.android ? tealTheme
: iOSTheme,
home: new BottomNavBar(),
);
}
} |
import 'package:flutter/material.dart';
import 'live_chat_tab_base.dart';
import 'posts_tab_base.dart';
import 'events_tab_base.dart';
import 'universities_tab_base.dart';
import 'notifications_tab_base.dart';
import 'profile_tab_base.dart';
class BottomNavBar extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new Scaffold(
body: new BottomNav(),
);
}
}
class BottomNav extends StatefulWidget {
@override
_State createState() => _State();
}
class _State extends State<BottomNav> with SingleTickerProviderStateMixin {
TabController bottomNavTabController;
@override
void initState() {
super.initState();
bottomNavTabController = new TabController(length: 6, vsync: this);
}
@override
void dispose() {
bottomNavTabController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return new Scaffold(
bottomNavigationBar: new Material(
color: Theme.of(context).platform == TargetPlatform.android
? Theme.of(context).primaryColor
: Theme.of(context).primaryColor.withOpacity(0.7),
child: new TabBar(
indicatorColor: Theme.of(context).accentColor,
controller: bottomNavTabController,
tabs: <Widget>[
new Tab(
icon: new Icon(Icons.edit, color: Theme.of(context).splashColor),
),
new Tab(
icon: new Icon(Icons.question_answer,
color: Theme.of(context).splashColor),
),
new Tab(
icon: new Icon(Icons.event_note,
color: Theme.of(context).splashColor),
),
new Tab(
icon: new Icon(Icons.account_balance,
color: Theme.of(context).splashColor),
),
new Tab(
icon: new Icon(Icons.notifications_active,
color: Theme.of(context).splashColor),
),
new Tab(
icon:
new Icon(Icons.person, color: Theme.of(context).splashColor),
),
],
),
),
body: new TabBarView(
children: <Widget>[
new LiveChatTabBase(),
new PostsTabBase(),
new EventsTabBase("Events"),
new UniversitiesTabBase("Universities"),
new NotificationsTabBase("Notifications"),
new ProfileTabBase("Profile"),
],
controller: bottomNavTabController,
),
);
}
} |
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'dart:math';
import 'package:cloud_firestore/cloud_firestore.dart';
const jsonCodec = const JsonCodec();
class LiveChatTabBase extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new Scaffold(
body: new ChatScreen(),
);
}
}
class ChatScreen extends StatefulWidget {
@override
State createState() => new ChatScreenState();
}
class ChatScreenState extends State<ChatScreen> with TickerProviderStateMixin {
final List<ChatMessage> _messages = <ChatMessage>[];
final TextEditingController _textController = new TextEditingController();
bool _isComposing = false;
@override
void dispose() {
for (ChatMessage message in _messages)
message.animationController.dispose();
super.dispose();
}
Widget _buildTextComposer() {
return new IconTheme(
data: new IconThemeData(
color: Theme.of(context).accentColor,
),
child: new Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
new Row(
children: <Widget>[
new Container(
margin: new EdgeInsets.only(
left: 5.0,
),
child: new IconButton(
icon: new Icon(
Icons.add_circle,
color: Colors.black87,
size: 28.0,
),
onPressed: () => _handleAddContent(),
),
),
new Flexible(
child: Padding(
padding: new EdgeInsets.only(
left: 5.0,
),
child: new TextField(
controller: _textController,
maxLines: null,
// maxLength: 2000,
onChanged: (String text) {
setState(() {
_isComposing = text.replaceAll(" ", "").length > 0;
});
},
decoration: new InputDecoration.collapsed(
hintText: "Write a message",
hintStyle: new TextStyle(
color: Colors.black87,
),
),
style: new TextStyle(
color: Colors.black87,
fontSize: 17.0,
),
// onChanged: () => _valueChanged(_textController.text),
),
),
),
new Container(
margin: new EdgeInsets.only(
right: 5.0,
),
child: _isComposing
? Theme.of(context).platform == TargetPlatform.android
? new IconButton(
icon: new Icon(
Icons.send,
color: Colors.black87,
size: 28.0,
),
onPressed: () =>
_handleSubmitted(_textController.text),
)
: new CupertinoButton(
child: new Text('Send'),
onPressed: () =>
_handleSubmitted(_textController.text),
)
: new IconButton(
icon: new Icon(
Icons.keyboard_voice,
color: Colors.black87,
size: 28.0,
),
onPressed: () => _handleVoiceInput(),
),
),
],
),
],
),
);
}
@override
Widget build(BuildContext context) {
return new Scaffold(
backgroundColor: Theme.of(context).backgroundColor,
appBar: new AppBar(
backgroundColor: Theme.of(context).primaryColor,
title: new Text(
'Live chat',
style: new TextStyle(color: Theme.of(context).hintColor),
),
elevation:
Theme.of(context).platform == TargetPlatform.android ? 4.0 : 0.0,
),
body: new Container(
child: new Column(
children: <Widget>[
new Flexible(
child:
// new ListView.builder(
// padding: new EdgeInsets.all(8.0),
// reverse: true,
// itemBuilder: (_, int index) => _messages[index],
// itemCount: _messages.length,
// ),
new StreamBuilder(
stream:
Firestore.instance.collection('live_chat').snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) return const Text('Loading...');
return new ListView.builder(
itemCount: snapshot.data.documents.length,
padding: const EdgeInsets.all(8.0),
reverse: true,
itemExtent: 55.0,
itemBuilder: (context, index) {
DocumentSnapshot ds = snapshot.data.documents[index];
return new Text(
" ${ds['message']}",
style: TextStyle(color: Colors.white70),
);
},
);
},
),
),
new Divider(
height: 1.0,
),
new Container(
decoration: new BoxDecoration(
color: Theme.of(context).cardColor, //Colors.white70,
),
child: _buildTextComposer(),
),
],
),
decoration: Theme.of(context).platform == TargetPlatform.iOS
? new BoxDecoration(
border: new Border(
top: new BorderSide(color: Colors.grey[200]),
),
)
: null),
);
}
void _handleSubmitted(String text) {
_textController.clear();
setState(() {
_isComposing = false;
});
// TODO: Change color to a color based on email id so that every person's color remains constant
final String username = "sahilwad";
List<int> ints = username.codeUnits;
var range = new Random();
ChatMessage message = new ChatMessage(
text,
ints[5] + ints[6],
ints[2],
ints[1] + ints[0],
ints[3] + ints[4],
new AnimationController(
duration: new Duration(milliseconds: 400),
vsync: this,
),
);
setState(() {
_messages.insert(0, message);
});
message.animationController.forward();
}
_handleVoiceInput() {
print('Voice input method');
}
_handleAddContent() {
print('Add content clicked');
}
}
class ChatMessage extends StatelessWidget {
final String text;
final int colorA;
final int colorR;
final int colorG;
final int colorB;
final AnimationController animationController;
ChatMessage(this.text, this.colorA, this.colorR, this.colorG, this.colorB,
this.animationController);
@override
Widget build(BuildContext context) {
return new SizeTransition(
sizeFactor: new CurvedAnimation(
parent: animationController,
curve: Curves.easeOut,
),
axisAlignment: 0.0,
child: new Container(
margin: const EdgeInsets.symmetric(vertical: 7.0),
child: new Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
new Container(
margin: const EdgeInsets.only(
right: 10.0,
),
child: new Padding(
padding: new EdgeInsets.only(top: 12.0),
child: new CircleAvatar(
maxRadius: 13.0,
backgroundColor:
Color.fromARGB(colorA, colorR, colorG, colorB),
),
),
),
new Expanded(
child: new Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
new Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Padding(
padding: new EdgeInsets.only(
bottom: 4.0,
right: 35.0,
),
child: new Text(
'25 June 2018, 4:11 am',
style: new TextStyle(
color: Theme.of(context).platform ==
TargetPlatform.android
? Colors.white70
: Colors.black54,
fontSize: 12.0,
letterSpacing: 0.6,
),
),
),
],
),
new Container(
width: 300.0,
child: new Text(
text,
style: new TextStyle(
color:
Theme.of(context).platform == TargetPlatform.android
? Colors.white
: Colors.black87,
letterSpacing: 0.4,
),
),
),
],
),
),
],
),
),
);
}
} |
import 'package:flutter/material.dart';
class NotificationsTabBase extends StatelessWidget {
final String title;
NotificationsTabBase(this.title);
@override
Widget build(BuildContext context) {
return new Scaffold(
backgroundColor: Theme.of(context).backgroundColor,
appBar: new AppBar(
title: new Text(
title,
style: new TextStyle(
color: Theme.of(context).hintColor,
),
),
elevation:
Theme.of(context).platform == TargetPlatform.android ? 4.0 : 0.0,
backgroundColor: Theme.of(context).primaryColor,
),
body: new Container(
child: new Center(
child: new Text(title),
),
decoration: Theme.of(context).platform == TargetPlatform.iOS
? new BoxDecoration(
border: new Border(
top: new BorderSide(color: Colors.grey[200]),
),
)
: null),
);
}
} |
Also, you may not be able to see but I have top level TabBar within Bottom TabBar on some tabs. So it's a complex structure. Please help! As much as I wanted to keep the code private, I guess there is no other option. I have a private repo on GitHub. |
I'm now using BottomNavigationBar instead of TabBar for bottom navigation. That fixed one of the issues. The app doesn't crash while switching between tabs. |
@escamoteur Is this issue related to #11895? |
@sahil311289 I hope it's fine with you if I close this as dup of #11895. |
Is #11895 really duplicate? I see exceptions are raised at different places. For me this issue is important as well so I am afraid that it could be lost and never fixed :) P.S. My case is just Tabs in Tabs (I am not using BottomNavigationBar) |
@s-limo no prob. I'll leave it open then. |
@sahil311289 I created https://github.com/timsneath/tabbar_exception to try and produce a repro based off your files. On the latest Flutter master builds, I get the following exception when I type in the live tab and then select the notifications tab:
Different error to yours, so could you confirm that this is the issue you're hitting, or help me adapt to a more accurate repro? |
@timsneath, I will summarise two issues related to TabBarView we have experienced. One happens when you have a nested TabBarView and second is when you have a TextField in focus in one of the tab pages. In the app we are building we have both scenarios. @sahil311289 had the TextField issue. I believe he fixed the issue by using Stack instead of TabBarView along with the BottomNavigation as implemented in the Gallery app. Stack-BottomNavigation combo is fine for simple child widgets. But if the tab pages have more heavy widgets then it might consume more memory because Stack is rendering all children. On the other hand I believe TabBarView has some optimization which removes the pages that is not displayed in the view port. I guess this optimization is the reason for these exceptions as it conflicts with the focus keep alive of the text field and scroll position of nested tab. I have posted gists to reproduce the issue below. I have also added the complete stack trace in the gist. This gist reproduces nested TabBarView issue. There is a TabBarView for the bottom navigation with 4 children. And there is another TabBarView inside the second tab page. If you navigate from 1st to 3rd or 4th without visiting the second page it gives the following exception.
This gist reproduces the focused TextField issue. There is a TabBarView for the bottom navigation with 4 children. In the first page, I have added a TextField. If you focus the text field and move to the 4th page below exception happens.
|
I was getting same issue, but have a temp fix (really not idea fix) which is to just take focus off during build.
Temp fix:
final FocusNode urlFocus = FocusNode();
final FocusNode apiFocus = FocusNode();
void unFocusAll() {
urlFocus.unfocus();
apiFocus.unfocus();
}
....
@override
Widget build(BuildContext context) {
unFocusAll();
return Scaffold(
.....
new TextFormField(
.....
focusNode: urlFocus,
),
.... |
In It's not clear to my why it's important that @override
void dispose() {
assert(pixels != null);
activity?.dispose(); // it will be null if it got absorbed by another ScrollPosition
_activity = null;
super.dispose();
} If I remove the assert, and use my app, I don't see any issues arising. Is this assert necessary and correct? Is a fix (at least to the nested TabBarView aspect of this issue) to simply remove this assert? |
Got the exactly same error. But only appear when i have more than 4 tabs... |
@apat183 if I try your fix then the textField wont let me input text |
@andrescr94 you might need to use TextEditingControllers but i wouldn't use my temp solution anymore. I ended up moving to a move permanent solution of navigating to form in new page rather then in tab page and everything working fine now. |
Any updates on this issue, it is also occuring on my app, do you need code examples or something else? |
This happens to me when I use an ExpandedTile widget and have gridview inside each tile. Both grid and tile are growable. Each grid view taps to open a dialog with a text field.
|
I'm having the same issue and the fix of removing the assert solved it for me, but I'm not using TabBars and the issue happens when either using |
Hi all I could resolve this issue by removing a parent scrollview inside which I had a listview. The parent is a column and the child listview in wrapped inside an expanded widget
Get Outlook for iOS<https://aka.ms/o0ukef>
…________________________________
From: Gildásio Filho <notifications@github.com>
Sent: Friday, March 22, 2019 7:14:42 PM
To: flutter/flutter
Cc: vijaykanta; Comment
Subject: Re: [flutter/flutter] Exception while scrolling through TabBar navigation (#18756)
I'm having the same issue and the fix of removing the assert solved it for me, but I'm not using TabBars and the issue happens when either using Navigator.of(context).pop() or the automatically generated BackButton for the AppBar. The error doesn't happen when in release mode, only when in debug.
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub<#18756 (comment)>, or mute the thread<https://github.com/notifications/unsubscribe-auth/AB5YVdI3nobMgWPlhMo1yotXvjdntbBSks5vZN5KgaJpZM4U020J>.
|
Hi! The solution is just not to forget to dispose TabContoller:
Check, please, if it is the right solution and tag people who faced this trouble in this issue |
Hi @MichaelDark, I'm currently working through a different issue, but I'm planning to get to this this after I'm done. That could definitely be a solution for some, if they forget to dispose their TabControllers. I'll provide an update once I've had an opportunity to dive deeper into the issue. |
I looked at @ajinasokan's first gist and noticed that However, I did create a reproducible sample that throws the exception with two TabBar/TabBarView/TabController combinations, and will be looking into it. |
I think it would be useful.
I did not use BottomNavigationBar and I think this issue is related with
deeper level of `flutter/material`. I had a TabView/TabBar/TabController in
of tabs of the another TabView/TabBar/TabController, and it throws the
exception that you have mentioned before
…On Fri, Apr 5, 2019, 11:51 PM Shi-Hao Hong ***@***.***> wrote:
I looked at @ajinasokan <https://github.com/ajinasokan>'s first gist
<https://gist.github.com/ajinasokan/e9fc78e5eaad5b60bff22411b3d084a1> and
noticed that TabController was paired with BottomNavigationBar, and I'm
not sure if they were meant to be used like that. I was able to get a running
sample
<https://gist.github.com/shihaohong/ba4512652c2bf1b638821afe68c5729d>
using BottomNavigationBar, while nesting the TabBarView.
However, I did create a reproducible sample
<https://gist.github.com/shihaohong/1909464287ce2f23b74088cf95ce02a6>
that throws the exception with two TabBar/TabBarView/TabController
combinations, and will be looking into it.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#18756 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AbPPYeSDsv5MnxTpeb2puDbyT7v1zGlzks5vd7dOgaJpZM4U020J>
.
|
I resolved it during debug by commenting out |
This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of |
The text was updated successfully, but these errors were encountered: