When scrolling the page, Cursor bubble overlap the other widgets and Appbar. Can you help me?
This GIF file shows my issue
Widget
class Sample extends StatefulWidget {
Sample({Key? key}) : super(key: key);
#override
_SampleState createState() => _SampleState();
}
class _SampleState extends State<Sample> {
#override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: true,
extendBodyBehindAppBar: false,
extendBody: false,
appBar: AppBar(
title: Text('AppBar'),
backgroundColor: Colors.orange,
elevation: 0.0,
),
body: SafeArea(
child: Column(
children: [
ListView(
addAutomaticKeepAlives: true,
shrinkWrap: true,
children: [
Container(
color: Colors.yellow,
height: 70,
width: MediaQuery.of(context).size.width,
child: Center(
child: Text(
'This part want not be scrolled',
style: TextStyle(color: Colors.red),
),
),
)
],
),
Expanded(
child: Scrollbar(
child: ListView(
shrinkWrap: true,
scrollDirection: Axis.vertical,
children: [
Table(
children: [
TableRow(children: [
Column(
children: [Text('Name')],
),
Column(
children: [
TextFormField(decoration: InputDecoration())
],
)
]),
TableRow(
children: [
Column(
children: [Text('Name')],
),
Column(
children: [
TextFormField(decoration: InputDecoration())
],
)
],
),
TableRow(
children: [
Column(
children: [Text('Name')],
),
Column(
children: [
TextFormField(decoration: InputDecoration())
],
)
],
),
TableRow(
children: [
Column(
children: [Text('Name')],
),
Column(
children: [
TextFormField(decoration: InputDecoration())
],
)
],
),
],
),
],
),
),
),
],
),
),
);
}
}
Table widget is made for non-scrollable GridView. It renders full Table widget tree once and keep its children alive. You can think it is similar like SingleChildScrollView. Here in your Table children generate only once and don't call dispose even though it is not visible on screen, and it is the nature of Table Widget. To test this, you create a statefullWidget and pass it to column children.
For more
Table (Flutter Widget of the Week)
Table-class
Solution
you can simply use ListView.Builder
Related
I want the search bar to stick always on top while the user is scrolling vertically on the screen in the ListView. How can i achieve the result? i have attached my code below.
return Scaffold(
//bottomNavigationBar: ,
body: SafeArea(
child: ListView(
children: [
searchBox(),
Text(
'What can we help you find, Sandor?',
),
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children: [
ImageCard(
imageLink: 'home.jpg',
imageTitle: 'Homes',
)
],
),
),
Text(
'Introdcing Airbnb plus',
),
// Image,
],
),
),
);
}
SearchBox class
class searchBox extends StatelessWidget {
const searchBox({
Key? key,
}) : super(key: key);
#override
Widget build(BuildContext context) {
return TextField(
decoration: InputDecoration(
fillColor: Colors.white,
filled:true,
hintText: 'Try "Costa Tropical"' '',
),
);
}
}
You can solve it in many ways, this is one of them:
SafeArea(
child: Column(
children: [
searchBox(),
Expanded(
child: ListView(
children: [
Text(
'What can we help you find, Sandor?',
),
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children: [
ImageCard(
imageLink: 'home.jpg',
imageTitle: 'Homes',
)
],
),
),
Text(
'Introdcing Airbnb plus',
),
// Image,
],
),
),
],
),
),
In my page I have a customized Appbar then I want to display a message with icon, and it should be in the center of the page. i mean the customized Appbar is on the top then in the center of the page we have the icon with the message
child: Scaffold(
body: SafeArea(
child: SingleChildScrollView(
child: Column(children: [
const CustomAppBar("Réglages et paramétrages", true, false,
returnToHistory: true),
Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Row(
mainAxisAlignment : MainAxisAlignment.center,
children: const [
Icon(Icons.warning, color: Color(0xFFFF9500), size: 100 ,),
],
),
Row(
children: const [
Text(
"be careful",
textAlign: TextAlign.center,)
],
)
],
),
]),
)),
));
you can try doing it this way by using an expanded widget to adjust the flex of the custom appbar and scrollview
return Scaffold(
body: SafeArea(
child: Column(
children: [
Expanded(
child: const CustomAppBar("Réglages et paramétrages", true, false,
returnToHistory: true),
),
Expanded(
flex: 7,
child: Center(
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
children: const [
Icon(
Icons.warning,
color: Color(0xFFFF9500),
size: 100,
),
Text(
"be careful",
textAlign: TextAlign.center,
)
],
),
),
),
),
],
),
),
);
Remove SingleChildScrollView and wrap the inner column with an expanded widget.
You can create custom appbar as widget and provide on Scaffold's appbar. To do this, you need to implements PreferredSizeWidget
class CustomAppBar extends StatelessWidget implements PreferredSizeWidget {
final String title;
const CustomAppBar({
Key? key,
required this.title,
}) : super(key: key);
#override
Widget build(BuildContext context) {
return Container(
child: Text(title),
);
}
#override
Size get preferredSize => const Size.fromHeight(kToolbarHeight);
}
And your layout will be
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: const CustomAppBar(title: "Réglages et paramétrages"),
body: SafeArea(
child: Center(
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: const [
Icon(Icons.warning, color: Color(0xFFFF9500)),
Text(
"be careful ",
textAlign: TextAlign.center,
)
],
),
]),
),
),
),
);
}
You can find more about ui/layout on flutter dev .
I need a global area on top to show some ads. This are remains the same for all pages and widgets. So far I've got this:
Stack(
children: [
Column(
children: <Widget>[
Container(
color: Theme.of(context).primaryColor,
width: double.infinity,
height: bannerHeight,
child: MY_BANNER,
),
Expanded(child: child!), // this has to be dynamic
],
),
],
);
What's the problem? It creates an extra padding for the AppBar that I don't know how to remove:
Instead of creating a space on top of AppBar you can put your banner ads below it. For this you can make a custom MyAppBar widget and use this custom widget inside the Scaffold.
class MyAppBar extends StatelessWidget with PreferredSizeWidget {
final String title;
MyAppBar(this.title) : preferredSize = const Size.fromHeight(110);
#override
final Size preferredSize;
#override
Widget build(BuildContext context) {
return Column(
mainAxisSize: MainAxisSize.max,
children: [
AppBar(
title: Text(
title,
),
),
Center(
child: Container( // Place your ad here
color: Colors.red,
width: MediaQuery.of(context).size.width / 2,
height: 50,
),
),
],
);
}
}
and use it like
Scaffold(
appBar: MyAppBar(
"Hello App",
),
),
return Scaffold(
body: SafeArea(
child: Column(
children: [
Row(
children: [
Expanded(
child: MY_BANNER
),
],
),
Expanded(child: child!),
],
),
),
);
I'm learning flutter to make an app. Here I'm trying to make a page to show the full post. The problem is that the page isn't scrolling as a single unit.
class SinglePostPage extends StatefulWidget {
final Post? post;
const SinglePostPage({Key? key, this.post}) : super(key: key);
#override
State<SinglePostPage> createState() => _SinglePostPageState();
}
class _SinglePostPageState extends State<SinglePostPage> {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
mainAxisSize: MainAxisSize.min,
children: [
Container(
margin: const EdgeInsets.only(top: 22.5),
padding: const EdgeInsets.fromLTRB(0, 5, 0, 6),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const BackButton(),
Row(
children: [
InkWell(
onTap: () {
showDialog(...);
},
child: CircleAvatar(...),
Container(
padding: const EdgeInsets.only(left: 5.4),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
GestureDetector(
onTap: () {
showDialog(...);
},
child: Text(
widget.post!.author[0].profileName,
),
),
const SizedBox(height: 4),
Text(
showTimeAgo(widget.post!.postTime).toString(),
),
],
),
),
],
),
PopupMenuButton(
icon: const Icon(Icons.more_vert),
itemBuilder: (context) => [...],
),
Container(
margin: const EdgeInsets.fromLTRB(12, 9, 12, 3),
// when the text is longer than the screen height it showed RenderFlex overflowed error so I put constraints. how to show it full and make this scroll
constraints: BoxConstraints(
maxHeight: MediaQuery.of(context).size.height * 0.54,
minHeight: 50),
child: SingleChildScrollView(
child: Text(
widget.post!.postText,
textAlign: TextAlign.start,
),
),
),
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
if (widget.post!.postMedia.isNotEmpty)
CarouselSlider.builder(...),
const SizedBox(height: 4.5),
if (widget.post!.postMedia.length > 1)
buildDotIndicator(widget.post!.postMedia),
],
),
],
),
),
Container(
// post reactions row
),
CommentBodyWidget(
postId: widget.post!.postId,
),
],
),
);
}
}
I looked up for other answers and tried wrapping it with SingleChildScrollView, but it didn't work , and ListView with shrinkWrap: true also gave 'Incorrect use of ParentDataWidget' error.
CommentBodyWidget has a listview builder. It's scrolling on its own but the widget above isn't scrolling along with it.
How can I show this whole page and scroll together without having to limit the long post in a constrained container? Please help.
You can wrap body Column with SingleChildScrollView and use shrinkWrap: true, and use physics: NeverScrollableScrollPhysics(),. This will solve the issue.
return Scaffold(
body: SingleChildScrollView(
child: Column(
children: [
//...
ListView.builder(
itemCount: itemlength,
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemBuilder: (context, index) {
return Text("item $index");
},
),
/// instead of listView
...List.generate(itemlength, (index) => Text("itemWidget"))
],
),
),
);
But I will encourage you to check CustomScrollView.
In order for the SingleChildScrollView to work, its parent's height should be defined.
You can achieve this by wrapping the SingleChildScrollView in a Container/SizedBox with defined height, or by wrapping it with the Expanded widget.
Pass SingleChildScrollView as body of your scaffold. Also shrinkwrap: true for the ListView is recommended so that it only takes up as much space as required, which will avoid unbounded height errors.
So instead of
...
Widget build(BuildContext context) {
return Scaffold(
body: Column(
mainAxisSize: MainAxisSize.min,
children: [
Container(
...
Do this
...
Widget build(BuildContext context)
return Scaffold(
body: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Container(...
I recommend you to use CustomScrollView.
Try this:
CustomScrollView(
slivers: [
SliverFillRemaining(
hasScrollBody: false,
child: Column("""HERE PUT YOUR CODE""")
)]
),
I can't work this out. It should be really simple. (This is Flutter Desktop)
I want a Row with 2 columns. The first column should be full height available but only 200 wide. Column 2 should be full height and use the remainder of the width.
I have tried all sorts but always get an overflow rather than a scrollable list.
What am I doing wrong?
This is the last iteration of my code.
class HomePage extends StatelessWidget {
const HomePage({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Bnode Management'),
),
body: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text('This is the title'),
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Container(
width: 200,
child: ListView.builder(
shrinkWrap: true,
itemCount: piItems.length,
itemBuilder: (BuildContext context, int index) {
return Container(width: 40, color: Colors.red, child: Text(piItems[index].id));
}),
),
),
Container(color: Colors.blue, child: const Text('Column 1')),
],
),
],
),
);
}
}
The second Column like to have max space, therefor we can use Expanded on it instead of using on 1st Column. Also, the Row is needed to have max height. For this, we will wrap this Row with Expanded.
body: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text('This is the title'),
Expanded(
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
width: 200,
child: ListView.builder(
shrinkWrap: true,
itemCount: piItems.length,
itemBuilder: (BuildContext context, int index) {
return Container(
width: 40,
color: Colors.red,
child: Text(piItems[index].id));
}),
),
Expanded(
child: Container(
color: Colors.blue,
child: Column(
children: [
const Text('Column 1'),
],
),
),
)
],
),
),
],
),
I also prefer using LayoutBuilder on body in this case.
You almost got it right, just mixed some things. Let's go step by step.
I want a Row with 2 columns
Ok, that's just a Row with two children.
Row(
children: [child1, child2],
)
The first column should be full height available but only 200 wide.
It would take the full height automatically but I see that in your code example you have a Column with Text title, so we should wrap our Row with Expanded. Also, the first Column should take 200 px.
Column(
children: [
const Text('This is the title'),
Expanded(
child: Row(
children: [
Container(
width: 200,
child: child1,
),
child2,
],
),
),
],
)
Column 2 should be full height and use the remainder of the width.
So we wrap our 2nd child with Expanded inside the Row.
Column(
children: [
const Text('This is the title'),
Expanded(
child: Row(
children: [
Container(
width: 200,
child: child1,
),
Expanded(
child: child2,
),
],
),
),
],
)
The end result based on your code:
class HomePage extends StatelessWidget {
const HomePage({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Bnode Management'),
),
body: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text('This is the title'),
Expanded(
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
width: 200,
child: ListView.builder(
shrinkWrap: true,
itemCount: piItems.length,
itemBuilder: (BuildContext context, int index) {
return Container(
width: 40,
color: Colors.red,
child: Text(piItems[index].id));
},
),
),
Expanded(
child: Container(
color: Colors.blue,
child: const Text('Column 1'),
),
),
],
),
),
],
),
);
}
}