How to dynamically sort by date in flutter? - flutter

I am working on a to do list app on flutter and I will like to sort the uploaded tasks by date(new ones appear first). for doing this I think a key should be givin to each of the uploaded items in the to do list and this key should include a Date. In react native for doing this I added a function to the data in a flatlist which sorted by date but since I am new to flutter I dont know how can that be done. Any Idea helps :)
main.dart
List<String> _toDoItems = []; //this is the array in which the uploaded tasks are stored, btw Im not using any database.
TextEditingController _controller = TextEditingController();
void _addToDoItem(String task) {
if(task.length > 0) {
setState(() {
_toDoItems.add(task);
});
}
}
void _removeTodoItem(int index) {
setState(() => _toDoItems.removeAt(index));
}
Widget _buildToDoItem(String toDoText, int index) {
return SizedBox(
child: Container(
height: 58,
margin: EdgeInsets.only(left: 22.0, right: 22.0, bottom: 12,),
decoration: BoxDecoration(
border: Border.all(width: 1.5, color: Colors.red),
borderRadius: BorderRadius.all(Radius.circular(18)),
),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children:[
Expanded(
child: ListTile(
title: Text(
toDoText,
style: TextStyle(fontSize: 18),
),
onTap: () => _removeTodoItem(index),
),
),
FlatButton(
child: Text('Delete', style: TextStyle(color: Colors.red, fontSize: 16.5),),
onPressed: () => _removeTodoItem(index),
),
],
),
),
);
}
Widget _buildToDoList() {
return Expanded(
child: ListView.builder(
itemBuilder: (context, index) {
if (index < _toDoItems.length) {
return _buildToDoItem(_toDoItems[index], index);
}
},
),
);
}
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: PreferredSize(
preferredSize: Size.fromHeight(50),
child: AppBar(
centerTitle: true,
backgroundColor: Colors.red,
title: Text('To Do List', style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold,),),
)
),
backgroundColor: Colors.white,
body: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Container(
height: 60,
margin: EdgeInsets.all(22),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(
flex: 10,
child: Container(
height: double.infinity,
child: TextField(
controller: _controller,
autofocus: true,
onSubmitted: (val) {
_addToDoItem(val);
_controller.clear();
},
style: TextStyle(fontSize: 18,),
),
),
),
Expanded(
flex: 4,
child: Container(
height: double.infinity,
margin: EdgeInsets.only(left: 12),
child: RaisedButton(
textColor: Colors.white,
color: Colors.red,
child: Text('ADD', style: TextStyle(fontSize: 18)),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(12)),
),
onPressed: () {
_addToDoItem(_controller.text);
_controller.clear();
FocusScope.of(context).requestFocus(FocusNode());
},
),
),
),
],
),
),
_buildToDoList()
]
),
),
);
}

You need to use the sort() method of List, also you need to be able to stock in a way or another the time of creation of your task.
I've made an example with the code you've posted. Using it your last created element will always be the first of the list.
import 'package:flutter/material.dart';
class ToDoElement {
final String task;
final DateTime timeOfCreation;
ToDoElement(this.task, this.timeOfCreation);
}
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
#override
createState() => _MyAppState();
}
class _MyAppState extends State {
TextEditingController _controller = TextEditingController();
List<ToDoElement> _toDoItems = [];
void _removeTodoItem(int index) {
setState(() => _toDoItems.removeAt(index));
}
void _addToDoItem(String task) {
if (task.isNotEmpty) {
setState(() => _toDoItems.add(ToDoElement(task, DateTime.now())));
}
}
Widget _buildToDoItem(String toDoText, int index) {
return SizedBox(
child: Container(
height: 58,
margin: EdgeInsets.only(left: 22, right: 22, bottom: 12),
decoration: BoxDecoration(
border: Border.all(width: 1.5, color: Colors.red),
borderRadius: BorderRadius.all(Radius.circular(18)),
),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(
child: ListTile(
title: Text(
toDoText,
style: TextStyle(fontSize: 18),
),
onTap: () => _removeTodoItem(index),
),
),
FlatButton(
child: Text(
'Delete',
style: TextStyle(color: Colors.red, fontSize: 16.5),
),
onPressed: () => _removeTodoItem(index),
),
],
),
),
);
}
int compareElement(ToDoElement a, ToDoElement b) =>
a.timeOfCreation.isAfter(b.timeOfCreation) ? -1 : 1;
Widget _buildToDoList() {
_toDoItems.sort(compareElement);
return Expanded(
child: ListView.builder(
itemCount: _toDoItems.length,
itemBuilder: (context, index) {
return _buildToDoItem(_toDoItems[index].task, index);
},
),
);
}
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: PreferredSize(
preferredSize: Size.fromHeight(50),
child: AppBar(
centerTitle: true,
backgroundColor: Colors.red,
title: Text(
'To Do List',
style: TextStyle(
fontSize: 24,
fontWeight: FontWeight.bold,
),
),
)),
backgroundColor: Colors.white,
body: Column(crossAxisAlignment: CrossAxisAlignment.center, children: [
Container(
height: 60,
margin: EdgeInsets.all(22),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(
flex: 10,
child: Container(
height: double.infinity,
child: TextField(
controller: _controller,
autofocus: true,
onSubmitted: (val) {
_addToDoItem(val);
_controller.clear();
},
style: TextStyle(
fontSize: 18,
),
),
),
),
Expanded(
flex: 4,
child: Container(
height: double.infinity,
margin: EdgeInsets.only(left: 12),
child: RaisedButton(
textColor: Colors.white,
color: Colors.red,
child: Text('ADD', style: TextStyle(fontSize: 18)),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(12)),
),
onPressed: () {
_addToDoItem(_controller.text);
_controller.clear();
FocusScope.of(context).requestFocus(FocusNode());
},
),
),
),
],
),
),
_buildToDoList()
]),
),
);
}
}

Related

Container not changing color until file is refreshed

I want to change color of container onTap from shade of grey to white and everything works alright in my FeedScreen file but in filter file I need to exit and then go back to see the change even tho i did everything exactly same in FeedScreen and Filter file. i think the problem has something to do with the fact that i enter filter menu from feed screen on tap of the button but im not sure.
this is filter file that doesnt work properly:
class _ExampleState extends State<Example> {
int _selectedindex = 0;
void _onItemTapped(int index) {
setState(() {
_selectedindex = index;
});
}
int index = 0;
var random = Random();
List<Color> myColors = [
Colors.white,
Colors.grey.shade900,
Colors.green,
Colors.cyan,
Colors.pink,
];
void changeColorsIndex() {
setState(() {
index = random.nextInt(4);
});
}
#override
Widget build(BuildContext context) {
Size size = MediaQuery.of(context).size;
return Container(
width: size.width,
height: 40,
color: Color.fromARGB(255, 28, 28, 28),
child: Row(
children: [
Padding(
padding: const EdgeInsets.only(left: 1.5),
child: IconButton(
onPressed: (() {
setState(
() {
showDialog(
context: context,
builder: (BuildContext context) {
return SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Container(
width: size.width,
height: size.height,
child: Scaffold(
backgroundColor: Colors.black,
body: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Padding(
padding: const EdgeInsets.only(bottom: 30),
child: Column(
children: [
Center(
child: Padding(
padding:
const EdgeInsets.only(top: 5),
child: IconButton(
onPressed: () {
Navigator.pop(
context,
MaterialPageRoute(
builder: (context) =>
TopTab(),
),
);
},
icon: const Icon(
Icons.arrow_drop_down),
iconSize: 45,
color: Colors.white,
),
),
),
const Gap(15),
Container(
child: Row(
mainAxisAlignment:
MainAxisAlignment.center,
children: [
InkWell(
onTap: () {
setState(() {
changeColorsIndex();
});
},
child: Container(
width: 199,
height: 50,
color: myColors[index],
child: const Center(
child: Text(
'Men\'s',
style: TextStyle(
fontSize: 14,
fontWeight:
FontWeight.w600,
color: Colors.white),
),
),
),
),
],
),
),
],
),
),
),
),
),
);
},
);
},
);
}),
icon: Icon(Ionicons.options_outline),
iconSize: 20,
color: Colors.white,
),
),
const Gap(6),
Text(
'Filter by size',
style: TextStyle(
color: Colors.grey.shade600,
fontSize: 14,
fontWeight: FontWeight.w700),
),
],
),
);
}
}
and this is FeedScreen file that works normally:
class _FeedScreenState extends State<FeedScreen> {
int index = 0;
var random = Random();
List<Color> myColors = [
Colors.white,
Colors.grey.shade900,
Colors.green,
Colors.cyan,
Colors.pink,
];
void changeColorsIndex() {
setState(() {
index = random.nextInt(4);
});
}
#override
Widget build(BuildContext context) {
Size size = MediaQuery.of(context).size;
return Scaffold(
body: ListView(
children: [
Container(
width: size.width,
height: size.height,
color: Colors.black,
child: Column(
// this column is start of everything and container below is filter part just below app bar
children: [
Example(),
InkWell(
onTap: changeColorsIndex,
child: Container(
width: size.width,
height: 450,
color: myColors[index],
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: const [
Padding(
padding: EdgeInsets.only(top: 15, left: 15),
child: Text(
'Air Force 1 x Premium Goods',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 17,
color: Colors.white),
),
),
Gap(5),
Padding(
padding: EdgeInsets.only(left: 15),
child: Text(
'The Sophia',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 30,
color: Colors.white),
),
),
Gap(50),
Image(
image: AssetImage('assets/AF1xPGmain.png'),
),
],
),
),
),
],
),
)
],
),
);
}
}
i tried with GestureDecoration also even tho its same thing but it just doesnt work
you can add a StatefulBuilder Widget to make your showDialog able to use setState
try it and let me please know if it works
class _ExampleState extends State<Example> {
int _selectedindex = 0;
void _onItemTapped(int index) {
setState(() {
_selectedindex = index;
});
}
int index = 0;
var random = Random();
List<Color> myColors = [
Colors.white,
Colors.grey.shade900,
Colors.green,
Colors.cyan,
Colors.pink,
];
void changeColorsIndex() {
setState(() {
index = random.nextInt(4);
});
}
#override
Widget build(BuildContext context) {
Size size = MediaQuery.of(context).size;
return Container(
width: size.width,
height: 40,
color: Color.fromARGB(255, 28, 28, 28),
child: Row(
children: [
Padding(
padding: const EdgeInsets.only(left: 1.5),
child: IconButton(
onPressed: (() {
setState(
() {
showDialog(
context: context,
builder: (BuildContext context) {
return StatefulBuilder(builder: (context, setState) {
return SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Container(
width: size.width,
height: size.height,
child: Scaffold(
backgroundColor: Colors.black,
body: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Padding(
padding: const EdgeInsets.only(bottom: 30),
child: Column(
children: [
Center(
child: Padding(
padding:
const EdgeInsets.only(top: 5),
child: IconButton(
onPressed: () {
Navigator.pop(
context,
MaterialPageRoute(
builder: (context) =>
TopTab(),
),
);
},
icon: const Icon(
Icons.arrow_drop_down),
iconSize: 45,
color: Colors.white,
),
),
),
const Gap(15),
Container(
child: Row(
mainAxisAlignment:
MainAxisAlignment.center,
children: [
InkWell(
onTap: () {
setState(() {
changeColorsIndex();
});
},
child: Container(
width: 199,
height: 50,
color: myColors[index],
child: const Center(
child: Text(
'Men\'s',
style: TextStyle(
fontSize: 14,
fontWeight:
FontWeight.w600,
color: Colors.white),
),
),
),
),
],
),
),
],
),
),
),
),
),
);
});
},
);
},
);
}),
icon: Icon(Ionicons.options_outline),
iconSize: 20,
color: Colors.white,
),
),
const Gap(6),
Text(
'Filter by size',
style: TextStyle(
color: Colors.grey.shade600,
fontSize: 14,
fontWeight: FontWeight.w700),
),
],
),
);
}
}
you have written different onTap method in the filter file
change
onTap: () {
setState(() {
changeColorsIndex();
});
},
To
onTap: changeColorsIndex,
In filter file wrap your dialog with stateful builder as shown here

data not rendered in the first time

currently i'm trying to implement getx to my app, so far so good, i got the data i wanted but i'm kinda having some trouble when i tried to display the data to the screen.
This is where data supposed to be rendered as a horizontal listview
Home Screen
But apparently the data will only appear if i click the promo section and click back to the home section on bottom navigation.
Home Screen 2
Here is my home_controller.dart
class HomeController extends GetxController {
RxList<Hotels> listHotel = <Hotels>[].obs;
RxList<Province> listProvince = <Province>[].obs;
Future getListHotel() async {
final listHotel = await ApiService.getHotel();
this.listHotel.value = listHotel;
}
Future getListProvince() async {
final listProvince = await ApiService.getProvince();
this.listProvince.value = listProvince;
}
#override
void onInit() {
super.onInit();
getListHotel();
getListProvince();
}
}
and this is my home_screen.dart
Widget build(BuildContext context) {
final homeController = Get.put(HomeController());
final authController = Get.put(AuthController());
final orientation = MediaQuery.of(context).orientation;
return Scaffold(
body: SingleChildScrollView(
child: Builder(builder: (context) {
return Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
SafeArea(
child: Padding(
padding: EdgeInsets.only(
left: 5.w, right: 5.w, top: 100.h <= 667 ? 5.h : 4.h),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Daftar Hotel",
style: TextStyle(
color: const Color(0xffF0B900),
fontSize: 10.sp,
fontWeight: FontWeight.bold),
),
SizedBox(
height: 31.h,
width: orientation == Orientation.landscape
? 100.h
: 100.w,
child: ListView.separated(
shrinkWrap: true,
separatorBuilder: (BuildContext context, int index) {
return SizedBox(
width: 1.h,
);
},
scrollDirection: Axis.horizontal,
itemCount: homeController.listHotel.length,
itemBuilder: (context, i) {
return InkWell(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => HotelDetailScreen(
id: homeController
.listHotel[i].id,
checkin: checkInController.text
.toString(),
checkout: checkOutController.text
.toString(),
)));
},
child: SizedBox(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
width: 70.w,
height: 20.h,
child: ClipRRect(
borderRadius: BorderRadius.circular(20),
child: Image.network(
homeController.listHotel[i].cover,
fit: BoxFit.cover,
),
),
),
Padding(
padding: const EdgeInsets.symmetric(
vertical: 8.0),
child: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Text(
homeController.listHotel[i].name,
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 10.sp),
),
SizedBox(
width: 70.w,
child: Text(
homeController.listHotel[i].address,
maxLines: 2,
style: TextStyle(
fontWeight: FontWeight.w300,
fontSize: 10.sp),
overflow: TextOverflow.clip,
),
)
],
),
),
],
)),
);
},
),
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0),
child: Text(
"Rekomendasi",
style: TextStyle(
color: const Color(0xffF0B900),
fontSize: 10.sp,
fontWeight: FontWeight.bold),
),
),
SizedBox(
height: 25.h,
width: orientation == Orientation.landscape
? 100.h
: 100.w,
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: homeController.listProvince.length,
itemBuilder: (context, i) {
String imageUrl = "http://$CURRENT_URL/image/" +
homeController.listProvince[i].cover;
return InkWell(
onTap: () async {
await launch("https://turu.id/property");
},
child: Padding(
padding: const EdgeInsets.only(right: 8.0),
child: SizedBox(
width: 30.w,
child: Stack(
children: [
SizedBox(
width: 30.w,
height: 25.h,
child: ClipRRect(
borderRadius:
BorderRadius.circular(12),
child: Image.network(
imageUrl,
fit: BoxFit.cover,
),
),
),
Container(
decoration: BoxDecoration(
borderRadius:
BorderRadius.circular(12),
color:
Colors.black.withOpacity(0.2),
),
),
Padding(
padding: EdgeInsets.only(
left: 2.h, bottom: 2.h),
child: Column(
mainAxisAlignment:
MainAxisAlignment.end,
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Text(
homeController
.listProvince[i].name,
style: TextStyle(
color: Colors.white,
fontSize: 10.sp,
fontWeight:
FontWeight.bold),
),
],
),
)
],
),
),
),
);
}),
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0),
child: Text(
"Promo Mantap",
style: TextStyle(
color: const Color(0xffF0B900),
fontSize: 10.sp,
fontWeight: FontWeight.bold),
),
),
],
),
),
),
],
);
}),
),
);
}
also my index.dart (botnav)
class Index extends StatefulWidget {
const Index({Key? key}) : super(key: key);
#override
_IndexState createState() => _IndexState();
}
class _IndexState extends State<Index> {
int _currentIndex = 0;
final List<Widget> _container = [
const HomeScreen(),
const PromoScreen(),
const BookingStatusScreen(),
];
#override
Widget build(BuildContext context) {
return Scaffold(
body: _container[_currentIndex],
bottomNavigationBar: BottomNavigationBar(
selectedItemColor: const Color(0xffF0B900),
unselectedItemColor: const Color(0xffAFAFAF),
currentIndex: _currentIndex,
onTap: (index) {
setState(() {
_currentIndex = index;
});
},
items: const [
BottomNavigationBarItem(
icon: Icon(
Icons.home,
),
label: "Beranda",
),
BottomNavigationBarItem(
icon: Icon(
Icons.price_change_outlined,
),
label: "Promo",
),
BottomNavigationBarItem(
icon: Icon(
Icons.receipt_long_rounded,
),
label: "Transaksi",
),
])
);
}
}
Any help will be appreciated, Thank you.

Flutter Navigator.pop(context) won't work

I have seen many questions about Navigator.pop(context) but I didn't find my answer.
As you can see there are three screens so far. The Navigator.pop(context) works fine in the StoryDetailScreen and turns me back to the MainPage. The problem here with EditStoryScreen page, when I get into it I cant go back to the MainPage, when I click on the IconButton I see a black screen.
main.dart
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return
MultiProvider(
providers: [
ChangeNotifierProvider<Stories>(
create: (_) =>
Stories(),
),
ChangeNotifierProvider<Story>(
create:(ctx) => Story(),
),
],
child: MaterialApp(
title: 'MyShop',
theme: ThemeData(
primarySwatch: Colors.purple,
accentColor: Colors.deepOrange,
fontFamily: 'Lato',
),
home: Mainpage(),
routes: {
StoryDetailScreen.routeName: (ctx) => StoryDetailScreen(),
UserStory.routeName: (ctx) => UserStory(),
EditStoryScreen.routeName: (ctx) => EditStoryScreen(),
}),
);
}
}
Mainpage.dart
class Mainpage extends StatefulWidget {
static const routeName = 'main';
#override
_MainpageState createState() => _MainpageState();
}
class _MainpageState extends State<Mainpage> {
var _showOnlyFav = false;
#override
Widget build(BuildContext context) {
final storyCon = Provider.of<Stories>(context);
return Scaffold(
body: SingleChildScrollView(
child: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage("images/back.jpg"), fit: BoxFit.fill)),
child: Column(children: <Widget>[
SizedBox(
height: 50,
),
Container(
child: Text("Short Stories",
style: TextStyle(
fontSize: 40, backgroundColor: Colors.grey[300])),
Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
child: Row(
children: [
Container(
height: 40,
width: 290,
decoration: BoxDecoration(
color: Colors.grey[300],
border: Border.all(width: 1, color: Colors.black),
borderRadius: BorderRadius.circular(7)
// image: DecorationImage(
// image: AssetImage("images/text.png"))
),
child: Center(
child: Row(
children: [
InkWell(
onTap: () {
Navigator.of(context).pushReplacementNamed(UserStory.routeName);
},
child: Text(
"Edit Stroy",
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.black,
fontSize: 30,
// backgroundColor: Colors.grey[300]),
),
),
),
InkWell(
onTap: () {
Navigator.of(context).pushReplacementNamed(EditStoryScreen.routeName);
},
child:Text(
"Add Stroy",
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.black,
fontSize: 30,
// backgroundColor: Colors.grey[300]),
),
),)
],
),
),
),
],
))),
StorysGrid(_showOnlyFav),
]),
),
),
);
}
}
EditStoryScreen.dart
class EditStoryScreen extends StatefulWidget {
static const routeName = 'edit';
#override
_EditStoryScreenState createState() => _EditStoryScreenState();
}
class _EditStoryScreenState extends State<EditStoryScreen> {
final _storyFocusNode = FocusNode();
final _imgController = TextEditingController();
final _imgFocusNode = FocusNode();
#override
void initState() {
_imgFocusNode.addListener(updateImg);
super.initState();
}
#override
void dispose() {
_imgFocusNode.removeListener(updateImg);
_storyFocusNode.dispose();
_imgController.dispose();
_imgFocusNode.dispose();
super.dispose();
}
void updateImg() {
if (!_imgFocusNode.hasFocus) {
setState(() {});
}
}
// void backToHome(context) {
// Navigator.pushReplacementNamed(BuildContext(), context);
// }
#override
Widget build(BuildContext context) {
return Scaffold(
body: SingleChildScrollView(
child: Container(
height: 650,
color: Colors.white,
child: Column(
children: [
SizedBox(
height: 30,
),
Align(
alignment: Alignment.topLeft,
child: RaisedButton(
child: Icon(Icons.arrow_back_ios),
onPressed: () => Navigator.pop(context)
)),
Padding(
padding: const EdgeInsets.fromLTRB(15, 10, 15, 15),
child: Form(
child: ListView(
shrinkWrap: true,
children: <Widget>[
TextFormField(
decoration: InputDecoration(labelText: "Title"),
textInputAction: TextInputAction.next,
onFieldSubmitted: (_) {
FocusScope.of(context).requestFocus(_storyFocusNode);
},
),
TextFormField(
decoration: InputDecoration(labelText: "Story's text"),
maxLines: 14,
keyboardType: TextInputType.multiline,
focusNode: _storyFocusNode,
),
Row(
children: [
Container(
width: 100,
height: 100,
margin: EdgeInsets.only(top: 8, right: 10),
decoration: BoxDecoration(
border: Border.all(width: 1, color: Colors.grey),
),
child: _imgController.text.isEmpty
? Text("Enter a Url")
: Center(
child: FittedBox(
child: Image.network(
_imgController.text,
),
),
),
),
Container(
width: 200,
child: TextFormField(
decoration: InputDecoration(
labelText: "Image URL",
),
keyboardType: TextInputType.url,
textInputAction: TextInputAction.done,
controller: _imgController,
focusNode: _imgFocusNode,
),
)
],
),
],
),
),
),
],
),
),
),
);
}
}
StoryDetailScreen.dart
class StoryDetailScreen extends StatelessWidget {
// final String title;
// final double price;
// ProductDetailScreen(this.title, this.price);
static const routeName = '/story-detail';
#override
Widget build(BuildContext context) {
final storyId =
ModalRoute.of(context).settings.arguments as String; // is the id!
final loadedStory = Provider.of<Stories>(
context,
listen: false,
).findById(storyId);
return Scaffold(
body: SingleChildScrollView(
child: Container(
width: double.infinity,
// height: 700,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage("images/back1.jpg"), fit: BoxFit.fill)),
// color: Color(0xfffae3d9),
// child: Column(children: <Widget>[
// SizedBox(
// height: 10,
// ),
// Container(
// width: 340,
child:
Column(crossAxisAlignment: CrossAxisAlignment.center, children: [
SizedBox(
height: 50,
),
Align(
alignment: Alignment.topLeft,
child: RaisedButton(
child: Icon(Icons.arrow_back_ios),
onPressed: (){
Navigator.pop(context);
})
),
Card(
elevation: 10,
margin: EdgeInsets.all(10),
child: Text("${loadedStory.title}",
softWrap: false,
textDirection: TextDirection.ltr,
style: TextStyle(
color: Color(0xFF6a2c70),
decorationColor: Colors.black,
fontSize: 25,
fontWeight: FontWeight.bold,
)),
),
SizedBox(height: 30),
Container(
width: double.infinity,
color: Colors.white70,
child: Padding(
padding:
const EdgeInsets.symmetric(vertical: 10, horizontal: 5),
child: Text(
loadedStory.story,
textDirection: TextDirection.rtl,
style: TextStyle(
color: Color(0xFF6a2c70),
decorationColor: Colors.black,
fontSize: 25,
fontWeight: FontWeight.bold,
// fontFamily: "Kufam"),
),
),
),
),
SizedBox(
height: 20,
),
Card(
child: Container(
height: 60,
width: 210,
decoration: BoxDecoration(color: Colors.white60),
child: Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Like(),
]),
),
),
),
// ],
// )
SizedBox(
height: 30,
)
]),
)
// ]
,
),
// ),
// ),
);
}
}
You're invoking
Navigator.of(context).pushReplacementNamed(UserStory.routeName)
so this is removing your Mainpage from the navigation stack and replacing it with UserStory, which is why when you call Navigator.pop(context), there's nothing to go back to and all you get is a black screen.
Change it to Navigator.of(context).pushNamed(UserStory.routeName).
You have to define the Mainpage route as well in the routes.

how to create add minus button on my product in flutter?

May I know how to create a function that displays the value and have the button remove and add to the product list? I already create an icon button for remove and add to the screen but I do not have any clues on how to use the button.
GUI on application:
my aim is to have this kind of button:
my full code for this GUI:
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:flutter/material.dart';
import 'CartList.dart';
import 'bottom_navi_iconW.dart';
import 'globals.dart' as globals;
class SarapanPagi extends StatefulWidget {
final List list;
final int index;
final String category;
SarapanPagi({this.index,this.list,this.category});
#override
_SarapanPagiState createState() => _SarapanPagiState();
}
class _SarapanPagiState extends State<SarapanPagi> {
Future<List> getData() async{
var url = 'http://10.0.2.2/foodsystem/breakfastlist.php';
var data = {
'product_type': globals.jenisCategory,
'product_owner': widget.list[widget.index]['restaurant_id'],
};
var response = await http.post(url, body: json.encode(data));
//final response= await http.get("http://10.0.2.2/foodsystem/getdata.php");
return json.decode(response.body);}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
iconTheme: IconThemeData(color: Colors.black),
title: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
//Text("Restaurant's Owner Page"),
Text(widget.list[widget.index]['restaurant_name'], textAlign: TextAlign.center, style: TextStyle(fontWeight: FontWeight.w700), ),
],
),
centerTitle: false,
//automaticallyImplyLeading: false,
),
body:
Padding(
padding: const EdgeInsets.only(bottom: 0, left: 5, right: 5),
child: Column(
children: [
/*FloatingActionButton(
onPressed: (){
return showDialog(
context: context,
builder: (context){
return AlertDialog(
content: Text(
globals.jenisCategory
),
);
},
);
},
),*/
//SizedBox(height: 30,),
Container(
//decoration: BoxDecoration(border: Border.all(color: Colors.black, width: 4), borderRadius: BorderRadius.circular(15)),
height: 627,
child: FutureBuilder<List>(
future: getData(),
builder: (context, snapshot){
if(snapshot.hasError) print(snapshot.error);
return snapshot.hasData ?
ItemList(list: snapshot.data,) :
Center(child: CircularProgressIndicator(),);
},
),
),
],
),
),
bottomNavigationBar:
Container(
height: 70,
color: Colors.red,
child: BottomNavIcon(
onTap: (){
Navigator.of(context).push(new MaterialPageRoute(
builder: (BuildContext context)=> new CartListItem()),);
},
image: "troli.png",
name: "CART",
),
),
);
}
}
class ItemList extends StatelessWidget {
final List list;
ItemList({this.list});
#override
Widget build(BuildContext context) {
return SingleChildScrollView(
child: Container(
//color: Colors.red.shade100,
height: 627,
child: ListView.builder(
itemCount: list==null ? 0 : list.length,
itemBuilder: (context, i){
return new Container(
//decoration: BoxDecoration(border: Border.all(color: Colors.blue, width: 4), borderRadius: BorderRadius.circular(15)),
height: 250,
child: new GestureDetector(
onTap: (){},
child: new Card(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Column(
children: [
Padding(
padding: const EdgeInsets.only(bottom : 5.0),
child: Text(list[i]["product_name"], textAlign: TextAlign.center, style: TextStyle(fontSize: 23, fontWeight: FontWeight.bold),),
),
Row(
children: [
//Text(list[i]["product_name"], textAlign: TextAlign.center, style: TextStyle(fontSize: 30),),
Padding(
padding: const EdgeInsets.all(8.0),
child: Image.asset(
"menulist/${list[i]['image']}",
width: 150,
height: 150,
),
),
Padding(
padding: const EdgeInsets.only(left: 20.0, bottom: 0),
child:
Column(
children: [
//Text(list[i]["product_name"], textAlign: TextAlign.center, style: TextStyle(fontSize: 30),),
Text("Price RM : ${list[i]["product_price"]}", textAlign: TextAlign.center, style: TextStyle(fontSize: 25),),
Row(
children: [
IconButton(
icon: Icon(Icons.remove),
onPressed: (){},
iconSize: 15,
),
IconButton(
icon: Icon(Icons.add),
onPressed: (){},
iconSize: 15,
),
],
),
RaisedButton(
shape: RoundedRectangleBorder(borderRadius: new BorderRadius.circular(40.0)),
color: Colors.red.shade300,
child: Text("Add to Cart", style: TextStyle(fontWeight: FontWeight.bold),),
onPressed: (){},
)
],
),
),
],
),
],
),
/*ListTile(
title: Text(list[i]["product_name"], textAlign: TextAlign.center, style: TextStyle(fontSize: 30),),
leading:
Image.asset(
"images/${list[i]['image']}",
width: 100,
height: 100,
),
subtitle: Text("Price RM : ${list[i]["product_price"]}", textAlign: TextAlign.center, style: TextStyle(fontSize: 25),),
),*/
],
),
),
),
);
},
),
),
);
}
}
First of all you need to change it to StatefulWidget, since the UI interaction is rendered (changed price). Then something like
onPressed: () => setState(() => list[i]["product_price"] += unitprice),
will do

How to put searchBar into appBar - Flutter?

I'm having trouble placing my search bar in the AppBar,
right now my searchBar is below my AppBar, I tried use another Container into my AppBar but without success.
My code:
class _HomePageState extends State<HomePage> {
#override
Widget build(BuildContext context) {
return MaterialApp(
home:Scaffold(
appBar: PreferredSize(
preferredSize: Size.fromHeight(100.0),
child: AppBar(
iconTheme: IconThemeData(color: Color.fromRGBO(9, 133, 46, 100)),
backgroundColor: Colors.white,
actions: <Widget>[
IconButton(
icon: Icon(
Icons.shopping_cart,
color: Color.fromRGBO(9, 133, 46, 100),
),
onPressed: (){
print('klikniete');
},
),
],
),
),
body: Builder(
builder: (context) => Container(
child: FutureBuilder(
future: fetchOrders(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (_ordersForDisplay.length == null) {
return Container(
child: Center(child: Text("Ładowanie...")),
);
} else {
return ListView.builder(
itemCount: _ordersForDisplay.length + 1,
itemBuilder: (BuildContext context, int index) {
return index == 0 ? _searchBar() : _listItem(index - 1);
},
);
}
},
),
),
),
)
);
}
_searchBar() {
return Padding(
padding: const EdgeInsets.all(8.0),
child: TextField(
decoration: InputDecoration(
hintText: 'Wyszukaj po mieście...'
),
onChanged: (text) {
text = text.toLowerCase();
setState(() {
_ordersForDisplay = _orders.where((note) {
var noteTitle = note.city.toLowerCase();
return noteTitle.contains(text);
}).toList();
});
},
),
);
}
_listItem(index) {
return GestureDetector(
onTap: () => Navigator.of(context).push(
MaterialPageRoute(builder: (context) => DetailPage(item: _ordersForDisplay[index])),
),
child: Card(
child: Padding(
padding: const EdgeInsets.only(
top: 32.0, bottom: 32.0, left: 16.0, right: 16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
_ordersForDisplay[index].firstName,
style: TextStyle(fontSize: 22, fontWeight: FontWeight.bold),
),
Text(
_ordersForDisplay[index].lastName,
style: TextStyle(
color: Colors.grey.shade600
),
),
],
),
),
),
);
}
}
i'm put searchBar into my appBar by use title: _searchBar, next I remove
return index == 0 ? _searchBar() : _listItem(index - 1); and paste only return _listItem(index, context), but right now i have error: RangeError (index): Invalid value: Only valid value is 0: 1
Are you expecting to this
OR this?
Code:
class CustomSearchBarDemo extends StatefulWidget {
#override
_CustomSearchBarDemoState createState() => _CustomSearchBarDemoState();
}
class _CustomSearchBarDemoState extends State<CustomSearchBarDemo> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
elevation: 0.0,
backgroundColor: Colors.white,
title: Text("Search",style: TextStyle(color: Colors.black),),
centerTitle: true,
bottom: PreferredSize(
preferredSize: Size.fromHeight(kToolbarHeight),
child: Container(
// padding: const EdgeInsets.all(8),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Colors.grey[300],
),
child: Padding(
padding: const EdgeInsets.all(5.0),
child: Material(
color: Colors.grey[300],
child: Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Icon(Icons.search,color: Colors.grey),
Expanded(
child: TextField(
// textAlign: TextAlign.center,
decoration: InputDecoration.collapsed(
hintText: ' Search by name or address',
),
onChanged: (value) {
},
),
),
InkWell(
child: Icon(Icons.mic,color: Colors.grey,),
onTap: () {
},
)
],
),
),
)
) ,
),
),
);
}
}
OR
class CustomSearchBarDemo extends StatefulWidget {
#override
_CustomSearchBarDemoState createState() => _CustomSearchBarDemoState();
}
class _CustomSearchBarDemoState extends State<CustomSearchBarDemo> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar:
PreferredSize(
preferredSize: Size.fromHeight(kToolbarHeight),
child: Container(
padding: const EdgeInsets.only(top:20),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Colors.grey[300],
),
child: Padding(
padding: const EdgeInsets.all(5.0),
child: Material(
color: Colors.grey[300],
child: Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Icon(Icons.search,color: Colors.grey),
Expanded(
child: TextField(
// textAlign: TextAlign.center,
decoration: InputDecoration.collapsed(
hintText: ' Search by name or address',
),
onChanged: (value) {
},
),
),
InkWell(
child: Icon(Icons.mic,color: Colors.grey,),
onTap: () {
},
)
],
),
),
)
) ,
),
);
}
}
You can basically add any widget in the title property of appbar.
AppBar(
title: TextField(
autofocus: true,
decoration: InputDecoration(
hintText: " Search...",
border: InputBorder.none,
suffixIcon: IconButton(icon:Icon(Icons.search), onPressed: () {
},)
),
style: TextStyle(color: Colors.white, fontSize: 14.0),
),
iconTheme: IconThemeData(color: Color.fromRGBO(9, 133, 46, 100)),
backgroundColor: Colors.white,
actions: <Widget>[
IconButton(
icon: Icon(
Icons.shopping_cart,
color: Color.fromRGBO(9, 133, 46, 100),
),
onPressed: (){
print('klikniete');
},
),
],
),