在this之后,检测语言方向的方法似乎是在已经输入的文本上使用一些Java库。
我有一个AutoCompleteTextView,所以我想在弹出软键盘时知道所选语言(在用户输入文本之前)。因此,当用户打开键盘语言时,我可以知道所选语言是RTL还是LTR(因此相应地改变布局)。例如,大多数使用本机RTL语言的用户都使用键盘语言和英语。
谢谢,
答案 0 :(得分:3)
要在EditText获得焦点时检测键盘的语言,您可以使用以下代码段
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
EditText editText = (EditText) findViewById(R.id.et);
editText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus) {
String language = getKeyboardLanguage();
Log.d("language is", language);
}
}
});
}
private String getKeyboardLanguage() {
InputMethodManager inputMethodManager = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
InputMethodSubtype inputMethodSubtype = inputMethodManager.getCurrentInputMethodSubtype();
return inputMethodSubtype.getLocale();
}
}
起初,我的键盘语言是荷兰语,并打印
D/language is: nl
然后,我将我的键盘语言改为英语/美国状态并打印
D/language is: en_US
要检测语言是RTL还是LTR,您可以使用此
private boolean isRTL(Locale locale) {
final int directionality = Character.getDirectionality(locale.getDisplayName().charAt(0));
return directionality == Character.DIRECTIONALITY_RIGHT_TO_LEFT ||
directionality == Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC;
}
这是我在https://stackoverflow.com/a/23203698/1843331
找到的RTL()方法使用从String language
:
String language = getKeyboardLanguage();
boolean isRTL = isRTL(new Locale(language));
答案 1 :(得分:1)
蒂姆所写的内容基本上是正确的,但仍存在问题。在解决之前 - 为什么这个问题是重要的设计模式?假设具有原生RTL语言的用户具有双键盘(英语和他的母语)并且使用英语版本的谷歌地图等应用程序。当他想要搜索地点时 - 他的逻辑是他可能想要用他的键盘的两种语言输入地址,搜索的文本视图应该支持这个。这一切都是常见的用户行为。我们来看看Google Maps App现在的设计:
正如您所看到的那样,由于软键盘语言的改变,搜索栏没有改变她的对齐方式,并且输入RTL语言并不直观。从UX的角度来看,我们需要同时监控onFocus
(当键盘出现时 - 什么是开放语言)和第一个字母输入时(因为用户可能会键入键盘)。
现在我的改进使Tim的解决方案更加准确(除了添加监控首字母类型的UX)。 Tim根据预期使用母语的locale.getDisplayName()
选择键盘语言。但根据Java Local documentation,当设备的默认语言环境是阿拉伯语时,所以当键盘为英语时locale.getDisplayName()
会尝试用阿拉伯语打印“英语”,依此类推。所以我的解决方案基于这样的假设,即如果用户的母语是RTL(阿拉伯语或希伯来语)之一,那么他的设备默认语言环境是英语(作为最流行的语言等)或他的母语是有道理的 - 然后locale.getDisplayName()
将在RTL字符中。如果这个假设不正确 - 那么我将在这里发布的相同逻辑应该应用于其他主要语言(并且学习者将检查所有受支持的Locale语言,即封闭组)。
//Under onCreate or etc.
textView.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus) {
detectRTL();
} else {
changeLayoutToLTR(); //default layout is LTR...
}
}
});
//in order to detect RTL in first letter
textView.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
detectRTL();
}
@Override
public void afterTextChanged(Editable s) {}
});
//Activity method
private void detectRTL() {
InputMethodManager inputMethodManager = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
InputMethodSubtype inputMethodSubtype = inputMethodManager.getCurrentInputMethodSubtype();
Locale mLocale = new Locale(inputMethodSubtype.getLocale());
String localeDisplayName = mLocale.getDisplayName();
//If the device Locale is English
if (Locale.getDefault().getISO3Language().equals("eng")) {
//this is how those languages displayed on English
if (localeDisplayName.equals("Hebrew") || localeDisplayName.equals("Arabic")) {
changeLayoutToRTL();
} else {
changeLayoutToLTR();
}
}
//Hidden assumption: If the device Locale isn't English - probably it's the RTL
else {
int directionality = Character.getDirectionality(localeDisplayName.charAt(0)); //display name of locale in it's native language...
if ( directionality == Character.DIRECTIONALITY_RIGHT_TO_LEFT ||
directionality == Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC ||
directionality == Character.DIRECTIONALITY_ARABIC_NUMBER ) {
changeLayoutToRTL();
} else {
changeLayoutToLTR();
}
}
}