Reputation: 248
context :
I want to click on a particular services person/product and open a page where details can be shown more like a details page
Problem
I think that Gesture control should work but I'm not able to put it the right way in my code
How to change chip color on selection the data is getting filtered but i want to add 2 more things
My Code
class _HomeScreenState extends State<HomeScreen> {
int _selectedIndex = 0;
int _selectedCategoryIndex = -1;
String _selectedUserType = "Maid";
PageController pageController = PageController();
List array = ["Maid", "Driver", "Engineer", "Gardener", "Pilot","carpainter", "guard", "plumber"];
List data = [
{
"name": "Sachin Rajput",
"profilePic":
"https://lh3.googleusercontent.com/a-/AAuE7mCfQn-gP_FJZUUU4GC4aSU1km9t_e5PL6zsV-NwdA=k-s48",
"category": ["Maid", "Engineer"],
"rating": 5,
"bg": Colors.red
},
{
"name": "Sachin Tendulkar",
"profilePic":
"https://lh3.googleusercontent.com/a-/AAuE7mCfQn-gP_FJZUUU4GC4aSU1km9t_e5PL6zsV-NwdA=k-s48",
"category": ["Gardener", "Pilot", "Engineer"],
"rating": 5,
"bg": Colors.amberAccent
},
{
"name": "Sachin Test",
"profilePic":
"https://lh3.googleusercontent.com/a-/AAuE7mCfQn-gP_FJZUUU4GC4aSU1km9t_e5PL6zsV-NwdA=k-s48",
"category": ["carpainter", "guard", "plumber"],
"rating": 5,
"bg": Colors.blue
}
];
List product_data = [
{
"name": "P1",
"profilePic":
"https://lh3.googleusercontent.com/a-/AAuE7mCfQn-gP_FJZUUU4GC4aSU1km9t_e5PL6zsV-NwdA=k-s48",
"category": ["Dusting"],
"rating": 5,
"bg": Colors.red
},
{
"name": "P2",
"profilePic":
"https://lh3.googleusercontent.com/a-/AAuE7mCfQn-gP_FJZUUU4GC4aSU1km9t_e5PL6zsV-NwdA=k-s48",
"category": ["Mopping"],
"rating": 5,
"bg": Colors.amberAccent
},
{
"name": "P3",
"profilePic":
"https://lh3.googleusercontent.com/a-/AAuE7mCfQn-gP_FJZUUU4GC4aSU1km9t_e5PL6zsV-NwdA=k-s48",
"category": ["cleaning"],
"rating": 5,
"bg": Colors.blue
}
];
List filteredData = [];
void onTapped(int index) {
setState(() {
_selectedIndex = index;
});
pageController.jumpToPage(index);
}
void tappedCategory(int index) {
_selectedCategoryIndex = index;
_selectedUserType = array[index];
_filterData();
}
@override
void initState() {
super.initState();
_filterData();
}
_filterData() {
print(_selectedUserType);
filteredData = data.where((element) => element["category"].contains(_selectedUserType)).toList();
print(filteredData);
setState(() {});
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: PageView(
controller: pageController,
children: [
SafeArea(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: EdgeInsets.symmetric(vertical: 5),
child: Container(
// color: Colors.purple,
// margin: const EdgeInsets.only(top: 45, bottom: 15),
padding: const EdgeInsets.only(left: 10, right: 10),
child: Row(
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("Bengaluru",
style: TextStyle(
color: APP_COLOR.mainColor,
),
),
Text("R.T Nagar")
]),
),
customContainer(iconData: Icons.search,),
SizedBox(width: 10,),
customContainer(iconData: Icons.notifications,),
])),
),
Expanded(
child: SingleChildScrollView(
child: Column(
children: [
Padding(
padding: EdgeInsets.symmetric(vertical: 10,horizontal: 10),
child: Align(
alignment: Alignment.centerLeft,
child:
Text(
'Popular Services',
),
),
),
Container(
height: MediaQuery.of(context).size.height / 12,
child: ListView(
shrinkWrap: true,
scrollDirection: Axis.horizontal,
children: List<Widget>.generate(
array.length, // place the length of the array here
(int index) {
return Container(
margin: const EdgeInsets.all(2.0),
child: GestureDetector(
onTap: () {
tappedCategory(index);
},
child: Chip(label: Text(array[index])),
),
);
}).toList(),
),
),
Container(
height: MediaQuery.of(context).size.height / 6,
child: ListView.builder(
scrollDirection: Axis.horizontal,
// physics: NeverScrollableScrollPhysics(),
itemCount: filteredData.length,
itemBuilder: (context, index) {
var item = filteredData[index];
return Padding(
padding: EdgeInsets.symmetric(horizontal: 10),
child: Container(
color: item['bg'],
child: Center(
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 20),
child: Text(item["name"].toString()),
),
),
),
);
},
// This next line does the trick.
),
),
Padding(
padding: EdgeInsets.symmetric(vertical: 10,horizontal: 10),
child: Row(
mainAxisAlignment:MainAxisAlignment.spaceBetween,
children: [
Text(
'Popular Products',
),
Align(
alignment: Alignment.centerRight,
child:
Text(
'View All',
),
),
],
),
),
Container(
height: MediaQuery.of(context).size.height / 6,
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: product_data.length,
itemBuilder: (context, index) {
var item = product_data[index];
return Padding(
padding: EdgeInsets.symmetric(horizontal: 10),
child: Container(
color: item['bg'],
child: Center(
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 60),
child: Text(item["name"].toString()),
),
),
),
);
},
// This next line does the trick.
),
),
Padding(
padding: EdgeInsets.symmetric(vertical: 10,horizontal: 10),
child: Row(
mainAxisAlignment:MainAxisAlignment.spaceBetween,
children: [
Text(
'Our Products',
),
Align(
alignment: Alignment.centerRight,
child:
Text(
'View All',
),
),
],
),
),
Container(
height: MediaQuery.of(context).size.height / 6,
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: product_data.length,
itemBuilder: (context, index) {
var item = product_data[index];
return Padding(
padding: EdgeInsets.symmetric(horizontal: 10),
child: Container(
color: item['bg'],
child: Center(
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 60),
child: Text(item["name"].toString()),
),
),
),
);
},
// This next line does the trick.
),
),
Padding(
padding: EdgeInsets.symmetric(vertical: 10,horizontal: 10),
child: Row(
mainAxisAlignment:MainAxisAlignment.spaceBetween,
children: [
Text(
'New Products',
),
Align(
alignment: Alignment.centerRight,
child:
Text(
'View All',
),
),
],
),
),
Container(
height: MediaQuery.of(context).size.height / 6,
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: product_data.length,
itemBuilder: (context, index) {
var item = product_data[index];
return Padding(
padding: EdgeInsets.symmetric(horizontal: 10),
child: Container(
color: item['bg'],
child: Center(
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 60),
child: Text(item["name"].toString()),
),
),
),
);
},
),
),
],
),
),
)
]),
),
Container(color: Colors.blue,),
Container(color: Colors.white,),
Container(color: Colors.yellow,),
Container(color: Colors.blue,),
Container(color: Colors.white,),
Container(color: Colors.yellow,)
],
),
bottomNavigationBar: BottomNavigationBar(
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(icon: Icon(Icons.home), label: 'Home'),
BottomNavigationBarItem(
icon: Icon(Icons.cleaning_services), label: 'Services'),
BottomNavigationBarItem(
icon: Icon(Icons.local_convenience_store), label: 'Store'),
BottomNavigationBarItem(
icon: Icon(Icons.account_balance_wallet), label: 'Wallet'),
BottomNavigationBarItem(
icon: Icon(Icons.bookmarks), label: 'Bookmarked'),
BottomNavigationBarItem(
icon: Icon(Icons.assessment), label: 'Current Orders'),
BottomNavigationBarItem(icon: Icon(Icons.person), label: 'Profile'),
],
currentIndex: _selectedIndex,
selectedItemColor: APP_COLOR.mainColor,
unselectedItemColor: Colors.grey,
onTap: onTapped,
));
}
Widget customContainer({required IconData iconData}){
return Container(
width: 45,
height: 45,
padding: const EdgeInsets.only(left: 0, right: 0),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
color: APP_COLOR.mainColor,),
child: Icon(
iconData,
color: Colors.white,
),
);
}
}
I've recently started the flutter journey so i might have asked a very basic question so it will be great if you can explain the changes as well taht you made so i can understand it better
Upvotes: 1
Views: 248
Reputation: 1544
Hope this helps
class HomeScreen extends StatefulWidget {
const HomeScreen({Key? key}) : super(key: key);
@override
State<HomeScreen> createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
PageController pageController = PageController();
int _selectedIndex = 0;
void onTapped(int index) {
setState(() {
_selectedIndex = index;
});
pageController.jumpToPage(index);
}
@override
void dispose() {
pageController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: PageView(
controller: pageController,
children: [
const HomePage(),
Container(
color: Colors.blue,
),
Container(
color: Colors.white,
),
Container(
color: Colors.yellow,
),
Container(
color: Colors.blue,
),
Container(
color: Colors.white,
),
Container(
color: Colors.yellow,
)
],
),
bottomNavigationBar: BottomNavigationBar(
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(icon: Icon(Icons.home), label: 'Home'),
BottomNavigationBarItem(
icon: Icon(Icons.cleaning_services), label: 'Services'),
BottomNavigationBarItem(
icon: Icon(Icons.local_convenience_store), label: 'Store'),
BottomNavigationBarItem(
icon: Icon(Icons.account_balance_wallet), label: 'Wallet'),
BottomNavigationBarItem(
icon: Icon(Icons.bookmarks), label: 'Bookmarked'),
BottomNavigationBarItem(
icon: Icon(Icons.assessment), label: 'Current Orders'),
BottomNavigationBarItem(icon: Icon(Icons.person), label: 'Profile'),
],
currentIndex: _selectedIndex,
selectedItemColor: Colors.red,
unselectedItemColor: Colors.grey,
onTap: onTapped,
));
}
}
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
int _selectedCategoryIndex = 0;
String _selectedUserType = "Maid";
List array = [
"Maid",
"Driver",
"Engineer",
"Gardener",
"Pilot",
"carpainter",
"guard",
"plumber"
];
List data = [
{
"name": "Sachin Rajput",
"profilePic":
"https://lh3.googleusercontent.com/a-/AAuE7mCfQn-gP_FJZUUU4GC4aSU1km9t_e5PL6zsV-NwdA=k-s48",
"category": ["Maid", "Engineer"],
"rating": 5,
"bg": Colors.red
},
{
"name": "Sachin Tendulkar",
"profilePic":
"https://lh3.googleusercontent.com/a-/AAuE7mCfQn-gP_FJZUUU4GC4aSU1km9t_e5PL6zsV-NwdA=k-s48",
"category": ["Gardener", "Pilot", "Engineer"],
"rating": 5,
"bg": Colors.amberAccent
},
{
"name": "Sachin Test",
"profilePic":
"https://lh3.googleusercontent.com/a-/AAuE7mCfQn-gP_FJZUUU4GC4aSU1km9t_e5PL6zsV-NwdA=k-s48",
"category": ["carpainter", "guard", "plumber"],
"rating": 5,
"bg": Colors.blue
}
];
List product_data = [
{
"name": "P1",
"profilePic":
"https://lh3.googleusercontent.com/a-/AAuE7mCfQn-gP_FJZUUU4GC4aSU1km9t_e5PL6zsV-NwdA=k-s48",
"category": ["Dusting"],
"rating": 5,
"bg": Colors.red
},
{
"name": "P2",
"profilePic":
"https://lh3.googleusercontent.com/a-/AAuE7mCfQn-gP_FJZUUU4GC4aSU1km9t_e5PL6zsV-NwdA=k-s48",
"category": ["Mopping"],
"rating": 5,
"bg": Colors.amberAccent
},
{
"name": "P3",
"profilePic":
"https://lh3.googleusercontent.com/a-/AAuE7mCfQn-gP_FJZUUU4GC4aSU1km9t_e5PL6zsV-NwdA=k-s48",
"category": ["cleaning"],
"rating": 5,
"bg": Colors.blue
}
];
List filteredData = [];
void tappedCategory(int index) {
_selectedCategoryIndex = index;
_selectedUserType = array[index];
_filterData();
}
@override
void initState() {
super.initState();
_filterData();
}
@override
void dispose() {
super.dispose();
}
_filterData() {
filteredData = data
.where((element) => element["category"].contains(_selectedUserType))
.toList();
setState(() {});
}
Widget customContainer({required IconData iconData}) {
return Container(
width: 45,
height: 45,
padding: const EdgeInsets.only(left: 0, right: 0),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
color: Colors.red,
),
child: Icon(
iconData,
color: Colors.white,
),
);
}
Widget customProductsList({required String title, required List dataList}) {
return Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 10),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(title),
const Align(
alignment: Alignment.centerRight,
child: Text(
'View All',
),
),
],
),
),
SizedBox(
height: MediaQuery.of(context).size.height / 6,
child: dataList.isNotEmpty
? ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: dataList.length,
itemBuilder: (context, index) {
var item = dataList[index];
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 10),
child: Container(
color: item['bg'],
child: Center(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 60),
child: Text(item["name"].toString()),
),
),
),
);
},
// This next line does the trick.
)
: const Center(
child: Text('No data found.'),
),
),
],
);
}
@override
Widget build(BuildContext context) {
return SafeArea(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.symmetric(vertical: 5),
child: Container(
// color: Colors.purple,
// margin: const EdgeInsets.only(top: 45, bottom: 15),
padding: const EdgeInsets.only(left: 10, right: 10),
child: Row(children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
"Bengaluru",
style: TextStyle(
color: Colors.red,
),
),
const Text("R.T Nagar")
]),
),
customContainer(
iconData: Icons.search,
),
const SizedBox(
width: 10,
),
customContainer(
iconData: Icons.notifications,
),
])),
),
Expanded(
child: SingleChildScrollView(
child: Column(
children: [
const Padding(
padding: EdgeInsets.symmetric(
vertical: 10, horizontal: 10),
child: Align(
alignment: Alignment.centerLeft,
child: Text(
'Popular Services',
),
),
),
SizedBox(
height: MediaQuery.of(context).size.height / 12,
child: ListView(
shrinkWrap: true,
scrollDirection: Axis.horizontal,
children: List<Widget>.generate(
array
.length, // place the length of the array here
(int index) {
return Container(
margin: const EdgeInsets.all(2.0),
child: GestureDetector(
onTap: () {
tappedCategory(index);
},
child: Chip(
label: Text(array[index]),
backgroundColor:
_selectedCategoryIndex == index
? Colors.green
: Colors.grey,
),
),
);
}).toList(),
),
),
SizedBox(
height: MediaQuery.of(context).size.height / 6,
child: filteredData.isNotEmpty
? ListView.builder(
scrollDirection: Axis.horizontal,
// physics: NeverScrollableScrollPhysics(),
itemCount: filteredData.length,
itemBuilder: (context, index) {
var item = filteredData[index];
return Padding(
padding: const EdgeInsets.symmetric(
horizontal: 10),
child: GestureDetector(
onTap: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) =>
DetailPage(
user: item)));
},
child: Container(
color: item['bg'],
child: Center(
child: Padding(
padding: const EdgeInsets
.symmetric(
horizontal: 20),
child: Text(
item["name"].toString()),
),
),
),
),
);
},
// This next line does the trick.
)
: const Center(
child: Text(
"No records available for the selected category"),
),
),
customProductsList(
title: 'Popular Products',
dataList: product_data),
customProductsList(
title: 'Our Products', dataList: product_data),
customProductsList(
title: 'New Products', dataList: product_data)
],
),
),
)
]),
);
}
}
class DetailPage extends StatelessWidget {
const DetailPage({Key? key, this.user}) : super(key: key);
final dynamic user;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(user["name"]),
),
body: Container(
padding: EdgeInsets.all(8),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
// mainAxisAlignment: MainAxisAlignment.center,
children: [
CircleAvatar(child: Image.network(user["profilePic"]), minRadius: 60,),
SizedBox(height: 10,),
Text("${user["name"]}"),
],
),
)
);
}
}
Upvotes: 1
Reputation: 822
Chip(
label: "label",
backgroundColor: _selectedCategoryIndex == index ? Colors.blue : Colors.green,
),
do not forgot to change tappedCategory function replace your function with this,
void tappedCategory(int index) {
_selectedCategoryIndex = index;
_selectedUserType = array[index];
_filterData();
setState(() {});
}
Upvotes: 1
Reputation: 2433
You can use: <true/false expressions> ? <if true> : <if false>
highlight the chip that is selected
Add an backgroundColor
to Chip
. index == _selectedCategoryIndex
will check that chip is selected or not by index
then set the color you want. In this case, that ex mean If the chip is selected chip, colored it!
- child: Chip(label: Text(array[index])),
+ child: Chip(
+ label: Text(array[index]),
+ backgroundColor: index == _selectedCategoryIndex ? APP_COLOR.mainColor : null),
+ )
so a text message stating Not Available if there is nothing available, rather then leaving blank and
Check filteredData
have data then render what you want. In this case, ex mean If the filtered list is EMPTY, then render the Text insteads.
Detailer:
- Container(
- height: MediaQuery.of(context).size.height / 6,
- child: ListView.builder(...),
- ),
+ Container(
+ height: MediaQuery.of(context).size.height / 6,
+ child: filteredData.isNotEmpty
+ ? ListView.builder(...)
+ : Text('YOUR FILTERED LIST IS EMPTY'),
+ ),
Upvotes: 1