Flutter state widget is not updated - flutter

I want to put a book as bookmarked, and if I click in the favorite button, the book is added, but when I go to another window and come back, the icon button change color.
CupertinoButton(
child: Icon(
widget.book.starred
?
CupertinoIcons.heart_solid
: CupertinoIcons.heart,
color: Colors.red,
),
onPressed: () {
setState(() {
widget.book.starred = !widget.book.starred;
addToFavorites(this.book);
});
})//Cupertino Button
How can I handle the build method to read the value of widget.book.starred and then print the right icon ?
EDIT
to show more code
class ReadBook extends StatefulWidget {
Book book;
ReadBook({Key key, this.book}) : super(key: key);
#override
State<StatefulWidget> createState() {
return new ReadBookState(this.book);
}
}
class ReadBookState extends State<ReadBook> {
// Declare a field that holds the Todo
Book book;
bool res;
final controller = new PageController(initialPage: 0, keepPage: true);
static const IconData baseball = const IconData(0xf397,
fontFamily: CupertinoIcons.iconFont,
fontPackage: CupertinoIcons.iconFontPackage);
ReadBookState(this.book);
initState() {
super.initState();
}
void addToFavorites(Book book) async {
Database.checkBookExist(book).then((value) {
if (!value) {
print("${widget.book.englishName} added successfully");
Database.addBookToFirestore(widget.book);
} else {
print("${widget.book.englishName} already added");
}
});
#override
Widget build(BuildContext context) {
Widget toRet;
bool rest = retrieveFromFavorites(book);
if (Platform.isAndroid) {
// Android-specific code
toRet = MaterialApp(
home: Scaffold(
appBar: AppBar(
leading: IconButton(
icon: Icon(Icons.arrow_back),
onPressed: () => Navigator.pop(context, false),
),
actions: <Widget>[],
backgroundColor: Color.fromRGBO(245, 205, 121, 1.0),
title: Text(book.name,
textDirection: TextDirection.rtl,
style:
TextStyle(fontSize: 35.0, fontFamily: 'SCHEHERAZADE')),
),
body: new ListView(
controller: controller,
scrollDirection: Axis.vertical,
children: <Widget>[
new Center(
child: new Text(("Title"),
textDirection: TextDirection.rtl,
style: TextStyle(
fontSize: 35.0, fontFamily: 'SCHEHERAZADE'))),
new Center(
child: new Text((t1 + t2),
textDirection: TextDirection.rtl,
style: TextStyle(
fontSize: 25.0, fontFamily: 'SCHEHERAZADE')))
],
)));
} else if (Platform.isIOS) {
// iOS-specific code
toRet = CupertinoApp(
home: CupertinoPageScaffold(
navigationBar: CupertinoNavigationBar(
backgroundColor: Color.fromRGBO(245, 205, 121, 1.0),
leading: CupertinoButton(
padding: EdgeInsets.only(right: 25.0, bottom: 8.0),
child: Icon(
CupertinoIcons.back,
color: Colors.black,
),
onPressed: () => Navigator.pop(context, false),
),
trailing: Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
CupertinoButton(
child: Icon(
widget.book.starred
?
CupertinoIcons.heart_solid
: CupertinoIcons.heart,
color: Colors.red,
),
onPressed: () {
// PopupMenuButton
setState(() {
widget.book.starred = !widget.book.starred;
addToFavorites(this.book);
});
}),
CupertinoButton(
child: Icon(
baseball,
color: Colors.black,
),
onPressed: () =>
// PopupMenuButton
popUpOptionsButton()),
],
),
middle: Text(book.name),
),
child: new ListView(
controller: controller,
scrollDirection: Axis.vertical,
children: <Widget>[
new Center(
child: new Text(("Title"),
textDirection: TextDirection.rtl,
style: TextStyle(
fontSize: 35.0, fontFamily: 'SCHEHERAZADE'))),
new Center(
child: new Text((t1 + t2),
textDirection: TextDirection.rtl,
style: TextStyle(
fontSize: 25.0, fontFamily: 'SCHEHERAZADE')))
],
),
),
);
}
return toRet;
}
}

Related

when i typing in flutter textfield it type in backward direction how to solve it?

I have one page of technical skill and I want to add new textfield on onatap and get the value of it and remove that skill on ontap of delete button and this is working now but only problem was that the when i am typing in textfield its typing in backward direction(right to left i want to type left to right.)
import 'package:flutter/material.dart';
class Technical extends StatefulWidget {
const Technical({Key? key}) : super(key: key);
#override
State<Technical> createState() => _TechnicalState();
}
class _TechnicalState extends State<Technical> {
List<String> skill = <String>[];
List<TextEditingController> mycontroller = <TextEditingController>[];
#override
Widget build(BuildContext context) {
double h = MediaQuery.of(context).size.height;
double w = MediaQuery.of(context).size.width;
return Scaffold(
resizeToAvoidBottomInset: false,
appBar: AppBar(
centerTitle: true,
elevation: 0,
backgroundColor: Colors.blue,
title: const Text(
'Technical Skills',
),
),
body: Column(
children: [
const Align(
alignment: Alignment.centerLeft,
child: Text(
'Enter Your Skills',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Colors.blue,
),
),
),
...skill
.map(
(e) => Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(
width: 100,
child: TextField(
enableInteractiveSelection: true,
controller: TextEditingController(text: e),
onChanged: (String value) {
setState(() {
skill[skill.indexOf(e)] = value;
});
},
),
),
IconButton(
onPressed: () {
setState(() {
skill.remove(e);
mycontroller.clear();
print(e);
});
},
icon: const Icon(Icons.delete))
],
),
)
.toList(),
Center(
child: Text(
'$skill',
style: const TextStyle(fontSize: 30),
),
),
const Spacer(),
OutlinedButton(
onPressed: () {
setState(() {
skill.add("");
});
},
child: const Icon(Icons.add),
),
],
),
);
}
}
The issue is you are creating new controller on every state change, the cursor position is not handling in this.
So the solution will we
controller: TextEditingController.fromValue(
TextEditingValue(
text: e,
selection: TextSelection(
baseOffset: e.length,
extentOffset: e.length,
)),
),
With controller
class _TechnicalState extends State<Technical> {
List<String> skill = <String>[];
List<TextEditingController> mycontroller = <TextEditingController>[];
#override
Widget build(BuildContext context) {
double h = MediaQuery.of(context).size.height;
double w = MediaQuery.of(context).size.width;
return Scaffold(
resizeToAvoidBottomInset: false,
appBar: AppBar(
centerTitle: true,
elevation: 0,
backgroundColor: Colors.blue,
title: const Text(
'Technical Skills',
),
),
body: Column(
children: [
const Align(
alignment: Alignment.centerLeft,
child: Text(
'Enter Your Skills',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Colors.blue,
),
),
),
for (int i = 0; i < mycontroller.length; i++) row_build(i),
Center(
child: Text(
'$skill',
style: const TextStyle(fontSize: 30),
),
),
const Spacer(),
OutlinedButton(
onPressed: () {
mycontroller.add(TextEditingController());
setState(() {
skill.add("");
});
},
child: const Icon(Icons.add),
),
],
),
);
}
Row row_build(int i) {
return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(
width: 100,
child: TextField(
enableInteractiveSelection: true,
controller: mycontroller[i],
onChanged: (String value) {
setState(() {
skill[i] = value;
});
},
),
),
IconButton(
onPressed: () {
setState(() {
skill.remove(skill[i]);
mycontroller.removeAt(i);
});
},
icon: const Icon(Icons.delete))
],
);
}
}
The textfield works fine for me (left to right)
Check your code if the textDirection property is set correctly to TextDirection.ltr instead of TextDirection.rtl
child: TextField(
textDirection: TextDirection.ltr,

How to custom appbar style inside SearchDelegate

I created a search function with new class extends SearchDelegate. And I want to custom appBar background color, font size. How to achieve this?
My search class
import 'package:flutter/material.dart';
class Search extends SearchDelegate {
final List countryList;
Search(this.countryList);
#override
List<Widget> buildActions(BuildContext context) {
return [
IconButton(
icon: Icon(Icons.clear),
onPressed: () {
query = '';
},
)
];
}
#override
Widget buildLeading(BuildContext context) {
return IconButton(
icon: Icon(Icons.arrow_back_ios),
onPressed: () {
Navigator.pop(context);
},
);
}
#override
Widget buildResults(BuildContext context) {
return Container();
}
#override
Widget buildSuggestions(BuildContext context) {
final suggestionList = query.isEmpty
? countryList
: countryList
.where((element) =>
element['country'].toString().toLowerCase().startsWith(query))
.toList();
return ListView.builder(
itemCount: suggestionList.length,
itemBuilder: (context, index) {
return Card(
child: Container(
height: 70,
margin: EdgeInsets.symmetric(horizontal: 10, vertical: 10),
child: Row(
children: <Widget>[
Container(
width: 200,
margin: EdgeInsets.symmetric(horizontal: 10),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
suggestionList[index]['country'],
style: TextStyle(fontWeight: FontWeight.bold),
),
Image.network(
suggestionList[index]['countryInfo']['flag'],
height: 50,
width: 60,
),
],
),
),
Expanded(
child: Container(
child: Column(
children: <Widget>[
Text(
'CONFIRMED:' +
suggestionList[index]['cases'].toString(),
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.red,
),
),
Text(
'ACTIVE:' + suggestionList[index]['active'].toString(),
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.blue,
),
),
Text(
'RECOVERED:' +
suggestionList[index]['recovered'].toString(),
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.green,
),
),
Text(
'DEATHS:' + suggestionList[index]['deaths'].toString(),
style: TextStyle(
fontWeight: FontWeight.bold,
color: Theme.of(context).brightness == Brightness.dark
? Colors.grey[100]
: Colors.grey[900],
),
),
],
),
))
],
),
),
);
},
);
}
}
This class create a appbar like this
When I try to change backgound color use
ThemeData appBarTheme(BuildContext context) {
return ThemeData(
primaryColor: Color(0xff202c3b),
);
}
Background color changed but some style are changed too
I want to custom a little bit style like
Font size bigger
Font color to white
Don't use underline
How to achieve this? I can't find any TextStyle or something like that
EDITED
CountryPage class for use search
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'package:tgd_covid_tracker/pages/search.dart';
class CountryPage extends StatefulWidget {
#override
_CountryPageState createState() => _CountryPageState();
}
class _CountryPageState extends State<CountryPage> {
List countryData;
fetchCountryData() async {
if (this.mounted) {
http.Response response =
await http.get('https://corona.lmao.ninja/v2/countries');
setState(() {
countryData = json.decode(response.body);
});
}
}
#override
void initState() {
fetchCountryData();
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
centerTitle: true,
actions: <Widget>[
countryData == null
? Container()
: searchButton(
context,
countryData,
),
],
title: Text('Country Stats'),
),
body: countryData == null
? Center(
child: CircularProgressIndicator(),
)
: ListView.builder(
itemBuilder: (context, index) {
return Card(
child: Container(
height: 70,
margin: EdgeInsets.symmetric(horizontal: 10, vertical: 10),
child: Row(
children: <Widget>[
Container(
width: 200,
margin: EdgeInsets.symmetric(horizontal: 10),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
countryData[index]['country'],
style: TextStyle(fontWeight: FontWeight.bold),
),
Image.network(
countryData[index]['countryInfo']['flag'],
height: 50,
width: 60,
),
],
),
),
Expanded(
child: Container(
child: Column(
children: <Widget>[
Text(
'CONFIRMED:' +
countryData[index]['cases'].toString(),
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.red,
),
),
Text(
'ACTIVE:' +
countryData[index]['active'].toString(),
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.blue,
),
),
Text(
'RECOVERED:' +
countryData[index]['recovered']
.toString(),
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.green,
),
),
Text(
'DEATHS:' +
countryData[index]['deaths'].toString(),
style: TextStyle(
fontWeight: FontWeight.bold,
color: Theme.of(context).brightness ==
Brightness.dark
? Colors.grey[100]
: Colors.grey[900],
),
),
],
),
),
)
],
),
),
);
},
itemCount: countryData == null ? 0 : countryData.length,
),
);
}
}
Widget searchButton(BuildContext context, countryData) {
return IconButton(
icon: Icon(Icons.search),
onPressed: () {
showSearch(context: context, delegate: Search(countryData));
},
);
}
The following works flawlessly:
class CustomSearchDelegate extends SearchDelegate {
#override
ThemeData appBarTheme(BuildContext context) {
return ThemeData(
textTheme: TextTheme(
// Use this to change the query's text style
headline6: TextStyle(fontSize: 24.0, color: Colors.white),
),
appBarTheme: const AppBarTheme(
backgroundColor: Colors.green,
),
inputDecorationTheme: InputDecorationTheme(
border: InputBorder.none,
// Use this change the placeholder's text style
hintStyle: TextStyle(fontSize: 24.0),
),
);
}
}
You can provide style to the title like this:
title: Text("MyApp", style:TextStyle(color:Colors.black,fontWeight:FontWeight.w300,fontSize:20)
and for the underline add the following attribute
decoration:TextDecoration.none
you have to add this in AppBar() properties.
So finally:
title: Text("MyApp",
style:TextStyle(
color:Colors.black,
fontWeight:FontWeight.w300,
fontSize:20,
decoration:TextDecoration.none
)
I understand the issue, and my solution won't fix the whole problem, but if what you want is just change some of the appBarTheme properties, you can do so by using the .copyWith method and indicating what are the properties that you want to override.
#override
ThemeData appBarTheme(BuildContext context) {
// TODO: implement appBarTheme
return super.appBarTheme(context).copyWith(//OVERRIDE PROPERTIES HERE);
}
You can override your appBarTheme like this :
#override
ThemeData appBarTheme(BuildContext context) {
assert(context != null);
final ThemeData theme = Theme.of(context).copyWith(
appBarTheme: AppBarTheme(
color: Colors.black, //new AppBar color
elevation: 0,
),
textTheme: TextTheme(
headline6: TextStyle(
color: Colors.white,
),
),
);
}
You could use appBarTheme Method from SearchDelegate class for changing AppBar Theme. (https://api.flutter.dev/flutter/material/SearchDelegate-class.html)
Examples:
// Default App Theme
#override
ThemeData appBarTheme(BuildContext context) {
return Theme.of(context);
}
// Changing AppBar color only for current AppBar
#override
ThemeData appBarTheme(BuildContext context) {
return Theme.of(context).copyWith(
appBarTheme: Theme.of(context).appBarTheme.copyWith(
color: const Color(0xff202c3b),
),
);
}

Listview with Checkbox using StatefulWidget(setState)

I am trying to develop an app in flutter, that has topics that the user can select and check box state will change when i scroll on listview check box state will not collapse and finally user give the submit the value are will bring out.i tried i am not able do that.
the error message shows:
The method 'setState' isn't defined for the class 'ItemDepletionList'.
Try correcting the name to the name of an existing method, or defining a method named 'setState'
class ItemDepletion extends StatefulWidget {
#override
_GetShaftsState createState() => _GetShaftsState();
}
class _GetShaftsState extends State<ItemDepletion> {
ItemDepletionBloc _bloc;
String json =
'{"RECORD_ID": "0", "REQTYPE": "ITEMDEPELTION", "CLINIC_ID": "1012"}';
#override
void initState() {
super.initState();
_bloc = ItemDepletionBloc(json);
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
elevation: 0.0,
automaticallyImplyLeading: false,
title: Text('Chucky Categories',
style: TextStyle(color: Colors.white, fontSize: 20)),
backgroundColor: Color(0xFF333333),
),
backgroundColor: Color(0xFF333333),
body: RefreshIndicator(
onRefresh: () => _bloc.fetchCategories(json),
child: StreamBuilder<Response<List<Idepeltion>>>(
stream: _bloc.chuckListStream,
builder: (context, snapshot) {
if (snapshot.hasData) {
switch (snapshot.data.status) {
case Status.LOADING:
return Loading(loadingMessage: snapshot.data.message);
break;
case Status.COMPLETED:
return ItemDepletionList(
itemdepletionlst: snapshot.data.data);
break;
case Status.ERROR:
return Error(
errorMessage: snapshot.data.message,
onRetryPressed: () => _bloc.fetchCategories(json),
);
break;
}
}
return Container();
},
),
),
);
}
#override
void dispose() {
_bloc.dispose();
super.dispose();
}
}
class ItemDepletionList extends StatelessWidget {
// final Itemdepeltion categoryList;
final List<Idepeltion> itemdepletionlst;
const ItemDepletionList({Key key, this.itemdepletionlst}) : super(key: key);
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new Myappbar(title: new Text("Home Page")),
body: Column(children: [
Expanded(
child: ListView.builder(
itemCount: itemdepletionlst.length,
itemBuilder: (context, index) {
return ListTile(
title: new Container(
child: Row(
children: <Widget>[
new Checkbox(
value: itemdepletionlst[index].isCheck,
onChanged: (bool value) {
setState(() {
itemdepletionlst[index].isCheck = value;
});
}),
new Expanded(
child: new Container(
padding: new EdgeInsets.only(left: 8.0, right: 8.0),
child: new Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
new Text(
'${itemdepletionlst[index].itemName}',
style: new TextStyle(
color: Colors.black,
fontWeight: FontWeight.w600,
fontSize: 16.0,
),
),
new Text(
'${itemdepletionlst[index].category}',
style: new TextStyle(color: Colors.grey),
),
],
),
),
),
new Expanded(
child: GestureDetector(
onTap: () {
selectedItem(
context, itemdepletionlst[index].suggQtyUnit);
},
child: new Container(
padding: new EdgeInsets.only(left: 8.0, right: 8.0),
child: new Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
new Text(
'${itemdepletionlst[index].suggReorderQty} ${itemdepletionlst[index].suggQtyUnit}',
style: new TextStyle(
color: Colors.black,
fontWeight: FontWeight.w600,
fontSize: 16.0,
),
),
new Text(
'${itemdepletionlst[index].manuf}',
style: new TextStyle(color: Colors.grey),
),
],
),
),
)),
],
)));
},
),
),
RaisedButton(
// onPressed: getCheckboxItems,
textColor: Colors.white,
padding: const EdgeInsets.all(0.0),
child: Container(
decoration: const BoxDecoration(
gradient: LinearGradient(
colors: <Color>[
Color(0xFF09a3c8),
Color(0xFF39B9B4),
Color(0xFF0fb188),
],
),
),
padding: const EdgeInsets.all(10.0),
child: const Text('Submit',
style: TextStyle(fontSize: 20, color: Colors.white)),
),
),
])
);
}
}
Your ItemDepletionList class is stateless and You are trying to call setstate in it because of that you are getting that error. make it Stateful then it will work.
replace Following line.
class ItemDepletionList extends StatelessWidget {
With this
class ItemDepletionList extends StatefulWidget {
final List<Idepeltion> itemdepletionlst;
ItemDepletionList({this.itemdepletionlst});
#override
_ItemDepletionListState createState() => _ItemDepletionListState();
}
class _ItemDepletionListState extends State<ItemDepletionList> {
And now to access itemdepletionlst you have use widget.
widget.itemdepletionlst

How can I show/hide menu items in Nav Drawer and enable/disable overflow menu items in App Bar programatically in Flutter?

I have been trying to do what the title says but have found no information on the web at all. In regular Android code, this is as simple as finding the ViewID of the drawer/toolbar, getting the menu item, and either calling .setEnabled() or .setVisible() on the menu item. How can I do this in Flutter? Basically when a certain url is loaded in webView, I want to either enable/disable or show/hide programatically (in the onLoadStart and onLoadFinished methods for webview_flutter). For reference, my scaffold:
return new Scaffold(
appBar: new AppBar(
title: new Text(appBarTitle),
actions: <Widget>[
IconButton(
icon: Icon(
Icons.refresh,
color: Colors.white,
),
onPressed: () {
webView.reload();
},
),
PopupMenuButton<Choice> ( //showchoice??
onSelected: _select,
itemBuilder: (BuildContext context) {
return choices.map((Choice choice) {
return PopupMenuItem<Choice>(
value: choice,
child: Text(choice.title),
);
}).toList();
},
),
],
),
drawer: Drawer(
child: ListView(
children: <Widget>[
new DrawerHeader(
child: Column (
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget> [
Text(
'HLS Grades',
textAlign: TextAlign.left,
style: TextStyle(
color: Colors.white,
fontSize: 20,
),
),
Text(
'Canvas Online Grading System',
style: TextStyle(
color: Colors.white,
fontSize: 12,
),
),
]),
decoration: BoxDecoration(
color: Colors.blue,
),
),
Divider(),
Text(
'Course Actions',
style: TextStyle(
color: Colors.black,
fontSize: 12,
),
),
ListTile(
leading: Icon(MyFlutterApp.assignment),
title: Text('Assignments'),
onTap: () {
setState(() => _selectedDrawerIndex = 0);
_onSelectNavItem(0);
},
),
ListTile(
leading: Icon(MyFlutterApp.grades),
title: Text('Grades'),
onTap: () {
setState(() => _selectedDrawerIndex = 1);
_onSelectNavItem(1);
},
),
ListTile(
leading: Icon(MyFlutterApp.people),
title: Text('Users'),
onTap: () {
setState(() => _selectedDrawerIndex = 2);
_onSelectNavItem(2);
},
),
ListTile(
leading: Icon(MyFlutterApp.syllabus),
title: Text('Syllabus'),
onTap: () {
setState(() => _selectedDrawerIndex = 3);
_onSelectNavItem(3);
},
),
ListTile(
leading: Icon(MyFlutterApp.discussions),
title: Text('Discussions'),
onTap: () {
setState(() => _selectedDrawerIndex = 4);
_onSelectNavItem(4);
},
),
Divider(),
Text(
'App Actions',
style: TextStyle(
color: Colors.black,
fontSize: 12,
),
),
ListTile(
leading: Icon(MyFlutterApp.logout),
title: Text('Logout'),
onTap: () {
_onSelectNavItem(5);
},
),
ListTile(
leading: Icon(MyFlutterApp.settings),
title: Text('Settings'),
onTap: () {
_onSelectNavItem(6);
},
),
],
),
),
And the code for my choice class:
class Choice {
const Choice({this.title, this.icon});
final String title;
final IconData icon;
}
const List<Choice> choices = const <Choice>[
const Choice(title: 'All Grading Periods'),
const Choice(title: 'Trimester 1'),
const Choice(title: 'Trimester 2'),
const Choice(title: 'Trimester 3'),
];
class ChoiceCard extends StatelessWidget {
const ChoiceCard({Key key, this.choice}) : super(key: key);
final Choice choice;
#override
Widget build(BuildContext context) {
final TextStyle textStyle = Theme.of(context).textTheme.headline4;
return Card(
color: Colors.white,
child: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Icon(choice.icon, size: 128.0, color: textStyle.color),
Text(choice.title, style: textStyle),
],
),
),
);
}
}
Any help would be appreciated!
For whoever is stumped by this and is looking for an answer, just wrap your ListTile in a
Visibility (
visible: _visible
child: ListTile(...)
);
and whenever you want to remove, just
setState(() {
_visible = false;
});
or whenever you want to show
setState(() {
_visible = true;
});

Get Time Picker's Value within a Widget

I am trying to get the DateTime that is chosen from the user and save it within an object.
This is implemented within the following construction:
return Scaffold(
appBar: AppBar(
title: Text('Add/Edit Shift'),
),
body: Container(
color: Colors.white,
margin: EdgeInsets.all(16.0),
child: Form(
key: _formKey,
child: SingleChildScrollView(
child: Column(
// crossAxisAlignment: CrossAxisAlignment.center,
// mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
height: 40.0,
decoration:
BoxDecoration(borderRadius: BorderRadius.circular(5.0)),
alignment: Alignment.center,
width: MediaQuery.of(context).size.width,
child: Text(
'Scheduling Date: ${_dateformat.format(widget.shiftDate)}',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 19.0,
color: Colors.teal,
),
),
),
// fixme: how to get the clicked value from the user?
// the value has to get saved within an object that will be returned
MyTimePicker(_startOfShift),
MyTimePicker(_endOfShift),
RaisedButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(5.0),
),
child: Text(
"Submit",
style: TextStyle(
color: Colors.teal,
fontSize: 18.0,
fontWeight: FontWeight.bold),
),
onPressed: () {
// todo: return the shift to the calendar
// print(MyTimePicker(_startOfShift).chosenTime);
Navigator.pop(
context,
);
},
)
],
),
),
),
),
);
And this is how it looks like:
The MyTimePickerClass is created as a separate Dart file. Within the MyTimePicker class, I construct a RaisedButton labeled as Start and End where the user is capable to choose the wanting time.
import 'package:flutter/material.dart';
import 'package:flutter_datetime_picker/flutter_datetime_picker.dart';
class MyTimePicker extends StatefulWidget {
String typeOfShift;
MyTimePicker(this.typeOfShift);
#override
_MyTimePickerState createState() => _MyTimePickerState();
}
class _MyTimePickerState extends State<MyTimePicker> {
#override
Widget build(BuildContext context) {
return RaisedButton(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(5.0)),
elevation: 4.0,
onPressed: () {
DateTime test = _MyDatePicker(context);
widget.typeOfShift = test.toString();
setState(() {});
},
child: Container(
alignment: Alignment.center,
height: 50.0,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Row(
children: <Widget>[
Container(
child: Row(
children: <Widget>[
Icon(
Icons.access_time,
size: 18.0,
color: Colors.teal,
),
Text(
" ${widget.typeOfShift}",
style: TextStyle(
color: Colors.teal,
fontWeight: FontWeight.bold,
fontSize: 18.0),
),
],
),
)
],
),
Text(
" Change",
style: TextStyle(
color: Colors.teal,
fontWeight: FontWeight.bold,
fontSize: 18.0),
),
],
),
),
color: Colors.white,
);
}
DateTime _MyDatePicker(BuildContext context) {
DateTime _myDateTime;
DatePicker.showTimePicker(context,
showSecondsColumn: false,
theme: DatePickerTheme(
containerHeight: 210.0,
),
showTitleActions: true, onConfirm: (time) {
// _chosenTime = time;
_myDateTime = time;
print('confirm $time');
// widget.typeOfShift = '${time.hour} : ${time.minute}';
setState(() {});
}, currentTime: DateTime.now(), locale: LocaleType.de);
return _myDateTime;
}
}
Then the time is displayed in the UI. How could I access this time??
You can copy paste run full code below
You can define two MyTimePicker and use it
When onPressed , you can use startPicker.typeOfShift to get String
MyTimePicker startPicker = MyTimePicker("Start");
MyTimePicker endPicker = MyTimePicker("End");
...
startPicker,
endPicker,
RaisedButton(
...
onPressed: () {
print(startPicker.typeOfShift);
print(endPicker.typeOfShift);
output
I/flutter (31204): 1 : 23
I/flutter (31204): 1 : 25
working demo
full code
import 'package:flutter/material.dart';
import 'package:flutter_datetime_picker/flutter_datetime_picker.dart';
class MyTimePicker extends StatefulWidget {
String typeOfShift;
MyTimePicker(this.typeOfShift);
#override
_MyTimePickerState createState() => _MyTimePickerState();
}
class _MyTimePickerState extends State<MyTimePicker> {
#override
Widget build(BuildContext context) {
return RaisedButton(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(5.0)),
elevation: 4.0,
onPressed: () {
DateTime test = _MyDatePicker(context);
widget.typeOfShift = test.toString();
setState(() {});
},
child: Container(
alignment: Alignment.center,
height: 50.0,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Row(
children: <Widget>[
Container(
child: Row(
children: <Widget>[
Icon(
Icons.access_time,
size: 18.0,
color: Colors.teal,
),
Text(
" ${widget.typeOfShift}",
style: TextStyle(
color: Colors.teal,
fontWeight: FontWeight.bold,
fontSize: 18.0),
),
],
),
)
],
),
Text(
" Change",
style: TextStyle(
color: Colors.teal,
fontWeight: FontWeight.bold,
fontSize: 18.0),
),
],
),
),
color: Colors.white,
);
}
DateTime _MyDatePicker(BuildContext context) {
DateTime _myDateTime;
DatePicker.showTimePicker(context,
showSecondsColumn: false,
theme: DatePickerTheme(
containerHeight: 210.0,
),
showTitleActions: true, onConfirm: (time) {
// _chosenTime = time;
_myDateTime = time;
print('confirm $time');
widget.typeOfShift = '${time.hour} : ${time.minute}';
setState(() {});
}, currentTime: DateTime.now(), locale: LocaleType.de);
return _myDateTime;
}
}
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
MyTimePicker startPicker = MyTimePicker("Start");
MyTimePicker endPicker = MyTimePicker("End");
void _incrementCounter() {
setState(() {
_counter++;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Add/Edit Shift'),
),
body: Container(
color: Colors.white,
margin: EdgeInsets.all(16.0),
child: Form(
//key: _formKey,
child: SingleChildScrollView(
child: Column(
// crossAxisAlignment: CrossAxisAlignment.center,
// mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
height: 40.0,
decoration:
BoxDecoration(borderRadius: BorderRadius.circular(5.0)),
alignment: Alignment.center,
width: MediaQuery.of(context).size.width,
child: Text(
'Scheduling Date: ',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 19.0,
color: Colors.teal,
),
),
),
// fixme: how to get the clicked value from the user?
// the value has to get saved within an object that will be returned
startPicker,
endPicker,
RaisedButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(5.0),
),
child: Text(
"Submit",
style: TextStyle(
color: Colors.teal,
fontSize: 18.0,
fontWeight: FontWeight.bold),
),
onPressed: () {
print(startPicker.typeOfShift);
print(endPicker.typeOfShift);
// todo: return the shift to the calendar
// print(MyTimePicker(_startOfShift).chosenTime);
Navigator.pop(
context,
);
},
)
],
),
),
),
),
);
}
}