Add title and Subtitle to Listview - flutter

Very new flutter. I know how to add one title to the list. I want to add 2 or more title to the list.
I defined 2 lists as list and subtitle. I think I'm making a mistake giving the index number.
I can't solve how to use lists in ListView.builder.
How can I do about this?
main.dart
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart';
import 'harf_buyuklugu.dart';
void main() => runApp(defectList());
class todolist extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: "PROGRAM",
home: Iskele(),
);
}
}
class Iskele extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Program'),
),
body: AnaEkran(),
);
}
}
class AnaEkran extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Icerik();
}
}
class Icerik extends StatefulWidget {
#override
_IcerikState createState() => _IcerikState();
}
class _IcerikState extends State<Icerik> {
TextEditingController _title_Textfield = TextEditingController();
TextEditingController _subtitleTextfield = TextEditingController();
List<String> title = [];
List<String> subtitle = [];
elemanEkle() {
setState(() {
title.add(_title_Textfield.text);
_title_Textfield.clear();
});
}
elemanCikar() {
title.clear();
_subtitleTextfield.clear();
setState(() {});
}
#override
Widget build(BuildContext context) {
return Container(
child: Column(
children: [
Padding(
padding: const EdgeInsets.only(left: 25, right: 25, top: 25),
child: TextField(
maxLength: 100,
controller: _title_Textfield,
inputFormatters: [BuyukHarfTxt()],
minLines: 1,
maxLines: 3,
decoration: InputDecoration(
border: OutlineInputBorder(
borderRadius: BorderRadius.all(
Radius.circular(60),
),
),
hintText: "Add somethings...",
labelText: "Title",
suffixIcon: IconButton(
onPressed: () => _title_Textfield.clear(),
icon: Icon(Icons.clear),
),
),
),
),
Padding(
padding: const EdgeInsets.only(left: 25, right: 25, top: 25),
child: TextField(
controller: _subtitleTextfield,
inputFormatters: [BuyukHarfTxt()],
minLines: 1,
maxLines: 3,
decoration: InputDecoration(
border: OutlineInputBorder(
borderRadius: BorderRadius.all(
Radius.circular(60),
),
),
hintText: "Add somethings...",
labelText: "Subtitle",
suffixIcon: IconButton(
onPressed: () => _subtitleTextfield.clear(),
icon: Icon(Icons.clear),
),
),
),
),
Row(
children: [
IconButton(
onPressed: elemanEkle,
icon: Icon(Icons.save),
color: Colors.amber,
iconSize: 50,
),
IconButton(
onPressed: elemanCikar,
icon: Icon(Icons.delete_forever_rounded),
color: Colors.amber,
iconSize: 50,
),
],
),
Flexible(
child: ListView.builder(
itemCount: title.length,
itemBuilder: (context, indeksNumarasi) => ListTile(
title: Text(
'${title[indeksNumarasi]} (${subtitle[indeksNumarasi]})',
),
),
),
)
], //children
),
);
}
}
harf_buyuklugu.dart
import 'package:flutter/services.dart';
class BuyukHarfTxt extends TextInputFormatter {
#override
TextEditingValue formatEditUpdate(
TextEditingValue txtEski, TextEditingValue txtYeni) {
return txtYeni.copyWith(
text: txtYeni.text.toUpperCase(),
);
}
}
Result image
I want this

I have made some changes to your code and commented the changes, Now it works
Copy Paste this code
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart';
import 'harf_buyuklugu.dart';
void main() => runApp(defectList());
class todolist extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: "PROGRAM",
home: Iskele(),
);
}
}
class Iskele extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Program'),
),
body: AnaEkran(),
);
}
}
class AnaEkran extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Icerik();
}
}
class Icerik extends StatefulWidget {
#override
_IcerikState createState() => _IcerikState();
}
class _IcerikState extends State<Icerik> {
TextEditingController _title_Textfield = TextEditingController();
TextEditingController _subtitleTextfield = TextEditingController();
List<String> title = [];
List<String> subtitle = [];
elemanEkle() {
setState(() {
title.add(_title_Textfield.text);
subtitle.add(_subtitleTextfield.text); //added this line other wise index error will come
_title_Textfield.clear();
_subtitleTextfield.clear();
});
}
elemanCikar() {
title.clear();
_subtitleTextfield.clear();
setState(() {});
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
child: Column(
children: [
Padding(
padding: const EdgeInsets.only(left: 25, right: 25, top: 25),
child: TextField(
maxLength: 100,
controller: _title_Textfield,
// inputFormatters: [BuyukHarfTxt()],
minLines: 1,
maxLines: 3,
decoration: InputDecoration(
border: OutlineInputBorder(
borderRadius: BorderRadius.all(
Radius.circular(60),
),
),
hintText: "Add somethings...",
labelText: "Title",
suffixIcon: IconButton(
onPressed: () => _title_Textfield.clear(),
icon: Icon(Icons.clear),
),
),
),
),
Padding(
padding: const EdgeInsets.only(left: 25, right: 25, top: 25),
child: TextField(
controller: _subtitleTextfield,
// inputFormatters: [BuyukHarfTxt()],
minLines: 1,
maxLines: 3,
decoration: InputDecoration(
border: OutlineInputBorder(
borderRadius: BorderRadius.all(
Radius.circular(60),
),
),
hintText: "Add somethings...",
labelText: "Subtitle",
suffixIcon: IconButton(
onPressed: () => _subtitleTextfield.clear(),
icon: Icon(Icons.clear),
),
),
),
),
Row(
children: [
IconButton(
onPressed: elemanEkle,
icon: Icon(Icons.save),
color: Colors.amber,
iconSize: 50,
),
IconButton(
onPressed: () {
elemanCikar();
},
icon: Icon(Icons.delete_forever_rounded),
color: Colors.amber,
iconSize: 50,
),
],
),
Flexible(
child: ListView.builder(
itemCount: title?.length ?? 0, //when list is null nothing will shows up (some null opeartions)
itemBuilder: (context, indeksNumarasi) => ListTile(
title: new Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'${title[indeksNumarasi]})',
),
Text("${subtitle[indeksNumarasi]}"),
],
),
subtitle: Container(height: 5, color: Colors.green),
),
),
)
], //children
),
),
);
}
}

Related

Validate Elevated Button in Flutter

I'm making an app using Flutter which calculates motor vehicle tax.
It calculates it perfectly fine when I enter the cost of vehicle.
But I want to add a validation to it. When I don't enter any cost of vehicle and keeps it empty and then click the calculate button, I want it show - please enter the cost.
How do I add this validation as this is not a form.
Here is the code of that part:
TextField(
controller: costController,
decoration: const InputDecoration(labelText: "Cost of Vehicle"),
keyboardType: TextInputType.number,
inputFormatters: <TextInputFormatter>[
FilteringTextInputFormatter.digitsOnly
],
),
const SizedBox(
height: 20,
),
ElevatedButton(
style: ElevatedButton.styleFrom(
primary: Theme.of(context).primaryColor,
),
onPressed: () {
setState(() {
toPrint = calc(
dropDownValue!,
int.parse(costController.text),
).toString();
});
},
child: const Text("Calculate")),
const SizedBox(
height: 20,
),
Container(
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 5),
decoration: BoxDecoration(
color: Colors.lightGreenAccent[100],
border: const Border(
bottom: BorderSide(color: Colors.grey),
)),
child: Text("Tax : $toPrint "),
),
Wrap the column with a Form widget add avalidator to the textfield
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
#override
Widget build(BuildContext context) {
const appTitle = 'Form Validation Demo';
return MaterialApp(
title: appTitle,
home: Scaffold(
appBar: AppBar(
title: const Text(appTitle),
),
body: const MyCustomForm(),
),
);
}
}
// Create a Form widget.
class MyCustomForm extends StatefulWidget {
const MyCustomForm({super.key});
#override
MyCustomFormState createState() {
return MyCustomFormState();
}
}
// Create a corresponding State class.
// This class holds data related to the form.
class MyCustomFormState extends State<MyCustomForm> {
// Create a global key that uniquely identifies the Form widget
// and allows validation of the form.
//
// Note: This is a GlobalKey<FormState>,
// not a GlobalKey<MyCustomFormState>.
final _formKey = GlobalKey<FormState>();
#override
Widget build(BuildContext context) {
// Build a Form widget using the _formKey created above.
return Form(
key: _formKey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
TextField(
controller: costController,
decoration: const InputDecoration(labelText: "Cost of Vehicle"),
keyboardType: TextInputType.number,
inputFormatters: <TextInputFormatter>[
FilteringTextInputFormatter.digitsOnly
],
// The validator receives the text that the user has entered.
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter some text';
}
return null;
},
),
ElevatedButton(
style: ElevatedButton.styleFrom(
primary: Theme.of(context).primaryColor,
),
onPressed: () {
if (_formKey.currentState!.validate()) {
setState(() {
toPrint = calc(
dropDownValue!, int.parse(costController.text),
).toString();
});
}
},
child: const Text("Calculate")),
const SizedBox(
height: 20,
),
Container(
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 5),
decoration: BoxDecoration(
color: Colors.lightGreenAccent[100],
border: const Border(
bottom: BorderSide(color: Colors.grey),
)),
child: Text("Tax : $toPrint "),
),
],
),
);
}
}
Use Form Widget and Convert TextField to TextFormField like that.
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
class FormWidget extends StatefulWidget {
const FormWidget({Key? key}) : super(key: key);
#override
State<FormWidget> createState() => _FormWidgetState();
}
class _FormWidgetState extends State<FormWidget> {
final TextEditingController costController = TextEditingController();
final _formKey = GlobalKey<FormState>();
#override
Widget build(BuildContext context) {
return Scaffold(
key: _formKey,
body: Column(
children: [
Form(
child: TextFormField(
validator: (value) {
if (value.isEmpty) {
return "Please enter the cost.";
}
return null;
},
controller: costController,
decoration: const InputDecoration(labelText: "Cost of Vehicle"),
keyboardType: TextInputType.number,
inputFormatters: <TextInputFormatter>[
FilteringTextInputFormatter.digitsOnly
],
),
),
const SizedBox(
height: 20,
),
ElevatedButton(
style: ElevatedButton.styleFrom(
primary: Theme.of(context).primaryColor,
),
onPressed: () {
if(_formKey.currentState.validate()){
//do your setState stuff
setState(() {
});
}
},
child: const Text("Calculate")),
const SizedBox(
height: 20,
),
Container(
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 5),
decoration: BoxDecoration(
color: Colors.lightGreenAccent[100],
border: const Border(
bottom: BorderSide(color: Colors.grey),
)),
child: Text("Tax : "),
),
],
),
);
}
}

I got an error when i want to pass the qr read data to my text field

I got an error when I want to pass the QR read data to my text field. I open camera first and dont get any error. But in second, i get a dump
Exception has occurred.
_AssertionError ('package:flutter/src/rendering/object.dart': Failed assertion: line 2250 pos 12: '!_debugDisposed': is not true.)
QR Scanner Widget:
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:intesasoft_case_study/screens/home_screen.dart';
import 'package:intesasoft_case_study/widgets/custom_appbar.dart';
import 'package:qr_code_scanner/qr_code_scanner.dart';
import '../controllers/controller.dart';
class ScannerWidget extends StatefulWidget {
const ScannerWidget({Key? key}) : super(key: key);
#override
State<ScannerWidget> createState() => _ScannerWidgetState();
}
class _ScannerWidgetState extends State<ScannerWidget> {
CitiesController c = Get.find();
final qrKey = GlobalKey(debugLabel: 'QR');
Barcode? barcode;
QRViewController? controller;
#override
void dispose() {
controller?.dispose();
super.dispose();
}
#override
void reassemble() async {
super.reassemble();
if (Platform.isAndroid) {
await controller!.pauseCamera();
}
controller!.resumeCamera();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: const PreferredSize(
child: CustomAppbar(),
preferredSize: Size.fromHeight(70),
),
body: Stack(
alignment: Alignment.center,
children: [
buildQrView(context),
Positioned(bottom: 10, child: buildResult())
],
),
);
}
Widget buildResult() => Container(
color: Colors.white,
child: Text(
barcode != null ? 'Result : ${barcode!.code}' : 'Scan a code',
maxLines: 3,
),
);
Widget buildQrView(BuildContext context) => QRView(
key: qrKey,
onQRViewCreated: onQRViewCreated,
overlay: QrScannerOverlayShape(),
);
void onQRViewCreated(QRViewController controller) {
setState(() => this.controller = controller);
controller.scannedDataStream.listen((barcode) => setState(() {
this.barcode = barcode;
print(barcode.code);
c.qrVal.value = barcode.code!;
Get.back();
}));
}
}
HomeScreen:
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:intesasoft_case_study/models/response_model.dart';
import 'package:intesasoft_case_study/screens/city_details_screen.dart';
import 'package:intesasoft_case_study/utils/colors.dart';
import 'package:intesasoft_case_study/widgets/custom_appbar.dart';
import 'package:intesasoft_case_study/widgets/drawer.dart';
import 'package:intesasoft_case_study/widgets/scanner.dart';
import '../controllers/controller.dart';
class HomeScreen extends StatefulWidget {
const HomeScreen({Key? key}) : super(key: key);
#override
State<HomeScreen> createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
final textController = TextEditingController();
List<ResponseModel> _foundedCityList = [];
var scaffoldKey = GlobalKey<ScaffoldState>();
void openDrawer() {
scaffoldKey.currentState!.openDrawer();
}
CitiesController c = Get.find();
#override
void initState() {
c.getCitiesData();
_foundedCityList = c.cities;
super.initState();
}
void _runFilter(String enteredKeyword) {
List<ResponseModel> results = [];
if (enteredKeyword.isEmpty) {
results = c.cities;
} else {
results = c.cities
.where((data) =>
data.name!.toLowerCase().contains(enteredKeyword.toLowerCase()))
.toList();
// toLowerCase() method to make it case-insensitive
}
setState(() {
_foundedCityList = results;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
key: scaffoldKey,
appBar: PreferredSize(
child: CustomAppbar(
onPressed: () => openDrawer(),
),
preferredSize: const Size.fromHeight(70),
),
drawer: const DrawerWidget(),
body: Container(
padding: const EdgeInsets.all(24),
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15.0),
),
elevation: 10,
child: Obx(
() => Column(
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: [
Expanded(
child: TextField(
controller: textController,
onChanged: (value) {
_runFilter(value);
},
textInputAction: TextInputAction.search,
decoration: InputDecoration(
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: borderColor,
),
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Colors.grey,
),
),
hintText: c.qrVal.value,
hintStyle: TextStyle(color: Colors.grey)),
),
),
IconButton(
onPressed: () {
Get.to(() => ScannerWidget());
},
icon: const Icon(Icons.camera_alt_rounded),
),
],
),
),
const SizedBox(height: 10),
Container(
padding: const EdgeInsets.only(left: 16, top: 8),
color: Colors.red,
width: double.infinity,
height: 40,
child: const Text(
'Şehirler',
textAlign: TextAlign.start,
style: TextStyle(color: Colors.white),
),
),
Expanded(
child: ListView.builder(
itemCount: _foundedCityList.length,
itemBuilder: (ctx, i) {
return Column(
children: [
ListTile(
leading: CircleAvatar(
radius: 25,
backgroundColor: Colors.white,
child: Image.network(
_foundedCityList[i].image == null
? imageUrl
: _foundedCityList[i].image!,
fit: BoxFit.cover,
),
),
title: Text(_foundedCityList[i].name!),
subtitle: Text('Nüfus: ' +
_foundedCityList[i]
.populations![0]
.population!),
trailing: IconButton(
onPressed: () {
Get.to(const CityDetailsScreen(),
arguments: _foundedCityList[i].id);
print(_foundedCityList[i].id);
},
icon: const Icon(Icons.remove_red_eye)),
),
const Divider(
color: Colors.red,
thickness: 1,
),
],
);
},
),
),
],
),
),
),
),
);
}
}

Comment Box as Facebook in flutter

Here is my code
TextField(
controller: commentController,
maxLines: 3,
selectionHeightStyle: BoxHeightStyle.tight,
decoration: new InputDecoration(
hintText: 'Write a Comment',
hintStyle: new TextStyle(
color: Colors.grey,
),
prefixIcon: InkWell(
child: Icon(Icons.camera_alt),
onTap: () {
chooseImage();
},
),
suffixIcon: InkWell(
child: Icon(
Icons.send,
),
onTap: () {
if (filePickedName == 'nofile') {
insertMethod();
commentController.clear();
_fleshScreen();
getCommentData();
} else {
upload();
commentController.clear();
_fleshScreen();
getCommentData();
}
},
)),
style: new TextStyle(
color: Colors.black,
),
),
I want to create as this box with ImageView
facebook comment multimedia box
let me give you a widget for that
class CommentBox extends StatefulWidget {
final Widget image;
final TextEditingController controller;
final BorderRadius inputRadius;
final Function onSend,onImageRemoved;
const CommentBox({Key key, this.image, this.controller, this.inputRadius, this.onSend , this.onImageRemoved }) : super(key: key);
#override
_CommentBoxState createState() => _CommentBoxState();
}
class _CommentBoxState extends State<CommentBox> {
Widget image;
#override
void initState() {
image = widget.image;
super.initState();
}
#override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Divider(
height: 1,
color: Colors.grey[300],
thickness: 1,
),
const SizedBox(height: 20),
if (image != null)
_removable(
context,
_imageView(context),
),
if(widget.controller!=null) TextFormField(
controller: widget.controller,
decoration: InputDecoration(
suffixIcon: IconButton(
icon: Icon(Icons.send,color: Theme.of(context).primaryColor,),
onPressed: widget.onSend,
),
filled: true,
border: OutlineInputBorder(
borderSide: BorderSide.none,
borderRadius: widget.inputRadius ?? BorderRadius.circular(32),
),
),
),
],
);
}
Widget _removable(BuildContext context, Widget child) {
return Stack(
alignment: Alignment.topRight,
children: [
child,
IconButton(
icon: Icon(Icons.clear),
onPressed: () {
setState(() {
image = null;
widget.onImageRemoved();
});
},
)
],
);
}
Widget _imageView(BuildContext context) {
return Padding(
padding: EdgeInsets.all(16),
child: ClipRRect(
borderRadius: BorderRadius.circular(16),
child: image,
),
);
}
}
USE IT LIKE ANY WIDGET
MaterialApp(
home: Scaffold(
body: SafeArea(
child: Column(
children: [
SizedBox(height: 128,),
Spacer(),
CommentBox(
image: Image.asset(
"assets/svg/barber.svg",
height: 64,
width: 64,
),
controller: TextEditingController(),
onImageRemoved: (){
//on image removed
},
onSend: (){
//on send button pressed
},
),
],
),
),
),
)

Why is my TextField and List not showing when both are together in flutter

I have just started learning flutter this week!, After following a 5 hour video I decided that I would be a good Idea to work on a to do list using my knowledge. I have been having some problems with the layout order because I am used to react native and html. So I have a TextField in which a user can type the a task and then submit it so that it can appear on a list of the added tasks which is below this textfield. In the process I realized that the code is not displaying anything. The code just shows something if the TextField is removed or the list is removed but it looks that they cant be in the same page. How can I fix that problem?
My current code which doesnt display anything (main.dart)
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
#override
createState() => MyAppState();
}
class MyAppState extends State<MyApp> {
List<String> _toDoItems = [];
void _addToDoItem(String task) {
if(task.length > 0) {
setState(() {
_toDoItems.add(task);
});
}
}
Widget _buildToDoItem(String toDoText) {
return ListTile(
title: Text(toDoText)
);
}
Widget _buildToDoList() {
return ListView.builder(
itemBuilder: (context, index) {
if (index < _toDoItems.length) {
return _buildToDoItem(_toDoItems[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(
margin: EdgeInsets.all(22),
child: TextField(
autofocus: true,
onSubmitted: (val) {
_addToDoItem(val);
},
),
), _buildToDoList(),
],
),
),
);
}
}
Now the following code is the one that does display the list but not the TextField
body: _buildToDoList(),
code that does display the TextField but not the List
body: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Container(
margin: EdgeInsets.all(22),
child: TextField(
autofocus: true,
onSubmitted: (val) {
_addToDoItem(val);
},
decoration: InputDecoration(
hintText: 'Add a tak 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: 1.5),
),
),
),
), // the list widget here is removed so that the text field could appear
],
),
for button next to text field:
body: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Container(
margin: EdgeInsets.all(22),
child: Row(children: [
TextField(
autofocus: true,
onSubmitted: (val) {
_addToDoItem(val);
},
decoration: InputDecoration(
hintText: 'Add a tak 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: 1.5),
),
),
),
RaisedButton(
child: Text('ADD'),
onPressed: null,
),
],)
),
_buildToDoList(),
],
),
You can copy paste run full code below
You can wrap ListView with Expanded
code snippet
Widget _buildToDoList() {
return Expanded(
child: ListView.builder(
itemBuilder: (context, index) {
if (index < _toDoItems.length) {
return _buildToDoItem(_toDoItems[index]);
}
},
),
);
}
working demo
full code
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
#override
createState() => MyAppState();
}
class MyAppState extends State<MyApp> {
List<String> _toDoItems = [];
void _addToDoItem(String task) {
if (task.length > 0) {
setState(() {
_toDoItems.add(task);
});
}
}
Widget _buildToDoItem(String toDoText) {
return ListTile(title: Text(toDoText));
}
Widget _buildToDoList() {
return Expanded(
child: ListView.builder(
itemBuilder: (context, index) {
if (index < _toDoItems.length) {
return _buildToDoItem(_toDoItems[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(
margin: EdgeInsets.all(22),
child: TextField(
autofocus: true,
onSubmitted: (val) {
_addToDoItem(val);
},
),
),
_buildToDoList(),
],
),
),
);
}
}
full code 2
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
#override
createState() => MyAppState();
}
class MyAppState extends State<MyApp> {
List<String> _toDoItems = [];
void _addToDoItem(String task) {
if (task.length > 0) {
setState(() {
_toDoItems.add(task);
});
}
}
Widget _buildToDoItem(String toDoText) {
return ListTile(title: Text(toDoText));
}
Widget _buildToDoList() {
return Expanded(
child: ListView.builder(
itemBuilder: (context, index) {
if (index < _toDoItems.length) {
return _buildToDoItem(_toDoItems[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(
margin: EdgeInsets.all(22),
child: Row(
children: [
Expanded(
flex: 1,
child: TextField(
autofocus: true,
onSubmitted: (val) {
_addToDoItem(val);
},
decoration: InputDecoration(
hintText: 'Add a tak 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: 1.5),
),
),
),
),
Expanded(
flex: 1,
child: RaisedButton(
child: Text('ADD'),
onPressed: null,
),
),
],
)),
_buildToDoList(),
],
),
),
);
}
}

The Hero widget doesn't launch the first time (Flutter)

The animation doesn't work the first time it's launched (onTap in GestureDetector), but it works the next time if I go backwards. And I don't know why.
Here is my code :
in main.dart :
import 'package:fairlove/screen/splash_screen.dart';
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: SplashScreen(),
);
}
}
splash_screen and login_screen are under the 'screen' folder.
in screen/splash_screen.dart :
import 'package:flutter/material.dart';
import 'login_screen.dart';
class SplashScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Hero(
tag: 'homeLogo',
child: GestureDetector(
onTap: () => Navigator.push(context, MaterialPageRoute(builder: (context) => LoginScreen(),)),
child: Image.asset('assets/logo.png')
),
),
);
}
}
when I click on the image the first time, it goes to LoginScreen, ok, but without animation.
and in in screen/login_screen.dart :
import 'package:flutter/material.dart';
const users = const {
'a#a.a': 'aaa',
'hunter#gmail.com': 'hunter',
};
class LoginScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
final userNameController = TextEditingController();
final passwordController = TextEditingController();
final logo = Hero(
tag: 'homeLogo',
child: CircleAvatar(
backgroundColor: Colors.transparent,
radius: 40.0,
child: Image.asset('assets/logo.png'),
));
final txtUserName = TextField(
controller: userNameController,
decoration: InputDecoration(
hintText: 'Username',
contentPadding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0),
border: OutlineInputBorder(borderRadius: BorderRadius.circular(30.0))
),
);
final txtPassword = TextField(
controller: passwordController,
obscureText: true,
decoration: InputDecoration(
hintText: 'Password',
contentPadding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0),
border: OutlineInputBorder(borderRadius: BorderRadius.circular(30.0))
),
);
final btnLogin = RaisedButton(
color: Colors.deepPurpleAccent,
textColor: Colors.white,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(10.0))),
onPressed: () {
if(userNameController != null && userNameController.text == "abc"
&& passwordController!= null && passwordController.text == "123") {
//Navigator.of(context).pushReplacement(newRoute)
}
},
child: Text('Login', style: TextStyle(fontSize: 20.0),),
);
final btnForgetPassword = FlatButton(
onPressed: () { },
child: Text('Forget Password', style: TextStyle(color: Colors.blue),),
);
return Scaffold(
body: Center(
child: Container(
width: 400,
height: 400,
child: ListView(
padding: EdgeInsets.only(left: 25.0, right: 25.0),
children: <Widget>[
logo,
SizedBox(height: 20.0),
txtUserName,
SizedBox(height: 20.0),
txtPassword,
SizedBox(height: 20.0),
btnLogin,
btnForgetPassword
],
),
),
),
);
}
}
If I go back or/and click again the image on the previous screen, Hero animation works.