3

I want to make a Password TextField in which the content visibility can be controlled by the suffix icon.

The code may like this:

import 'package:flutter/material.dart';
import 'package:get/get.dart';

void main() {
  runApp(TestGetX());
}

class TestGetX extends StatelessWidget {
  var eyeClosed = true.obs;

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text("Test GetX"),
        ),
        body: Align(
          alignment: Alignment.center,
          child: Padding(
            padding: EdgeInsets.all(20),
            child: TextFormField(
              obscureText: eyeClosed.value,
              decoration: InputDecoration(
                icon: Icon(
                  Icons.security,
                  color: Colors.purple,
                ),
                hintText: "Your Password",
                hintStyle: TextStyle(color: Colors.grey),
                suffix: Obx(
                  () => InkWell(
                    child: eyeClosed.value
                        ? Icon(Icons.visibility_off, color: Colors.grey)
                        : Icon(Icons.visibility, color: Colors.purple),
                    onTap: () {
                      eyeClosed.value = !eyeClosed.value;
                    },
                  ),
                ),
              ),
            ),
          ),
        ),
      ),
    );
  }
}

The suffix icon can be controlled by the Obx(), but the obscureText doesn't work. The direct way is to use Obx() on the TextFormField, but I don't think it is the best way.

Here is the result:

enter image description here

littleironical
  • 1,593
  • 1
  • 11
  • 25
刘维兵
  • 109
  • 1
  • 5

4 Answers4

3

You need to wrap Obx() in TextFormField

Obx(() => TextFormField(...))
Wesley
  • 186
  • 6
2
  • Create a controller for your login screen
class LoginController extends GetxController {
  RxBool hidePassword = true.obs;
  final passwordTextController = TextEditingController();
}
  • Extends your login screen widget from GetWidget
class LoginScreen extends GetWidget<LoginController> { 
  final LoginController controller = Get.find<LoginController>();
  @override
  Widget build(BuildContext context) {
   return(); //Define your widget
  }
}
  • Wrap your textfield in Obx(()=> )
Obx(() => FormBuilderTextField(
  name: 'password',
  controller: controller.passwordTextController,
  obscureText: controller.hidePassword.value,
  decoration: InputDecoration(
     suffixIcon: IconButton(
       icon: controller.hidePassword.value ? Icon(Icons.visibility_off) 
       : Icon(Icons.visibility),
       onPressed: () {
          controller.hidePassword.value = !controller.hidePassword.value;
       },
     ),
  ),
),
rubone
  • 53
  • 6
1

I have tried with your code & works fine with a little bit change

class LoginPage extends GetView<LoginController>

Also wrap the whole textFormField in Obx(()=>)

i extend a controller for taking values & calling methods in Getx.i can share my full code if you need.

  • Yes, thank you. Wrap the whole TextFormField in Obx is the best way to make it. But I am just wondering why getx cannot observe changes on a property, I mean why the argument of Obx() must be a builder retured a widget, rather than a value? if it is possible, I can simply do like this `Obx(() => eyeClosed.value)`. – 刘维兵 May 29 '21 at 07:09
0

You should use StatefulWidget when your state is changing. Plus, you can reach the same result you want, without "Get" package. I show you an example here:

import 'package:flutter/material.dart';

class Example extends StatefulWidget {
  @override
  _ExampleState createState() => _ExampleState();
}
class _ExampleState extends State<Example> {
  bool hidePassword = true;
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Padding(
          padding: EdgeInsets.symmetric(horizontal: 15),
          child: TextFormField(
            obscureText: hidePassword, // which is true by default
            decoration: InputDecoration(
                hintText: "Enter Password",
                suffixIcon: IconButton(
                  icon: hidePassword == false
                      ? Icon(
                          Icons.visibility_rounded,
                          color: Colors.purple,
                        )
                      : Icon(
                          Icons.visibility_off_rounded,
                          color: Colors.grey,
                        ),
                  onPressed: () {
                    setState(() {
                      // here we change the value
                      // if it's false, it gets true
                      // and if it's true, it gets false
                      hidePassword = !hidePassword;
                    });
                  },
                ),
            ),
          ),
        ),
      ),
    );
  }
}
  • Yes, that's the normal solution. But I plan to use GetX in my project and for consistency's sake I want to try in GetX way. – 刘维兵 May 10 '21 at 06:46