First of all, I'm completely new to programming. I'm trying to make a to do app. My problem is that when the button on the bottom left is pressed, it should open up a text field, in which the user can type in his task. However if the button is pressed nothing happens. I was told on a discord to add setState() but that didnt change anything. Thanks for your help.
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return const MaterialApp(
home: HomeView(),
);
}
}
class HomeView extends StatelessWidget {
const HomeView({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: const Color.fromRGBO(35, 35, 35, 1),
appBar: AppBar(
title: const Center(
child: Text(
'To-Do',
style: TextStyle(
fontSize: 24,
fontFamily: "averagesans",
fontWeight: FontWeight.bold,
),
),
),
backgroundColor: const Color.fromRGBO(30, 30, 30, 1),
),
floatingActionButton: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
FloatingActionButton(
backgroundColor: const Color.fromRGBO(255, 255, 255, 1),
onPressed: () {
const TextFieldInput();
},
child: const Icon(
Icons.add_rounded,
size: 35,
color: Color.fromRGBO(35, 35, 35, 1),
),
),
],
),
);
}
}
class TextFieldInput extends StatefulWidget {
const TextFieldInput({Key? key}) : super(key: key);
@override
_TextFieldInputState createState() => _TextFieldInputState();
}
class _TextFieldInputState extends State<TextFieldInput> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
TextField(
decoration: InputDecoration(border: OutlineInputBorder()),
)
],
),
);
}
}
CodePudding user response:
your on pressed does nothing really. What you want to do is to control this with a flag.
Declare bool _shouldOpenTextField = false. And then inside inside the onPressed:
onPressed: () {
setState(() => {
_shouldOpenTextField = true; // or _shouldOpenTextField = !_shouldOpenTextField if you want to show/hide with the button press.
});
}
In you Scaffold children:
children: [
if(_shouldOpenTextField)
TextField(.....),
)
],
Edit: In this case, your TextField don't really need to be in a class this is enough:
children: [
if(_shouldOpenTextField)
TextField(
decoration: InputDecoration(border: OutlineInputBorder()),
)
],
CodePudding user response:
The concept here is a bit different, everything in Flutter is a Widget and should be rendered in your Widget Tree, so you can't create a widget and show it on the fly like a dialog or something like that
First of all, convert your HomeView widget to a StatefulWidget, then you can show your test input by the help of a variable:
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return const MaterialApp(
home: HomeView(),
);
}
}
class HomeView extends StatefulWidget {
const HomeView({Key? key}) : super(key: key);
@override
State<HomeView> createState() => _HomeViewState();
}
class _HomeViewState extends State<HomeView> {
bool _showTextFiled = false;
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: const Color.fromRGBO(35, 35, 35, 1),
appBar: AppBar(
title: const Center(
child: Text(
'To-Do',
style: TextStyle(
fontSize: 24,
fontFamily: "averagesans",
fontWeight: FontWeight.bold,
),
),
),
backgroundColor: const Color.fromRGBO(30, 30, 30, 1),
),
body: (_showTextFiled == true)
? TextFieldInput()
: const Center(
child: Text('...'),
),
floatingActionButton: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
FloatingActionButton(
backgroundColor: const Color.fromRGBO(255, 255, 255, 1),
onPressed: () {
setState((){
_showTextFiled = true;
});
},
child: const Icon(
Icons.add_rounded,
size: 35,
color: Color.fromRGBO(35, 35, 35, 1),
),
),
],
),
);
}
}
class TextFieldInput extends StatefulWidget {
const TextFieldInput({Key? key}) : super(key: key);
@override
_TextFieldInputState createState() => _TextFieldInputState();
}
class _TextFieldInputState extends State<TextFieldInput> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
TextField(
decoration: InputDecoration(border: OutlineInputBorder()),
)
],
),
);
}
}
Another option is to use showModalBottomSheet function:
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return const MaterialApp(
home: HomeView(),
);
}
}
class HomeView extends StatefulWidget {
const HomeView({Key? key}) : super(key: key);
@override
State<HomeView> createState() => _HomeViewState();
}
class _HomeViewState extends State<HomeView> {
void _ShowTextFieldDialog(BuildContext ctx) {
showModalBottomSheet(
context: ctx,
builder: (bCtx) {
return const Padding(
padding: EdgeInsets.all(20),
child: TextFieldInput(),
);
},
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: const Color.fromRGBO(35, 35, 35, 1),
appBar: AppBar(
title: const Center(
child: Text(
'To-Do',
style: TextStyle(
fontSize: 24,
fontFamily: "averagesans",
fontWeight: FontWeight.bold,
),
),
),
backgroundColor: const Color.fromRGBO(30, 30, 30, 1),
),
body: const Center(
child: Text('...'),
),
floatingActionButton: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
FloatingActionButton(
backgroundColor: const Color.fromRGBO(255, 255, 255, 1),
onPressed: () {
_ShowTextFieldDialog(context);
},
child: const Icon(
Icons.add_rounded,
size: 35,
color: Color.fromRGBO(35, 35, 35, 1),
),
),
],
),
);
}
}
class TextFieldInput extends StatefulWidget {
const TextFieldInput({Key? key}) : super(key: key);
@override
_TextFieldInputState createState() => _TextFieldInputState();
}
class _TextFieldInputState extends State<TextFieldInput> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
TextField(
decoration: InputDecoration(border: OutlineInputBorder()),
)
],
),
);
}
}
CodePudding user response:
convert
HomeViewas astatefulwidget as we need to add a state in it.declare a variable to maintain state
bool shoulShowInput = false;
- update state in onPress button
onPressed: () {
// const TextFieldInput();
setState(() {
shoulShowInput = true;
});
print('pressed');
},
- add body property to Scaffold and show input element conditionally.
Update code:
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return const MaterialApp(
home: HomeView(),
);
}
}
class HomeView extends StatefulWidget {
const HomeView({Key? key}) : super(key: key);
@override
State<HomeView> createState() => _HomeViewState();
}
class _HomeViewState extends State<HomeView> {
bool shoulShowInput = false;
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: const Color.fromRGBO(35, 35, 35, 1),
appBar: AppBar(
title: const Center(
child: Text(
'To-Do',
style: TextStyle(
fontSize: 24,
fontFamily: "averagesans",
fontWeight: FontWeight.bold,
),
),
),
backgroundColor: const Color.fromRGBO(30, 30, 30, 1),
),
body: Column(
children: [
if (shoulShowInput) ...[const TextFieldInput()],
],
),
floatingActionButton: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
FloatingActionButton(
backgroundColor: const Color.fromRGBO(255, 255, 255, 1),
onPressed: () {
setState(() {
shoulShowInput = true;
});
},
child: const Icon(
Icons.add_rounded,
size: 35,
color: Color.fromRGBO(35, 35, 35, 1),
),
),
],
),
);
}
}
class TextFieldInput extends StatefulWidget {
const TextFieldInput({Key? key}) : super(key: key);
@override
_TextFieldInputState createState() => _TextFieldInputState();
}
class _TextFieldInputState extends State<TextFieldInput> {
@override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: const [
TextField(
decoration: InputDecoration(border: OutlineInputBorder()),
)
],
);
}
}
