Related
I am using Default Sidebar but getting error while scroll
'The $controllerForError is currently attached to more than one '
'ScrollPosition.',
here is Sidebar Widget
#override
Widget build(BuildContext context) {
return ListView(
children: <Widget>[
DrawerHeader(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/images/bgimage.jpg"),
fit: BoxFit.cover),
color: Colors.blue,
),
child: Center(
child: Column(
children: [
Text(
'${store.user['name']}',
style: TextStyle(color: Colors.white, fontSize: 25),
),
Lottie.asset(
'assets/lottie/coin.json',
width: 50,
height: 50,
),
Text(
'${store.user['wallet']}',
style: TextStyle(color: Colors.white, fontSize: 20),
),
],
)),
),
ListTile(
leading: Icon(Icons.home),
title: Text('Home'),
onTap: () {
Navigator.popAndPushNamed(context, '/home');
},
),
ListTile(
leading: Icon(Icons.assessment_outlined),
title: Text('Loss/Profit'),
onTap: () {
Navigator.pop(context);
},
),
ListTile(
leading: Icon(Icons.calendar_today),
title: Text('Results'),
onTap: () {
Navigator.popAndPushNamed(context, '/result');
},
),
ListTile(
leading: Icon(Icons.supervised_user_circle),
title: Text('Referrals'),
onTap: () {
Navigator.pop(context);
},
),
],
);
}
}
Using in homepage
drawer: Drawer(
child: Sidebar(),
),
where is scroll position is using multiple
by default drawer is already scrollable. i think the cause of not being able to scroll is not in the drawer
Hi I'm trying to add a drawer to my scaffold with the help of https://flutter.dev/docs/cookbook/design/drawer
And so far I'm getting multiple errors when I try to use it (and found 2, I don't know if there is more).
Code:
#override
Widget build(BuildContext context) {
return Scaffold(
drawer: Drawer(
child: Row(
children: <Widget>[
IconButton(icon: Icon(Icons.add), onPressed: () {}),
ListView(
padding: EdgeInsets.zero,
children: <Widget>[
DrawerHeader(
child: Text(
"What's up?",
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 30),
),
decoration: BoxDecoration(color: Color(0xff171719)),
),
ListTile(
title: Text(
"Change Theme",
style: TextStyle(fontSize: 24),
),
// ignore: todo
onTap: () {}, //TODO add dark mode
),
ListTile(
title: Text(
"Sign Out",
style: TextStyle(fontSize: 24),
),
onTap: () {
AuthMethods().signOut().then(
(s) {
Navigator.pushReplacement(context,
MaterialPageRoute(builder: (context) => SignIn()));
Navigator.pop(context);
},
);
// ignore: todo
}, //TODO sign out
),
],
),
],
),
),
Exception caught by gesture:
Exception caught by rendering library:
I couldn’t reproduce it on my end, but this usually means that there’s a widget whose viewport doesn’t have the dimensions established.
This generally happens when you add a ListView directly to a Row or Column. Y would suggest wrapping your ListView with an Expanded widget (or a Container).
You should put your ListView inside a Widget that will constraint the ListView vertically, such as Expanded:
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
void main() {
runApp(
MaterialApp(
title: 'Flutter Demo',
home: Scaffold(body: MyWidget()),
),
);
}
class MyWidget extends HookWidget {
#override
Widget build(BuildContext context) {
final _drawerKey = useState<GlobalKey<ScaffoldState>>(GlobalKey());
return Scaffold(
key: _drawerKey.value,
drawer: Drawer(
child: Row(
children: <Widget>[
IconButton(icon: Icon(Icons.add), onPressed: () {}),
Expanded(
child: ListView(
padding: EdgeInsets.zero,
children: <Widget>[
DrawerHeader(
child: Text(
"What's up?",
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 30),
),
decoration: BoxDecoration(color: Color(0xff171719)),
),
ListTile(
title: Text(
"Change Theme",
style: TextStyle(fontSize: 24),
),
// ignore: todo
onTap: () {}, //TODO add dark mode
),
ListTile(
title: Text(
"Sign Out",
style: TextStyle(fontSize: 24),
),
onTap: () {
print('SIGN OUT');
}, //TODO sign out
),
],
),
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () => _drawerKey.value.currentState.openDrawer(),
),
);
}
}
Solution 1: Set ListView inside Expanded
Solution 2: ListView with the attribute: shrinkWrap: true,
I'm trying to create Paginated Data Table to fill the height. However, whatever I'm trying nothing seems to work. How can I make the table fill the height? Also, how can I change the pagination background color?
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(state.department.name),
),
body: Column(
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
TextButton(onPressed: () {}, child: Text('TEst 1')),
TextButton(onPressed: () {}, child: Text('TEst 1'))
],
),
Container(
child: PaginatedDataTable(
showCheckboxColumn: false,
headingRowHeight: 35,
columns: const <DataColumn>[
DataColumn(
label: Text(
'First Name',
style: TextStyle(fontStyle: FontStyle.italic),
),
),
DataColumn(
label: Text(
'Last Name',
style: TextStyle(fontStyle: FontStyle.italic),
),
),
DataColumn(
label: Text(
'Id',
style: TextStyle(fontStyle: FontStyle.italic),
),
),
DataColumn(
label: Text(
'Time',
style: TextStyle(fontStyle: FontStyle.italic),
),
),
DataColumn(
label: Text(
'Operator',
style: TextStyle(fontStyle: FontStyle.italic),
),
),
],
source: tableSource
),
)
],
),
);
}
With Container the container itself is filling up the height, but the paginated data table not.
Solution
static const double topViewHeight = 50.0;
static const double paginateDataTableHeaderRowHeight = 35.0;
static const double pagerWidgetHeight = 56;
static const double paginateDataTableRowHeight = kMinInteractiveDimension;
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Hello'),
),
body: LayoutBuilder(
builder: (context, constraint) {
return Column(
children: <Widget>[
Container(
width: constraint.maxWidth,
height: topViewHeight,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
TextButton(onPressed: () {}, child: Text('TEst 1')),
TextButton(onPressed: () {}, child: Text('TEst 1'))
],
),
),
Container(
color: Colors.greenAccent,
height: constraint.maxHeight - topViewHeight,
child: Center(
child: PaginatedDataTable(
showCheckboxColumn: false,
headingRowHeight: paginateDataTableHeaderRowHeight,
rowsPerPage: ((constraint.maxHeight -
topViewHeight -
paginateDataTableHeaderRowHeight -
pagerWidgetHeight) ~/
paginateDataTableRowHeight)
.toInt(),
columns: const <DataColumn>[
DataColumn(
label: Text(
'First Name',
style: TextStyle(fontStyle: FontStyle.italic),
),
),
],
source: TableSource()),
))
],
);
},
),
);
}
Need to know
note:
Column is an infinite height constraint so it will not suit to fit the height.
If, you warp the column inside the SingleChildScrollViewWidget to avoid constraint errors and warnings
There's a derivative of Flutter's DataTable widget on pub.dev (called DataTable2) which solves exactly that issues - filling the height of the parent widget. It is in-place substitute for DataTable and also provides data rows scrolling and sticky header.
https://pub.dev/packages/data_table_2
I have been trying to do what the title says but have found no information on the web at all. In regular Android code, this is as simple as finding the ViewID of the drawer/toolbar, getting the menu item, and either calling .setEnabled() or .setVisible() on the menu item. How can I do this in Flutter? Basically when a certain url is loaded in webView, I want to either enable/disable or show/hide programatically (in the onLoadStart and onLoadFinished methods for webview_flutter). For reference, my scaffold:
return new Scaffold(
appBar: new AppBar(
title: new Text(appBarTitle),
actions: <Widget>[
IconButton(
icon: Icon(
Icons.refresh,
color: Colors.white,
),
onPressed: () {
webView.reload();
},
),
PopupMenuButton<Choice> ( //showchoice??
onSelected: _select,
itemBuilder: (BuildContext context) {
return choices.map((Choice choice) {
return PopupMenuItem<Choice>(
value: choice,
child: Text(choice.title),
);
}).toList();
},
),
],
),
drawer: Drawer(
child: ListView(
children: <Widget>[
new DrawerHeader(
child: Column (
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget> [
Text(
'HLS Grades',
textAlign: TextAlign.left,
style: TextStyle(
color: Colors.white,
fontSize: 20,
),
),
Text(
'Canvas Online Grading System',
style: TextStyle(
color: Colors.white,
fontSize: 12,
),
),
]),
decoration: BoxDecoration(
color: Colors.blue,
),
),
Divider(),
Text(
'Course Actions',
style: TextStyle(
color: Colors.black,
fontSize: 12,
),
),
ListTile(
leading: Icon(MyFlutterApp.assignment),
title: Text('Assignments'),
onTap: () {
setState(() => _selectedDrawerIndex = 0);
_onSelectNavItem(0);
},
),
ListTile(
leading: Icon(MyFlutterApp.grades),
title: Text('Grades'),
onTap: () {
setState(() => _selectedDrawerIndex = 1);
_onSelectNavItem(1);
},
),
ListTile(
leading: Icon(MyFlutterApp.people),
title: Text('Users'),
onTap: () {
setState(() => _selectedDrawerIndex = 2);
_onSelectNavItem(2);
},
),
ListTile(
leading: Icon(MyFlutterApp.syllabus),
title: Text('Syllabus'),
onTap: () {
setState(() => _selectedDrawerIndex = 3);
_onSelectNavItem(3);
},
),
ListTile(
leading: Icon(MyFlutterApp.discussions),
title: Text('Discussions'),
onTap: () {
setState(() => _selectedDrawerIndex = 4);
_onSelectNavItem(4);
},
),
Divider(),
Text(
'App Actions',
style: TextStyle(
color: Colors.black,
fontSize: 12,
),
),
ListTile(
leading: Icon(MyFlutterApp.logout),
title: Text('Logout'),
onTap: () {
_onSelectNavItem(5);
},
),
ListTile(
leading: Icon(MyFlutterApp.settings),
title: Text('Settings'),
onTap: () {
_onSelectNavItem(6);
},
),
],
),
),
And the code for my choice class:
class Choice {
const Choice({this.title, this.icon});
final String title;
final IconData icon;
}
const List<Choice> choices = const <Choice>[
const Choice(title: 'All Grading Periods'),
const Choice(title: 'Trimester 1'),
const Choice(title: 'Trimester 2'),
const Choice(title: 'Trimester 3'),
];
class ChoiceCard extends StatelessWidget {
const ChoiceCard({Key key, this.choice}) : super(key: key);
final Choice choice;
#override
Widget build(BuildContext context) {
final TextStyle textStyle = Theme.of(context).textTheme.headline4;
return Card(
color: Colors.white,
child: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Icon(choice.icon, size: 128.0, color: textStyle.color),
Text(choice.title, style: textStyle),
],
),
),
);
}
}
Any help would be appreciated!
For whoever is stumped by this and is looking for an answer, just wrap your ListTile in a
Visibility (
visible: _visible
child: ListTile(...)
);
and whenever you want to remove, just
setState(() {
_visible = false;
});
or whenever you want to show
setState(() {
_visible = true;
});
I have been trying again today to center the title of a Flutter ListTile. Over the past few days I have spent an hour or two Googling and trying things then loosing my cool and giving up.
I am just learning Flutter and love the concept but can find no video training courses (Lynda.com, uDemy.com etc). I have read through the relevant documentation but cannot get rid of all the red lines that appear when I try to apply them to my code.
There must be logic in the syntax but after 2 weeks I have not worked it out yet.
Back to the problem, I have tried
List<Widget> list = <Widget>[
new ListTile(
new child: Center (
title:
new Text('Title 1',
style: new TextStyle(
fontWeight: FontWeight.w500,
color: Colors.deepOrangeAccent,
fontSize: 25.0)),
)
),
];
List<Widget> list = <Widget>[
new ListTile(
title:
new child: Center (
new Text('Title 2',
style: new TextStyle(
fontWeight: FontWeight.w500,
color: Colors.deepOrangeAccent,
fontSize: 25.0)),
)
),
];
List<Widget> list = <Widget>[
new ListTile(
child: Center
title: (
new Text('Title 3',
style: new TextStyle(
fontWeight: FontWeight.w500,
color: Colors.deepOrangeAccent,
fontSize: 25.0)),
)
),
];
List<Widget> list = <Widget>[
new ListTile(
title: Center
new Text('Title 4',
style: new TextStyle(
fontWeight: FontWeight.w500,
color: Colors.deepOrangeAccent,
fontSize: 25.0)),
)
),
];
Please help me with this problem and also where to find a video course on Flutter?
On the upside, if this continues I will no longer be grey, I will be bald instead.
I thought I worked it out when I added 'textAlign: TextAlign.center,' to the text object. There were no red lines but the text was still left aligned.
I am not sure what have you tried, but you in order to center the title of the ListTile you can use a center widget like you did in your code, or wrap your text within a Row widget and set mainAxisAlignment: MainAxisAlignment.center.
Using Center widget:
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(title: new Text("ListTile Example"),),
body: new ListView(
children: new List.generate(7, (int index) {
return new ListTile(
title: new Center(child: new Text("Centered Title#$index",
style: new TextStyle(
fontWeight: FontWeight.w500, fontSize: 25.0),)),
subtitle: new Text("My title is centered"),
);
}),
),
);
}
Using Row widget:
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(title: new Text("ListTile Example"),),
body: new ListView(
children: new List.generate(7, (int index) {
return new ListTile(
title: new Row(children: <Widget>[new Text("Centered Title#$index",
style: new TextStyle(
fontWeight: FontWeight.w500, fontSize: 25.0),)
], mainAxisAlignment: MainAxisAlignment.center,),
subtitle: new Text("My title is centered"),
);
}),
),
);
}
However, your problem is not about centering the title, it is about you are trying to insert too big of a Text inside a small area, that is why you are getting the red lines, so one solution is choose a smaller fontSize, a better solution is to get rid of ListTile and build your own custom widget, since a ListTile is
A single fixed-height row that typically contains some text as well as
a leading or trailing icon.
So it should not be used if you are using bigger widgets.
This is simple example of how to create a custom widget that resembles ListTile, but is more flexible and customizable when dealing with larger items:
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(title: new Text("ListTile Example"),),
body: new ListView(
children: new List.generate(7, (int index) {
return new Container(
padding: const EdgeInsets.symmetric(
vertical: 10.0, horizontal: 20.0),
child: new Column(
children: <Widget>[
new Align (child: new Text("Centered Title $index",
style: new TextStyle(fontSize: 40.0),), //so big text
alignment: FractionalOffset.topLeft,),
new Divider(color: Colors.blue,),
new Align (child: new Text("Subtitle $index"),
alignment: FractionalOffset.topLeft,),
new Divider(color: Colors.blue,),
new Align (child: new Text("More stuff $index"),
alignment: FractionalOffset.topLeft,),
new Row(mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[ //add some actions, icons...etc
new FlatButton(onPressed: () {}, child: new Text("EDIT")),
new FlatButton(onPressed: () {},
child: new Text("DELETE",
style: new TextStyle(color: Colors.redAccent),))
],),
],
),
);
}),
)
);
}
You can change the alignment of the text by using textAlign
Use this to center the Title of a ListTile:
ListTile(title: Text('YOUR TEXT', textAlign: TextAlign.center));
Here is my example of a three-row tile:
class ThreeRowTile extends StatelessWidget {
final Widget title;
final Widget detail;
final String utility1;
final String utility1Help;
final String utility2Help;
final String utility2;
final Icon icon;
final String cell;
final String home;
final String office;
final String email;
final VoidCallback cellTapped;
final VoidCallback cellLongPressed;
final VoidCallback iconTapped;
ThreeRowTile({
this.title,
this.icon,
this.detail,
this.utility1,
this.utility1Help,
this.utility2,
this.utility2Help,
this.cellTapped,
this.home,
this.email,
this.cell,
this.office,
this.cellLongPressed,
this.iconTapped,
});
#override
Widget build(BuildContext context) {
List<Widget> buildChildren() {
List<Widget> builder = [];
if (cell.isNotEmpty && !cell.toString().contains("--")) {
builder.add(ListTile(
leading: const Icon(Icons.phone),
title: Text(
'Cell',
textScaleFactor: globals.textScaleFactor,
style: TextStyle(
fontWeight: FontWeight.bold,
),
),
subtitle: Text(
cell.toString().length > 0 ? cell : "No Number Found",
textScaleFactor: globals.textScaleFactor,
),
onTap: cell.toString().contains("--")
? null
: () {
globals.Utility.makePhoneCall(context, cell);
},
));
}
if (office.isNotEmpty && !office.toString().contains("--")) {
builder.add(ListTile(
leading: const Icon(Icons.work),
title: Text(
'Office',
textScaleFactor: globals.textScaleFactor,
style: TextStyle(
fontWeight: FontWeight.bold,
),
),
subtitle: Text(
office.toString().length > 0 ? office : "No Number Found",
textScaleFactor: globals.textScaleFactor,
),
onTap: office.toString().contains("--")
? null
: () {
globals.Utility.makePhoneCall(context, office);
},
));
}
if (home.isNotEmpty && !home.toString().contains("--")) {
builder.add(ListTile(
leading: const Icon(Icons.home),
title: Text(
'Home',
textScaleFactor: globals.textScaleFactor,
style: TextStyle(
fontWeight: FontWeight.bold,
),
),
subtitle: Text(
home.toString().length > 0 ? home : "No Number Found",
textScaleFactor: globals.textScaleFactor,
),
onTap: home.toString().contains("--")
? null
: () {
globals.Utility.makePhoneCall(context, home);
},
));
}
if (email.isNotEmpty && !email.contains('No Email Address')) {
builder.add(ListTile(
leading: const Icon(Icons.email),
title: Text(
'Email',
textScaleFactor: globals.textScaleFactor,
style: TextStyle(
fontWeight: FontWeight.bold,
),
),
subtitle: Text(
email.toString().length > 0 ? email : "No Email Found",
textScaleFactor: globals.textScaleFactor,
),
onTap: email.toString().isEmpty
? null
: () {
globals.Utility.sendEmail(context, email);
},
));
}
if (builder.isEmpty) {
builder.add(
ListTile(
leading: const Icon(Icons.info),
title: Text(
'No Contact Information Found',
textScaleFactor: globals.textScaleFactor,
style: TextStyle(
fontWeight: FontWeight.bold,
),
),
),
);
}
return builder;
}
String _utility1 =
utility1 == null || utility1.contains("1-1-1800") ? "" : utility1;
String _utility2 =
utility2 == null || utility2.contains("1-1-1800") ? "" : utility2;
var rowCard = Container(
decoration: BoxDecoration(
border: Border(bottom: BorderSide(color: Colors.grey[300]))),
child: Container(
padding: const EdgeInsets.symmetric(vertical: 10.0, horizontal: 5.0),
child: new Column(
children: <Widget>[
Row(
children: <Widget>[
Align(
child: IconButton(
icon: icon,
onPressed: iconTapped,
),
alignment: FractionalOffset.centerLeft,
),
Expanded(
child: Column(
children: <Widget>[
new Align(
child: title, //so big text
alignment: FractionalOffset.topLeft,
),
// new Divider(),
new Align(
child: detail,
alignment: FractionalOffset.topLeft,
),
// new Divider(),
Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Expanded(
child: Container(
margin: const EdgeInsets.all(3.0),
padding: const EdgeInsets.all(3.0),
decoration: BoxDecoration(
border: Border.all(
color: _utility1.length > 1
? Colors.grey
: Colors.transparent)),
child: Tooltip(
message:
utility1Help == null ? "" : utility1Help,
child: Text(
_utility1,
maxLines: 1,
textAlign: TextAlign.center,
textScaleFactor: globals.textScaleFactor,
),
),
),
),
Expanded(
child: Container(
margin: const EdgeInsets.all(3.0),
padding: const EdgeInsets.all(3.0),
decoration: BoxDecoration(
border: Border.all(
color: _utility2.length > 1
? Colors.grey
: Colors.transparent)),
child: Tooltip(
message: utility2 == null ? "" : utility2,
child: Text(
_utility2,
maxLines: 1,
textAlign: TextAlign.center,
textScaleFactor: globals.textScaleFactor,
),
),
),
),
],
),
],
),
),
Align(
child: IconButton(
icon: Icon(Icons.arrow_drop_down),
onPressed: () {
showModalBottomSheet<void>(
context: context,
builder: (BuildContext context) {
return Container(
child: Padding(
padding: EdgeInsets.only(bottom: 10.0),
child: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min,
children: buildChildren()),
),
));
});
},
),
alignment: FractionalOffset.centerRight,
),
],
),
],
),
),
// color: globals.isDarkTheme ? Colors.black45 : Colors.white,
);
return (rowCard);
}
}
And it can be used like this:
ThreeRowTile(
icon: Icon(Icons.person),
title: _contacts?.items[index]?.lastName.toString().isEmpty &&
_contacts?.items[index]?.firstName.toString().isEmpty
? null
: Text(
(_contacts?.items[index]?.lastName ?? "") +
", " +
(_contacts?.items[index]?.firstName ?? ""),
textScaleFactor: globals.textScaleFactor,
),
detail: Text(
_contacts?.items[index]?.lastActivity,
textScaleFactor: globals.textScaleFactor,
),
utility1: _contacts?.items[index]?.dateCreated,
utility1Help: 'Date Created',
utility2: _contacts?.items[index]?.dateModified,
utility2Help: "Date Modified",
cell: _contacts?.items[index]?.cell,
home: _contacts?.items[index]?.home,
office: _contacts?.items[index]?.office,
email: _contacts?.items[index]?.email,
cellTapped: () {
globals.contactID = _contacts?.items[index]?.contactID;
Navigator.of(context).pushNamed("/contact_details").then((value) {
if (globals.infoChanged) {
_getData("", false).then((newitems) {
setState(() {
_contacts = newitems;
});
});
}
});
},
);