I have a list view with list tiles with each containing a region with its specific time.
I am using a Getx controller with the class WorldTime with two parameters location and time.
There is already a timer that's called during setState to update the clock widget, but how do I implement this to update each list tile time or is there any other way to update the time automatically without calling setState.
class _WorldClockState extends State<WorldClock> {
final WorldTimeController worldTimeController =
Get.put(WorldTimeController());
String formattedTime = DateFormat('h:mm').format(DateTime.now());
String hour = DateFormat('a').format(DateTime.now());
late Timer _timer;
#override
void initState() {
super.initState();
_timer =
Timer.periodic(const Duration(milliseconds: 500), (timer) => _update());
}
void _update() {
setState(() {
formattedTime = DateFormat('h:mm').format(DateTime.now());
hour = DateFormat('a').format(DateTime.now());
});
}
#override
void dispose() {
_timer.cancel();
super.dispose();
}
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
resizeToAvoidBottomInset: false,
body: SingleChildScrollView(
child: Column(
children: [
Padding(
padding: const EdgeInsets.only(top: 20.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(formattedTime,
style: GoogleFonts.lato(
fontSize: 80.0,
color: Colors.blue,
fontStyle: FontStyle.normal,
letterSpacing: 5.0)),
Padding(
padding: const EdgeInsets.only(top: 40.0, left: 5.0),
child: Text(
hour,
style: GoogleFonts.lato(
color: Colors.blue,
fontSize: 30.0,
),
),
),
],
),
),
Container(
child: Text(
DateFormat('EE, MMM d').format(DateTime.now()),
style: GoogleFonts.lato(
color: Colors.white,
fontSize: 20.0,
letterSpacing: 2.0,
),
),
),
const Padding(
padding: EdgeInsets.only(top: 20.0, left: 30.0, right: 30.0),
child: Divider(
color: Colors.white,
height: 2.0,
),
),
GetBuilder<WorldTimeController>(
id: 'Clockid',
builder: (value) => Container(
height: 600.0,
width: 450.0,
child: Padding(
padding: const EdgeInsets.only(top: 20.0),
child: ListView.builder(
scrollDirection: Axis.vertical,
physics: const BouncingScrollPhysics(),
shrinkWrap: true,
itemCount: worldTimeController.WorldTimeList.length,
itemBuilder: (BuildContext context, index) => Padding(
padding: const EdgeInsets.only(bottom: 18.0),
child: Slidable(
key: UniqueKey(),
startActionPane: ActionPane(
motion: ScrollMotion(),
dismissible: DismissiblePane(onDismissed: () {
worldTimeController.WorldTimeList.removeAt(index);
}),
children: const [],
),
child: ListTile(
leading: Text(
worldTimeController
.WorldTimeList[index].location,
style: GoogleFonts.lato(
color: Colors.white70, fontSize: 25)),
trailing: Text(
'${value.getTime(worldTimeController.WorldTimeList[index].location)}',
style: GoogleFonts.lato(
color: Colors.white70, fontSize: 35.0),
),
),
),
),
),
),
),
),
],
),
),
floatingActionButton: Padding(
padding: const EdgeInsets.only(right: 192.0, bottom: 20.0),
child: FloatingActionButton(
onPressed: () {
Get.to(() => const RegionSelectScreen());
},
child: const Icon(Icons.public),
),
),
),
);
}
}
controller:
class WorldTimeController extends GetxController {
var WorldTimeList = <WorldTime>[].obs;
var newUrl;
var newResponse;
Future<dynamic> getTime(location) async {
newUrl = "http://worldtimeapi.org/api/timezone/${location}";
newResponse = await get(Uri.parse(newUrl));
Map newData = jsonDecode(newResponse.body);
var time = newData['datetime'];
String dateTime = newData["utc_datetime"];
String offset = newData["utc_offset"];
DateTime now = DateTime.parse(dateTime);
now = now.add(Duration(
hours: int.parse(offset.substring(1, 3)),
minutes: int.parse(offset.substring(4))));
update(['Clockid']);
return time = DateFormat.jm().format(now);
}
#override
void onInit() {
List? storedWorldTime = GetStorage().read<List>('WorldTime');
if (storedWorldTime != null) {
WorldTimeList.assignAll(
storedWorldTime.map((e) => WorldTime.fromJson(e)).toList());
}
ever(WorldTimeList, (_) {
GetStorage().write('WorldTime', WorldTimeList.toList());
});
super.onInit();
}
}
In your getXcontroller class you can create function to update the hours and on this function you can add
update(['clockId']);
then in your screen
return GetBuilder<WorldTimeController>(
id: 'clockId',
init: WorldTimeController(), // If is init this line is not necessary
builder: (worldTimeController) => Container(
height: 600.0,
width: 450.0,
child: Padding(
padding: const EdgeInsets.only(top: 20.0),
child: ListView.builder(
scrollDirection: Axis.vertical,
physics: const BouncingScrollPhysics(),
shrinkWrap: true,
itemCount: worldTimeController.WorldTimeList.length,
itemBuilder: (BuildContext context, index) => Padding(
padding: const EdgeInsets.only(bottom: 18.0),
child: Slidable(
key: UniqueKey(),
startActionPane: ActionPane(
motion: ScrollMotion(),
dismissible: DismissiblePane(onDismissed: () {
worldTimeController.WorldTimeList.removeAt(
index);
}),
children: [],
),
child: ListTile(
leading: Text(
'${worldTimeController.WorldTimeList[index].location}',
style: GoogleFonts.lato(
color: Colors.white70, fontSize: 25)),
trailing: Text(
"${worldTimeController.WorldTimeList[index].time}",
style: GoogleFonts.lato(
color: Colors.white70, fontSize: 35.0),
),
),
),
)),
),
),
);
Then even that change something in your function this will refresh all the list inside your clockId.
Try to avoid setState because this method rebuild all the view and when your app grows does't has good performance
Here an example:
https://github.com/alcampospalacios/GetX_UpdateAll_Example
Related
I am trying to get the Text value of the selected container in a GridView. I am able to print the selected index. But I need to get the text value of the selected container so that I can save it in sharedPreferences and later get it and store it on the server.
Please assist. Your help will be gladly appreciated.
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
class QuickSurveyScreen extends StatefulWidget {
const QuickSurveyScreen({super.key});
#override
State<QuickSurveyScreen> createState() => _QuickSurveyScreenState();
}
class _QuickSurveyScreenState extends State<QuickSurveyScreen> {
int selectedIndex = -1;
List<String> gasUsage = [
"Heater",
"Stove",
"Geyser",
"Fireplace",
];
#override
Widget build(BuildContext context) {
return Scaffold(
body: NestedScrollView(
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
return [
SliverToBoxAdapter(
child: Padding(
padding: const EdgeInsets.only(top: 120.0, right: 30, left: 30),
child: Column(
children: const [
Text(
"What do you use \nLP Gas for?",
textAlign: TextAlign.center,
style: TextStyle(fontSize: 35, fontWeight: FontWeight.bold),
),
Padding(
padding: EdgeInsets.symmetric(
vertical: 16.0,
horizontal: 20,
),
child: Text(
"Please choose one or more options from below",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 18,
),
),
),
],
),
))
];
},
body: SafeArea(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: Column(
children: [
Expanded(
child: GridView.builder(
gridDelegate:
const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
childAspectRatio: 1.0,
crossAxisSpacing: 20.0,
mainAxisSpacing: 20.0,
),
physics: const NeverScrollableScrollPhysics(),
itemCount: gasUsage.length,
itemBuilder: (BuildContext context, int index) {
return gasUsageContainer("", gasUsage[index], index);
}),
),
ElevatedButton(
onPressed: () {},
style: ElevatedButton.styleFrom(
minimumSize: const Size(double.infinity, 65.0),
backgroundColor: const Color(0xFFF0A202),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(26.0),
),
textStyle: const TextStyle(
color: Colors.white,
fontSize: 18,
fontWeight: FontWeight.w600,
),
),
child: const Text('Continue'),
),
],
),
),
),
),
);
}
gasUsageContainer(String image, String name, int index) {
return GestureDetector(
onTap: () {
setState(() {
if (selectedIndex == index) {
selectedIndex = -1;
} else {
selectedIndex = index;
}
if (kDebugMode) {
print(selectedIndex);
}
});
},
child: AnimatedContainer(
duration: const Duration(milliseconds: 300),
padding: const EdgeInsets.all(10.0),
decoration: BoxDecoration(
color: selectedIndex == index
? Colors.amber.shade50
: Colors.grey.shade200,
border: Border.all(
color: selectedIndex == index
? Colors.amber
: Colors.blue.withOpacity(0),
width: 2.0,
),
borderRadius: BorderRadius.circular(22.0),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
name,
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: selectedIndex == index
? Colors.amber.shade800
: Colors.black,
),
)
]),
),
);
}
}
You can get it from List with index. Checkout the change I did for onTap in gasUsageContainer
onTap: () {
setState(() {
String? selected;
if (selectedIndex == index) {
selectedIndex = -1;
selected = null;
} else {
selectedIndex = index;
selected = gasUsage[index];//Here you get the value
}
if (kDebugMode) {
print('selectedIndex:$selectedIndex, selected: $selected');
}
});
}
Edited
class _QuickSurveyScreenState extends State<QuickSurveyScreen> {
final selectedItems = <String>[];
...
gasUsageContainer(String image, String name, int index) {
String item = gasUsage[index];
return GestureDetector(
onTap: () {
setState(() {
if (selectedItems.contains(item)) {
selectedItems.remove(item);
} else {
selectedItems.add(item);
}
if (kDebugMode) {
print('selectedItems: $selectedItems');
}
});
},
child: AnimatedContainer(
duration: const Duration(milliseconds: 300),
padding: const EdgeInsets.all(10.0),
decoration: BoxDecoration(
color: selectedItems.contains(item)
? Colors.amber.shade50
: Colors.grey.shade200,
border: Border.all(
color: selectedItems.contains(item)
? Colors.amber
: Colors.blue.withOpacity(0),
width: 2.0,
),
borderRadius: BorderRadius.circular(22.0),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
name,
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: selectedItems.contains(item)
? Colors.amber.shade800
: Colors.black,
),
)
]),
),
);
}
}
I have a screen with a container that shows the current time and under that a list view that contains list tiles with different regions and their corresponding time. I have a Future function that gets the time of a location. The problem is the text field that I have wrapped with future builder keeps blinking. It goes from null to time and back and forth. I want it to keep rebuilding to update the time, but how I do remove the blinking problem. and when I wrap newTime in setState it returns null. Any help will be really appreciated
class _WorldClockState extends State<WorldClock> {
final WorldTimeController worldTimeController =
Get.put(WorldTimeController());
String formattedTime = DateFormat('h:mm').format(DateTime.now());
String hour = DateFormat('a').format(DateTime.now());
late Timer _timer;
var location;
var time;
#override
void initState() {
super.initState();
_timer =
Timer.periodic(const Duration(milliseconds: 500), (timer) => _update());
}
void _update() {
setState(() {
formattedTime = DateFormat('h:mm').format(DateTime.now());
hour = DateFormat('a').format(DateTime.now());
});
}
var newUrl;
var newResponse;
getTime(location) async {
newUrl = "http://worldtimeapi.org/api/timezone/$location";
newResponse = await get(Uri.parse(newUrl));
Map newData = jsonDecode(newResponse.body);
var time = newData['datetime'];
String dateTime = newData["utc_datetime"];
String offset = newData["utc_offset"];
DateTime now = DateTime.parse(dateTime);
now = now.add(Duration(
hours: int.parse(offset.substring(1, 3)),
minutes: int.parse(offset.substring(4))));
String newtime = DateFormat.jm().format(now);
return newtime;
}
#override
void dispose() {
_timer.cancel();
super.dispose();
}
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
resizeToAvoidBottomInset: false,
body: SingleChildScrollView(
child: Column(
children: [
Padding(
padding: const EdgeInsets.only(top: 20.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(formattedTime,
style: GoogleFonts.lato(
fontSize: 80.0,
color: Colors.blue,
fontStyle: FontStyle.normal,
letterSpacing: 5.0)),
Padding(
padding: const EdgeInsets.only(top: 40.0, left: 5.0),
child: Text(
hour,
style: GoogleFonts.lato(
color: Colors.blue,
fontSize: 30.0,
),
),
),
],
),
),
Container(
child: Text(
DateFormat('EE, MMM d').format(DateTime.now()),
style: GoogleFonts.lato(
color: Colors.white,
fontSize: 20.0,
letterSpacing: 2.0,
),
),
),
const Padding(
padding: EdgeInsets.only(top: 20.0, left: 30.0, right: 30.0),
child: Divider(
color: Colors.white,
height: 2.0,
),
),
Container(
height: 600.0,
width: 450.0,
child: Padding(
padding: const EdgeInsets.only(top: 20.0),
child: ListView.builder(
scrollDirection: Axis.vertical,
physics: const BouncingScrollPhysics(),
shrinkWrap: true,
itemCount: worldTimeController.WorldTimeList.length,
itemBuilder: (BuildContext context, index) => Padding(
padding: const EdgeInsets.only(bottom: 18.0),
child: Slidable(
key: UniqueKey(),
startActionPane: ActionPane(
motion: ScrollMotion(),
dismissible: DismissiblePane(onDismissed: () {
worldTimeController.WorldTimeList.removeAt(index);
}),
children: const [],
),
child: ListTile(
leading: Text(
worldTimeController.WorldTimeList[index].location,
style: GoogleFonts.lato(
color: Colors.white70, fontSize: 25)),
trailing: FutureBuilder(
future: getTime(worldTimeController
.WorldTimeList[index].location),
builder: (context, AsyncSnapshot snapshot) {
return Text(
'${snapshot.data}',
style: GoogleFonts.lato(
color: Colors.white70, fontSize: 35.0),
);
}),
),
),
),
),
),
)
],
),
),
Replace your Future Func
FutureBuilder(
future: getTime(worldTimeController.WorldTimeList[index].location),
initialData:"",
builder: (context, AsyncSnapshot snapshot) {
return Text(
'${snapshot?.data??""}',
style: GoogleFonts.lato(
color: Colors.white70, fontSize: 35.0),
);
}),
I fixed the error by just removing the slidable widget that was wrapping the future builder, don't know why that was causing an error
I am a beginner in flutter.
I have created two ListView Builder where one ListView.builder is inside another builder as given below.
I have a list of categories which is inside one listview.builder and other are the list of products which also listview.builder Wrapped inside the above listview build>
So now i need to display the only items belonging to the 1st listview builder which means If I have a categories named soup (1st ListView.builder) Now i need to display only the products that belongs to soup categories from 2nd Listview.Builder but all the products are listed inside all the categories list. So, Please help me to find solution any help would be appriciated.Thank you in advance.
Below are the codes.
//lib/routes/menu_description.dart(File name)
import 'package:flutter/material.dart';
import '../api_service.dart';
import 'package:html/parser.dart';
import 'package:percent_indicator/percent_indicator.dart';
class MenuDescription extends StatefulWidget {
MenuDescription({Key key}) : super(key: key);
#override
_MenuDescriptionState createState() => _MenuDescriptionState();
}
int itemspressed;
class _MenuDescriptionState extends State<MenuDescription> {
#override
Widget build(BuildContext context) {
return Container(
// color: Colors.grey[200],
child: FutureBuilder(
future: fetchWpPosts(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return ListView.separated(
separatorBuilder: (context, index) => Divider(
height: 20.0,
color: Colors.black,
),
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemCount: snapshot.data.length,
itemBuilder: (BuildContext context, int index) {
Map wpcategoriespost = snapshot.data[index];
return Container(
color: Colors.grey[200],
child: InkWell(
splashColor: Colors.grey[800],
onTap: () {
setState(() {
itemspressed = index;
});
},
child: Padding(
padding: const EdgeInsets.only(
left: 5, right: 5, bottom: 5, top: 15),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Center(
child: Text(
"${wpcategoriespost['name']}",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 16.0,
fontWeight: FontWeight.bold,
color: Colors.lightGreen[900],
),
),
),
Center(
child: Text(
parse(("${wpcategoriespost['description']}")
.toString())
.documentElement
.text,
style:
TextStyle(fontSize: 14, color: Colors.black),
),
),
Container(
padding: EdgeInsets.only(top: 20.0),
child: Categories(),)
],
),
),
),
);
},
);
}
return new CircularPercentIndicator(
radius: 120.0,
lineWidth: 13.0,
animation: true,
percent: 1.0,
progressColor: Colors.orange,
center: new Text(
"100.0%",
style:
new TextStyle(fontWeight: FontWeight.bold, fontSize: 20.0),
));
},
),
);
}
}
class Categories extends StatefulWidget {
#override
_CategoriesState createState() => _CategoriesState();
}
class _CategoriesState extends State<Categories> {
#override
Widget build(BuildContext context) {
return Container(
child: FutureBuilder(
future: fetchWpPosts(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return ListView.builder(
physics: NeverScrollableScrollPhysics(),
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemCount: snapshot.data.length,
itemBuilder: (BuildContext context, int index) {
Map wppost = snapshot.data[index];
return Card(
margin: const EdgeInsets.only(
left: 15,
right: 15,
bottom: 15,
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(5),
),
elevation: 3,
child: InkWell(
splashColor: Colors.grey[300],
onTap: () {
setState(() {
itemspressed = index;
});
},
child: Padding(
padding: const EdgeInsets.only(
left: 12, right: 5, bottom: 12, top: 5),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
"${wppost['name']}",
style: TextStyle(
fontSize: 16.0,
fontWeight: FontWeight.bold,
color: Colors.lightGreen[900]),
),
Container(
height: 40,
width: 40,
decoration: BoxDecoration(
shape: BoxShape.rectangle,
border: Border.all(color: Colors.grey[350]),
color: itemspressed == index
? Colors.grey[350]
: null,
),
child: IconButton(
iconSize: 22,
icon: Icon(
Icons.add,
color: Colors.blueAccent[400],
),
onPressed: () {
setState(() {});
print('Add to cart');
},
),
),
],
),
Text(
parse(("${wppost['description']}").toString())
.documentElement
.text,
style: TextStyle(fontSize: 14, color: Colors.black),
),
Text(
parse(("${wppost['price']} €").toString())
.documentElement
.text,
style: TextStyle(
fontSize: 15,
color: Colors.amber[700],
fontWeight: FontWeight.bold),
),
],
),
),
),
) ;
},
);
}
return new CircularPercentIndicator(
radius: 120.0,
lineWidth: 13.0,
animation: true,
percent: 1.0,
progressColor: Colors.orange,
center: new Text(
"100.0%",
style:
new TextStyle(fontWeight: FontWeight.bold, fontSize: 20.0),
));
},
),
);
}
}
//lib/api_service.dart
import 'package:http/http.dart' as http;
import 'dart:convert';
Future<List> fetchWpPosts() async{
final response = await http.get('https://word.tkco.in/wp-json/wc/v3/products?consumer_key=ck_94114a31e4576e61a9292f961489e7701029753e&consumer_secret=cs_dd4dc6e7945d8dcd14d888bc1d0ea0806b116dfb');
var convertDatatoJson = jsonDecode(response.body);
if (response.statusCode == 200) {
}
return convertDatatoJson;
}
i am missing a small piece of information about constructors, i am trying to pass some data through the widget PromotionCard( [ ... ] ) i can't see any error in my debug console i tried Cards widgets and other different stuff to show the data but i can't find out what is wrong with this code down below.
Note: when i print snapshot.data i can see it perfectly returned
any help please.
**promotions_page.dart**
class PromotionsPage extends StatefulWidget {
#override
_PromotionsPageState createState() => _PromotionsPageState();
}
class _PromotionsPageState extends State<PromotionsPage> {
Future<Result> _promotionsResultsData;
#override
void initState() {
_promotionsResultsData = PromotionApi().fetchPromotions();
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
margin: EdgeInsets.symmetric(horizontal: 10.0, vertical: 20.0),
child: ListView(
physics: PageScrollPhysics(),
children: [
Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'Акции',
style: TextStyle(
fontSize: 18.0,
fontWeight: FontWeight.bold,
fontFamily: 'BuffetBold',
),
),
InkWell(
onTap: () => print('Archive promotion pressed!'),
child: Text(
'Архив Акции',
style: TextStyle(
fontSize: 16.0,
fontWeight: FontWeight.bold,
fontFamily: 'BuffetBold',
color: Colors.grey[400],
),
),
),
],
),
SizedBox(
height: 10.0,
),
Container(
child: FutureBuilder<Result>(
future: _promotionsResultsData,
builder: (context, snapshot) {
if (snapshot.hasData) {
return GridView.builder(
padding: EdgeInsets.zero,
gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount(
childAspectRatio: (45 / 35),
crossAxisCount: 1,
),
shrinkWrap: true,
physics: ScrollPhysics(),
itemCount: snapshot.data.result.length,
itemBuilder: (BuildContext context, int index) {
//print(snapshot.data.result.length);
var promos = snapshot.data.result[index];
PromotionCard(
id: promos.id,
title: promos.title,
description: promos.description,
image: promos.image);
},
);
} else {}
return Center(
child: Text(
"Loading ...",
style: TextStyle(
fontWeight: FontWeight.w900, fontSize: 30.0),
),
);
},
),
),
],
),
],
),
),
);
}
}
i am trying to pass data to this screen
**w_promotion_card.dart**
class PromotionCard extends StatelessWidget {
final String id;
final String title;
final String description;
final String image;
PromotionCard({this.id, this.title, this.description, this.image});
#override
Widget build(BuildContext context) {
return Container(
width: MediaQuery.of(context).size.width,
height: 200.0,
margin: EdgeInsets.fromLTRB(0.0, 20.0, 0.0, 10.0),
padding: EdgeInsets.zero,
decoration: BoxDecoration(
image: DecorationImage(
image: NetworkImage(image),
alignment: Alignment.topCenter,
),
borderRadius: BorderRadius.circular(10.0),
border: Border.all(
width: 1.5,
color: Colors.grey[300],
),
),
child: Container(
width: MediaQuery.of(context).size.width,
margin: EdgeInsets.zero,
child: Padding(
padding: EdgeInsets.fromLTRB(10, 170.0, 10.0, 10.0),
child: Text(
title,
style: TextStyle(
fontSize: 16.0,
fontFamily: 'BuffetRegular',
),
),
),
),
);
}
}
You missed the return statement
itemBuilder: (BuildContext context, int index) {
//print(snapshot.data.result.length);
var promos = snapshot.data.result[index];
// you have to return the widget
return PromotionCard(
id: promos.id,
title: promos.title,
description: promos.description,
image: promos.image);
},
I'm trying to make a combobox and when I select an item, I want it to be added in a listview when a button is pressed.
I tried multiple solutions, but none seems to work, as far as I did, I could make a input field and add the items manually, but I can't do it with a combobox ( without letting the user write them manually ).
Here is what I did:
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:searchable_dropdown/searchable_dropdown.dart';
class LocationTab extends StatefulWidget {
#override
_LocationTabState createState() => _LocationTabState();
}
class _LocationTabState extends State<LocationTab> {
List<String> mylist = List();
List<ParentCategoryComboBox> _visibility =
ParentCategoryComboBox.getParentCategory();
List<DropdownMenuItem<ParentCategoryComboBox>> _dropdownMenuItems;
List<PlatformReachComboBox> _platformReach =
PlatformReachComboBox.getPlatformReach();
List<DropdownMenuItem<PlatformReachComboBox>> _dropdownPlatformReach;
PlatformReachComboBox _selectedPlatformReach;
ParentCategoryComboBox _selectedVisibility;
#override
void initState() {
_dropdownMenuItems = buildDropDownMenuItems(_visibility);
_selectedVisibility = _dropdownMenuItems[0].value;
_dropdownPlatformReach =
buildDropdownMenuItemsPlatformReach(_platformReach);
_selectedPlatformReach = _dropdownPlatformReach[0].value;
super.initState();
}
#override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.only(top: 10.0, left: 20.0, right: 20.0),
child: SingleChildScrollView(
physics: BouncingScrollPhysics(),
scrollDirection: Axis.vertical,
child: Column(
children: <Widget>[
SizedBox(
height: 20,
),
Column(
children: [
Align(
alignment: Alignment.centerLeft,
child: Text(
"Select visibility:",
style: TextStyle(
color: Colors.indigoAccent,
fontWeight: FontWeight.bold,
fontSize: 16,
),
),
),
],
),
DropdownButton(
icon: Icon(
Icons.visibility,
color: Colors.black45,
),
isExpanded: true,
value: _selectedVisibility,
items: _dropdownMenuItems,
onChanged: (ParentCategoryComboBox selectedVisibility) {
setState(() {
_selectedVisibility = selectedVisibility;
});
},
),
SizedBox(
height: 35,
),
Container(
padding: new EdgeInsets.symmetric(horizontal: 5.0),
decoration: BoxDecoration(
border: Border.all(
width: 1,
color: Colors.grey,
),
borderRadius: BorderRadius.circular((10))),
child: Column(
children: <Widget>[
SizedBox(
height: 10,
),
Align(
alignment: Alignment.centerLeft,
child: Text(
"Select platform reach:",
style: TextStyle(
color: Colors.indigoAccent,
fontWeight: FontWeight.bold,
fontSize: 16,
),
),
),
SizedBox(
height: 20,
),
Row(
children: <Widget>[
Expanded(
child: SearchableDropdown(
isExpanded: true,
value: _selectedPlatformReach,
items: _dropdownPlatformReach,
isCaseSensitiveSearch: false,
onChanged:
(PlatformReachComboBox selectedPlatformReach) {
setState(() {
_selectedPlatformReach = selectedPlatformReach;
});
},
),
flex: 2,
),
Expanded(
child: Container(
height: 50.0,
width: 80,
child: Material(
borderRadius: BorderRadius.circular(20.0),
shadowColor: Colors.blue,
color: Colors.deepPurpleAccent,
elevation: 0.0,
child: GestureDetector(
onTap: () {
setState(() {
mylist.add(_selectedPlatformReach.toString());
});
},
child: Center(
child: Text(
'ADD',
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
),
),
),
),
),
),
flex: 0,
),
],
),
SizedBox(
height: 10,
),
Align(
alignment: Alignment.centerLeft,
child: Text(
"Added:",
style: TextStyle(
color: Colors.indigoAccent,
fontWeight: FontWeight.bold,
fontSize: 16,
),
),
),
SizedBox(
height: 10,
),
ListView.builder(
padding: EdgeInsets.only(left: 10),
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemCount: mylist.length,
itemBuilder: (BuildContext ctxt, int Index) {
return Text(
mylist[Index]
);
},
),
// ListView.builder(
// padding: EdgeInsets.only(left: 10),
// scrollDirection: Axis.vertical,
// shrinkWrap: true,
// itemCount: _platformReach.length,
// itemBuilder: (BuildContext ctxt, int Index) {
// return Text(
// "Galati"
// );
//// return DropdownButton(
//// value: _selectedPlatformReach.toString(),
//// items: _dropdownPlatformReach,
//// onChanged: (value) {
//// _selectedPlatformReach = value;
//// setState(() {});
//// },
//// hint: Text('Select drowdown'),
//// );
//// return new Text(_dropdownPlatformReach[Index].value);
// },
// ),
],
),
),
],
),
),
);
}
}
Mock data class:
import 'package:flutter/material.dart';
class PlatformReachComboBox {
String name;
String hint;
PlatformReachComboBox(this.name, this.hint);
static List<PlatformReachComboBox> getPlatformReach() {
return <PlatformReachComboBox>[
PlatformReachComboBox('Jud Galati', '(RO, [Galati] County)'),
PlatformReachComboBox('Jud Braila', '(RO, [Braila] County)'),
PlatformReachComboBox('Jud Prahova', '(RO, [Ploiesti] County)'),
PlatformReachComboBox('Jud Maramures', '(RO, [Baia Mare] County)'),
];
}
}
List<DropdownMenuItem<PlatformReachComboBox>>
buildDropdownMenuItemsPlatformReach(List platforms) {
List<DropdownMenuItem<PlatformReachComboBox>> items = List();
for (PlatformReachComboBox platform in platforms) {
items.add(
DropdownMenuItem(
value: platform,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
platform.name,
style: TextStyle(fontWeight: FontWeight.bold),
textAlign: TextAlign.start,
),
Text(
platform.hint,
style:
TextStyle(fontWeight: FontWeight.normal, color: Colors.grey),
textAlign: TextAlign.end,
)
],
),
),
);
}
return items;
}
And this is where I encounter the problem, I don't know what to return in ListView for me pressing the button, and then the item to be added in there:
ListView.builder(
padding: EdgeInsets.only(left: 10),
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemCount: _platformReach.length,
itemBuilder: (BuildContext ctxt, int Index) {
return Text(
"Galati"
);
},
),
please try this way ... define a list
List<String> mylist = List();
and use it below
ListView.builder(
padding: EdgeInsets.only(left: 10),
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemCount: mylist.length,
itemBuilder: (BuildContext ctxt, int Index) {
return Text(
mylist[Index]
);
},
),
and After button Clicked
setState(() {
mylist.add(_selectedVisibility.name);
});