The getter 'visible' was called on null - flutter

I am trying to create a page that consist of Search Bar, Infinite scroll product page and buttons (add product, remove product and notification). There is an error for the below statement...
The getter 'visible' was called on null,
Receiver : null,
Tried calling : null
please help me in rectifying this code.
class Inventory extends StatefulWidget {
#override
_InventoryState createState() => _InventoryState();
}
class _InventoryState extends State<Inventory> {
Color _color = Colors.white;
#override
Widget build(BuildContext context) {
double width = MediaQuery.of(context).size.width;
double height = MediaQuery.of(context).size.height;
return Scaffold(
resizeToAvoidBottomInset: false,
appBar: PreferredSize(
preferredSize: Size.fromHeight(70),
child: AppBar(
backgroundColor: Theme.Colors.darkBlue,
iconTheme: IconThemeData(size: 10, color: Colors.white),
elevation: 0,
title: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
AutoSizeText(
"Inventory ",
style: TextStyle(
fontSize: 35,
),
),
],
)),
),
drawer: MainDrawer(),
backgroundColor: Color(0xFF09182C),
body: Center(
child: Column(
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Container(
height: 70,
width: width * 0.76,
child: TextField(
decoration: InputDecoration(
contentPadding: EdgeInsets.all(10.0),
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.white),
),
hintText: 'Search Inventory',
hintStyle:
TextStyle(color: Color(0xFFE0E0E0), fontSize: 20),
suffixIcon: Icon(
Icons.search,
color: Colors.white,
size: 30,
)),
style: TextStyle(color: _color),
),
),
Container(
padding: EdgeInsets.only(bottom: 30.0),
child: IconButton(
onPressed: () {},
icon: Icon(Icons.filter_list,
size: 40, color: Color(0xFFFFAE40)),
),
),
],
),
LoadingPage(),
Spacer(),
Container(
margin: EdgeInsets.only(bottom: 70),
padding: EdgeInsets.only(left: 30, right: 30),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Material(
type: MaterialType.transparency,
child: Ink(
decoration: BoxDecoration(
border:
Border.all(color: Color(0xFF57D0F4), width: 2.0),
color: Colors.transparent,
shape: BoxShape.circle,
),
child: InkWell(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => AddProduct()),
);
},
child: Padding(
padding: EdgeInsets.all(13.0),
child: Icon(
Icons.add,
size: 55.0,
color: Color(0xFF57D0F4),
),
),
),
),
),
Material(
type: MaterialType.transparency,
child: Ink(
decoration: BoxDecoration(
border:
Border.all(color: Color(0xFF57D0F4), width: 2.0),
color: Colors.transparent,
shape: BoxShape.circle,
),
child: InkWell(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => RemoveProduct()),
);
},
child: Padding(
padding: EdgeInsets.all(13.0),
child: Icon(
Icons.delete_outline,
size: 55.0,
color: Color(0xFF57D0F4),
),
),
),
),
),
Material(
type: MaterialType.transparency,
child: Ink(
decoration: BoxDecoration(
border:
Border.all(color: Color(0xFF57D0F4), width: 2.0),
color: Colors.transparent,
shape: BoxShape.circle,
),
child: InkWell(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Notify()),
);
},
child: Padding(
padding: EdgeInsets.all(13.0),
child: Icon(
Icons.notifications_none,
size: 55.0,
color: Color(0xFF57D0F4),
),
),
),
),
),
],
),
)
],
),
));
}
}
class LoadingPage extends StatefulWidget {
#override
_LoadingPageState createState() => _LoadingPageState();
}
class _LoadingPageState extends State<LoadingPage> {
List prd;
ScrollController _scrollController = ScrollController();
int _currentMax = 10;
#override
void initState() {
super.initState();
prd = List.generate(10, (i) => "Product ${i + 1}");
_scrollController.addListener(() {
if (_scrollController.position.pixels ==
_scrollController.position.maxScrollExtent) {
_getMoreData();
}
});
}
_getMoreData() {
for (int i = _currentMax; i < _currentMax + 10; i++) {
return prd.add("Product ${i + 1}");
}
_currentMax = _currentMax + 10;
setState(() {});
}
#override
Widget build(BuildContext context) {
return ListView.builder(
controller: _scrollController,
itemCount: prd.length + 1,
itemExtent: 70,
itemBuilder: (context, i) {
if (i == prd.length) {
return CupertinoActivityIndicator();
}
return ListTile(
title: AutoSizeText(prd[i]),
);
});
}
}

Thanks for your help #Mobina and #JohnJoe.
I wrapped the ListView.builder with Flexible which fixed the problem and added COntainer to put it inside a greyish background.
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.only(top: 10.0, bottom: 10.0),
height: 450,
width: 350,
decoration: BoxDecoration(
color: Color(0xFF707070),
borderRadius: BorderRadius.all(
Radius.circular(
10.0,
),
)),
child: Flexible(
child: ListView.builder(
controller: _scrollController,
itemCount: prd.length + 1,
itemExtent: 42.5,
itemBuilder: (context, i) {
if (i == prd.length) {
return CupertinoActivityIndicator();
}
return ListTile(
title: AutoSizeText(prd[i]),
);
}),
),
);
}

Related

The method 'userLogin' isn't defined for the type 'BottomSheet'

I have this error in the onPressed :() function of the login: The method 'userLogin' is not defined for the type 'BottomSheet'.
Could anyone help me solve? Thank you.
CustomButton(
label: "LOGIN",
primaryColor: Theme.of(context).primaryColor,
secondaryColor: Colors.white,
onPressed: () => {
// Validate returns true if the form is valid, or false otherwise.
if (_formKey.currentState.validate()) {
userLogin()}
},
),
Here is the complete code:
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:login_ui/home2.dart';
import 'clipper.dart';
class Home extends StatefulWidget {
#override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
TextEditingController _emailController,
_passwordController,
_nameController = TextEditingController();
//
bool _visible = false;
Future userLogin() async {
//Login API URL
//use your local IP address instead of localhost or use Web API
String url = "https://www.toptradeitaly.com/login_api/user_login.php";
// Showing LinearProgressIndicator.
setState(() {
_visible = true;
});
// Getting username and password from Controller
var data = {
'username': _emailController.text,
'password': _passwordController.text,
};
//Starting Web API Call.
var response = await http.post(url, body: json.encode(data));
if (response.statusCode == 200) {
//Server response into variable
print(response.body);
var msg = jsonDecode(response.body);
//Check Login Status
if (msg['loginStatus'] == true) {
setState(() {
//hide progress indicator
_visible = false;
});
// Navigate to Home Screen
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
HomePage(uname: msg['userInfo']['NAME'])));
} else {
setState(() {
//hide progress indicator
_visible = false;
//Show Error Message Dialog
showMessage(msg["message"]);
});
}
} else {
setState(() {
//hide progress indicator
_visible = false;
//Show Error Message Dialog
showMessage("Error during connecting to Server.");
});
}
}
Future<dynamic> showMessage(String _msg) {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: new Text(_msg),
actions: <Widget>[
TextButton(
child: new Text("OK"),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
//
#override
Widget build(BuildContext context) {
//GO logo widget
Widget logo() {
return Padding(
padding:
EdgeInsets.only(top: MediaQuery.of(context).size.height * 0.15),
child: Container(
width: MediaQuery.of(context).size.width,
height: 220,
child: Stack(
children: <Widget>[
Positioned(
child: Container(
child: Align(
child: Container(
decoration: BoxDecoration(
shape: BoxShape.circle, color: Colors.white),
width: 150,
height: 150,
),
),
height: 154,
)),
Positioned(
child: Container(
height: 154,
child: Align(
child: Text(
"GO",
style: TextStyle(
fontSize: 120,
fontWeight: FontWeight.bold,
color: Theme.of(context).primaryColor,
),
),
)),
),
Positioned(
width: MediaQuery.of(context).size.width * 0.15,
height: MediaQuery.of(context).size.width * 0.15,
bottom: MediaQuery.of(context).size.height * 0.046,
right: MediaQuery.of(context).size.width * 0.22,
child: Container(
decoration: BoxDecoration(
shape: BoxShape.circle, color: Colors.white),
),
),
Positioned(
width: MediaQuery.of(context).size.width * 0.08,
height: MediaQuery.of(context).size.width * 0.08,
bottom: 0,
right: MediaQuery.of(context).size.width * 0.32,
child: Container(
decoration: BoxDecoration(
shape: BoxShape.circle, color: Colors.white),
),
),
],
),
),
);
}
void _loginSheet(context) {
showBottomSheet<void>(
context: context,
builder: (BuildContext context) {
return BottomSheet(
emailController: _emailController,
passwordController: _passwordController,
);
},
);
}
void _registerSheet(context) {
showBottomSheet<void>(
context: context,
builder: (BuildContext context) {
return BottomSheet(
emailController: _emailController,
passwordController: _passwordController,
nameController: _nameController,
);
},
);
}
return Scaffold(
resizeToAvoidBottomInset: false,
backgroundColor: Theme.of(context).primaryColor,
body: Builder(builder: (context) {
return Column(
children: <Widget>[
logo(),
Padding(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
CustomButton(
label: "LOGIN",
primaryColor: Colors.white,
secondaryColor: Theme.of(context).primaryColor,
onPressed: () => _loginSheet(context),
),
SizedBox(height: 20),
CustomButton(
label: "REGISTER",
primaryColor: Theme.of(context).primaryColor,
secondaryColor: Colors.white,
onPressed: () => _registerSheet(context),
),
],
),
padding: EdgeInsets.only(top: 80, left: 20, right: 20),
),
Expanded(
child: Align(
child: ClipPath(
child: Container(
color: Colors.white,
height: 300,
),
clipper: BottomWaveClipper(),
),
alignment: Alignment.bottomCenter,
),
)
],
crossAxisAlignment: CrossAxisAlignment.stretch,
);
}),
);
}
}
class CustomButton extends StatelessWidget {
final Color primaryColor;
final Color secondaryColor;
final String label;
final Function() onPressed;
const CustomButton({
Key key,
this.primaryColor,
this.secondaryColor,
#required this.label,
this.onPressed,
}) : super(key: key);
#override
Widget build(BuildContext context) {
return SizedBox(
height: 50,
width: double.infinity,
child: RaisedButton(
highlightElevation: 0.0,
splashColor: secondaryColor,
highlightColor: primaryColor,
elevation: 0.0,
color: primaryColor,
shape: RoundedRectangleBorder(
borderRadius: new BorderRadius.circular(30.0),
side: BorderSide(color: Colors.white, width: 3)),
child: Text(
label,
style: TextStyle(
fontWeight: FontWeight.bold, color: secondaryColor, fontSize: 20),
),
onPressed: onPressed,
),
);
}
}
class CustomTextField extends StatelessWidget {
final Icon icon;
final String hint;
final TextEditingController controller;
final bool obsecure;
const CustomTextField({
this.controller,
this.hint,
this.icon,
this.obsecure,
Key key,
}) : super(key: key);
#override
Widget build(BuildContext context) {
return TextField(
controller: controller,
obscureText: obsecure ?? false,
style: TextStyle(
fontSize: 20,
),
decoration: InputDecoration(
hintStyle: TextStyle(fontWeight: FontWeight.bold, fontSize: 20),
hintText: hint,
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(30),
borderSide: BorderSide(
color: Theme.of(context).primaryColor,
width: 2,
),
),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(30),
borderSide: BorderSide(
color: Theme.of(context).primaryColor,
width: 3,
),
),
prefixIcon: Padding(
child: IconTheme(
data: IconThemeData(color: Theme.of(context).primaryColor),
child: icon,
),
padding: EdgeInsets.only(left: 30, right: 10),
)),
);
}
}
//
final _formKey = GlobalKey<FormState>();
//
class BottomSheet extends StatelessWidget {
const BottomSheet({
Key key,
#required TextEditingController emailController,
#required TextEditingController passwordController,
TextEditingController nameController,
}) : _emailController = emailController,
_passwordController = passwordController,
_nameController = nameController,
super(key: key);
final TextEditingController _emailController;
final TextEditingController _passwordController;
final TextEditingController _nameController;
List<Widget> get _registerLogo => [
Positioned(
child: Container(
padding: EdgeInsets.only(bottom: 25, right: 40),
child: Text(
"REGI",
style: TextStyle(
fontSize: 38,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
alignment: Alignment.center,
),
),
Positioned(
child: Align(
child: Container(
padding: EdgeInsets.only(top: 40, left: 28),
width: 130,
child: Text(
"STER",
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.white,
fontSize: 38),
),
),
alignment: Alignment.center,
),
),
];
List<Widget> get _loginLogo => [
Align(
alignment: Alignment.center,
child: Container(
child: Text(
"LOGIN",
style: TextStyle(
fontSize: 42,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
alignment: Alignment.center,
),
),
];
#override
Widget build(BuildContext context) {
return DecoratedBox(
decoration: BoxDecoration(color: Theme.of(context).canvasColor),
child: ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(40.0), topRight: Radius.circular(40.0)),
child: Container(
child: ListView(
children: <Widget>[
Container(
child: Stack(
children: <Widget>[
Positioned(
left: 10,
top: 10,
child: IconButton(
onPressed: () {
Navigator.of(context).pop();
_emailController.clear();
_passwordController.clear();
_nameController?.clear();
},
icon: Icon(
Icons.close,
size: 30.0,
color: Theme.of(context).primaryColor,
),
),
)
],
),
height: 50,
width: 50,
),
//
Form(
key: _formKey,
child:
//
SingleChildScrollView(
child: Padding(
padding: EdgeInsets.only(left: 20, right: 20),
child: Column(
children: <Widget>[
Container(
width: MediaQuery.of(context).size.width,
height: 140,
child: Stack(
children: <Widget>[
Align(
child: Container(
width: 130,
height: 130,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Theme.of(context).primaryColor),
),
alignment: Alignment.center,
),
..._nameController != null
? _registerLogo
: _loginLogo
],
),
),
SizedBox(height: 60),
if (_nameController != null)
CustomTextField(
controller: _nameController,
hint: "NAME",
icon: Icon(Icons.person),
),
SizedBox(height: 20),
CustomTextField(
controller: _emailController,
hint: "EMAIL",
icon: Icon(Icons.email),
),
SizedBox(height: 20),
CustomTextField(
controller: _passwordController,
hint: "PASSWORD",
icon: Icon(Icons.lock),
obsecure: true,
),
SizedBox(height: 20),
if (_nameController != null)
CustomButton(
label: "REGISTER",
primaryColor: Theme.of(context).primaryColor,
secondaryColor: Colors.white,
onPressed: () {},
),
SizedBox(height: 20),
if (_nameController == null)
CustomButton(
label: "LOGIN",
primaryColor: Theme.of(context).primaryColor,
secondaryColor: Colors.white,
onPressed: () => {
// Validate returns true if the form is valid, or false otherwise.
if (_formKey.currentState.validate()) {
userLogin()}
},
),
SizedBox(height: 20),
],
),
),
),),
],
),
height: MediaQuery.of(context).size.height / 1.1,
width: MediaQuery.of(context).size.width,
color: Colors.white,
),
),
);
}
}

Pixel Overflow Problem While Opening the Keyboard

For the following code, I am getting a pixel overflow whenever I am trying to open the keyboard to search for something in the search bar.
I cannot remove the container having the specified height of 500 because doing so produces other errors.
import 'package:chatapp/services/database.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
class Search extends StatefulWidget {
_Search createState() => _Search();
}
class _Search extends State<Search> {
QuerySnapshot<Map<String, dynamic>>? searchResultSnapshot;
bool isLoading = false;
bool haveUserSearched = false;
DatabaseMethods databaseMethods = new DatabaseMethods();
var searchEditingController = TextEditingController();
InitiateSearch() async {
if (searchEditingController.text.isNotEmpty) {
setState(() {
isLoading = true;
});
await databaseMethods.GetUserByUsername(searchEditingController.text)
.then((snapshot) {
searchResultSnapshot = snapshot;
print("$searchResultSnapshot");
setState(() {
isLoading = false;
haveUserSearched = true;
});
});
}
}
Widget UserList() {
return Container(
height: 500,
child: isLoading
? Container(
child: Center(
child: CircularProgressIndicator(),
),
)
: ListView.builder(
itemCount: searchResultSnapshot?.docs.length ?? 0,
itemBuilder: (context, index) {
return ListTile(
searchResultSnapshot?.docs[index].data()["userName"],
searchResultSnapshot?.docs[index].data()["userEmail"],
);
}),
);
}
Widget ListTile(String? userName, String? userEmail) {
return Container(
padding: EdgeInsets.symmetric(horizontal: 24, vertical: 16),
child: Row(
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
userName ?? "",
style: TextStyle(color: Colors.white, fontSize: 16),
),
Text(
userEmail ?? "",
style: TextStyle(color: Colors.white, fontSize: 16),
)
],
),
Spacer(),
GestureDetector(
onTap: () {
null;
},
child: Container(
padding: EdgeInsets.symmetric(horizontal: 12, vertical: 8),
decoration: BoxDecoration(
color: Colors.redAccent,
borderRadius: BorderRadius.circular(24)),
child: Text(
"Message",
style: TextStyle(color: Colors.white, fontSize: 16),
),
),
)
],
),
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.transparent,
titleSpacing: 0,
leading: Builder(
builder: (BuildContext context) {
return IconButton(
icon: const Icon(
Icons.arrow_back_ios,
color: Colors.white,
),
onPressed: () {
Navigator.pop(context);
});
},
),
title: Text('Search'),
),
body: Padding(
padding: const EdgeInsets.all(15.0),
child: Column(
children: [
Container(
height: 36,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(10)),
boxShadow: [
BoxShadow(
color: Colors.black,
),
BoxShadow(
color: Colors.black,
spreadRadius: -12.0,
blurRadius: 12.0,
),
],
),
margin: EdgeInsets.symmetric(horizontal: 10.0, vertical: 8.0),
child: Padding(
padding:
const EdgeInsets.symmetric(vertical: 0, horizontal: 10.0),
child: TextFormField(
style: TextStyle(color: Colors.black),
controller: searchEditingController,
decoration: InputDecoration(
border: InputBorder.none,
hintText: 'Search',
hintStyle: TextStyle(color: Colors.grey),
icon: GestureDetector(
onTap: () {
InitiateSearch();
},
child: GestureDetector(
onTap: () {
InitiateSearch();
print('tap');
},
child: Icon(
Icons.search,
color: Colors.grey,
),
),
),
suffixIcon: IconButton(
onPressed: searchEditingController.clear,
icon: Icon(
Icons.cancel_rounded,
color: Colors.grey,
),
),
),
),
),
), //Search
SizedBox(
height: 12,
),
UserList(),
],
),
));
}
}
Could anyone solve this? Also are there anyways to make the container height dynamic. Your help will be highly appreciated.
Okay I found the solution myself. Under UserList() I replaced:
return Container(...);
with:
return Expanded(...);

when using SingleChildScrollView can't drag down botttom sheet

I've created an app with bottomsheet and listview builder.In the bottom, there is a text button when I drag it up bottom sheet must appear. There is a form in that bottom sheet. I wrap bottom sheet with SingleChildScrollView. But when I click TextFormField key board appear and I can scroll the bottom sheet. But I can't drag it down and close the bottom sheet. Even when I press back arrow in the phone to get rid of the key board.
import 'package:flutter/material.dart';
class Home extends StatefulWidget {
const Home({Key key}) : super(key: key);
#override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
#override
Widget build(BuildContext context) {
var width = MediaQuery.of(context).size.width;
return Scaffold(
resizeToAvoidBottomInset: false,
body: Stack(
children: [
ListView.builder(
itemCount: 1,
itemBuilder: (context, index) {
return Card(
);
}),
Positioned(
bottom: 0,
child: GestureDetector(
onPanEnd: (details) {
if (details.velocity.pixelsPerSecond.dy < 10) {
//Bottom Sheet.................................................................................................................
showModalBottomSheet(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(
top: Radius.circular(25)),
),
backgroundColor: Colors.green,
context: context,
builder: (context) {
return SingleChildScrollView(
child: Container(
padding: EdgeInsets.all(10),
child: Form(
child: Column(
children: [
Icon(Icons.arrow_drop_down),
Text("Drag down to Close"),
Container(
color: Colors.red,
child: Column(
children: [
Row(
children: [
Expanded(
child: TextFormField(
decoration: InputDecoration(
labelText: "Current amount",
),
),
),
],
),
Row(
children: [
Expanded(
child: TextButton(
onPressed: () {},
child: Text("Submit"))),
],
),
],
),
),
],
)),
),
);
});
// Bottom Sheet Ends ......................................................................................................................................................
}
},
child: Container(
color: Colors.blue,
width: width,
padding: EdgeInsets.all(10),
child: Column(
children: [
Icon(Icons.arrow_drop_up),
Text("Drag up to Enter an Account"),
],
),
),
),
)
]),
);
}
}
brother create your model bottom sheet in seprate widget its will open when you click and sceond wrap singlechild scroll view with bottom model sheet.
showModalBottomSheet(
enableDrag: true,
isDismissible: false,
isScrollControlled: true,
)
and complete example of bottom sheet
Widget updatebottomSheet()
{
Size size = MediaQuery.of(context).size;
showModalBottomSheet(
enableDrag: false,
isDismissible: false,
isScrollControlled: true,
context: context,
builder:(context)
{
return GestureDetector(
behavior: HitTestBehavior.opaque,
child: SingleChildScrollView(
child: Container(
padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom+10),
// height: size.height*0.6,
decoration: BoxDecoration(
color: Colors.white,
),
child: Column(
children: [
Padding(
padding: const EdgeInsets.all(25.0),
child: Container(
decoration: BoxDecoration(
//color: Colors.red,
borderRadius: BorderRadius.circular(20),
),
height: size.height*0.5,
width: double.infinity,
child: Card(
elevation: 4,
child: Padding(
padding: const EdgeInsets.all(12.0),
child: Form(
key: _formKey,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
NameField(
name:sectionname,
controller: null,
icon: Icons.person,
hintText: "Please enter section name",
text: "you not enter Smaster",
onchanged: (value)
{
setState(() {
Administrative.instance.SectionName=value;
});
},
),
NameField(
controller:null,
name:smaster,
icon: Icons.vpn_key_outlined,
hintText: "Please enter Section Smaster",
text: "your enter empty Smaster",
onchanged: (value)
{
setState(() {
Administrative.instance.Smaster=value;
});
},
),
],
),
),
),
),
),
),
Padding(
padding: const EdgeInsets.only(left: 20.0,right: 20.0,top: 8.0,bottom: 8.0),
child: Container(
width: double.infinity,
height: 60,
child: FlatButton(
color: Colors.black,
onPressed: (){
if(!_formKey.currentState.validate()){
return;
}
else
{
_formKey.currentState.save();
// signupauth.instance.addstudent();
if(Administrative.instance.SectionName==null)
{
Administrative.instance.SectionName=sectionname;
}
else if(Administrative.instance.Smaster==null)
{
Administrative.instance.Smaster=smaster;
}
print("hello"+ids);
FirebaseFirestore.instance
.collection("Section")
.doc(ids).update({
"SectionName":Administrative.instance.SectionName,
"Smaster":Administrative.instance.Smaster,
});
Fluttertoast.showToast(
msg: "Section is added",
toastLength: Toast.LENGTH_LONG,
gravity: ToastGravity.CENTER,
timeInSecForIosWeb: 1,
backgroundColor: Colors.grey,
textColor: Colors.white,
fontSize: 16.0
);
Navigator.pop(context);
}
},
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
child: Text("Save",style: TextStyle(color: Colors.white,fontSize: 18,fontWeight: FontWeight.bold),),
),
),
),
Padding(
padding: const EdgeInsets.only(left: 20.0,right: 20.0,top: 8.0,bottom: 8.0),
child: Container(
width: double.infinity,
height: 60,
child: FlatButton(
color: Colors.black,
onPressed: (){
Navigator.pop(context);
},
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
child: Text("Cancel",style: TextStyle(color: Colors.white,fontSize: 18,fontWeight: FontWeight.bold),),
),
),
),
],
),
),
),
);
}
);
}

How to edit a selected item from a list in flutter

I have been trying to add an edit function to my to do list in which a user can select the item the user wants to edit, then that should pop a dialog where there is a textfield to enter the new value of the selected item and a Button that saves the changes. Currently I have a function that calls the array where the tasks are stored then it is supposed to triger the selected item using index so that at the end that selected value could be given a new value when onPressed, see this edit functionality as instagrams one except it edits text.
The problem comes when calling that function into the dialog's edit button because I am doing it like this onPressed: () => _editToDoItem(_controller.text, index) and since I have to pass 2 parameters there, the error I am getting is Undefined name 'index'. How can this problem be solved to make this edit function work?. By the way, I haven't get to try the edit function because of this error so please correct me if the function or any part of the code is incorrect.
everything to do with the edit function below.
List<ToDoElement> _toDoItems = [];
TextEditingController _controller = TextEditingController();
// this function adds a task to the list
void _addToDoItem(String task) {
if(task.isNotEmpty) {
setState(() {
_toDoItems.add(ToDoElement(task, DateTime.now()));
});
}
}
// this is the function that is supposed to edit the selected index from the _toDoItems array
void _editToDoItem(String newText, int index) {
setState(() {
_toDoItems[index].task = newText;
});
}
_editDialog(BuildContext context) {
return showDialog(context: context, builder: (context) {
return Dialog(
child: Container(
height: 180,
width: 100,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
height: 60,
child: TextField(
controller: _controller,
autofocus: true,
style: TextStyle(fontSize: 18,),
)
),
Container(
height: 65,
width: double.infinity,
margin: EdgeInsets.only(top: 5,),
child: RaisedButton(
textColor: Colors.white,
color: Colors.red,
child: Text('EDIT'),
onPressed: () {
_editToDoItem(_controller.text, index); // error on index, Undefined name 'index'
FocusScope.of(context).requestFocus(FocusNode());
},
),
),
],
),
),
);
});
}
full main.dart file
class ToDoElement {
String task;
final DateTime timeOfCreation;
ToDoElement(this.task, this.timeOfCreation);
}
void main() => runApp(MaterialApp(home: MyApp()));
class MyApp extends StatefulWidget {
#override
createState() => MyAppState();
}
class MyAppState extends State<MyApp> {
List<ToDoElement> _toDoItems = [];
TextEditingController _controller = TextEditingController();
void _addToDoItem(String task) {
if(task.isNotEmpty) {
setState(() {
_toDoItems.add(ToDoElement(task, DateTime.now()));
});
}
}
void _editToDoItem(String newText, int index) {
setState(() {
_toDoItems[index].task = newText;
});
}
void _removeTodoItem(int index) {
setState(() => _toDoItems.removeAt(index));
}
_editDialog(BuildContext context) {
return showDialog(context: context, builder: (context) {
return Dialog(
backgroundColor: Colors.transparent,
child: Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(20.0)),
),
padding: EdgeInsets.all(20),
height: 180,
width: 100,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
height: 60,
child: TextField(
controller: _controller,
autofocus: true,
/*onSubmitted: (val) {
_addToDoItem(val);
_controller.clear();
},*/
style: TextStyle(fontSize: 18,),
decoration: InputDecoration(
hintText: 'Add a task here...',
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(12.0)),
borderSide: BorderSide(color: Colors.red, width: 2),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(12.0)),
borderSide: BorderSide(color: Colors.red, width: 2),
),
),
)
),
Container(
height: 65,
width: double.infinity,
margin: EdgeInsets.only(top: 5,),
child: RaisedButton(
textColor: Colors.white,
color: Colors.red,
child: Text('EDIT', style: TextStyle(fontSize: 18)),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(12)),
),
onPressed: () {
_editToDoItem(_controller.text, index);
FocusScope.of(context).requestFocus(FocusNode());
},
),
),
],
),
),
);
});
}
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: () => null,
),
),
FlatButton(
child: Text('Edit', style: TextStyle(color: Colors.red, fontSize: 16.5),),
onPressed: () => _editDialog(context),
),
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) {
if (index < _toDoItems.length) {
return _buildToDoItem(_toDoItems[index].task, index);
}
},
),
);
}
#override
Widget build(BuildContext context) {
return 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: GestureDetector(
onTap: () {
FocusScope.of(context).requestFocus(FocusNode());
},
child: 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,),
decoration: InputDecoration(
hintText: 'Add a task here...',
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(12.0)),
borderSide: BorderSide(color: Colors.red, width: 2),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(12.0)),
borderSide: BorderSide(color: Colors.red, width: 2),
),
),
),
),
),
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()
]
),
),
);
}
}
If you have any questions please let me know in the comments;)
You can copy paste run full code below
You can provide index to _editDialog then _editToDoItem can get index
code snippet
_editDialog(BuildContext context, int index)
...
FlatButton(
child: Text(
'Edit',
style: TextStyle(color: Colors.red, fontSize: 16.5),
),
onPressed: () => _editDialog(context, index),
),
working demo
full code
import 'package:flutter/material.dart';
class ToDoElement {
String task;
final DateTime timeOfCreation;
ToDoElement(this.task, this.timeOfCreation);
}
void main() => runApp(MaterialApp(home: MyApp()));
class MyApp extends StatefulWidget {
#override
createState() => MyAppState();
}
class MyAppState extends State<MyApp> {
List<ToDoElement> _toDoItems = [];
TextEditingController _controller = TextEditingController();
TextEditingController _controller1 = TextEditingController();
void _addToDoItem(String task) {
if (task.isNotEmpty) {
setState(() {
_toDoItems.add(ToDoElement(task, DateTime.now()));
});
}
}
void _editToDoItem(String newText, int index) {
setState(() {
_toDoItems[index].task = newText;
});
}
void _removeTodoItem(int index) {
setState(() => _toDoItems.removeAt(index));
}
_editDialog(BuildContext context, int index) {
return showDialog(
context: context,
builder: (context) {
return Dialog(
backgroundColor: Colors.transparent,
child: Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(20.0)),
),
padding: EdgeInsets.all(20),
height: 180,
width: 100,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
height: 60,
child: TextField(
controller: _controller,
autofocus: true,
/*onSubmitted: (val) {
_addToDoItem(val);
_controller.clear();
},*/
style: TextStyle(
fontSize: 18,
),
decoration: InputDecoration(
hintText: 'Add a task here...',
enabledBorder: OutlineInputBorder(
borderRadius:
BorderRadius.all(Radius.circular(12.0)),
borderSide: BorderSide(color: Colors.red, width: 2),
),
focusedBorder: OutlineInputBorder(
borderRadius:
BorderRadius.all(Radius.circular(12.0)),
borderSide: BorderSide(color: Colors.red, width: 2),
),
),
)),
Container(
height: 65,
width: double.infinity,
margin: EdgeInsets.only(
top: 5,
),
child: RaisedButton(
textColor: Colors.white,
color: Colors.red,
child: Text('EDIT', style: TextStyle(fontSize: 18)),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(12)),
),
onPressed: () {
_editToDoItem(_controller.text, index);
FocusScope.of(context).requestFocus(FocusNode());
},
),
),
],
),
),
);
});
}
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: () => null,
),
),
FlatButton(
child: Text(
'Edit',
style: TextStyle(color: Colors.red, fontSize: 16.5),
),
onPressed: () => _editDialog(context, 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) {
if (index < _toDoItems.length) {
return _buildToDoItem(_toDoItems[index].task, index);
}
},
),
);
}
#override
Widget build(BuildContext context) {
return 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: GestureDetector(
onTap: () {
FocusScope.of(context).requestFocus(FocusNode());
},
child: 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: _controller1,
autofocus: true,
onSubmitted: (val) {
_addToDoItem(val);
_controller1.clear();
},
style: TextStyle(
fontSize: 18,
),
decoration: InputDecoration(
hintText: 'Add a task here...',
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(12.0)),
borderSide: BorderSide(color: Colors.red, width: 2),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(12.0)),
borderSide: BorderSide(color: Colors.red, width: 2),
),
),
),
),
),
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(_controller1.text);
_controller1.clear();
FocusScope.of(context).requestFocus(FocusNode());
},
),
),
),
],
),
),
_buildToDoList()
]),
),
);
}
}

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');
},
),
],
),