I am making an e-commerce application and I want to make a category ListView, but I want to filter the products depending on which ListView button is selected, I tried to do it in setState() but it didn't work.
This is my app with de ListView
And when selecting another category, I need the information below the ListView to change too
This is my home_page() :
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
int activeIndex = 0;
int selectedIndex = 0;
final urlImages = [
'assets/chair.png',
'assets/table.jpeg',
'assets/lamp.jpeg',
'assets/sillon.jpeg'
];
List category = ['Trending now', 'Sofa', 'Table', 'Chair'];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Home", style: TextStyle(color: Colors.black),),
elevation: 0,
centerTitle: true,
backgroundColor: Colors.transparent,
actions: [
IconButton(icon: const Icon(Icons.qr_code, color: Colors.black,), onPressed: () {
},
),
IconButton(icon: const Icon(Icons.settings, color: Colors.black,), onPressed: () {
Navigator.push(context,
MaterialPageRoute(
builder: (context) => const SettingsAppBar()
)
);
},)
],
leading: IconButton(icon: const Icon(Icons.menu, color: Colors.black,), onPressed: () {
Navigator.push(context,
MaterialPageRoute(
builder: (context) => const MenuAppBar()
)
);
},),
),
body: SafeArea(
child: Stack(
children: [
ListView(
scrollDirection: Axis.vertical,
shrinkWrap: true,
children: [
GestureDetector(
onTap: () {
Navigator.push(context,
MaterialPageRoute(
builder: (context) => Descounts()
)
);
},
child: CarouselSlider.builder(
options: CarouselOptions(height: 250,
enableInfiniteScroll: false,
autoPlay: true,
autoPlayInterval: const Duration(seconds: 3),
onPageChanged: (index, reason){
setState(() {
activeIndex = index;
});
}
),
itemCount: urlImages.length,
itemBuilder: (context, index, realIndex){
final urlImage = urlImages[index];
return buildCard(urlImage, index);
}
),
),
Container(
height: 30,
child: ListView.builder(
physics: const BouncingScrollPhysics(),
scrollDirection: Axis.horizontal,
itemCount: category.length,
itemBuilder: (context, index) => GestureDetector(
onTap: () {
setState(() {
selectedIndex = index;
if (category[selectedIndex] == "Trending now"){
TrendingNow();
}
});
},
child: Container(
alignment: Alignment.center,
margin: const EdgeInsets.only(left: 18),
padding: const EdgeInsets.symmetric(horizontal: 40),
decoration: BoxDecoration(
color: index == selectedIndex
? Colors.deepOrangeAccent
: Colors.grey.shade400,
borderRadius: BorderRadius.circular(40),
),
child: Text(
category[index], style: const TextStyle(color: Colors.white),
),
),
),
),
),
SizedBox(
height: 20,
),
TrendingNow()
],
),
],
),
)
);
}
Widget buildCard(String urlImage, int index) => Container(
width: 430,
padding: const EdgeInsets.symmetric(horizontal: 1),
height: 430,
child: Image.asset(urlImage),
);
}
This is my TrendingNow() class:
class TrendingNow extends StatefulWidget {
const TrendingNow({Key? key}) : super(key: key);
@override
State<TrendingNow> createState() => _TrendingNowState();
}
class _TrendingNowState extends State<TrendingNow> {
@override
Widget build(BuildContext context) {
return Column(
children: [
GridView.builder(
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
childAspectRatio: 0.77,
mainAxisSpacing: 10),
itemBuilder: (context, index) =>
ProductSection(
product: furProducts[index],
press: () {
Navigator.push(context,
MaterialPageRoute(
builder: (context) => DetailScreen(product: furProducts[index])
)
);
},
),
shrinkWrap: true,
itemCount: furProducts.length,
physics: const ScrollPhysics(),),
],
);
}
}
what I need is to show different information below the listview depending on which category is selected
Can someone help me?
CodePudding user response:
first you use the condition for only first (trending) one not for other:
onTap: () {
setState(() {
selectedIndex = index;
if (category[selectedIndex] == "Trending now"){
TrendingNow();
}
});
},
replace this code with:
onTap: (){
setState((){
selectedIndex = index;
Navigator.push(MaterialPageRoute(builder: (context) => TrendingNow(index: selectedIndex),),);
});
}
and in trendingNow page call data according to index