Hi, I'm new to the flutter and looking for a way to expand a widget so that when I click on it, I get a text field that allows me to input data from the user.
So far, I've tried dynamic test fields or gesture detectors, but I couldn't find the answer I wanted, so I'm asking questions. Is there any class that I can refer to?
CodePudding user response:
You need to do few things...
create a variable
bool textFieldDisplayed = false;
Wrap your widget with GestureDetector and use onTap of GestureDetector.
onTap: () {
textFieldDisplayed = true;
setState(() {});
},
check the condition before your textField
if(textFieldDisplayed)
TextFormField()
The whole code is below and you can make some changes as per yours....
class _MyHomePageState extends State<MyHomePage> {
TextEditingController controller = TextEditingController();
bool textFieldDisplayed = false;
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
textFieldDisplayed = false;
setState(() {});
},
child: Scaffold(
body: GestureDetector(
onTap: () {
textFieldDisplayed = true;
setState(() {});
},
child: Center(
child: Container(
color: Colors.blue,
child: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: [
if(textFieldDisplayed)
Padding(
padding: const EdgeInsets.all(10.0),
child: SizedBox(
width: 100,
child: TextFormField(
decoration: InputDecoration(
enabledBorder: OutlineInputBorder(
borderSide: const BorderSide(width: 1, color: Colors.white),
borderRadius: BorderRadius.circular(5.0),
),
border: OutlineInputBorder(
borderSide: const BorderSide(width: 1, color: Colors.white),
borderRadius: BorderRadius.circular(5.0),
),
focusedBorder: OutlineInputBorder(
borderSide: const BorderSide(width: 1,color: Colors.white),
borderRadius: BorderRadius.circular(5.0),
),
),
controller: controller,
),
),
),
Container(height: 20,width: 100,)
],
),
),
),
),
),
);
}
}
CodePudding user response:
You can achieve this using the Visibility widget. Rohan's answer is correct but I wouldn't recommend using if statements in building widgets in a list since it makes the code look messy. I'll put and example bellow:
import 'package:flutter/material.dart';
const Color darkBlue = Color.fromARGB(255, 18, 32, 47);
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
bool showWidget = false;
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark().copyWith(
scaffoldBackgroundColor: darkBlue,
),
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Center(
child: Column(
children: [
Visibility(
visible: showWidget,
child: MyWidget()
),
MyButton(
onTap: (){
setState((){
showWidget = !showWidget;
});
}
)
],
),
),
),
);
}
}
class MyWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Text(
'Hello, World!',
style: Theme.of(context).textTheme.headline4,
);
}
}
class MyButton extends StatelessWidget {
final Function() onTap;
const MyButton({required this.onTap});
@override
Widget build(BuildContext context) {
return InkWell(
onTap: onTap,
child: const Text('Press me!')
);
}
}
When visibility's value is true, it will display the content of its child property. Otherwise it will return a const SizedBox.shrink() by default. Or, you can change whatever widget you want to return adding the 'replacement' property.
Copy the code above and try on a new DartPad. Good Luck!