Как обновить извлеченный текст в пользовательском представлении редактора
Я создал собственный редактор для вертикального монгольского текста. Окруженные представления показывают мой пользовательский редактор. Их клавиатурами внизу являются системные клавиатуры.
Когда системная клавиатура вводит в нее текст в горизонтальной ориентации, клавиатура, скорее всего, будет отображать извлеченный текст, а не мой пользовательский редактор. Представление в кружке ниже - это извлеченное текстовое представление (которое не обновляется моим пользовательским редактором).
Мне нужно как-то отправлять обновления из моего представления в менеджер методов ввода. Это указано в InputConnection
документация:
Авторы редактора: как правило, старайтесь соблюдать поля в запросе количества возвращаемых символов, но если производительность или удобство требуют иного, пожалуйста, не стесняйтесь делать то, что наиболее подходит для вашего случая. Кроме того, если
GET_EXTRACTED_TEXT_MONITOR
флаг установлен, вы должны звонитьInputMethodManager.updateExtractedText(View, int, ExtractedText)
всякий раз, когда вы звонитеInputMethodManager.updateSelection(View, int, int, int, int)
,
Я изучал исходный код, связанный с извлеченным текстом
но я потерялся
Вот самое близкое, что я получил. Это метод внутри моего пользовательского редактора.
private void reportExtractedText() {
// TODO we should be modifying this based on an ExtractedTextRequest
ExtractedText et = new ExtractedText();
final CharSequence content = getText();
final int length = content.length();
et.partialStartOffset = 0;
et.partialEndOffset = length;
et.startOffset = 0;
et.selectionStart = getSelectionStart();
et.selectionEnd = getSelectionEnd();
et.flags = 0;
et.text = content.subSequence(0, length);
// FIXME: should be returning this from the ExtractedTextRequest
int requestToken = 0;
InputMethodManager imm = (InputMethodManager) getContext()
.getSystemService(Context.INPUT_METHOD_SERVICE);
if (imm == null) return;
imm.updateExtractedText(this, requestToken, et);
}
Когда я нахожусь в моем редакторе, у меня нет ссылки на ExtractedTextRequest
, который должен использоваться, чтобы изменить то, что я включаю в свое извлеченное текстовое обновление.
Вот еще один метод внутри моего BaseInputConnection
подкласс (немного измененный отсюда). У меня есть доступ к ExtractedTextRequest
но это не то, откуда я звоню обновления. Это приведет к тому, что извлеченное текстовое представление будет правильно отображать исходный текст, но обновления по-прежнему не будут применены. Этот метод вызывается InputMethodService
и также может быть вызван пользовательскими методами ввода.
@Override
public ExtractedText getExtractedText(ExtractedTextRequest request, int flags) {
if (request == null)
return null;
if ((flags & GET_EXTRACTED_TEXT_MONITOR) != 0)
mExtractedTextRequest = request; // mExtractedTextRequest currently doing nothing
Editable editable = getEditable();
if (editable == null) {
return null;
}
int selStart = Selection.getSelectionStart(editable);
int selEnd = Selection.getSelectionEnd(editable);
ExtractedText extract = new ExtractedText();
extract.flags = 0;
extract.partialStartOffset = -1;
extract.partialEndOffset = -1;
extract.selectionStart = selStart;
extract.selectionEnd = selEnd;
extract.startOffset = 0;
if ((request.flags & GET_TEXT_WITH_STYLES) != 0) {
extract.text = new SpannableString(editable);
} else {
extract.text = editable.toString();
}
return extract;
}
Я добавил более общий MCVE здесь.
1 ответ
Ключом к обновлению извлеченного текстового представления является установка ExtractedTextRequest
маркер. Без токена обновления не вступают в силу. Спасибо за этот ответ за помощь с токеном.
Мы можем токен во входном соединении getExtractedText()
с request.token
а затем добавьте метод в пользовательское представление, чтобы установить его:
@Override
public ExtractedText getExtractedText(ExtractedTextRequest request, int flags) {
if (request == null)
return null;
Editable editable = getEditable();
if (editable == null) {
return null;
}
// passing the token to the custom view here
mMongolEditText.setExtractedTextToken(request.token);
int selStart = Selection.getSelectionStart(editable);
int selEnd = Selection.getSelectionEnd(editable);
ExtractedText extract = new ExtractedText();
extract.flags = 0;
extract.partialStartOffset = -1;
extract.partialEndOffset = -1;
extract.selectionStart = selStart;
extract.selectionEnd = selEnd;
extract.startOffset = 0;
if ((request.flags & GET_TEXT_WITH_STYLES) != 0) {
extract.text = new SpannableString(editable);
} else {
extract.text = editable.toString();
}
return extract;
}
Это позволяет мне использовать токен, когда я звоню InputMethodManager.updateExtractedText()
из моего собственного представления.
private int mExtractedTextRequestToken = 0;
void setExtractedTextToken(int token) {
mExtractedTextRequestToken = token;
}
private void reportExtractedText() {
int requestToken = mExtractedTextRequestToken;
ExtractedText et = new ExtractedText();
final CharSequence content = getText();
final int length = content.length();
et.partialStartOffset = -1;
et.partialEndOffset = -1;
et.startOffset = 0;
et.selectionStart = getSelectionStart();
et.selectionEnd = getSelectionEnd();
et.flags = 0;
et.text = content.subSequence(0, length);
InputMethodManager imm = (InputMethodManager) getContext()
.getSystemService(Context.INPUT_METHOD_SERVICE);
if (imm == null) return;
imm.updateExtractedText(this, requestToken, et);
}
Вы можете посмотреть мой полный код здесь: