前言

Android 开发中,要监听 EditText 输入内容的变化,可以通过 addTextChangedListener 方法来实现,非常方便。

但是在 Cocos2d 中要监听 TextField 却没有那么容易,我经过实验发现有两种方法可以达到同样的目的,一种是监听文本的输入事件、另一种是在每一帧里监听文本变化。

监听文本输入事件

TextField 中可以通过 addEventListener 来监听事件的变化,它接受一个回调函数作为参数,并通过事件类型进行触发。回调函数中可以执行特定的操作,根据事件类型的不同,来响应用户的输入或者其他交互行为。

TextField 中有以下几种类型

  • EventType::ATTACH_WITH_IME:输入框获得焦点时触发的事件。
  • EventType::DETACH_WITH_IME:输入框失去焦点时触发的事件。
  • EventType::INSERT_TEXT:在输入框中插入文本时触发的事件。
  • EventType::DELETE_BACKWARD:从输入框中删除文本时触发的事件。

我们要监听输入从而获取到文字的变化就只需要关心 INSERT_TEXTDELETE_BACKWARD 就可以了,代码如下所示

1
2
3
4
5
6
7
textField->addEventListener([](Ref* sender, TextField::EventType type) {
    if (TextField::EventType::INSERT_TEXT == type
            || TextField::EventType::DELETE_BACKWARD == type) {
        // do something
        log("文本发生变化");
    }
});

在 update 中监听

上面这种情况在只需要监听一个输入控件的时候非常方便,但当多个控件同时需要监听的时候,这样处理起来就会变得稍显复杂,每个控件都需要监听,而且还要考虑到两个空间相互影响的问题。

例如:在登录的场景中,登录按钮需要在输入用户名和密码的情况下才能够被点击,只要有一个没有输入那就不能被点击。

类似这种多个输入框的情况在每一帧进行绘制的时候监听也是一种办法。代码如下

1
2
3
4
5
6
void update(float delta) {
    auto user = userTextField.getString();
    auto pwd = pwdTextField.getString();
    bool isLoginEnabled = user.empty() || pwd.empty();
    loginButton.setEnabled(!isLoginEnabled);
}

这样处理就会比每个控件里添加监听更简单了。

最后别忘了要想 update 生效,需要调用 scheduleUpdate

总结

本文介绍了在 Cocos2d 中两种监听 TextField 的方法,选用哪一种方法,需要根据场景选择合适的,在 update 中不适合做太复杂的逻辑,因为没一帧都会调用,逻辑太复杂会影响性能。