Explanation of what I am trying to do
I'm making a custom in-app keyboard that works on the same principle of this example. However, in my keyboard I'm using popup windows to display extra letter forms. In traditional Mongolian letters have different forms depending on if they are located at the beginning, middle, or end of a word. Usually these can be determined from the context, but sometimes a user needs to choose an alternate form explicitly from the popup key candidates.
Lets say that a user starts typing a word (where -
represent letters):
---
Then they chose a
from the popup (I'm only using a
to represent the concept of choosing a special Mongolian glyph form). The Unicode for this letter will be rendered as follows if they continue typing:
---a--
However, the Unicode is rendered as
---A
at the end of words. (a
and A
have the same code in Unicode.) So the user is confused why they chose a
from the popup key but it gets rendered as A
in the editor. If they would just keep typing, though, it will be fine since it gets rendered as a
in middle of words.
What I want to do it set some sort of temporary span on the a
of ---a
so that it doesn't get rendered as ---A
before they type the next letter. But if they add a space or move the cursor to a different location, then it will revert back to the default ---A
form for final letters. (That is, the temporary span will be cancelled.)
Real example
If the abstract a
and A
are too confusing, here is a real example. The user wants to type a Mongolian UE
form (Unicode \u1826\u180c
) in this word
But since \u1826\u180c
gets rendered like this at the end of words
the user is confused until they continue typing. I want the span to make it look like this
which can be temporarily rendered with \u1826\u180c\u200d
.
Documentation
The documentation says
If your IME does text prediction or requires multiple steps to compose a glyph or word, you can show the progress in the text field until the user commits the word, and then you can replace the partial composition with the completed text.
And it gives this example and image:
InputConnection ic = getCurrentInputConnection();
ic.setComposingText("Composi", 1);
ic.setComposingText("Composin", 1);
ic.commitText("Composing ", 1);
Problem
I was going to describe why it wasn't working in this section, but in the process of setting up my question here, I discovered that it actually works. So I will add my answer below as an example for other people are who doing something similar.
The following code sets a temporary composing span when the string in question is returned by the popup window
where
selectedItem
is the string chosen by the user from the key popup window candidates.Note that the
a
has an underline indicating that it is a composing span. (This is a contrived example from the question wherea
would be rendered asA
if the text were committed immediately.)This also works for the real example in the question
Committing the composing span
When it is confirmed that the user wants to keep the composing span (ie, they keep typing more letters in the word), it can be committed with
Abandoning the composing span
If the user clicks somewhere else, the composing span is not cancelled. But this is a different question.
Your keyboard can override
onUpdateSelection
to listen for cursor changes there. Then callto keep whatever text was in the composing region. Or
to get rid of it. See this answer for more.