通过 EditText 输入 unicode

ilo*_*mbo 1 unicode android button android-edittext

我在 EditText 框上有一个 TextWatcher。当用户键入时,我将 EditText Box 上的任何内容设置为 Button 标签。

EditText et = rootView.findViewById(R.id.userInput);
et.addTextChangedListener(this);
...

@Override public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
@Override public void afterTextChanged(Editable s) {}

@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
    Button btn = (Button) rootView.findViewById(R.id.myButton);
    btn.setText(s.toString());
    //btn.setText("\u00A9");
}
Run Code Online (Sandbox Code Playgroud)

但我不知道如何编写unicode 符号。注释行在取消注释时将Button文本设置为版权符号 © 。尽管在 EditText 框中输入相同的 unicode 代码不起作用。我试图在 EditText 中输入双反斜杠,仍然不好。

注:与此无关,btn.setText(s)不带toString()部件使用时,按钮内的文字有下划线。

澄清 由于一些评论和答案(现已删除),我意识到我不清楚。让我改写:

我不想以任何方式干扰用户输入的文本。现在,当用户在 EditText 中输入“Hello \u0089”时,我使用以下行将其复制到 Button 文本:

btn.setText(s.toString());
Run Code Online (Sandbox Code Playgroud)

它显示为"Hello \u0089"。我期待“你好‰”。为什么?因为如果我运行一个小测试并使用这一行:

btn.setText("Hello \u0089");
Run Code Online (Sandbox Code Playgroud)

它显示为“你好‰”。那么,使 unicode 在直接方法中正确显示但在通过 EditText 输入时不显示的区别是什么?

R. *_*des 5

那么,使 unicode 在直接方法中正确显示但在通过 EditText 输入时不显示的区别是什么?

啊,我希望人们不要再说“unicode”了。它是“文本”,而不是“Unicode”。Unicode 是一种标准。用户输入的文本不是一种标准,它只是文本。

顺便说一下,让我们看看我是否可以解释其中的区别。

当您像"Hello \u0089"在 Java 中一样编写字符串文字时,您的源代码文件将包含以下字符序列:

  1. 一个U+0022 ????????? ???;
  2. 一个U+0048 ????? ??????? ??????? ;
  3. 一个U+0065 ????? ???? ??????? ;
  4. 一个U+006C ????? ???? ??????? ;
  5. 一个U+006C ????? ???? ??????? ;
  6. 一个U+006F ????? ???? ??????? ;
  7. 一个U+0020 秒????;
  8. 一个U+005C ?????s? s?????s(也称为反斜杠);
  9. 一个U+0075 ????? ???? ??????? ;
  10. 一个U+0030 ????? ???;
  11. 一个U+0030 ????? ???;
  12. 一个U+0038 ????? ????? ;
  13. 一个U+0039 ????? ???; 和
  14. 一个U+0022 ????????? ???.

这里不涉及魔法。你输入的就是你得到的。该\u0089序列不是神奇。

但是,当您将相同的源文件提供给 Java 编译器时,Java 编译器与您(程序员)达成协议:它将转换它在以字符 U+005C U+0075 开头的字符串文字中找到的任何序列,并且是后跟四个十六进制数字字符转换为与这些十六进制数字指定的 Unicode 值对应的字符。该协议还包括一项规定,当您作为程序员想要实际表示该序列时,带有反斜杠、u 和十六进制数字,即六个字符,而不是一个。为此,您在反斜杠前面加上另一个反斜杠,Java 编译器除了删除这两个反斜杠之一之外,不会执行任何其他转换。

因此,虽然源文件将包含在引号之间包含 12 个字符的字符串文字,但 Java 编译器将按照 Java 规范中规定的与程序员的协议,将其转换为仅包含 7 个字符的字符串。

  1. 一个U+0048 ????? ??????? ??????? ;
  2. 一个U+0065 ????? ???? ??????? ;
  3. 一个U+006C ????? ???? ??????? ;
  4. 一个U+006C ????? ???? ??????? ;
  5. 一个U+006F ????? ???? ??????? ;
  6. 一个U+0020 秒????;
  7. 一个U+0089 ????????? ??????????????s?????????? ;

现在,当用户在某些 UI 中输入文本时,他们输入的不是 Java 字符串文字,稍后将由 Java 编译器处理,还是这样?

他们不是。当用户键入反斜杠后跟 au 和一些数字时,用户会得到一个反斜杠后跟 au 和一些数字。当用户\u0089在文本字段中输入时,该文本字段包含一个包含六个字符的字符串,而不是一个。那里没有 Java 编译器具有任何预先商定的约定来用它们的 Unicode 值来表示字符;它只是用户输入文本,而不是 Java 代码。

当用户\u0089在文本字段中输入时,文本字段包含一个字符串,该字符串可以在 Java 源代码中表示为"\\u0089",而不是"\u0089"

如果您想赋予这种用户输入与 Java 编译器赋予这些 Unicode 转义序列相同的含义,您需要在显示之前调用执行此类转换的代码。

为了完整性这是我根据上面的答案编写的 OP 发布代码。

public static String convertUnicode(CharSequence s) {
    StringBuffer result = new StringBuffer();
    Matcher m = Pattern.compile("\\\\u([0-9a-zA-Z]{4,4})\\b").matcher(s);
    while ( m.find() ) {
        char c = (char) Integer.parseInt(m.group(1), 16);
        m.appendReplacement(result, String.valueOf(c) );
    }
    m.appendTail(result);
    return result.toString();
}
Run Code Online (Sandbox Code Playgroud)