Declare variable
TextEditingController _searchController = TextEditingController();
String _selectedFilter = 'Select Filter By';
Add input field
Padding(
padding: const EdgeInsets.all(8.0),
child: TextField(
controller: _searchController,
decoration: InputDecoration(
labelText: 'Search by name, country, state, city or social site',
border: OutlineInputBorder(),
),
onChanged: (value) {
setState(() {});
},
),
),
Apply search functionality logic
Widget build(BuildContext context) {
final influencerViewModel = Provider.of<InfluencerViewModel>(context);
print("Available influencerViewModel: ${influencerViewModel.influencers.map((c) => c.socialPrice).toList()}");
List<SearchInfluencer> filteredInfluencers = influencerViewModel.influencers.where((influencer) {
bool matchesSearch = influencer.userName != null &&
influencer.userName!.toLowerCase().contains(_searchController.text.toLowerCase());
bool matchesCountry = influencer.countryName != null &&
influencer.countryName!.toLowerCase().contains(_searchController.text.toLowerCase());
bool matchesState = influencer.stateName != null &&
influencer.stateName!.toLowerCase().contains(_searchController.text.toLowerCase());
bool matchesCity = influencer.cityName != null &&
influencer.cityName!.toLowerCase().contains(_searchController.text.toLowerCase());
Map<String, dynamic>? socialPrices;
try {
socialPrices = jsonDecode(influencer.socialPrice ?? '{}');
} catch (e) {
print('Error decoding socialPrice: $e');
}
bool matchesSocialSite = socialPrices != null &&
socialPrices.keys.any((key) => key.toLowerCase().contains(_searchController.text.toLowerCase()));
return matchesSearch || matchesCountry || matchesState || matchesCity || matchesSocialSite;
}).toList();
After search functionality renders data
Expanded(
child: influencerViewModel.isLoading
? const Center(child: CircularProgressIndicator())
: filteredInfluencers.isEmpty
? const Center(child: Text('No influencers found'))
: ListView.builder(
itemCount: filteredInfluencers.length,
itemBuilder: (context, index) {
final influencer = filteredInfluencers[index];
Map<String, dynamic>? socialPrices;
try {
socialPrices = jsonDecode(influencer.socialPrice ?? '{}');
} catch (e) {
print('Error decoding socialPrice: $e');
}
return Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 16.0),
child: Card(
elevation: 4,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8.0),
),
child: Column(
children: [
ListTile(
contentPadding: EdgeInsets.all(4.0),
leading: CircleAvatar(
backgroundImage: AssetImage('assets/avatar.png'), // Replace with the path to your avatar image
radius: 20,
),
title: Text(
influencer.userName ?? "No Name",
style: TextStyle(fontWeight: FontWeight.bold),
),
subtitle: Text(
'${influencer.countryName ?? "No Country"} / ${influencer.stateName ?? "No State"} / ${influencer.cityName ?? "No City"}',
style: TextStyle(color: Colors.black54),
),
),
socialPrices != null
? Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
child: Wrap(
spacing: 10.0,
runSpacing: 5.0,
children: socialPrices.entries.map((entry) {
return SizedBox(
width: (MediaQuery.of(context).size.width - 100) / 3,
child: Chip(
label: Text('${entry.key}: ${entry.value}'),
),
);
}).toList(),
),
)
: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
child: Text('No social data'),
),
],
),
),
);
},
),
),
Full code
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter_application_1/Screen/layout/mixins.dart';
import 'package:provider/provider.dart';
import 'package:flutter_application_1/Screen/Influencer/locationfilter.dart';
import 'package:flutter_application_1/Screen/Influencer/socialsitefilter.dart';
import 'package:flutter_application_1/model/search_influencer.dart';
import 'package:flutter_application_1/view_modal/influencer_view_model.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
class InfluencerScreen extends StatefulWidget {
const InfluencerScreen({super.key});
@override
State<InfluencerScreen> createState() => _InfluencerScreenState();
}
class _InfluencerScreenState extends State<InfluencerScreen> with NavigationMixin {
TextEditingController _searchController = TextEditingController();
String _selectedFilter = 'Select Filter By';
@override
void initState() {
super.initState();
Future.microtask(() async {
Provider.of<InfluencerViewModel>(context, listen: false).fetchInfluencers();
Map<String, String?> credentials = await _getCredentials();
String? email = credentials['email'];
String? password = credentials['password'];
if (email != null && password != null) {
print('Email: $email');
print('Password: $password');
} else {
print('No credentials found');
}
});
}
Future<Map<String, String?>> _getCredentials() async {
final secureStorage = FlutterSecureStorage();
String? email = await secureStorage.read(key: 'email');
String? password = await secureStorage.read(key: 'password');
return {'email': email, 'password': password};
}
@override
Widget build(BuildContext context) {
final influencerViewModel = Provider.of<InfluencerViewModel>(context);
print("Available influencerViewModel: ${influencerViewModel.influencers.map((c) => c.socialPrice).toList()}");
List<SearchInfluencer> filteredInfluencers = influencerViewModel.influencers.where((influencer) {
bool matchesSearch = influencer.userName != null &&
influencer.userName!.toLowerCase().contains(_searchController.text.toLowerCase());
bool matchesCountry = influencer.countryName != null &&
influencer.countryName!.toLowerCase().contains(_searchController.text.toLowerCase());
bool matchesState = influencer.stateName != null &&
influencer.stateName!.toLowerCase().contains(_searchController.text.toLowerCase());
bool matchesCity = influencer.cityName != null &&
influencer.cityName!.toLowerCase().contains(_searchController.text.toLowerCase());
Map<String, dynamic>? socialPrices;
try {
socialPrices = jsonDecode(influencer.socialPrice ?? '{}');
} catch (e) {
print('Error decoding socialPrice: $e');
}
bool matchesSocialSite = socialPrices != null &&
socialPrices.keys.any((key) => key.toLowerCase().contains(_searchController.text.toLowerCase()));
return matchesSearch || matchesCountry || matchesState || matchesCity || matchesSocialSite;
}).toList();
return buildBaseScreen(
currentIndex: 0, // Set the appropriate index for the bottom nav bar
title: 'Influencers',
body: Column(
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: TextField(
controller: _searchController,
decoration: InputDecoration(
labelText: 'Search by name, country, state, city or social site',
border: OutlineInputBorder(),
),
onChanged: (value) {
setState(() {});
},
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: DropdownButton<String>(
isExpanded: true,
value: _selectedFilter,
onChanged: (newValue) {
setState(() {
_selectedFilter = newValue!;
});
if (_selectedFilter == 'Location') {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => LocationFilterScreen()),
);
} else if (_selectedFilter == 'Social_site') {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => TagFilterScreen()),
);
}
},
items: ['Select Filter By', 'Location', 'Social_site'].map((filter) {
return DropdownMenuItem<String>(
value: filter,
child: Text(filter),
);
}).toList(),
),
),
Expanded(
child: influencerViewModel.isLoading
? const Center(child: CircularProgressIndicator())
: filteredInfluencers.isEmpty
? const Center(child: Text('No influencers found'))
: ListView.builder(
itemCount: filteredInfluencers.length,
itemBuilder: (context, index) {
final influencer = filteredInfluencers[index];
Map<String, dynamic>? socialPrices;
try {
socialPrices = jsonDecode(influencer.socialPrice ?? '{}');
} catch (e) {
print('Error decoding socialPrice: $e');
}
return Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 16.0),
child: Card(
elevation: 4,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8.0),
),
child: Column(
children: [
ListTile(
contentPadding: EdgeInsets.all(4.0),
leading: CircleAvatar(
backgroundImage: AssetImage('assets/avatar.png'), // Replace with the path to your avatar image
radius: 20,
),
title: Text(
influencer.userName ?? "No Name",
style: TextStyle(fontWeight: FontWeight.bold),
),
subtitle: Text(
'${influencer.countryName ?? "No Country"} / ${influencer.stateName ?? "No State"} / ${influencer.cityName ?? "No City"}',
style: TextStyle(color: Colors.black54),
),
),
socialPrices != null
? Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
child: Wrap(
spacing: 10.0,
runSpacing: 5.0,
children: socialPrices.entries.map((entry) {
return SizedBox(
width: (MediaQuery.of(context).size.width - 100) / 3,
child: Chip(
label: Text('${entry.key}: ${entry.value}'),
),
);
}).toList(),
),
)
: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
child: Text('No social data'),
),
],
),
),
);
},
),
),
],
),
);
}
@override
void dispose() {
_searchController.dispose();
super.dispose();
}
}
Another Way
Declare variable
TextEditingController _searchController = TextEditingController();
String _selectedFilter = 'Select Filter By';
Add input field
Padding(
padding: const EdgeInsets.all(8.0),
child: TextField(
controller: _searchController,
decoration: InputDecoration(
labelText: 'Search by name, country, state, city or social site',
border: OutlineInputBorder(),
),
onChanged: (value) {
setState(() {});
},
),
),
Apply search functionality logic
List<SearchInfluencer> filteredInfluencers = influencerViewModel.influencers.where((influencer) {
bool matchesSearch = (influencer.userName != null &&
influencer.userName!.toLowerCase().contains(_searchController.text.toLowerCase())) ||
(influencer.countryName != null &&
influencer.countryName!.toLowerCase().contains(_searchController.text.toLowerCase())) ||
(influencer.stateName != null &&
influencer.stateName!.toLowerCase().contains(_searchController.text.toLowerCase())) ||
(influencer.cityName != null &&
influencer.cityName!.toLowerCase().contains(_searchController.text.toLowerCase())) ||
(influencer.socialPrice != null &&
influencer.socialPrice!.toLowerCase().contains(_searchController.text.toLowerCase()));
return matchesSearch;
}).toList();
Renders data
Expanded(
child: influencerViewModel.isLoading
? const Center(child: CircularProgressIndicator())
: filteredInfluencers.isEmpty
? const Center(child: Text('No influencers found'))
: ListView.builder(
itemCount: filteredInfluencers.length,
itemBuilder: (context, index) {
final influencer = filteredInfluencers[index];
Map<String, dynamic>? socialPrices;
try {
socialPrices = jsonDecode(influencer.socialPrice ?? '{}');
} catch (e) {
print('Error decoding socialPrice: $e');
}
return Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 16.0),
child: Card(
elevation: 4,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8.0),
),
child: Column(
children: [
ListTile(
contentPadding: EdgeInsets.all(4.0),
leading: CircleAvatar(
backgroundImage: AssetImage('assets/avatar.png'), // Replace with the path to your avatar image
radius: 20,
),
title: Text(
influencer.userName ?? "No Name",
style: TextStyle(fontWeight: FontWeight.bold),
),
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 4.0, vertical: 2.0),
child: Text(
'${influencer.countryName ?? "No Country"} / ${influencer.stateName ?? "No State"} / ${influencer.cityName ?? "No City"}',
style: TextStyle(color: Colors.black54),
),
),
socialPrices != null
? Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
child: Wrap(
spacing: 10.0,
runSpacing: 5.0,
children: socialPrices.entries.map((entry) {
return SizedBox(
width: (MediaQuery.of(context).size.width - 100) / 3,
child: Chip(
label: Text('${entry.key}: ${entry.value}'),
),
);
}).toList(),
),
)
: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
child: Text('No social data'),
),
],
),
),
);
},
),
),
Top comments (0)