Comment Box as Facebook in flutter - 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
},
),
],
),
),
),
)

Related

Flutter -Widget Text, not updating when value change even with SetState

I have created a container. His child is a text.
When I tap on the container/text, it display a modal and a Picker.
Then, the user can select a value. Press the confirm button and my text widget should change to display the value selected by the user.
But in my case, it is not updating the value of the text widget. I have used that in the past and it was working very well. But here it is not and I do not see why. I am on this since 8:00. A little help would be appreciated. Many thanks.
int valuePickerUnitSelected =0;
String unitCount = '';
int unitCountInt;
String goal = "";
List <String> unitForHabits = ['Count', 'Minute(s)','Hour(s)','Gramme(s)', 'Pound(s)'];
class AddingHabitDetails extends StatefulWidget {
const AddingHabitDetails({Key key}) : super(key: key);
#override
_AddingHabitDetailsState createState() => _AddingHabitDetailsState();
}
class _AddingHabitDetailsState extends State<AddingHabitDetails> {
BuildContext get ctx => null;
#override
Widget build(BuildContext context) {
return Scaffold(
//drawer: new MyMenu(), //TODO a remettre
appBar: new AppBar(
title: new Text('Habits'),
),
body: Column(
children: [
titleZone('Name'),
textFieldHabits('Habit name', context),
titleZone('Goals'),
FlatButton(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
if (unitCount.length < 2 )...[
Container(
width: 65,
decoration: BoxDecoration(
border: Border.all(color: Colors.blue,
),
color: Colors.blue,
borderRadius: BorderRadius.all(Radius.circular(20))),
child:
Center(child: Text(
'Time', style: TextStyle(color: Colors.black,))))
]
else
...[
Container(
width: 65,
decoration: BoxDecoration(
border: Border.all(color: Colors.blue,),
color: Colors.blue,
borderRadius: BorderRadius.all(
Radius.circular(20))),
child: Center(
child: Text(
unitCount, style: TextStyle(color: Colors.black,))))
],
],
),
onPressed: () {
setState(() {
showModalBottomSheet(
context: context,
builder: (BuildContext context) {
return ShowPickerUnite(unitForHabits);
});
},
);
},
),
//ChipGoalV3(ctx),// ChipGoal(),
textFieldHabits('Goals', context),
titleZone('Frequency'),
textFieldHabits('Frequency', context),
titleZone('Time Range'),
titleZone('Reminder'),
titleZone('Habits Term'),
],
),
);
}
}
//########################################################################
class ShowPickerUnite extends StatefulWidget {
List<String> myListUnit;
ShowPickerUnite(this.myListUnit, {Key key}) : super(key: key);
#override
_ShowPickerUniteState createState() => _ShowPickerUniteState(
myListUnit);
}
class _ShowPickerUniteState extends State<ShowPickerUnite> {
List <String> myListUnit;
_ShowPickerUniteState(this.myListUnit);
#override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Container(
decoration: BoxDecoration(
color: Color(0xffffffff),
border: Border(
bottom: BorderSide(
color: Color(0xffffffff),
width: 0.0,
),
),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
CupertinoButton(
child: Text('Cancel'),
onPressed: () {
Navigator.of(context).pop();
},
padding: const EdgeInsets.symmetric(
horizontal: 16.0,
vertical: 5.0,
),
),
DefaultTextStyle(
style: TextStyle(
fontSize: 16.0,
color: Colors.black,
fontWeight: FontWeight.bold),
child: Text('Select what you want'),
),
// Text('Energy Needed', style: TextStyle(fontSize: 12.0, color: Colors.black),
// ),
CupertinoButton(
child: Text('Confirm'),
onPressed: () {
setState(() {
unitCount = unitForHabits[valuePickerUnitSelected];
print(unitCount);
});
Navigator.of(context).pop();
},
padding: const EdgeInsets.symmetric(
horizontal: 16.0,
vertical: 5.0,
),
),
],
),
),
Container(
//width: 360,
height: 200,
decoration:BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(15.0)),
),
child: CupertinoPicker(
backgroundColor: Colors.white ,
useMagnifier: true,
magnification: 1.3,
scrollController: FixedExtentScrollController(initialItem: 0),
itemExtent: 25,
children: [
for (String name in myListUnit)
Center(
child:Text(name)),
],
onSelectedItemChanged: (value) {
setState(() {
valuePickerUnitSelected = value;
// taskEnergy = myListEnergy[valuePickerEnergySelected];
// taskNewValue ['task_Energy'] = taskEnergy;
});
}))
]);
}
}
Widget inputNameHabit (){
return Padding(
padding: const EdgeInsets.all(8.0),
child: Text ('Name Habits',style: TextStyle(
fontSize: 25,
fontWeight: FontWeight.bold),),
);
}
Widget titleZone (String _titleName){
return Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: [
Text ( _titleName,
style: TextStyle(
fontSize: 25,
fontWeight: FontWeight.bold),),
],
),
);
}
Widget textFieldHabits (String item,context){
return TextField(
decoration: InputDecoration(
hintText: item,
filled: true,
fillColor: Colors.grey[300],
border: OutlineInputBorder(
borderSide: BorderSide.none,
borderRadius: BorderRadius.circular(50)
),
),
onTap: (){
Navigator.push(context,
MaterialPageRoute(
builder: (context) => HabitGoalUnitSelection(), //TODO MODIFIER route selon source
),
);
},);
}
Wait for the dialog to finish and then call setState to update the UI.
Modify this way
onPressed: () async {
await showModalBottomSheet(
context: context,
builder: (BuildContext context) {
return ShowPickerUnite(unitForHabits);
});
setState(() {});

Flutter: Submit TextFormField on Enter

I'm working on a desktop application for Windows with Flutter. I want to listen to keyboard keys. I made a Login page and it has two TextFormFields, (one for Username and the other for Password).
When I press the 'enter' key on the keyboard, I want the form to be submitted as I pressed on 'Login' button. So if I pressed the 'enter' key from either Username or Password text fields, I want the app to act exactly as if I pressed the 'Login' Button.
Here is a picture of the Login Page:
--> Login Page
Here is the code of Login Page:
import 'package:flutter/material.dart';
import '../../api/services/login_services.dart';
import '../../api/models/login_models.dart';
import '../../constants/constant_methods.dart';
import '../main_page/main_screen.dart';
import '../../constants/constant_variables.dart';
class LoginPage extends StatefulWidget {
const LoginPage({Key? key}) : super(key: key);
#override
_LoginPageState createState() => _LoginPageState();
}
class _LoginPageState extends State<LoginPage> {
TextEditingController usernameController = TextEditingController();
TextEditingController passwordController = TextEditingController();
late LoginRequestModel loginRequestModel;
bool isUsernameEmpty = false;
bool isPasswordEmpty = false;
bool secure = true;
bool notSecure = false;
bool isLoading = false;
#override
void initState() {
super.initState();
loginRequestModel = LoginRequestModel(
usernameController.text,
passwordController.text,
);
}
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
body: Container(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
decoration: const BoxDecoration(
gradient: loginPageGradient,
),
child: Center(
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset(
'assets/images/cloud_soft_logo.png',
height: 90,
),
const SizedBox(height: 15),
Text(
'Hoomy\'s Real Estate',
style: Theme.of(context).textTheme.headline4,
),
const SizedBox(height: 20),
Container(
width: 310,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: borderRadius(10.0),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const SizedBox(height: 20),
Text(
'Welcome',
style: Theme.of(context)
.textTheme
.headline6!
.copyWith(
fontWeight: FontWeight.w600,
foreground: Paint()..shader = linearGradient),
),
Text(
'Please Log in to Your Account',
style: Theme.of(context).textTheme.headline2,
),
const SizedBox(height: 10),
loginTextField("Username", "Username can't be empty",
usernameController),
loginTextField("Password", "Password can't be empty",
passwordController),
forgetPasswordButton(),
loginButton(context),
const SizedBox(height: 40),
],
),
),
],
),
),
),
),
),
);
}
Widget loginTextField(
String labelText,
String errorText,
TextEditingController controller,
) {
return SizedBox(
width: 250,
child: TextFormField(
decoration: InputDecoration(
labelText: labelText,
errorText: labelText == "Username"
? isUsernameEmpty
? errorText
: null
: isPasswordEmpty
? errorText
: null,
suffixIcon: labelText == "Username"
? IconButton(
onPressed: () {}, icon: const Icon(Icons.person, size: 20))
: IconButton(
onPressed: () {
setState(() {
secure = !secure;
});
},
icon: Icon(
secure ? Icons.visibility_off : Icons.visibility,
size: 20,
),
)),
obscureText: labelText == "Username" ? notSecure : secure,
controller: controller,
),
);
}
Padding forgetPasswordButton() {
return Padding(
padding: const EdgeInsets.all(20).copyWith(right: 30),
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Theme(
data: ThemeData(splashColor: Colors.transparent),
child: TextButton(
child: const Text('Forget Password'),
onPressed: () {},
),
),
],
),
);
}
DecoratedBox loginButton(BuildContext context) {
return DecoratedBox(
decoration: BoxDecoration(
borderRadius: borderRadius(50.0),
gradient: loginButtonGradient,
),
child: ElevatedButton(
style: ElevatedButton.styleFrom(
primary: Colors.transparent,
fixedSize: const Size(250, 50),
shape: RoundedRectangleBorder(
borderRadius: borderRadius(50.0),
)),
child: isLoading
? CircularProgressIndicator(
color: Colors.blue[800],
backgroundColor: Colors.grey,
)
: const Text('Login'),
onPressed: () {
setState(() {
usernameController.text.isEmpty
? isUsernameEmpty = true
: isUsernameEmpty = false;
passwordController.text.isEmpty
? isPasswordEmpty = true
: isPasswordEmpty = false;
});
setState(() {
isLoading = true;
});
LoginService.login(usernameController.text, passwordController.text)
.then((response) {
setState(() {
isLoading = false;
});
if (response) {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => const MainScreen(),
),
);
} else if (!response &&
usernameController.text.isNotEmpty &&
passwordController.text.isNotEmpty) {
showErrorDialog(context, "Invalid Username or Password!");
}
});
}),
);
}
Future<dynamic> showErrorDialog(BuildContext context, String dialogContent) {
return showDialog(
context: context,
builder: (BuildContext context) {
return Center(
child: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: SizedBox(
width: 350,
child: AlertDialog(
backgroundColor: Colors.white,
shape: RoundedRectangleBorder(borderRadius: borderRadius(10.0)),
title: Text("Error",
style: Theme.of(context)
.textTheme
.bodyText1!
.copyWith(color: Colors.red)),
content: Text(dialogContent,
style: Theme.of(context)
.textTheme
.headline2!
.copyWith(color: Colors.black87)),
actions: <Widget>[
TextButton(
child: Text("OK",
style: Theme.of(context)
.textTheme
.bodyText1!
.copyWith(color: Colors.blue)),
onPressed: () {
Navigator.of(context).pop();
},
),
],
),
),
),
);
},
);
}
}
Add the field onFieldSubmitted and a FormKey:
// Widget attribute
final _formKey = GlobalKey<FormState>();
// Widget method: build()
Form(
key: _formKey,
child:
TextFormField(
onFieldSubmitted: (value) {
print('ENTER pressed');
// Will trigger validation for ALL fields in Form.
// All your TextFormFields (email, password) share
// the SAME Form and thus the SAME _formKey.
if (_formKey.currentState!.validate()) {
print('ALL FIELDS ARE VALID, GO ON ...');
}
}
)
)
Docs
https://api.flutter.dev/flutter/material/TextFormField-class.html

Flutter fixed button position

I'm developing an application on flutter and I'm having a problem with the position of the ElevatedButton. When the Validator returns the error message below the TextFormField, the widget expands downward and the position of the add button changes. I would like to keep the add button pinned to the same position as the beginning of the app
button in normal position
Button out of its original position after returning the validator
My code:
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Lista de Compras"),
backgroundColor: Colors.green,
centerTitle: true,
),
body: Column(
children: <Widget>[
Container(
padding: EdgeInsets.fromLTRB(15, 10, 5, 10),
child: Form(
key: _formKey,
child: Row(
children: <Widget>[
Theme(
data: ThemeData(
primaryColor: Colors.green,
hintColor: Colors.green),
child: Expanded(
child: TextFormField(
controller: _controlador,
validator: (value) {
if (value.isEmpty) {
return "Insira um item";
}
return null;
},
decoration: InputDecoration(
enabledBorder: OutlineInputBorder(
borderSide:
BorderSide(color: Colors.green),
borderRadius:
BorderRadius.circular(100)),
border: OutlineInputBorder(
borderRadius:
BorderRadius.circular(100)),
labelText: "Novo item",
hintText: "Insira um item",
hintStyle: TextStyle(color: Colors.grey),
labelStyle:
TextStyle(color: Colors.green),
suffixIcon: IconButton(
onPressed: () => _controlador.clear(),
icon: Icon(Icons.clear,
color: Colors.grey),
))))),
Padding(padding: EdgeInsets.only(right: 6)),
ElevatedButton(
style: ElevatedButton.styleFrom(
primary: Colors.green,
shape: CircleBorder(),
padding: EdgeInsets.all(12)),
child: Icon(Icons.add, color: Colors.white),
onPressed: () {
if (_formKey.currentState.validate()) {
_addCompras();
}
}),
],
),
)),
This is an expected behaviour, when TextFormField show an errorText this will append a text below the TextFormField adding extra height for about 22. Check working example below :
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.light(),
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Column(
children: [
MeasureSize(
child: FormWidget(),
onChange: (size) {
print(size);
},
),
MeasureSize(
child: FormWidget(hideError: false),
onChange: (size) {
print(size);
},
),
FormWidget(
hideError: false,
addPaddingToTrailingButton: true,
),
],
),
),
);
}
}
class FormWidget extends StatelessWidget {
final bool hideError;
final bool addPaddingToTrailingButton;
FormWidget({
this.hideError = true,
this.addPaddingToTrailingButton = false,
});
#override
Widget build(BuildContext context) {
Widget trailingButton = ElevatedButton(
style: ElevatedButton.styleFrom(
shape: CircleBorder(),
padding: EdgeInsets.all(12),
),
child: Icon(Icons.add),
onPressed: () {},
);
if (addPaddingToTrailingButton) {
trailingButton = Padding(
padding: const EdgeInsets.only(bottom: 22),
child: trailingButton,
);
}
return Container(
color: Colors.grey[300],
margin: const EdgeInsets.symmetric(vertical: 16),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SizedBox(width: 8),
Expanded(
child: TextField(
decoration: InputDecoration(
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(100),
),
labelText: "Label text field",
hintText: "Hint text field",
errorText: hideError ? null : 'Error text shown',
suffixIcon: IconButton(
onPressed: () {},
icon: Icon(Icons.clear),
),
),
),
),
SizedBox(width: 8),
trailingButton,
],
),
);
}
}
typedef void OnWidgetSizeChange(Size size);
class MeasureSizeRenderObject extends RenderProxyBox {
Size oldSize;
final OnWidgetSizeChange onChange;
MeasureSizeRenderObject(this.onChange);
#override
void performLayout() {
super.performLayout();
Size newSize = child.size;
if (oldSize == newSize) return;
oldSize = newSize;
WidgetsBinding.instance.addPostFrameCallback((_) {
onChange(newSize);
});
}
}
class MeasureSize extends SingleChildRenderObjectWidget {
final OnWidgetSizeChange onChange;
const MeasureSize({
Key key,
#required this.onChange,
#required Widget child,
}) : super(key: key, child: child);
#override
RenderObject createRenderObject(BuildContext context) {
return MeasureSizeRenderObject(onChange);
}
}
I have adding a background so it will show the height difference :
TextField without errorText shown.
TextField with errorText shown.
TextField with errorText shown, with additional padding on icon button.
Check dartpad here
the answer by Allan above is very great.
But if you are facing issues learning that do it this way:
Add Elevated button to Column and add SizedBox with height 22 as its children. Here the height is calculated as (Height of TextFormField with error - of TextFormField without error) using flutter inspector.
Column(
children: [
ElevatedButton(...),
SizedBox(
height: 22,
),
],
),
Now add helperText: ' ', in TextFormField InputDecoration:
TextFormField(
validator: (value) {
if (value == null || value.isEmpty) {
return "Insira um item";
}
return null;
},
decoration: InputDecoration(
helperText: ' ',
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.green),
borderRadius: BorderRadius.circular(100)),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(100)),
labelText: "Novo item",
hintText: "Insira um item",
hintStyle: TextStyle(color: Colors.grey),
labelStyle: TextStyle(color: Colors.green),
),
),
Here you can see the dartpad for full code.
This will get you this result:

Add title and Subtitle to Listview

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

Flutter Animated Container

I have a RaisedButton widget and an AnimatedContainer widget in a screen, and the idea is that upon pressing the RaisedButton the width of the AnimatedContainer would then decrease in a given duration. The documentation of the AnimatedContainer states that all I would need to do is declare the width of the widget as a variable, and then setState(() {}) after changing the value and it will automatically change to that value during the duration. I have tried to implement this and upon pressing the RaisedButton the variables value definitely changes (based on printing the value of it after pressing it), however the widget's width does not change with it. Am I missing something obvious?
My Widgets are within a container in a PageView and my code for the RaisedButton and AnimatedContainer is as follows:
RaisedButton (
onPressed: () {
setState(() {
loginWidth = 70.0;
});
},
),
AnimatedContainer (
duration: new Duration (seconds: 2),
width: loginWidth,
height: 40,
color: Colors.red,
)
Here is my widget tree:
pages.add(
Container(
color: chSecondary,
child: Stack(
children: <Widget>[
Container (
child: Align (
child: Image(image: AssetImage("graphics/signin.png")),
alignment: Alignment.bottomCenter,
),
),
Form(
key: _formKey,
child: new Container(
padding: EdgeInsetsDirectional.only(top: 100, start: 15, end: 15, bottom: 15),
child: new Column(
children: <Widget>[
Container (
child: Image(image: AssetImage("graphics/login.png"), height: 200, width: 200,),
margin: EdgeInsetsDirectional.only(bottom: 20),
),
Container (
padding: EdgeInsets.all(25.0),
decoration: new BoxDecoration(
borderRadius: BorderRadius.circular(10.0),
color: Colors.white,
),
child: Column (
children: <Widget>[
Align(
child: new Text("Email:", style: TextStyle(fontSize: tonSubTitle, color: Colors.black)),
alignment: Alignment.centerLeft,
),
new Container(
child: new TextFormField(
keyboardType: TextInputType.emailAddress,
controller: _email,
style: TextStyle(fontSize: tonText, color: Colors.black),
decoration: InputDecoration(
border: OutlineInputBorder(borderRadius: new BorderRadius.circular(tonRadius)),
contentPadding: EdgeInsetsDirectional.only(top: 15, start: 7.5),
focusedBorder: OutlineInputBorder(borderSide: new BorderSide(color: Colors.grey)),
hintText: "Email Address",
hintStyle: TextStyle(color: Colors.black),
),
validator: (value) {
if (value.isEmpty) {
return "Please enter an email";
}
if (!value.contains("#tonbridge-school.org")) {
return "Please enter a valid email address";
}
},
),
padding: const EdgeInsets.only(top: 10, bottom: 10)
),
Align (
child: new Text("Password:", style: TextStyle(fontSize: tonSubTitle, color: Colors.black)),
alignment: Alignment.centerLeft,
),
new Container(
child: new TextFormField(
obscureText: true,
controller: _password,
style: TextStyle(color: Colors.black, fontSize: tonText),
decoration: InputDecoration(
contentPadding: EdgeInsetsDirectional.only(top: 15, start: 7.5),
border: OutlineInputBorder(borderRadius: new BorderRadius.circular(tonRadius)),
focusedBorder: OutlineInputBorder(borderSide: new BorderSide(color: Colors.grey)),
hintText: "Password",
hintStyle: TextStyle(color: Colors.black),
),
validator: (value) {
if (value.isEmpty) {
return "Please enter a password";
}
},
),
padding: const EdgeInsets.only(top: 10, bottom: 10)
),
RaisedButton (
onPressed: () {
setState(() {
loginWidth = 70.0;
});
},
),
AnimatedContainer (
duration: new Duration (seconds: 2),
width: loginWidth,
height: 40,
color: Colors.red,
)
],
),
)
],
),
)
),
],
),
),
);
The code snippet you've posted is already correct.
Make sure that:
loginWidth is initialized
the new loginWidth value is actually different from the default value
I've copied it and built a minimal example so you can double check the rest of your code. This example also include a surrounding PageView:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: MyBody(),
),
);
}
}
class MyBody extends StatefulWidget {
#override
_MyBodyState createState() => _MyBodyState();
}
class _MyBodyState extends State<MyBody> {
double loginWidth = 40.0;
#override
Widget build(BuildContext context) {
return Center(
child: PageView(
children: <Widget>[
Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
RaisedButton (
child: Text('Animate!'),
onPressed: () {
setState(() {
loginWidth = 250.0;
});
},
),
AnimatedContainer (
duration: Duration (seconds: 1),
width: loginWidth,
height: 40,
color: Colors.red,
),
],
)
],
),
);
}
}
do you initialised loginWidth ?
var loginWidth =0.0;
Curve _curve = Curves.fastOutSlowIn;
_doanimation(){
setState(() {
loginWidth ==0.0? loginWidth =100: loginWidth =0.0;
});
}
change function with your case
Column(
children: <Widget>[
Text("welcome"),
RaisedButton(
onPressed: (){
_doanimation();
},
),
AnimatedContainer(
curve: _curve,
duration: Duration(seconds: 1),
width: loginWidth,
height:100
)
],
),
Where do you have loginWidth declared? It needs to outside the scope of the builder function or its value will get reinitialized on every build.
Can you update your example to show where you declare?
Correct:
class _WidgetState extends State<Widget> {
double loginWidth = 0;
#override
Widget build(BuildContext context) {
// return the new widget tree
}
}
Incorrect:
class _WidgetState extends State<Widget> {
#override
Widget build(BuildContext context) {
double loginWidth = 0;
//return the new widget tree
}
}