Related
I am trying to display a list using a list title but would like to add a text with a click event to the top of the list.
How could I do it?
I would be very grateful for the help.
I am trying to display a list using a list title but would like to add a text with a click event to the top of the list.
How could I do it?
I would be very grateful for the help.
Code and image::
Widget StatefulBuilderSuggestions(BuildContext context ,List <SearchDelegateModel> historialMenuPrincipal){
return Container(
child:StatefulBuilder(
builder:(context,setState)
{
return Container(
child: ListView.builder(
itemCount: historialMenuPrincipal.length,
itemBuilder: (context,i)
{
contentPadding: EdgeInsets.symmetric(vertical: 12,horizontal: 16);
return
ListTile(
subtitle: Text(historialMenuPrincipal[i] == null ? "no data" :historialMenuPrincipal[i].email,
overflow: TextOverflow.ellipsis,
style: TextStyle(fontSize: 20,
fontWeight: FontWeight.bold,
),
),
title: Text(historialMenuPrincipal[i] == null ? "no data" :historialMenuPrincipal[i].contrasena,
overflow: TextOverflow.ellipsis,
style: TextStyle(fontSize: 20,
fontWeight: FontWeight.bold,
),
),
trailing: historialMenuPrincipal[i] != null || historialMenuPrincipal.isEmpty
? IconButton(
icon: Icon(Icons.cancel,color: Colors.black,),
onPressed: () {
setState(() {
historialMenuPrincipal.remove(historialMenuPrincipal[i]);
});
},): null
);
}
),
);
}
)
);
}
use a column with 2 parts, title as a textbutton and above the list
Container(
child: Column(
children: [
TextButton(
onPressed: () {
hideList = !hideList;
},
child: Text("Title"),
),
hideList ? ListView() : Container(),
],
))
something like this
In order to add a Text widget above a list, both widgets should be inside a column and important thing to note is that ListView widget must be inside a Expanded widget and for the text widget to be clickable, use GestureDetector.
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Container(
padding: const EdgeInsets.all(16),
child: Column(
children: [
GestureDetector(
onTap: () {}, child: const Text("Some text above the list")),
Expanded(
child: ListView.builder(
itemCount: 50,
itemBuilder: (context, i) {
return Container(
margin: const EdgeInsets.all(16),
color: Colors.pinkAccent,
child: Text("$i"));
},
),
),
],
),
),
);
}
This question already has answers here:
Firestore search array contains for multiple values
(6 answers)
Closed 1 year ago.
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class SearchPage extends StatefulWidget {
#override
_SearchPageState createState() => _SearchPageState();
}
class _SearchPageState extends State<SearchPage> with TickerProviderStateMixin {
final searchController = TextEditingController();
final _firestore = FirebaseFirestore.instance;
static const defaultSearch = "";
String search = defaultSearch ;
void dispose() {
searchController.dispose();
super.dispose();
}
#override
void initState() {
super.initState();
searchController.addListener(searchChanged);
}
searchChanged() {
setState(() {
search = searchController.text;
});
}
#override
Widget build(BuildContext context) {
var tarifRef = _firestore
.collection("vehicles")
.where("models", arrayContains: search);
return Scaffold(
body: Container(
child: ListView(
children: <Widget>[
Expanded(
child: Container(
height: MediaQuery.of(context).size.height * 0.08,
margin: EdgeInsets.only(top: 25),
child: Text(
"Vehicles",
style: TextStyle(
fontSize: 20, fontFamily: "Quando", color: Colors.indigo),
),
),
),
Expanded(
child: Container(
margin: EdgeInsets.only(
top: 10.0, bottom: 10.0, right: 30, left: 30),
child: TextField(
keyboardType: TextInputType.text,
decoration: InputDecoration(
prefixIcon: Icon(Icons.search),
),
controller: searchController,
),
),
),
Expanded(
child: Container(
height: MediaQuery.of(context).size.height * 0.50,
child: StreamBuilder<QuerySnapshot>(
stream: tarifRef.snapshots(),
builder: (BuildContext context, AsyncSnapshot asyncsnapshot) {
if (asyncsnapshot.hasError) {
return Center(
child: Text("Error"),
);
} else {
if (asyncsnapshot.hasData) {
List<DocumentSnapshot> listOfDocumentSnapshot =
asyncsnapshot.data.docs;
return Flexible(
child: ListView.builder(
itemCount: listOfDocumentSnapshot.length,
itemBuilder: (context, index) {
return Card(
color: Colors.indigo,
child: ListTile(
title: Text(
"${listOfDocumentSnapshot[index]["name"]}",
style: TextStyle(
fontSize: 20,
color: Colors.white,
),
),
subtitle: Text(
"${listOfDocumentSnapshot[index]["models"]}",
style: TextStyle(
fontSize: 15,
color: Colors.white,
),
),
trailing: IconButton(
icon: Icon(
Icons.delete,
color: Colors.white,
),
onPressed: () async {
await listOfDocumentSnapshot[index]
.reference
.delete();
},
),
),
);
},
),
);
} else {
return Center(
child: CircularProgressIndicator(),
);
}
}
},
),
),
),
],
),
),
);
}
}
This my all code and also I have database in Firebase like this;
vehicles: [
{
"name": "Vehicle1",
"models": ["bus", "plane", "motorcycle"]
},
{
"name": "Vehicle2",
"models": ["motorcycle", "sporcar", "plane"]
},
{
"name": "Vehicle3",
"models": ["motorcycle", "plane", "bus"]
}
]
In this example I can take one input from user, I can query and display which list includes this data but I want to query more than one data is in lists or not.
For example in this code if user input bus, program display Vehicle1 list but I want user can input more than one data such as plane and motorcycle. And so when the user input the plane and motorcycle, I want it to be displayed the list of Vehicle 2 and Vehicle 3.
I try a lot of different ways but I can't found proparly solution to this problem.
I think you're looking for arrayContainsAny here:
var tarifRef = _firestore
.collection("vehicles")
.where("models", arrayContainsAny: ["bus", "plane"]);
This query will return documents whose models array contains either "bus", "plane" or both.
Also see the FlutterFire documentation for Query.where.
I have a class ViewTotalItemProvider which extends the ChangeNotifier. Inside the class, there is a list like this.
class ViewTotalItemProvider extends ChangeNotifier{
List<CartPlantLists> cartPlantList3 = [];
}
Additionally, there are 3 screens including class like, PlantFeatureScreen1, ParticularPlant2, CartDetais3. All are stateful widget and I am adding some items in second screen i.e. ParticularPlant2 class.
When I try to show the items from list in the second screen and the third screen it works.
But the value is not updated in the firstScreen i.e. PlantFeatureScreen1. However, when I reload the app, it shows the updated value.
why is this happening? How can I solve it?
Code
ViewTotalItemProvider
List<CartPlantLists> cartPlantList3 = [];
class ViewTotalItemProvider extends ChangeNotifier{
addQuantity(index){
cartPlantList3[index].qu++;
notifyListeners();
}
subtrachQuantity(index){
cartPlantList3[index].qu--;
notifyListeners();
}
}
firstScreen PlantFeatureScreen1 (Here I want to update the value in the very last widget)
class PlantFeatureScreen1 extends StatefulWidget {
#override
_PlantFeatureScreen1State createState() => _PlantFeatureScreen1State();
}
class _PlantFeatureScreen1State extends State<PlantFeatureScreen1> {
#override
Widget build(BuildContext context) {
return ChangeNotifierProvider<ViewTotalItemProvider>(
create: (context) => ViewTotalItemProvider(),
child:Builder(builder: (context) {
return Column(
children: <Widget>[
TopAppBar(),
Expanded(
flex: 1,
child: Align(
alignment: Alignment(-1, 0),
child: Container(
decoration: BoxDecoration(
color: Colors.white,
),
child: Text(
"Plants",
style: TextStyle(fontSize: 30, fontWeight: FontWeight.w700),
),
),
),
),
Expanded(
flex: 5,
child: Container(
width: double.infinity,
decoration: BoxDecoration(
color: Colors.blue,
),
child: DefaultTabController(
length: 5,
child: Column(
children: [
Container(
height: 50,
width: double.infinity,
child: TabBar(
isScrollable: true,
tabs: ourAllLists.tabMaker(),
),
),
Container(
height: 317,
width: double.infinity,
decoration: BoxDecoration(color: Colors.white),
child: TabBarView(
children: ourAllLists.tabViewerMaker(context),),),
],
),
),
),
),
Padding(
padding: const EdgeInsets.fromLTRB(20, 0, 20, 20),
child: Container(
alignment: Alignment.bottomRight,
height: 120,
width: double.infinity,
child: Stack(
overflow: Overflow.visible,
children: [
Container(
height: 70,
width: 105,
decoration: BoxDecoration(
color: Color(0xFF96CA2D),
borderRadius: BorderRadiusDirectional.horizontal(
end: Radius.circular(32),
start: Radius.circular(32))),
child: Icon(FontAwesomeIcons.shoppingBag,color:Colors.white,size:30),
),
Positioned(
// top: 0,
bottom: 50,
right: 0,
child: Consumer<ViewTotalItemProvider>(
builder: (context, value, child){
return Container(
height: 35,
width: 35,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(50),
border: Border.all(color: Color(0xFF96CA2D),width: 4)
),
child: Center(child: Text(ourAllLists.totalquantity().toString(),style:TextStyle(fontSize: 20,color: Color(0xFF96CA2D)))),
);
}),
),
],
),
),
)
],
);
})
);
}
}
secondScreen ParticularPlant2
class ParticularPlant2 extends StatefulWidget {
final indexNumber;
ParticularPlant2({#required this.indexNumber});
#override
_ParticularPlant2State createState() => _ParticularPlant2State();
}
class _ParticularPlant2State extends State<ParticularPlant2> {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: SafeArea(
child: Scaffold(
body: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
TopAppBar(),
Container(
decoration: BoxDecoration(
color: Colors.red,
borderRadius: BorderRadiusDirectional.only(
bottomStart: Radius.circular(50),
),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
ourAllLists
.mainListAllPlantDetailsList1[widget.indexNumber].pN,
style: kPlantNameStyle,
),
Text(
ourAllLists
.mainListAllPlantDetailsList1[widget.indexNumber].ca
.toUpperCase(),
style: TextStyle(
fontSize: 15,
),
),
Text(
"\$" +
ourAllLists
.mainListAllPlantDetailsList1[widget.indexNumber]
.pr
.toString(),
style: kItemPrice,
),
SizedBox(height: 100),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Container(
height: 80,
width: 80,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(50)),
child: Icon(
FontAwesomeIcons.flag,
color: Color(0xFF9DCD3C),
),
),
SizedBox(
height: 50,
),
FlatButton(
onPressed: () {
final tile = cartPlantList3.firstWhere(
(item) =>
item.pN ==
ourAllLists
.mainListAllPlantDetailsList1[
widget.indexNumber]
.pN,
orElse: () => null);
if (tile != null) {
} else {
cartPlantList3.add(
CartPlantLists(
quantity: 1,
plantName: ourAllLists
.mainListAllPlantDetailsList1[
widget.indexNumber]
.pN,
category: ourAllLists
.mainListAllPlantDetailsList1[
widget.indexNumber]
.ca,
price: ourAllLists
.mainListAllPlantDetailsList1[
widget.indexNumber]
.pr,
),
);
}
print(cartPlantList3.length);
},
child: Container(
height: 80,
width: 80,
decoration: BoxDecoration(
color: Color(0xFF9DCD3C),
borderRadius: BorderRadius.circular(50)),
child: Icon(FontAwesomeIcons.shoppingBag,
color: Colors.white),
),
)
],
),
Container(
height: 250,
child: Image(image: AssetImage("assets/tulip.png")),
)
],
)
],
),
)
],
),
),
),
);
}
}
It seems like you are using Provider the wrong way. The best way to do this in your scenario is to wrap MaterialApp inside MyApp() in your main.dart file with MultiProvider. Try something like this: https://pub.dev/packages/provider#multiprovider You can place a ChangeNotifierProvider inside it.
return MultiProvider(
providers: [
ChangeNotifierProvider<ViewTotalItemProvider>(
create: (context) => ViewTotalItemProvider()),
],
child: MaterialApp(...)
);
Also, you have to place a getter and setter in your Model. Here is an example:
class ImageModel extends ChangeNotifier {
String _base64Image;
get base64Image => _base64Image;
set base64Image(String base64Image) {
_base64Image = base64Image;
notifyListeners();
}
}
I would also recommend using Selector instead of Consumer (Ideally, you should use Selector instead of Consumer so that the widget only rebuilds if the value its listening to changes) Here is an example based on the model above:
#override
Widget build(BuildContext context) {
//other widgets
Selector<ImageModel, String>(
selector: (_, model) => model.base64Image,
builder: (_, image, __) {
return Text(image);
},
);
}
)
}
Here is how you can get and set it using a RaisedButton:
class _PlantFeatureScreen1State extends State<PlantFeatureScreen1> {
final itemModel;
List<CartPlantLists> myList=[];
#override
Widget build(BuildContext context) {
itemModel = Provider.of<ViewTotalItemProvider>(context,listen:false);
print(itemModel.yourVariable); //getting the value
return Container(
child: RaisedButton(
child:Text("Set Item");
onPressed:(){
itemModel.yourVariable=myList; //setting the value
},
),
);
}
}
Hope this helps! Good Luck!
Step 1:
add the dependency for the provider pattern in the pubspec.yaml file
dependencies:
flutter:
sdk: flutter
provider: ^4.1.2
Step 2:
create provider in seperate file :
class ViewTotalItemProvider with ChangeNotifier{
List<CartPlantLists> _cartPlantList1 = [];
get cartPlantList1 => _cartPlantList1 ;
set cartPlantList1 (List<CartPlantLists> selected){
_cartPlantList1 = selected;
notifyListeners();
}
}
step 3:
Use MultiProvider to wrap the MaterialApp widget in main.dart.
void main() => runApp(
MultiProvider (providers: [
ChangeNotifierProvider<ViewTotalItemProvider>.value(value:
ViewTotalItemProvider()),
],
child: MyApp()
)
);
class MyApp extends StatelessWidget {
Widget build(BuildContext context) {
return MaterialApp(
home: HomePage(),
);
}
}
Step 4:
use provider in your screen PlantFeatureScreen1 :
class PlantFeatureScreen1 extends StatefulWidget {
#override
_PlantFeatureScreen1State createState() => _PlantFeatureScreen1State();
}
class _PlantFeatureScreen1State extends State<PlantFeatureScreen1> {
var viewTotalItemProvider;
#override
Widget build(BuildContext context) {
viewTotalItemProvider = Provider.of<ViewTotalItemProvider>(context);
return Scaffold(
.......
);
}
}
step 5:
get cartPlantList1.
List<CartPlantLists> list = viewTotalItemProvider.cartPlantList1;
step 6 : set cartPlantList1.
List<CartPlantLists> list = [];
...
viewTotalItemProvider.cartPlantList1 = list;
similarly u can use for other two classes.
I have multiple images each with their own redirect link. Currently this works fine at displaying using a list view build to display the images inside a gesture detector.
However, I’d like to add a dot indicator to show which image is being viewed. How can I get the index of the image being displayed? Or increase / decrease a counter when swiping left or right.
I’ve looked into carousels but they don’t seem to allow each image to redirect to somewhere else.
As per example pointed to by #chunhunghan above in the comments, you need to replace map<Widget> ( (image, url) {..}
with
imgList.map((image) {int index = imgList.indexOf(image); ..}
I was able to get it to work with the above change. Revised code snippet for the build method:
#override
Widget build(BuildContext context) {
return Column(children: [
CarouselSlider(
items: child,
autoPlay: false,
enlargeCenterPage: true,
aspectRatio: 2.0,
onPageChanged: (index) {
setState(() {
_current = index;
print("${_current}");
});
},
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: imgList.map((image) { //these two lines
int index=imgList.indexOf(image); //are changed
return Container(
width: 8.0,
height: 8.0,
margin: EdgeInsets.symmetric(vertical: 10.0, horizontal: 2.0),
decoration: BoxDecoration(
shape: BoxShape.circle,
color: _current == index
? Color.fromRGBO(0, 0, 0, 0.9)
: Color.fromRGBO(0, 0, 0, 0.4)),
);
},
),
),
]);
}
If I understand you clear. with package https://pub.dev/packages/carousel_slider
swipe image to left or right can get current page from onPageChanged event
and use InkWell wrap image, you can navigate to other page. In my demo just print click message
code snippet
final List child = map<Widget>(
imgList,
(index, i) {
return Container(
margin: EdgeInsets.all(5.0),
child: ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(5.0)),
child: Stack(children: <Widget>[
InkWell(
onTap: () { print("you click ${index} "); },
child: Image.network(i, fit: BoxFit.cover, width: 1000.0)),
Positioned(
bottom: 0.0,
left: 0.0,
right: 0.0,
child: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [Color.fromARGB(200, 0, 0, 0), Color.fromARGB(0, 0, 0, 0)],
begin: Alignment.bottomCenter,
end: Alignment.topCenter,
),
),
padding: EdgeInsets.symmetric(vertical: 10.0, horizontal: 20.0),
child: Text(
'No. $index image',
style: TextStyle(
color: Colors.white,
fontSize: 20.0,
fontWeight: FontWeight.bold,
),
),
),
),
]),
),
);
},
).toList();
...
class _CarouselWithIndicatorState extends State<CarouselWithIndicator> {
int _current = 0;
#override
Widget build(BuildContext context) {
return Column(children: [
CarouselSlider(
items: child,
autoPlay: false,
enlargeCenterPage: true,
aspectRatio: 2.0,
onPageChanged: (index) {
setState(() {
_current = index;
print("${_current}");
});
},
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: map<Widget>(
imgList,
(index, url) {
return Container(
width: 8.0,
height: 8.0,
margin: EdgeInsets.symmetric(vertical: 10.0, horizontal: 2.0),
decoration: BoxDecoration(
shape: BoxShape.circle,
color: _current == index
? Color.fromRGBO(0, 0, 0, 0.9)
: Color.fromRGBO(0, 0, 0, 0.4)),
);
},
),
),
]);
}
}
The solution I found, besides change map to use imgList, was to put .toList() at the imgList.map function return as follows:
#override
Widget build(BuildContext context) {
return Column(children: [
CarouselSlider(
items: child,
autoPlay: false,
enlargeCenterPage: true,
aspectRatio: 2.0,
onPageChanged: (index) {
setState(() {
_current = index;
print("${_current}");
});
},
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: imgList.map((image) {
int index=imgList.indexOf(image);
return Container(
width: 8.0,
height: 8.0,
margin: EdgeInsets.symmetric(vertical: 10.0, horizontal: 2.0),
decoration: BoxDecoration(
shape: BoxShape.circle,
color: _current == index
? Color.fromRGBO(0, 0, 0, 0.9)
: Color.fromRGBO(0, 0, 0, 0.4)
),
);
},
).toList(), // this was the part the I had to add
),
]);
}
Vertical Indicators On Slider or Flutter Carousel
class VerticalSlider extends StatefulWidget {
#override
_VerticalSliderState createState() => _VerticalSliderState();
}
class _VerticalSliderState extends State<VerticalSlider> {
List imageSliders=[
//add your items here
];
int _current = 0;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Vertical sliding carousel ')),
body: Stack(
children: [
Container(
child: CarouselSlider(
options: CarouselOptions(
viewportFraction: .6,
aspectRatio: 1.2,
enlargeCenterPage: true,
scrollDirection: Axis.vertical,
autoPlay: true,
onPageChanged: (index, reason) {
setState(() {
_current = index;
});
}
),
items: imageSliders,
)
),
Positioned(
top: 50,
right: 10,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: imgList.map((url) {
int index = imgList.indexOf(url);
return Container(
width: 8.0,
height: 8.0,
margin: EdgeInsets.symmetric(vertical: 4.0, horizontal: 2.0),
decoration: BoxDecoration(
shape: BoxShape.circle,
color: _current == index
? Colors.white60
: Color.fromRGBO(0, 0, 0, 0.4),
),
);
}).toList(),
),
),
],
),
);
}
}
And you may add custom indicators too.
The easiest way is to use CarouselSlider with the AnimatedSmoothIndicator widget
int _current = 0;
#override
Widget build(BuildContext context) {
Column(children: [
CarouselSlider(
options: CarouselOptions(
height: MediaQuery.of(context).size.height / 2,
onPageChanged: (i, r) {
setState(() {
_current = i;
});
}),
items: imageList.map((e) => Container(
child: Image.network(e, fit: BoxFit.cover),
))
.toList(),
),
Container(
margin: EdgeInsets.symmetric(vertical: 10.0, horizontal: 2.0),
child: AnimatedSmoothIndicator(
activeIndex: _current,
count: imageList.length,
effect: ExpandingDotsEffect(
activeDotColor: Color.fromRGBO(0, 0, 0, 0.9),
dotWidth: 8,
dotHeight: 8),
),
)
]);
add auto slider code for flutter like this....
output screen shorts is here
class _ProductDetailsState extends State<ProductDetails> {
List imageSliders = [
'assets/images/man_1.png',
'assets/images/man_2.png',
'assets/images/man_3.png',
'assets/images/woman_1.png',
'assets/images/woman_2.png',
'assets/images/woman_3.png',
'assets/images/woman_4.png',
'assets/images/woman_5.png',
'assets/images/woman_6.png',
'assets/images/woman_7.png',
];
#override
Widget build(BuildContext context) {
SystemChrome.setSystemUIOverlayStyle(const SystemUiOverlayStyle(
systemNavigationBarColor: Color(0xFF000000),
systemNavigationBarIconBrightness: Brightness.dark,
systemNavigationBarDividerColor: null,
statusBarColor: Color(0xFFFFFFFF),
statusBarIconBrightness: Brightness.dark,
statusBarBrightness: Brightness.dark,
));
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
elevation: 0,
automaticallyImplyLeading: false,
backgroundColor: Colors.white,
leading: Padding(
padding: const EdgeInsets.only(
left: 20,
top: 10,
),
child: IconButton(
icon: Icon(
Icons.keyboard_backspace_sharp,
size: 35,
color: Colors.grey[600],
),
onPressed: () => Navigator.of(context).pop(),
),
),
actions: [
Padding(
padding: const EdgeInsets.only(
left: 0,
top: 10,
),
child: IconButton(
icon: const Icon(
Icons.search_outlined,
color: Colors.black,
size: 30,
),
onPressed: () {},
),
),
Padding(
padding: const EdgeInsets.only(
left: 0,
top: 10,
right: 20,
),
child: IconButton(
icon: Stack(
children: [
if (_newNotification)
Positioned(
right: 1,
top: 1,
child: Container(
decoration: BoxDecoration(
shape: BoxShape.circle, color: Colors.red),
width: 20.0 / 2.5,
height: 20.0 / 2.5,
),
),
Icon(
Icons.notifications_none_outlined,
color: Colors.black,
size: 30,
)
],
),
onPressed: () {},
),
),
],
),
body: Column(
children: [
Container(
child: CarouselSlider(
options: CarouselOptions(
height: 200,
viewportFraction: .6,
aspectRatio: 1.2,
enlargeCenterPage: true,
scrollDirection: Axis.horizontal,
autoPlay: true,
onPageChanged: (index, reason) {
setState(() {
activeIndex = index;
});
}
),
items: [
for(var item in imageSliders ) Image.asset(item)
],
)
),
Positioned(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: imageSliders.map((url) {
int index = imageSliders.indexOf(url);
return Container(
width: 8.0,
height: 8.0,
margin: EdgeInsets.symmetric(vertical: 4.0, horizontal: 2.0),
decoration: BoxDecoration(
shape: BoxShape.circle,
color: activeIndex == index
? Colors.blue
: Color.fromRGBO(0, 0, 0, 0.4),
),
);
}).toList(),
),
),
],
),
);
}
}
I am using the below SliverToBoxAdapter inside the CustomSrollView:
SliverToBoxAdapter(
child: Stack(
children: <Widget>[
Container(
width: double.infinity,
height: 50,
decoration: BoxDecoration(color: pink),
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 30),
child: ListView.builder(
padding: const EdgeInsets.all(0),
shrinkWrap: true,
itemBuilder: (context, index) {
return buildSongRow(songs[index]);
},
itemCount: songs.length,
),
)
],
))
The issues is that the list doesn't scroll, which is obvious as it has box constraints. I am using SliverToBoxAdapter here as I have to stack my list over some Container at the top of the list. How can I make my list scroll?
If it cannot be done using SliverToBoxAdapter, do I have any other options?
You can make Listview scrollable by adding the same scrollController of the parent CustomScrollView.
class ScrollExample extends StatelessWidget {
final scrollController = ScrollController();
#override
Widget build(BuildContext context) {
return CustomScrollView(
// add scrollController to sliver root
controller: scrollController,
slivers: <Widget>[
SliverToBoxAdapter(
child: Card(
child: ListView.builder(
// add the same scrollController here
controller: scrollController,
shrinkWrap: true,
itemCount: 19,
itemBuilder: (BuildContext context, int index) {
return Text("ibnShamas");
},
),
),
),
],
);
}
}