I'm trying to put these two buttons on the left, but to no avail. Can you give me any tips on how to make them stay on the left margin? I've tried to remove the Container and align using only the Row, but without success.
Container(
alignment: AlignmentDirectional.bottomStart,
padding: EdgeInsets.fromLTRB(0.0, 5.0, 70.0, 5.0),
child: Row(
children: [
Expanded(
child: ListTile(
title: const Text('CPF'),
leading: Radio<SingingCharacter>(
value: SingingCharacter.cpf,
groupValue: _character,
onChanged: (SingingCharacter? value) {
setState(() {
_character = value;
});
},
),
),
),
Expanded(
child: ListTile(
title: const Text('RNE'),
leading: Radio<SingingCharacter>(
value: SingingCharacter.rne,
groupValue: _character,
onChanged: (SingingCharacter? value) {
setState(() {
_character = value;
});
},
),
),
),
],
),
),
CodePudding user response:
enum SingingCharacter { cpf, rne }
class SignInScreen extends StatefulWidget {
const SignInScreen({Key? key}) : super(key: key);
@override
_SignInScreenState createState() => _SignInScreenState();
}
class _SignInScreenState extends State<SignInScreen> {
SingingCharacter? _character = SingingCharacter.cpf;
late AuthController authController;
TextEditingController userController = TextEditingController();
TextEditingController passwordController = TextEditingController();
final FocusNode focusNodePassword = FocusNode();
bool _obscureTextPassword = true;
@override
void initState() {
SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersive);
authController = AuthController.instance;
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.blue[800],
body: SizedBox(
width: double.maxFinite,
height: double.maxFinite,
child: Stack(
children: <Widget>[
Align(
alignment: Alignment.topCenter,
child: Image.asset(
"assets/images/onco.png",
width: 270,
height: 130,
color: Colors.white,
alignment: Alignment.center,
),
),
Positioned(
top: 120,
child: Container(
padding: const EdgeInsets.all(32),
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(20),
topRight: Radius.circular(20),
),
),
child: Column(
children: <Widget>[
Container(
alignment: AlignmentDirectional.topStart,
child: const Text(
"Acesso à minha conta",
style: TextStyle(
color: Colors.black54,
fontWeight: FontWeight.w600,
fontSize: 20,
),
),
),
const SizedBox(
height: 10,
),
Container(
alignment: AlignmentDirectional.topStart,
child: const Text(
"Tipo de documento",
style: TextStyle(
color: Colors.black38,
fontSize: 16,
),
),
),
Container(
alignment: AlignmentDirectional.bottomStart,
padding: EdgeInsets.fromLTRB(0.0, 5.0, 70.0, 5.0),
child: Row(
children: [
Expanded(
child: ListTile(
title: const Text('CPF'),
leading: Radio<SingingCharacter>(
value: SingingCharacter.cpf,
groupValue: _character,
onChanged: (SingingCharacter? value) {
setState(() {
_character = value;
});
},
),
),
),
Expanded(
child: ListTile(
title: const Text('RNE'),
leading: Radio<SingingCharacter>(
value: SingingCharacter.rne,
groupValue: _character,
onChanged: (SingingCharacter? value) {
setState(() {
_character = value;
});
},
),
),
),
],
),
),
if (_character == SingingCharacter.cpf)
TextFormField(
controller: userController,
inputFormatters: [
// obrigatório
FilteringTextInputFormatter.digitsOnly,
CpfInputFormatter(),
],
decoration: const InputDecoration(
labelText: 'CPF',
border: OutlineInputBorder(
borderSide: BorderSide(color: Colors.pinkAccent),
),
),
),
if (_character == SingingCharacter.rne)
TextFormField(
controller: userController,
inputFormatters: [
// obrigatório
FilteringTextInputFormatter.digitsOnly,
CpfInputFormatter(),
],
decoration: const InputDecoration(
labelText: 'RNE',
border: OutlineInputBorder(
borderSide: BorderSide(color: Colors.pinkAccent),
),
),
),
const SizedBox(height: 25),
Padding(
padding: const EdgeInsets.only(),
child: TextField(
focusNode: focusNodePassword,
controller: passwordController,
obscureText: _obscureTextPassword,
style: const TextStyle(
fontFamily: 'WorkSansSemiBold',
fontSize: 16.0,
color: Colors.black),
decoration: InputDecoration(
border: OutlineInputBorder(
borderSide: BorderSide(color: Colors.pinkAccent),
),
hintText: 'Senha',
hintStyle: const TextStyle(
fontFamily: 'WorkSansSemiBold',
fontSize: 16.0,
),
suffixIcon: GestureDetector(
onTap: _toggleLogin,
child: Icon(
_obscureTextPassword
? Icons.visibility_off
: Icons.visibility,
size: 25.0,
color: Colors.black,
),
),
),
onSubmitted: (_) {
_toggleSignInButton();
},
textInputAction: TextInputAction.go,
),
),
const SizedBox(height: 26),
Container(
alignment: AlignmentDirectional.topStart,
child: InkWell(
onTap: () {
Navigator.pushNamed(
context,
AppRoutes.forgotPasswordScreen,
);
},
child: const Text(
"ESQUECI MINHA SENHA",
style: TextStyle(
color: Color(0xff05498A),
fontWeight: FontWeight.w500,
fontSize: 16,
),
),
),
),
const SizedBox(height: 30),
Container(
height: 45,
width: double.maxFinite,
decoration: const BoxDecoration(
color: Color(0XFF1A5EB6),
borderRadius: BorderRadius.all(
Radius.circular(5),
),
),
child: TextButton(
child: const Text(
'ENTRAR',
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.w600,
fontSize: 18,
),
),
onPressed: () async {
try {
await authController.login(
username: userController.text,
password: passwordController.text,
);
Navigator.pushNamed(
context,
AppRoutes.changeUserScreen,
);
} catch (e) {
SnackBar snackError = SnackBar(
content: Text('$e', textAlign: TextAlign.center),
duration: const Duration(seconds: 5),
backgroundColor: Colors.red,
);
ScaffoldMessenger.of(context)
.showSnackBar(snackError);
}
},
),
),
const SizedBox(height: 24),
Container(
height: 45,
width: double.maxFinite,
decoration: BoxDecoration(
border: Border.all(
color: Colors.black12,
),
borderRadius: BorderRadius.circular(5.0),
),
child: TextButton(
child: const Text(
'CRIAR A CONTA',
style: TextStyle(
color: Color(0XFF1A5EB6),
fontWeight: FontWeight.w600,
fontSize: 18,
),
),
onPressed: () {
Navigator.pushNamed(context, AppRoutes.signUpScreen);
},
),
),
const SizedBox(height: 150),
const Text(
"Estou com dificuldades de acesso",
style: TextStyle(
color: Color(0xff828282),
fontWeight: FontWeight.w400,
fontSize: 16,
),
),
const SizedBox(
height: 15,
),
InkWell(
onTap: () {
showAlertDialog(context);
},
child: const Text(
"FALE CONOSCO",
style: TextStyle(
color: Color(0xff05498A),
fontWeight: FontWeight.w500,
fontSize: 16,
),
),
),
const SizedBox(
height: 15,
),
],
),
),
)
],
),
),
);
}
void _toggleSignInButton() {}
void _toggleLogin() {
setState(() {
_obscureTextPassword = !_obscureTextPassword;
});
}
}
CodePudding user response:
ListTile occupies an entire row, and if you wrap each ListTile with Expanded widget then it gets divided into 2 ListTile in the same row. So if you want to create 2 Radio's and align them into the left row, then don't use listTile and expanded.
Instead create a row, pass 2 columns. Each column will have 2 Widgets. A text widget and a Radio Widget. That's how you can achieve your desired outlook.
Scaffold(
appBar: AppBar(),
body: Column(children: [
Row(
children: [
Column(
children: [
const Text("Radio 1"),
Radio<SingingCharacter>(
value: SingingCharacter.cpf,
groupValue: _character,
onChanged: (SingingCharacter? value) {
setState(() {
_character = value;
});
},
),
],
),
const SizedBox(
width: 20,
),
Column(
children: [
const Text("Radio 2"),
Radio<SingingCharacter>(
value: SingingCharacter.rne,
groupValue: _character,
onChanged: (SingingCharacter? value) {
setState(() {
_character = value;
});
},
),
],
),
],
)
]),
);
CodePudding user response:
Container(
alignment: AlignmentDirectional.bottomStart,
padding: EdgeInsets.fromLTRB(0.0, 5.0, 70.0, 5.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.start, // add this line
children: [
// Expanded(
// child:
ListTile(
title: const Text('CPF'),
leading: Radio<SingingCharacter>(
value: SingingCharacter.cpf,
groupValue: _character,
onChanged: (SingingCharacter? value) {
setState(() {
_character = value;
});
},
),
),
// ),
// Expanded(
// child:
ListTile(
title: const Text('RNE'),
leading: Radio<SingingCharacter>(
value: SingingCharacter.rne,
groupValue: _character,
onChanged: (SingingCharacter? value) {
setState(() {
_character = value;
});
},
),
),
// ),
],
),
),