SliverPersistent in Row of CustomScrollView - flutter

Image
Hey guys, I want to achieve the persistent header for red area as in image. I achieved this for purple using SliverPersistentHeader but I have no idea for red area. Here's the code for my problem...
CustomScrollView(
slivers: [
const SliverToBoxAdapter(
child: DashboardSliderList(),
),
const SliverToBoxAdapter(
child: kDividerV,
),
const CategorySliverHeader(), //Sliver Persistent Header
const SliverToBoxAdapter(
child: kDividerV,
),
SliverFillRemaining(
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Filter List'), // I want to get persistent this
],
),
),
Expanded(
flex: 3,
child: GridView.builder(
itemCount: 16,
shrinkWrap: true,
gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 300,
crossAxisSpacing: 10,
mainAxisSpacing: 10,
),
itemBuilder: (context, index) {
return DashboardProductCards(
onTap: () {},
image: ImageString.dbGridviewImage,
title: 'Sweety Home',
amount: '1000000 Ks',
hoverTitle: 'L-72 W-32 H 36in ',
);
}),
),
],
),
),
],
)

Related

How to put two parallel flutter lists in a column

I wanna put two parallel lists inside the row marked in the picture. I've tried different types of structures, but all give me problems.
Each element of the dynamic lists will have a picture and a Text.
Screen
I've been trying to put two sized box inside the row:
Row(children: [
SizedBox(
width: MediaQuery.of(context).size.width * 0.5,
),
SizedBox(
width: MediaQuery.of(context).size.width * 0.5,
),
])
After the width putting the ListView
Everything I try gives me the next error:
error
Please refer to below code
Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Flexible(
child: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
ListView.builder(
physics:
NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemCount: 15,
itemBuilder: (BuildContext context,
int index) {
return ListTile(
leading: Icon(
Icons.star_border,
),
title: Text(
'List $index' +
"Lorem ipsum dolor sit amet, ",
),
);
},
),
],
),
),
Flexible(
child: Padding(
padding: EdgeInsets.only(left: 15.0),
child: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
ListView.builder(
physics:
NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemCount: 15,
itemBuilder: (BuildContext context,
int index) {
return Row(
children: [
Icon(
Icons.star,
),
Text("List item $index"),
],
);
},
),
],
),
),
)
],
),
Try this :
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
ListView.builder(
shrinkWrap:true,
builder:(context,index)=> Container(),
),
ListView.builder(
shrinkWrap:true,
builder:(context,index)=> Container(),
),
],
);

Flutter, fill the entire screen

I am designing an application and I have realized that in different mobiles the screen occupies different dimensions, I would like the size to be proportional to the size of the mobile, so that it always occupies the entire screen without the need to scroll.
I'd like that the Screen A could be look like the Screen B no matter of the size of the device.
But I have no idea how to do that, this is my code. I also noticed that because of cards I can't scrolling even having a ListView this is not a problem once they get the same size, because then there wont be reason to scroll through
#override
Widget build(BuildContext context) {
final height = MediaQuery.of(context).size.height;
return Scaffold(
key: _scaffoldKey,
appBar: AppBar(
centerTitle: true,
title: Text('Gestion de flota'),
actions: <Widget>[
IconButton(
icon: Icon(
Icons.exit_to_app,
),
onPressed: () async {
_signOut().whenComplete(() =>
navigatorKey.currentState.pushReplacementNamed('/login'));
},
)
],
),
body: Container(
padding: EdgeInsets.symmetric(horizontal: 20),
child: Form(
key: _formKey,
child: ListView(
children: <Widget>[
Column(
children: <Widget>[
SizedBox(
height: 20,
),
GridView.count(
childAspectRatio: (10 / 4),
crossAxisCount: 2,
shrinkWrap: true,
children: [
_getHourStart(),
_getHourEnd(),
_getDateStart(),
_getDateEnd(),
],
),
],
),
SizedBox(height: 10),
Column(
children: <Widget>[
GridView.count(
childAspectRatio: (3 / 0.7),
crossAxisCount: 1,
shrinkWrap: true,
children: [
_getHourStart(),
],
),
],
),
SizedBox(height: 10),
GridView.count(
crossAxisCount: 2,
childAspectRatio: (3 / 2),
shrinkWrap: true,
children: [
Card(
child: _uploadPic(Foto.primera, picList[0]),
),
Card(
child: _uploadPic(Foto.segunda, picList[1]),
),
Card(
child: _uploadPic(Foto.tercera, picList[2]),
),
Card(
child: _uploadPic(Foto.cuarta, picList[3]),
),
],
),
SizedBox(height: 20),
InkWell(
onTap: () async { // more code... }
child: SubmitButton(context, 'Enviar datos'),
),
Container(
padding: EdgeInsets.symmetric(vertical: 10),
alignment: Alignment.centerRight,
),
SizedBox(height: height * .14),
],
),
),
),
);
}
}
you can use MediaQuery
you retrieve the size of mobile screen by:
final height = MediaQuery.of(context).size.height
final width = MediaQuery.of(context).size.width
One solution to this problem is to add Expanded to all the children in the Column widget.
Another and preferable one is :
make your Container height the height of your screen.
body: Container(
height:MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
next add the mainAxisAlignment property to both Column widgets.
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
]

Flutter : SingleChildScrollView doesn't work with columns and grid view. Why?

I can't scroll to see my lower grid view. Why is that? What should I change to make this work? Please help!!!
Thank you in advance.
Scaffold(
body: SingleChildScrollView(
child: Container(
child: Column(
children: <Widget>[
Text('GridView 1'),
GridView.count(
crossAxisCount: 3,
shrinkWrap: true,
children: List.generate(
9,
(index) {
return TouchableImageCard(
imagePath: 'assets/images/view_${index + 1}.jpg',
);
},
),
),
Text('GridView 2'),
GridView.builder(
itemCount: list_item.length,
shrinkWrap: true,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3),
itemBuilder: (BuildContext context, int index) {
return TouchableImageCard(
imagePath: 'assets/images/view_${index + 1}.jpg',
// width: 150,
// height: 150,
);
},
),
],
),
),
),
);
Thank you for helping me in flutter.
It actually does work, just not the way you need it.
The problem is that GridView itself is a scrollable widget too. So when you try to scroll the page, it actually tries to scroll those GridViews and not the SingleChildScrollView.
To disable GridView scrolling ability - you need to add one more parameter.
GridView.count(
physics: NeverScrollableScrollPhysics(),
...
),
Try this:
Center(
child: SingleChildScrollView(
padding: const EdgeInsets.all(8.0),
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[]
multiple gridview scrollable
Scaffold(
body: SingleChildScrollView(
child: Column(
children: <Widget>[
Text('GridView 1'),
Container(
height: 400,
child: GridView.count(
crossAxisCount: 3,
shrinkWrap: true,
primary: false,
children: List.generate(
20,
(index) {
return TouchableImageCard(
imagePath: 'assets/images/view_${index + 1}.jpg',
);
},
),
),
),
Text('GridView 2'),
Container(
height: 400,
child: GridView.builder(
itemCount: 20,
shrinkWrap: true,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3),
itemBuilder: (BuildContext context, int index) {
return TouchableImageCard(
imagePath: 'assets/images/view_${index + 1}.jpg',
// width: 150,
// height: 150,
);
},
),
),
],
),
),
);

Flutter how to dynamically get the height of my page and my Listview.Builder?

I'm wondering how to get the height of my page dynamically with a Listview.Builder()` inside. This is my page tree:
This is my News.dart
return SafeArea(
child: Scrollbar(
child: SingleChildScrollView(
physics: BouncingScrollPhysics(),
dragStartBehavior: DragStartBehavior.start,
child: Container(
height: MediaQuery.of(context).size.height * 5,
margin: EdgeInsets.all(25),
child: Column(
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Column(
...
Later on we have the Listview.Builder()
Expanded(child: Consumer<Model>(
builder: (context, myModel, child) {
return ListView.builder(
physics: NeverScrollableScrollPhysics(),
scrollDirection: Axis.vertical,
itemCount: list.length,
itemBuilder: (ctx, index) =>
ChangeNotifierProvider.value(
value: list[index],
child: GestureDetector(
onTap: () {
setState(() {
},
child: Item(),
),
),
);
})),
Now below my SingleChildScrollView() I have a Container with height of MediaQuery.of(context).size.height * 5, I want to have my complete Screen height dynamic. If I remove the height value, I'm getting the render layout error because there is no parent defining a size. This Page here is Part of a TabbarNavigation and this is the content.
Can anybody tell me how to get the dynamic height of the ListView.Builder() ?
EDIT:
The following is my Tabbar where I define the pages inside the tabbar. One of them is my News.dart
This is the Tabbar.dart:
final List<Widget> _pages = [
NewsScreen(),
TrendScreen(),
OtherScreen(),
];
return Scaffold(
extendBodyBehindAppBar: true,
body: _pages[provider.currentIndex],
bottomNavigationBar: provider.currentIndex != 2
? Column(mainAxisSize: MainAxisSize.min, children: <Widget>[
CustomWidget(),
BottomNavigationBar(
onTap: _selectPage,
backgroundColor: Theme.of(context).primaryColor,
unselectedItemColor: Color.fromRGBO(130, 130, 130, 1),
selectedItemColor: Color.fromRGBO(236, 37, 105, 1),
selectedFontSize: 10,
iconSize: 22,
currentIndex: provider.currentIndex,
type: BottomNavigationBarType.fixed,
selectedLabelStyle: TextStyle(fontSize: 12),
items: [
BottomNavigationBarItem(
backgroundColor: Theme.of(context).primaryColor,
icon: Icon(Icons.home),
title: Text(
'home',
style: TextStyle(
fontSize: 10,
),
),
),
BottomNavigationBarItem(
backgroundColor: Theme.of(context).primaryColor,
icon: Icon(Icons.star),
title: Text(
'News',
style: TextStyle(
fontSize: 10,
),
),
),
BottomNavigationBarItem(
backgroundColor: Theme.of(context).primaryColor,
icon: Icon(Icons.play_arrow),
title: Text('other',
style: TextStyle(
fontSize: 10,
)),
),
],
),
])
: null,
);
}
Credits to #pskink !!
Working with CustomScrollView() instead of SingleChildScrollView(), SliverToBoxAdapter() and SliverList() made everything work like charm!
return SafeArea(
child: CustomScrollView(
//scrollDirection: Axis.vertical,
physics: BouncingScrollPhysics(),
slivers: <Widget>[
// Place sliver widgets here
SliverToBoxAdapter(
child: Padding(
padding: const EdgeInsets.fromLTRB(25, 30, 25, 20),
child: SizedBox(
height: 299,
child: Column(children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
...
And a list example:
SliverList(
delegate: SliverChildBuilderDelegate(
(ctx, index) => ChangeNotifierProvider.value(
value: list[index],
child: GestureDetector(
onTap: () {}),
childCount: rrr.length,
)),
You can Use the "Flex" property of the already used Expanded() widget.
first remove the Container at the Top.
return SafeArea(
child: Scrollbar(
child: SingleChildScrollView(
physics: BouncingScrollPhysics(),
dragStartBehavior: DragStartBehavior.start,
child: Column(
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Column(
...
and then,
Column(
children: <Widget>[
Expanded(
flex : 1,
child: Consumer<Model>(
builder: (context, myModel, child) {
return ListView.builder(
physics: NeverScrollableScrollPhysics(),
scrollDirection: Axis.vertical,
itemCount: list.length,
itemBuilder: (ctx, index) =>
ChangeNotifierProvider.value(
value: list[index],
child: GestureDetector(
onTap: () {
setState(() {
},
child: Item(),
),
),
;
})),
]),
API Docs : https://api.flutter.dev/flutter/widgets/Expanded-class.html
Flutter Widget of the Week : https://www.youtube.com/watch?v=_rnZaagadyo

Flutter GridView is not scrolling

I am adding a header in the grid view. The header is scrolling but when touching grid view. It is not scrolling. I want to scroll header and gridview.
I have used SingleChildScrollView and Expanded. How to solve the please help me.
My code is shown below
Widget ItemGridview() {
return Container(
color: Colors.white,
padding: EdgeInsets.all(10),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
new Expanded(
child: SingleChildScrollView(
child: Column(
children: <Widget>[
new Text(
'Items of products',
style: TextStyle(fontWeight: FontWeight.w700, fontSize: 18.0),
textAlign: TextAlign.left,
),
GridView.count(
shrinkWrap: true,
primary: true,
padding: EdgeInsets.only(top:15.0),
crossAxisCount: 3,
childAspectRatio: 0.60, //1.0
mainAxisSpacing: 0.2, //1.0
crossAxisSpacing: 4.0, //1.0
children: createCategoryList(),
),
],
),
)
)
]
),
);
}
In my code Items of products is the header.
List<Widget> createCategoryList() {
List<Widget> createCategoryList = List<Widget>();
for (int i = 0; i < documents.length; i++) {
createCategoryList
.add(makeGridCell(documents[i].data['title'], "name", 8,documents[i].data['id']));
}
return createCategoryList;
}
Container makeGridCell(String name, String image, int count, String id) {
return Container(
child: new GestureDetector(
onTap: () {
},
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisSize: MainAxisSize.min,
verticalDirection: VerticalDirection.down,
children: <Widget>[
new Container(
child: Image.asset('assets/' + image + ".jpg"),
),
new Container(
color: Colors.white,
padding: EdgeInsets.only(left: 5),
child: new Text(name,
style: TextStyle(
fontWeight: FontWeight.w500, fontSize: 18.0)),
),
],
),
));
}
The createCategoryList() is the list of items in grid written in widget.
I had similar widget tree like you
a gridview.count() wrapped in SingleChildScrollView adding
physics: ScrollPhysics(),
to GridView.count() Widget Solved my problem
source:https://github.com/flutter/flutter/issues/19205
Add physics: ScrollPhysics() property to Gridview. it iwll scroll.
just add some property in GridView
Widget _buildFields(BuildContext context) {
return Container(
color: Colors.white,
child: GridView.count(
crossAxisCount: 2,
crossAxisSpacing: 2.0,
mainAxisSpacing: 2.0,
shrinkWrap: true,
scrollDirection: Axis.vertical,
physics: NeverScrollableScrollPhysics(),
children: List.generate(choices.length, (index) {
return Center(
child: new Column(
children: [
new Expanded(
child: SelectCard(choice: choices[index]),//your card wight
),
],
),
);
}),
));
}
and use like this
class _Dashboard extends State<Dashboard> {
#override
Widget build(BuildContext context) {
return OrientationBuilder(builder: (context, orientation) {
return ListView(
children: <Widget>[
Container(
height: 200,
child: Image.network(
"https://www.gizbot.com/img/2013/11/23-weekend-deals-top-10-latest-smartphones.jpg"),
),
_buildFields(context),
],
);
});
}
}
You have some issues related to the Scroll of your widgets, you can reduce the amount of Widgets using Wrap, like this :
Container(
color: Colors.white,
padding: EdgeInsets.all(10),
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Text(
'Items of products',
style: TextStyle(fontWeight: FontWeight.w700, fontSize: 18.0),
textAlign: TextAlign.left,
),
Padding(
padding: const EdgeInsets.only(top: 15.0),
child: Wrap(
spacing: 20.0,
alignment: WrapAlignment.spaceEvenly,
children:createCategoryList(),
),
],
),
)
)
]
),
);
Add a constraint width or a fixed with to the widget of your item:
return Container(
constraints:
BoxConstraints(maxWidth: MediaQuery.of(context).size.width / 4),
child: new GestureDetector(
I think you need to use some custom scroll view
CustomScrollView(
primary: false,
slivers: <Widget>[
SliverPadding(
padding: const EdgeInsets.all(20.0),
sliver: SliverGrid.count(
crossAxisSpacing: 10.0,
crossAxisCount: 2,
children: <Widget>[
const Text('He\'d have you all unravel at the'),
const Text('Heed not the rabble'),
const Text('Sound of screams but the'),
const Text('Who scream'),
const Text('Revolution is coming...'),
const Text('Revolution, they...'),
],
),
),
],
)
Just ran into this myself, change your primary parameter for the GridView to false, give that a try.
In Gridview.builder scrolling is not working for smaller resolutions like tablet mode,mobile mode then just wrap the Gridview.builder under the listview.builder widget.
SizedBox(
width: screenSize.width,
height: screenSize.height * entry.contentHeightFactor,
child: ListView.builder(
itemCount: 1,
itemBuilder: (context, index) {
return Card(
child: Container(
width: screenSize.width * 0.8,
height: screenSize.height * 0.72,
padding: const EdgeInsets.all(10),
child: GridView.builder(
scrollDirection: Axis.vertical,
gridDelegate:
const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
),
padding: const EdgeInsets.all(5),
itemCount: 30,
itemBuilder: (BuildContext context, int index) {
return Padding(
padding: const EdgeInsets.all(8.0),
child:Card(....),
);
},
),
),
);
},
),
),