The previous article describes the minimum steps to complete the Android input method, and it can only Spating the characters that correspond to the keys. The General East Asian language has a conversion process, such as Chinese input pinyin, need to be converted from pinyin to Chinese characters and then on screen. This article will add the candidate windows necessary to complete the conversion process based on the previous article. This article code can be found in https://github.com/palanceli/AndroidXXIME/tree/v2.
As shown, the form with red box is a candidate window, the character is called candidate string, click on the candidate window to enter the input control is called the screen. Hide the candidate window when no input is present and display the candidate window when the input string is not on the screen:
The introduction of candidate Windows requires two steps to complete:
First, create the Candidateview, the window needs to cover the following two methods, completed self-painting:
- OnDraw (canvas canvas);
- onmeasure (int widthmeasurespec, int heightmeasurespec);
Second, the following two methods covering the Androidxxime class:
- Oncreatecandidateview ();
In this method, create the Candidateview.
- OnKey (int primarycode, int [] keycodes);
In this method, the response key message, such as: When the letter is pressed, the candidate window and the candidate string, when the space is pressed, the screen candidate string, and so on.
Create Candidateview
PublicCandidateview (Context context) {Super(context); LOG.D ( This. GetClass (). toString (), "Candidateview:"); //set foreground, background color, font, sizeResources r =context.getresources (); SetBackgroundColor (Getresources (). GetColor (R.color.candidate_background,NULL)); Mcolornormal= R.getcolor (R.color.candidate_normal,NULL); Mverticalpadding=r.getdimensionpixelsize (r.dimen.candidate_vertical_padding); Mpaint=NewPaint (); Mpaint.setcolor (Mcolornormal); Mpaint.setantialias (true); Mpaint.settextsize (R.getdimensionpixelsize (r.dimen.candidate_font_height)); Mpaint.setstrokewidth (0); Setwillnotdraw (false);//overriding the OnDraw function should clear the tag} @Overrideprotected voidOnmeasure (intWidthmeasurespec,intHeightmeasurespec) {LOG.D ( This. GetClass (). toString (), "Onmeasure:"); intWMode =Measurespec.getmode (WIDTHMEASURESPEC); intWsize =measurespec.getsize (WIDTHMEASURESPEC); intMeasuredwidth = Resolvesize (50, Widthmeasurespec); Final intDesiredheight = ((int) Mpaint.gettextsize ()) +mverticalpadding; //the system determines the size of the form based on the return valuesetmeasureddimension (Measuredwidth, Resolvesize (Desiredheight, Heightmeasurespec)); } @Overrideprotected voidOnDraw (canvas canvas) {LOG.D ( This. GetClass (). toString (), "OnDraw:"); Super. OnDraw (canvas); if(Msuggestions = =NULL) return; //draw each set of candidate strings in turn intx = 0; Final intCount =msuggestions.size (); Final intHeight =getheight (); Final inty = (int) (((Height-mpaint.gettextsize ())/2)-mpaint.ascent ()); for(inti = 0; I < count; i++) {String suggestion=Msuggestions.get (i); floatTextWidth =Mpaint.measuretext (suggestion); Final intWordwidth = (int) TextWidth + x_gap * 2; Canvas.drawtext (suggestion, X+x_gap, y, mpaint); X+=Wordwidth; } } Public voidSetsuggestions (list<string>suggestions) { //set list of candidate strings if(Suggestions! =NULL) {msuggestions=NewArraylist<string>(suggestions); } invalidate (); Requestlayout (); }}
Overwrite Oncreatecandidateview () method
The method is called every time the input method is exhaled, as shown in the function name, where the candidate window is created.
Public class extends Inputmethodservice Implements Keyboardview.onkeyboardactionlistener {... Public View Oncreatecandidatesview () { log.d(this. getclass (). toString (), " Oncreatecandidatesview: "); New Candidateview (this); return Candidateview; } ...}
Override OnKey (int primarycode, int [] keycodes) method
Public classAndroidxximeextendsInputmethodserviceImplementsKeyboardview.onkeyboardactionlistener {... @Override Public voidOnKey (intPrimarycode,int[] keycodes) {inputconnection IC=getcurrentinputconnection (); Playclick (Primarycode); Switch(primarycode) { CaseKeyboard.keycode_delete://If you receive a delete key, delete one character before the cursorIc.deletesurroundingtext (1, 0); Break; CaseKeyboard.keycode_done://If you receive a done key, perform a carriage returnIc.sendkeyevent (Newkeyevent (Keyevent.action_down, Keyevent.keycode_enter)); Break; default: CharCode = (Char) Primarycode; if(Code = = ") {//If you receive a space if(M_composestring.length () > 0) {//If there is a writing string, the first candidate submission on the screenIc.committext (m_composestring, M_composestring.length ()); M_composestring.setlength (0); }Else{//If there is no writing string, the space is directly on the screenIc.committext ("", 1); } }Else{//Otherwise, count the characters in the writing stringm_composestring.append (code); Ic.setcomposingtext (m_composestring,1); } updatecandidates (); } }}
In the Updatecandidates () function, plug the Candidateview into the list of candidate strings and trigger the window to update.
When you select an input method in the system language and IME-change keyboard
The input method Inputmethodservice is called by the system as follows:
- OnCreate ()
- Oninitializeinterface () can perform initialization operations related to input methods in this method, such as loading a thesaurus.
- Onstartinput () calls this method each time the input focus is switched, where it can be done with session-related initialization, which is described later.
When an input control gets the focus, the outbound input method is lost to the focus, and this period becomes a session. When a session starts, the system calls the input method Inputmethodservice as follows:
- Onstartinput () is responsible for session-related initialization work. The input method is responsible for clearing the intermediate data from the last session when the session is switched, to prevent intermediate data from channeling the previous session into the next session. This and the Windows platform under the input method is very different, under Windows, Input Method a DLL, which is attached to the process of cutting out the input method, therefore, each input method process to save their own input method context, if you need to share data between processes (such as thesaurus), you need to adopt a shared memory mechanism While on Android, the input method is a separate process, all the data is stored only in the process, it is necessary to consider how to isolate the private data between different processes, such as the previous process input half but not on the screen of data, cut to another process or input control, should be cleared out. This callback function is used to do this kind of work.
- Oncreateinputview () creates an Input method keyboard layout.
- Oncreatecandidatesview () Creates a candidate window.
After completing the above steps, the input method has more candidate windows, and the light blue form is both:
In the processing is still very simple, such as the BACKSPACE is not supported to delete the input string, also does not support the click on the screen, and so on. These are the details of the business logic and can be cultivated slowly and intensively.
Write an Android IME 02--candidate window, convert