Flutter高仿微信-第2篇-登录

Flutter高仿微信系列共59篇,从Flutter客户端、Kotlin客户端、Web服务器、数据库表结构、Xmpp即时通讯服务器、视频通话服务器、腾讯云服务器全面讲解。

Flutter高仿微信-项目实践59篇,点击查看详情

效果图:

/**
 * Author : wangning
 * Email : maoning20080809@163.com
 * Date : 2022/9/23 22:51
 * Description : 登录
 */
class Login extends StatelessWidget {
  const Login({super.key});

  @override
  Widget build(BuildContext context) {
    return const LoginPage(title: '登录页面');
  }
}

class LoginPage extends StatefulWidget {
  const LoginPage({super.key, required this.title});
  final String title;
  @override
  State<LoginPage> createState() => _LoginPageState();
}

class _LoginPageState extends State<LoginPage> {
  String account = SpUtils.getString(CommonUtils.LOGIN_ACCOUNT);
  final TextEditingController _usernameController = TextEditingController(text: "");
  final TextEditingController _passwordController = TextEditingController(text: "");
  String _username = '', _password = '';

  bool loadingVisible = false;

  //登录时loading对话框
  void _showLoadingDialog() {
    setState(() {
      loadingVisible = true;
    });
    Future.delayed(const Duration(seconds: 30),(){
      if(mounted){
        setState(() {
          loadingVisible = false;
        });
      }
    });
  }

  @override
  void initState() {
    super.initState();

    //界面build完成后执行回调函数,
    WidgetsBinding.instance.addPostFrameCallback((_) => showServiceTermsDialog());
  }

  //第一次进入,弹出服务条款对话框
  void showServiceTermsDialog(){
    bool isServiceTerms =  SpUtils.getBool(CommonUtils.SERVICE_TERMS);
    if(!isServiceTerms){
      WnBaseDialog.showServiceTermsDialog(context);
    }
  }

  //登录
  void _login(String account, String password) async {
    bool isNetwork = await CommonNetwork.isNetwork();
    if(!isNetwork) {
      CommonUtils.showNetworkError(context);
      return;
    }
    if(account.isEmpty){
      CommonToast.show(context, "账号不能为空");
      return;
    } else if(password.isEmpty){
      CommonToast.show(context, "密码不能为空");
      return;
    }
    _showLoadingDialog();
    LogUtils.d('登录: username=${account.trim()}, password=${password.trim()}');
    XmppManager.getInstance().connect(account, password, loginCallback: (data) async{
      LogUtils.d("登录返回状态:${data} , ${mounted}");
      if(mounted){
        if(data){

          VideoCallUtils.getInstance().connect(context);

          SpUtils.setString(CommonUtils.LOGIN_ACCOUNT, account);
          SpUtils.setString(CommonUtils.LOGIN_PASSWORD, password);
          await UserRepository.getInstance().syncFirst(account, AppManager.getInstance().packageName);
          _joinMucGroup();
          CommonToast.show(context, "登录成功!");
          Navigator.pop(context, true);

          eventBus.emit(BaseEvent(BaseEvent.TYPE_LOGIN, result: {}));
        } else {
          CommonToast.show(context, "登录失败!");
        }
        setState(() {
          loadingVisible = false;
        });
      }

    });
  }

  //登录成功自动加入群,
  void _joinMucGroup() async {
    List<GroupBean>? list = await GroupRepository.getInstance().findAllGroup();
    list?.forEach((groupBean) {
      XmppManager.getInstance().joinMucGroup(groupBean.groupId??"");
    });
  }

  @override
  Widget build(BuildContext context) {

    return WillPopScope(
        child: Stack(
          children: [
            Scaffold(
              appBar: WnAppBar.getAppBar(context, Text(widget.title), type : WnAppBar.TYPE_LOGIN),
              body: Center(
                child: SingleChildScrollView(
                  child: Column(
                    mainAxisAlignment: MainAxisAlignment.start,
                    children: <Widget>[
                      _getRoundImage('assets/icons/app_icon.png', 100.0),
                      SizedBox(
                        height: 60,
                      ),

                      _usernameAndPasswordWidget(),

                      SizedBox(height: 30,),
                      _getLoginButton(),
                      SizedBox(height: 30,),
                      _getRegisterButton(),
                    ],
                  ),
                ),
              ),

            ),

            Offstage(
              child: CommonLoadingDialog(msg: "请稍后。。。",),
              offstage: !loadingVisible,
            ),
          ],
        ), onWillPop: () async {
          //点击返回按钮,直接退出
            exit(0);
      }
    );
  }

  //账号、密码
  Widget _usernameAndPasswordWidget(){
    return Container(
      margin: const EdgeInsets.only(left: 12, right: 12),
      child: Column(
        children: [
          TextField(
            controller: _usernameController,
            keyboardType: TextInputType.emailAddress,
            decoration: InputDecoration(
              hintText: "请输入账号",
              icon: const Icon(
                Icons.account_box,
                size: 20.0,
              ),
              border: InputBorder.none,
              //使用 GestureDetector 实现手势识别
              suffixIcon: GestureDetector(
                child: Offstage(
                  child: Icon(Icons.clear),
                  offstage: _username == '',
                ),
                //点击清除文本框内容
                onTap: () {
                  setState(() {
                    _username = '';
                    _usernameController.clear();
                  });
                },
              ),
            ),
            onChanged: (value) {
              setState(() {
                _username = value;
              });
            },
          ),

          SizedBox(height:10),
          Container(
            height: 1,
            color: Colors.grey.shade400,
          ),
          // 密码输入框
          TextField(
            obscureText: true,
            controller: _passwordController,
            keyboardType: TextInputType.text,
            decoration: InputDecoration(
              hintText: "请输入密码",
              icon: const Icon(
                Icons.lock_open,
                size: 20.0,
              ),
              suffixIcon: GestureDetector(
                child: Offstage(
                  child: Icon(Icons.clear),
                  offstage: _password == '',
                ),
                onTap: () {
                  setState(() {
                    _password = '';
                    _passwordController.clear();
                  });
                },
              ),
              border: InputBorder.none,
            ),
            onChanged: (value) {
              setState(() {
                _password = value;
              });
            },
          ),

          Container(
            height: 1,
            color: Colors.grey.shade400,
          ),

        ],
      ),
    );
  }

  //头像按钮
  Widget _getRoundImage(String imageName, double size) {
    return Container(
      width: size,
      height: size,
      clipBehavior: Clip.antiAlias,
      decoration: BoxDecoration(
        borderRadius: BorderRadius.all(Radius.circular(size / 2)),
      ),
      child: Image.asset(
        imageName,
        fit: BoxFit.fitWidth,
      ),
    );
  }

  //登录按钮
  Widget _getLoginButton() {
    return MaterialButton(
        color: Colors.blue,
        textColor: Colors.white,
        padding: EdgeInsets.only(left: 28, top: 8, right: 28, bottom: 8),
        child: Text('登录',style: TextStyle(fontSize: 16),),
        onPressed: () {
          var username = _usernameController.text;
          var password = _passwordController.text;
          _login(username, password);
        },
    );
  }

  //注册按钮
  Widget _getRegisterButton() {
    return MaterialButton(
        color: Colors.blue,
        textColor: Colors.white,
        padding: EdgeInsets.only(left: 28, top: 8, right: 28, bottom: 8),
        child: Text('注册',style: TextStyle(fontSize: 16),),
        onPressed: () {
          Navigator.push(context, MaterialPageRoute(builder: (context) => Register()));
          //Navigator.pop(context, false);
        },
    );
  }

}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

六毛六66

你的鼓励是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值