Tap to edit text of a listtile - flutter

i'm a bit new to flutter and i'm trying to teach myself to build a groceries list, which will be linked to an API backend. I want the text on a listtile to be editable ontap, so if the user makes a typo they can quickly edit the listtile without going through an additional dialogue.
Screenshot of list tiles
Code:
Widget _shoppingListItem() {
return ListView.builder(
itemCount:
_shoppingList.shoppingListCategories.first.shoppingListItems.length,
itemBuilder: (context, index) {
return Dismissible(
background: Container(
child: Text("Delete",
style: TextStyle(
fontWeight: FontWeight.normal, color: Colors.white)),
color: Colors.red,
),
confirmDismiss: (direction) {
return showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: Text('Sure??'),
content: Text('Delete'),
actions: <Widget>[
FlatButton(
onPressed: () {
// Navigator.pop(context, false);
Navigator.of(
context,
// rootNavigator: true,
).pop(false);
},
child: Text('No'),
),
FlatButton(
onPressed: () {
// Navigator.pop(context, true);
Navigator.of(
context,
// rootNavigator: true,
).pop(true);
},
child: Text('Yes'),
),
],
);
},
);
},
key: UniqueKey(),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5),
color: Colors.white,
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.3),
spreadRadius: 1,
blurRadius: 6,
offset: Offset(0, 3), // changes position of shadow
),
],
),
child: ListTile(
title: Text(
_shoppingList.shoppingListCategories.first
.shoppingListItems[index].itemName,
style:
TextStyle(fontSize: 16, fontWeight: FontWeight.bold)),
trailing: Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
IconButton(
color: ColorPalette.dark2,
icon: icons.shoppingMinus.image(size: 24),
onPressed: () {
setState(() {
_shoppingList.shoppingListCategories.first
.shoppingListItems[index].itemCount--;
});
},
),
Text(
"${_shoppingList.shoppingListCategories.first.shoppingListItems[index].itemCount}",
style: TextStyle(
color: ColorPalette.dark2,
),
),
IconButton(
color: ColorPalette.dark2,
icon: icons.shoppingPlus.image(size: 24),
onPressed: () {
setState(() {
_shoppingList.shoppingListCategories.first
.shoppingListItems[index].itemCount++;
});
},
),
],
),
),
),
),
);
},
);
}
}

Related

Flutter Bloc pagination working correctly, but the entire ListView.builder is rebuilt instead of simply appending the new items

I am relatively new to flutter_bloc, so forgive me if this is a simple question. I have a ListView.builder that renders out a list from my API, and my goal is to paginate this list. I have accomplished that, but the problem is that when I add new items to the list from my bloc, the entire ListView is rebuilt and the page jumps back up to the first item in the list.
Here is my bloc: I think the problem is that I am emitting the "MemesBlocLoaded" state at the end again? Or is it something else?
final ApiRepository apiRepository;
int page = 0;
MemesBlocBloc(this.apiRepository) : super(MemesBlocInitial()) {
on<GetMemesList>((event, emit) async {
try {
emit(MemesBlocLoading());
List memesList = await apiRepository.fetchMemes(page);
emit(MemesBlocLoaded(memesList));
page++;
on<GetMore>((event, emit) async {
emit(const MemesBlocLoadingMore(true));
List memesListMore = await apiRepository.fetchMemes(page);
memesList.addAll(memesListMore);
emit(const MemesBlocLoadingMore(false));
emit(MemesBlocLoaded(memesList));
page++;
});
} on NetworkError {
emit(const MemesBlocError("Failed to fetch data."));
}
});
}
}
Edited with the build method:
if (state is MemesBlocLoaded) {
return SingleChildScrollView(
child: Column(
children: [
ListView.builder(
primary: false,
shrinkWrap: true,
itemCount: state.memes.length,
itemBuilder: (context, index) {
return Stack(
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: ClipRRect(
borderRadius: BorderRadius.circular(8.0),
child: Image.network(
state.memes[index].url,
width: double.infinity,
height: 400,
fit: BoxFit.cover,
),
),
),
Positioned(
right: 16,
bottom: 16,
child: Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
IconButton(
onPressed: () {},
icon: const Icon(Icons.arrow_upward),
color: Colors.white,
),
IconButton(
onPressed: () {},
icon: const Icon(Icons.arrow_downward),
color: Colors.white,
),
IconButton(
onPressed: () {},
icon: const Icon(Icons.comment),
color: Colors.white,
),
IconButton(
onPressed: () {},
icon: const Icon(
Icons.save_alt_outlined,
color: Colors.white,
)),
IconButton(
onPressed: () {},
icon: const Icon(
Icons.share,
color: Colors.white,
)),
IconButton(
onPressed: () {},
icon: const Icon(Icons.report_outlined),
color: Colors.white,
),
Padding(
padding:
const EdgeInsets.only(right: 4.0),
child: GestureDetector(
onTap: () {
print('profile');
},
child: const CircleAvatar(
radius: 16,
backgroundImage: NetworkImage(
'https://images.unsplash.com/photo-1554151228-14d9def656e4?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=686&q=80'),
)),
)
],
),
)
],
);
}),
state.memes.length >= 1
? state is MemesBlocLoadingMore
? const Center(
child: CircularProgressIndicator(
color: Colors.black),
)
: Padding(
padding: const EdgeInsets.all(8.0),
child: ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: Colors.white),
onPressed: () async {
context
.read<MemesBlocBloc>()
.add(GetMore());
},
child: const Text('View more',
style:
TextStyle(color: Colors.black))),
)
: const SizedBox()
],
),
);
}

Error: Undefined name 'context' in flutter

I am a beginner with flutter, I had just started a few days ago. I want to go from one page to another page . But when I use the navigator it shows an error.
I've tried to solve it using some answers to similar problems on stack overflow, but I can't solve it. Also, I am not able to understand those properly.
These are some of them:
Undefined name 'context'
_buildDrawer() {
return ClipPath(
clipper: OvalRightBorderClipper(),
child: Drawer(
child: Container(
padding: const EdgeInsets.only(left: 16.0, right: 40),
decoration: BoxDecoration(
color: primary, boxShadow: [BoxShadow(color: Colors.black45)]),
width: 300,
child: SafeArea(
child: SingleChildScrollView(
child: Column(
children: <Widget>[
Container(
alignment: Alignment.centerRight,
child: IconButton(
icon: Icon(
Icons.power_settings_new,
color: active,
),
onPressed: () {},
),
),
Container(
height: 90,
alignment: Alignment.center,
decoration: BoxDecoration(
shape: BoxShape.circle,
gradient:
LinearGradient(colors: [Colors.pink, Colors.red])),
child: CircleAvatar(
radius: 40,
backgroundImage: NetworkImage(profile),
),
),
SizedBox(height: 5.0),
Text(
"Mohd Amin bin Yaakob",
style: TextStyle(color: Colors.white, fontSize: 18.0),
),
Text(
"Pegawai",
style: TextStyle(color: active, fontSize: 16.0),
),
SizedBox(height: 30.0),
_buildRow(Icons.home, "Home", () {
Navigator.push(context,
MaterialPageRoute(
builder: (context) {
return HomePageWidgetPage();
},
),
);
}),
_buildDivider(),
_buildRow(Icons.home, "Home", () {
Navigator.push(context,
MaterialPageRoute(
builder: (context) {
return HomePageWidgetPage();
},
),
);
}),
_buildDivider(),
_buildRow(Icons.home, "Home", () {
Navigator.push(context,
MaterialPageRoute(
builder: (context) {
return HomePageWidgetPage();
},
),
);
}),
_buildDivider(),
_buildRow(Icons.home, "Home", () {
Navigator.push(context,
MaterialPageRoute(
builder: (context) {
return HomePageWidgetPage();
},
),
);
}),
_buildDivider(),
_buildRow(Icons.home, "Home", () {
Navigator.push(context,
MaterialPageRoute(
builder: (context) {
return HomePageWidgetPage();
},
),
);
}),
_buildDivider(),
],
),
),
),
),
),
);
}
Divider _buildDivider() {
return Divider(
color: active,
);
}
Widget _buildRow(IconData icon, String title, VoidCallback onTap) {
final TextStyle tStyle = TextStyle(color: active, fontSize: 16.0);
return InkWell(
child: Container(
padding: const EdgeInsets.symmetric(vertical: 8.0),
child: Row(
children: [
Icon(
icon,
color: active,
),
SizedBox(width: 10.0),
Text(
title,
style: tStyle,
),
],
),
),
onTap: onTap,
);
}
}
Undefined name 'context' in flutter navigation
You can pass the context like
_buildDrawer(BuildContext context){
And the place you call this method
_buildDrawer(context)

Dynamic listview in flutter

I'm new to Flutter, but I'm trying to make an app with a ListView. The ListView is a list of exercises, within each exercise the number of sets can be added. The problem comes when i press the button add exercise. The above exercise with sets is just copied. I would like a new exercise tab with 0 sets. Below the code can be found.
Here is a picture of the list.
final decoratedField = InputDecoration(
filled: false,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(20.0),
),
hintText: "null",
);
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Column(
children: [
titleSection,
// ignore: unnecessary_new
new TextField(
controller: eCtrl,
onSubmitted: (text) {
litems.add(text);
eCtrl.clear();
setState(() {});
},
),
Expanded(
// ignore: unnecessary_new
child: new ListView.builder(
itemCount: litems.length,
itemBuilder: (BuildContext ctxt, int Index) {
return Card(
child: Padding(
padding: EdgeInsets.all(10),
child: ExpansionTile(
initiallyExpanded: true,
title: Text(
litems[Index],
style: const TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
subtitle: Row(
children: [
Expanded(child: Text(" ")),
//Expanded(child: Text("data")),
//Expanded(child: Text("data")),
//Expanded(child: Text("data")),
],
),
// ignore: sort_child_properties_last
children: <Widget>[
ListView.builder(
shrinkWrap: true,
itemCount: sets.length,
itemBuilder:
(BuildContext context, int Index1) {
return Dismissible(
key: UniqueKey(),
// only allows the user swipe from right to left
direction:
DismissDirection.endToStart,
// Remove this product from the list
// In production enviroment, you may want to send some request to delete it on server side
onDismissed: (_) {
setState(() {
sets.removeAt(Index1);
});
},
// ignore: sort_child_properties_last
child: Card(
elevation: 0,
child: Padding(
padding: EdgeInsets.all(1),
child: ListTile(
title: Text(
" ",
style: const TextStyle(
fontSize: 10,
fontWeight:
FontWeight.bold,
),
),
subtitle: Row(
children: [
Expanded(
child: Text(" "),
),
Expanded(
child: TextField(
decoration:
decoratedField,
),
),
Expanded(
child: TextField(
decoration:
decoratedField,
),
),
Expanded(
child: TextField(
decoration:
decoratedField,
),
),
],
),
))),
background: Container(
color: Colors.red,
margin:
const EdgeInsets.symmetric(
horizontal: 15,
),
alignment: Alignment.centerRight,
child: const Text(
"Delete",
style: TextStyle(
color: Colors.white,
),
)));
}),
Padding(
padding: EdgeInsets.all(10),
child: ElevatedButton(
onPressed: () {
sets.add('sets-test');
setState(() {});
},
child: const Text('+ Add Set')),
),
const SizedBox(height: 5),
],
leading: IconButton(
icon: const Icon(
Icons.close,
color: Colors.red,
),
onPressed: () {
litems.removeAt(Index);
setState(() {});
},
),
)));
})),
ElevatedButton(
onPressed: () {
litems.add("new");
setState(() {});
},
child: const Text('Add Exercises')),
ElevatedButton(
onPressed: () {
createUser(user1, "5");
exercise.setExerciseTotals();
//saveExercise(exercise);
final workout = Workout([exercise, exercise1], "Det gik fint",
"10", 60, "type", "name", true, 0, 0, 0);
//workout.setWorkoutTotals();
saveWorkout(workout, userID);
},
child: const Text('pop')),
bottomSection,
],
),
));
}
You are not copy the item, you logic is that add new Item with null value, change decoratedField to this:
final decoratedField = InputDecoration(
filled: false,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(20.0),
),
hintText: "0",
);

Flutter Inkwell Ontap not working inside a Stack

I am building a flutter ecommerce app and I am having an issue where ontap isn't working inside my inkwell widget. I want the ontap to work so that I can show the product description. I have placed the inkwell widget as a child inside a Positioned widget, which happens to be one of the children of a Stack. How can I solve this?
Here's my code:
return Card(
shadowColor: Colors.grey,
surfaceTintColor: Colors.amber,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20)),
child: Stack(
children: [
Positioned(
right: 0,
child: InkWell(
onTap: () {
print('tapped');
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
ProductDetails(
id: bottleCategory
.bottleList[index].id,
bottleName: bottleCategory
.bottleList[index]
.bottleName,
image: bottleCategory
.bottleList[index]
.image,
price: bottleCategory
.bottleList[index]
.price)));
},
child: IconButton(
icon: favoriteProvider.isExist(
bottleCategory.bottleList[index])
? Icon(
Icons.favorite,
color: Colors.redAccent,
)
: Icon(
Icons.favorite_border,
),
onPressed: (() {
favoriteProvider.toggleFavorites(
bottleCategory.bottleList[index]);
if (favoriteProvider.isExist(
bottleCategory.bottleList[index])) {
ScaffoldMessenger.of(context)
.hideCurrentSnackBar();
ScaffoldMessenger.of(context)
.showSnackBar(
const SnackBar(
content: Text(
"Product Added to Favorite!",
style: TextStyle(fontSize: 16),
),
backgroundColor: Colors.green,
duration: Duration(seconds: 1),
),
);
} else {
ScaffoldMessenger.of(context)
.hideCurrentSnackBar();
ScaffoldMessenger.of(context)
.showSnackBar(
const SnackBar(
content: Text(
"Product Removed from Favorite!",
style: TextStyle(fontSize: 16),
),
backgroundColor: Colors.red,
duration: Duration(seconds: 1),
),
);
}
}),
),
),
),
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Center(
child: Image.asset(
bottleCategory.bottleList[index].image,
height: 200.0,
),
),
Center(
child: Text(
bottleCategory
.bottleList[index].bottleName,
style: const TextStyle(
fontSize: 20.0,
fontWeight: FontWeight.bold))),
Center(
child: Text(
'R${bottleCategory.bottleList[index].price}'),
)
],
),
Positioned(
bottom: 0,
right: 10,
child: IconButton(
icon: const Icon(Icons.add_circle),
iconSize: 40.0,
onPressed: () {
cart.addToCart(
bottleCategory.bottleList[index].id,
bottleCategory
.bottleList[index].bottleName,
bottleCategory
.bottleList[index].price,
bottleCategory
.bottleList[index].image);
},
))
],
),
);
Why do you use IconButton in the child of InkWell?
use one of them and Put all of your onPress functions into that widget.

Error : The argument type 'Context' can't be assigned to the parameter type 'BuildContext'

There was a problem with my code, while I was trying to exit a screen of mine from my bus tracking app main page but this is showing an error. I have tried importing everything given in StackOverflow.
help me to get this solved please
import 'dart:js';
import 'package:flutter/services.dart';
import 'registration_screen.dart';
import 'login_screen.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:lottie/lottie.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:path/path.dart';
class WelcomePage extends StatelessWidget {
From here the function starts
Future<bool?> _onBackPressed() async {
return showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(`enter code here`
title: Text('Do you want to exit?'),
actions: <Widget>[
TextButton(
child: Text('No'),
onPressed: () {
Navigator.of(context).pop(false);
},
),
TextButton(
child: Text('Yes'),
onPressed: () {
Navigator.of(context).pop(true);
SystemNavigator.pop();
},
),
],
);
}
);
}
Scaffold start here also the WillPopScope starts here which returns the _onBackPressed();
#override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () async {
bool? result = await _onBackPressed();
if (result == null) {
result = false;
}
return result;
},
child: Scaffold(
// return Scaffold(
body: SafeArea(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: Column(
children: [
Flexible(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(
height: 20,
),
Lottie.asset('assets/images/bus.json'),
SizedBox(
height: 20,
),
Text(
"Welcome to \n Bus Tracking",
style: GoogleFonts.poppins(
fontSize: 34, fontWeight: FontWeight.w700),
textAlign: TextAlign.center,
),
],
),
),
Padding(
padding: EdgeInsets.symmetric(vertical: 38),
child: Container(
height: 65,
decoration: BoxDecoration(
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.3),
spreadRadius: 2,
blurRadius: 3,
offset: Offset(0, 5))
],
color: Colors.deepPurple,
borderRadius: BorderRadius.circular(12),
),
child: Row(
children: [
Expanded(
child: GestureDetector(
onTap: () {
Navigator.push(
context,
CupertinoPageRoute(
builder: (context) =>
RegistrationScreen()));
},
child: Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(12),
border: Border.all(
color: Colors.deepPurple,
width: 0.9,
)
//textColor: Colors.black87,
),
child: const Center(
child: Text(
'Register',
style: TextStyle(
color: Colors.deepPurple,
fontWeight: FontWeight.bold,
fontSize: 15,
),
),
),
),
),
),
Expanded(
child: GestureDetector(
//bgColor: Colors.transparent,
//buttonName: 'Sign In',
onTap: () {
Navigator.push(
context,
CupertinoPageRoute(
builder: (context) => LoginScreen(),
));
},
child: Container(
decoration: BoxDecoration(
color: Colors.deepPurple,
borderRadius: BorderRadius.circular(12),
border: Border.all(
color: Colors.deepPurple,
width: 0.9,
)
//textColor: Colors.black87,
),
child: const Center(
child: Text(
'Login',
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 15,
),
),
),
),
),
),
],
),
),
),
],
),
),
),
));
}
}
Change the function _onBackPressed as
Future<bool?> _onBackPressed(BuildContext ctx) async {
return showDialog(
context: ctx,
builder: (BuildContext context) {
return AlertDialog(`enter code here`
title: Text('Do you want to exit?'),
actions: <Widget>[
TextButton(
child: Text('No'),
onPressed: () {
Navigator.of(context).pop(false);
},
),
TextButton(
child: Text('Yes'),
onPressed: () {
Navigator.of(context).pop(true);
SystemNavigator.pop();
},
),
],
);
}
);
}
Now in the build function use :
bool? result = await _onBackPressed(context);
context is getting clashed may de due to import 'package:path/path.dart'; if you don't need it remove it.
Here in the question i have been using a stateless widget but I need to use a stateful widget, so the solution is to create a new file as a stateful widget and dumb all this code in it and the error was solved.