Make a ListView scroll horizontal in a PageView - flutter

I'm trying to create a ListView of images that stays in a PageView so I can swipe left or right to move to other images.
But I currently end up with an error that it only displays as a column and swipe vertically not horizontally as I wanted.
Anyone who gets solutions or ideas, please help me.
Here is my code:
final PageController _controller = PageController(
initialPage: initialImageIndex, keepPage: true, viewportFraction: 1);
return SafeArea(
child: Scaffold(
body: PageView(
controller: _controller,
scrollDirection: Axis.horizontal,
onPageChanged: (index) {
print("changed to $index");
},
children: [
Row(
children: [
Container(
width: size.width,
child: ListView.builder(
controller: ScrollController(
),
scrollDirection: Axis.horizontal,
shrinkWrap: true,
// physics: NeverScrollableScrollPhysics(),
itemCount: imagesInCategory.length,
itemBuilder: (context, index) {
return BuildImageDetail(
size: size, imageData: imagesInCategory[index]);
},
),
),
],
),
])),

I just got it with a function to render the widgets that Listview currently does now.
Then in children of PageView , i just call this function .
Hope this helps somebody.

Related

flutter GridView.builder won't let rest of screen scroll

I have GridView.builder middle of my screen but it does not let my screen to scroll! I must find some white space in screen in order to be able to scroll rest of my screen.
Here is how my screen structure looks like:
Widget build(BuildContext context) {
return Scaffold(
appBar: const TopBarFile(),
drawer: const DrawerFile(),
body: SafeArea(
child: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(12.0),
child: FutureBuilder(
future: myCards,
builder: (context, AsyncSnapshot snapshot) {
if (snapshot.hasData) {
return Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// some widgets...
const SizedBox(height: 15),
// here middle of screen is GridView
SizedBox(
child: GridView.builder(
gridDelegate:
const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
mainAxisSpacing: 10,
crossAxisSpacing: 10,
),
shrinkWrap: true,
itemCount: snapshot.data['cards'].length,
itemBuilder: (BuildContext context, int index) {
return InkWell(...);
}
)
),
const SizedBox(height: 15),
// some more widgets...
]
);
} else {...}
return container();
}
),
),
),
),
),
}
Note: this grid view only has 6 items so I don't need it to be scrollable actually I just use it for design purpose but its causing scrolling issue, so I just need to be able to scroll my page even if I'm touching on top of this grid view items.
Any suggestions?
you can define a physics property with NeverScrollableScrollPhysics() value inside GridView, this will solve the issue. Always use physics property When you have nested scrollable widget.
You can give physics: NeverScrollableScrollPhysics() to GridView() or use Wrap() widget instead of GridView().
Use physics and shrinkWrap property as below:
SizedBox(
child: GridView.builder(
gridDelegate:
const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
mainAxisSpacing: 10,
crossAxisSpacing: 10,
),
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
itemCount: snapshot.data['cards'].length,
itemBuilder: (BuildContext context, int index) {
return InkWell(...);
}
)
),

Flutter listview builder Scroll controller listener not firing inside list view?

I have a listview builder widget inside another list view. Inner listview listener is not firing when scrolling position reaches to its end.
initState() {
super.initState();
_scrollController.addListener(() {
if (_scrollController.position.maxScrollExtent ==
_scrollController.position.pixels) {function();}
}
Container(
child: Listview(
children: <Widget>[
Container(),
ListView.builder(
controller: _scrollController,
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemCount: list.length,
itemBuilder: (BuildContext context, int index) {
return Container();
},
),
]
)
)
You might have SingleChildScrollView attached before any widget :
so attach _scrollController to singleChildScrollView not listview
body: SingleChildScrollView(
controller: _scrollController,
child: Column(
children: [
_chips(),
SizedBox(
height: 10,
),
_slider(),
_showGrid(),
],
),
),
the list view must scroll otherwise it won't work. Not only you have to remove the NeverScrollableScrollPhysics() but also add that list view into some container and set its height smaller then overall height of your ListView. Then the listView begin to scroll and the function will be triggered
ScrollController _scrollController = ScrollController();
List<int> list = [1, 2, 3, 4, 5];
initState() {
super.initState();
_scrollController.addListener(() {
if (_scrollController.position.maxScrollExtent ==
_scrollController.position.pixels) {
print('firing');
}
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: ControlBar(
title: Text('Home'),
),
),
body: ListView(
children: <Widget>[
Container(
height: 150,
child: ListView.builder(
controller: _scrollController,
shrinkWrap: true,
itemCount: list.length,
itemBuilder: (BuildContext context, int index) {
return ListTile(title: Text(list[index].toString()));
},
),
),
],
),
);
}

How to scroll both ways simultaneously in pageview widget in flutter?

I am using PageView for my application.
PageView has a property of scrollDirection which sets the scroll either horizontal or vertical.
code example:
Widget build(BuildContext context) {
return PageView.builder(
scrollDirection: Axis.horizontal,
itemBuilder: (context, position) {
return Container(
color: Colors.black,
child: Stack(
children: <Widget>[AppVideoPlayer(), onScreenControls()],
),
);
},
itemCount: 20);
}
Is there a way where PageView can be set to scroll both ways (horizontal and vertical) at the same time.
If not, then is there any way in which this can be achieved?
Widget build(BuildContext context) {
return PageView.builder(
scrollDirection: Axis.vertical,
itemBuilder: (context, position) {
return PageView.builder(
scrollDirection: Axis.horizontal,
itemBuilder: (context, position) {
return Container(
color: Colors.black,
child: Stack(
children: <Widget>[AppVideoPlayer(), onScreenControls()],
),
);
},
itemCount: 20);
},
itemCount: 20);
}

Card not clickable in a Stack

I am following https://github.com/devefy/Flutter-Story-App-UI to build some UI components but I can't seem to make the cards clickable.
The PageView builder is supposed to manipulate the currentPage value to change the page, but the PageView builder is on top of the stack and blocks all GestureDetectors under it.
I can't think of any solutions atm, any help is appreciated.
PageController cardController =
PageController(initialPage: images.length - 1);
cardController.addListener(() {
setState(() {
currentPage = cardController.page;
});
});
Stack(
children: <Widget>[
StackedCards(currentPage,postList),
Positioned.fill(
child: PageView.builder(
itemCount: images.length,
controller: cardController,
reverse: true,
itemBuilder: (context, index) {
return Container();
},
),
)
],
)
Some clickable widgets : GestureDetector, InkWell, InkResponse
GestureDetector(
onTap: ...,
child: Stack(
children: <Widget>[
StackedCards(currentPage,postList),
Positioned.fill(
child: PageView.builder(
itemCount: images.length,
controller: cardController,
reverse: true,
itemBuilder: (context, index) {
return Container();
},
),
)
],
));

How to add scroll indicator in ListView

Is there any way to show the scroll indicator on the ListView?
Here is my basic code:
ListView.builder(
itemCount: 50,
itemBuilder: (context, index) => ListTile(title: Text("Item= ${index + 1}"),),
)
Thanks to Günter Zöchbauer.
You can wrap your ListView in Scrollbar
Scrollbar(
child: ListView.builder(
itemCount: 50,
itemBuilder: (context, index) => ListTile(title: Text("Item= ${index + 1}"),),),
)
I think better to use CupertinoScrollbar instead of Scrollbar. CupertinoScrollbar is can touch and scroll to the bottom..
Ex:
CupertinoScrollbar(
child: ListView.builder(...),
Or
Scrollbar(
child: ListView.builder(...),
You can implement this designer scrollbar library :
draggable_scrollbar
alphabet scrolling
OR
You can wrap ListView in Scrollbar widget
Scrollbar(
child: ListView.builder(...),
)
Create a ScrollController variable (ScrollController _scrollController);
Instatiate _scrollController inside initState() or wherever you want, _scrollController = ScrollController();
Add _scrollController variable inside Scrollbar and ListView properties,
controller:_scrollController
Here's the code:
ScrollController _scrollController;
#override
void initState() {
super.initState();
_scrollController = ScrollController();
}
Scrollbar(
isAlwaysShown: true,
controller: _scrollController,
child: ListView(
controller: _scrollController,
)
if you don't want it always shown set to false
thumbVisibility: false,
Scrollbar(
thickness: 10,
isAlwaysShown: true,
child: ListView.builder(
itemCount: _controller().transactonsList.length,
itemBuilder: (context, index) {
return Card(
elevation: 5,
child: Container(
padding: const EdgeInsets.only(bottom: 16),
height: 80,
child: Row(
children: [
SizedBox(width: 10),
amountOfTransaction(index),
SizedBox(width: 16),
dateAndTitleOfTransaction(index),
],
),
),
);
},
),
)
final ScrollController _scroll = ScrollController();
#override
Widget build(BuildContext context) {
(...)
child: ListView.builder(
controller: _scroll,
)
}
If u need to style your scroll bar a bit wrap the ListView in RawScrollbar and use the same scroll controller instance for both widgets
final ScrollController _scrollController = ScrollController();
#override
Widget build(BuildContext context) {
(...)
child: RawScrollbar(
controller: _scrollController,
thumbColor: Colors.redAccent,
radius: const Radius.circular(8),
crossAxisMargin: 2,
child: ListView.builder(
controller: _scrollController,
itemCount: 50,
itemBuilder: (context, index) => ListTile(
title: Text("Item= ${index + 1}"),
),
),
),
}
Scrollbar(
child:ListView.builder(
itemCount:20,
itemBuilder:(c,i) => MyItem(i),
),
),
You have to give itemcount as how many list you have
-----Example: itemCount: items.length,-----