In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-03-28 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
In this issue, the editor will bring you about how to understand IMF in Android development. The article is rich in content and analyzes and narrates it from a professional point of view. I hope you can get something after reading this article.
Since SDK 1.5, Android has opened up its IMF (Input Method Framework), allowing us to develop our own input methods. The reference for the development of input method * is the Sample-SoftKeyboard that comes with Android. Although this example contains only English and digital input, it is still complete and clear, which is of great help for us to start Android development.
A brief introduction to IMF
An IMF structure consists of three main parts:
Input method manager: manages the interaction between parts. It is a client-side API that exists in the context of each application and is used to communicate and manage global system services that manage interactions between all processes.
Input method (IME): implements a stand-alone interaction module that allows users to generate text. The system binds a current input method. Let it be created and generated to determine when the input method hides or shows its UI. Only one IME can be running at a time.
Client application: controls the status of input focus and IME through the input method manager. Only one client can use IME at a time.
1 、 InputManager
Called by UI controls (View,TextView,EditText, etc.) to manipulate the input method. For example, open, close, switch input method and so on.
It is the core API of the entire input method framework (IMF) structure, dealing with the interaction between the application and the current input method. You can get an instance of InputMethodManager through Context.getSystemService ().
In the development process, the most basic and important thing is to form the habit of reading API. Good programmers should learn to lock themselves in a small dark room, cut off networking and contact with the outside world, and write excellent programs only by relying on the development environment and API documents in their computers, as well as three meals a day sent by beautiful maids. This is called closed door in martial arts novels and Clean Room in software development. Haha.
The API document for Android is at:% SDK_ROOM%/docs/reference/index.html
Location of the InputManager class:% SDK_ROOM%/docs/reference/android/view/inputmethod/InputMethodManager.html
Since this class has little to do with the Sample we are going to talk about, we will not analyze it in detail here. Please read the API doc by yourselves.
2 、 InputMethodService
Including the internal logic of the input method, keyboard layout, word selection, etc., and finally submit the selected characters through commitText. The basis for implementing an input method is a class called InputMethodService. For example, if you want to implement a Google input method, you need to extends this class. The SoftKeyboard Sample we are going to learn next is also the extends class. The location of the InputMethodService class is:% SDK_ROOM%/docs/reference/android/inputmethodservice/InputMethodService.html
InputMethodService is a complete implementation of InputMethod, on which you can extend and customize. Its main methods are as follows:
◆ onInitializeInterface (), as its name implies, is called when the interface is initialized, usually due to changes in the configuration file that cause the function to be executed
◆ onBinndInput (), which is called when another client connects to the input method
◆ onStartInput () is a very important callback, which is called when the user has already started typing in the edit box. For example, when you click on an input box, we need to set some features of the input method according to the information in the input box, which is very experienced in Sample.
◆ onCreateInputView () returns a hierarchical input view and is called only when the view is displayed * times
◆ onCreateCandidatesView () is the same as onCreateInputView (), except that you create a view of the candidate box.
◆ onCreateExtractTextView () is a special view in full-screen mode.
◆ onStartInputView () is called when the input view is displayed and the input has already started in a new input box.
Basically, the customization of the input method is implemented around this class, which mainly provides a basic user interface framework (including input view, candidate word view and full-screen mode). But these are customized by the implementers themselves. The implementation here is to place all the elements in a single window managed by InputMethodService. It provides a lot of callback API, which we need to implement ourselves. Some of the default settings include:
◆ soft keyboard input view, which is usually placed at the bottom of the screen.
◆ candidate word view, which is usually placed on top of the input view.
◆ when we type, we need to change the interface of the application to accommodate the placement rules of these views. For example, if you type on Android, the edit box will automatically deform to free up a soft keyboard.
Two very important views:
1. Soft input view. Is the main place to interact with users: keystrokes, drawing, or other ways. The usual implementation is to simply use a view to handle all the work and return a new instance when onCreateInputView () is called. Test whether the input view needs to be displayed by calling the system's onEvaluateInputViewShow (), which is implemented according to the current context. When the state of the input method changes, you need to call updateInputViewShown () to re-evaluate.
two。 Candidate word view. After the user enters some characters, the input method may need to provide the user with a list of available candidate words. The management of this view is different from that of the input view, because this view is very short-lived and is only displayed when there are candidates. You can use setCandidatesViewShow () to set whether this view needs to be displayed. Because of the frequency of this display, it is generally not destroyed and does not change the view of the current application.
* *, with regard to the generation of text, this is the ultimate goal of an IME. It links IME and applications through InputConnection: it can directly generate the desired keystroke information, or even edit it directly in candidate and submitted text. When the user switches between different input targets, IME keeps calling onFinishInput () and onStartInput (). In both functions, all you need to do over and over again is to reset the state and deal with the information of the new input box.
The above is the most basic introduction of an input method, which will be explained according to the SoftKeyboard in Sample below.
2. Create an Eclipse project
Here, we use the SoftKeyboard Sample under the * version of Android SDK 2.3.3 to create a project. In fact, the Sample has existed since version 1.5. At the same time, because SoftKeyboard can be misunderstood as a subclass of KeyBoard, it is specially renamed to InputMethodServiceSample, which is more in line with its functions and features.
Click Finish to complete the project creation, and you can see that the project structure is as follows:
To run this Sample on the Android SDK 2.3.3 simulator, you need to choose to use this Sample in Setting and select the name of this Sample in Language&keyboard.
When you try to select Sample Soft Keyboard, a security prompt appears on Android. IME does have to choose what it trusts, because it can collect and record all your input, which can be scary if used by willing people.
After selecting Sample Soft Keyboard as our input method, enter the place where you need the input method, here take the SMS interface as an example, press long in the input box, the "Edit text" menu will appear, and click "input method" to enter the input method selection box of the current input interface. You can use the input method to switch to this input method to see its keyboard.
Then you can see that the Soft keyboard keyboard is as follows:
III. Configuration and resource file parsing
In addition to the source code that will be analyzed later, the configuration and resource files are introduced here.
1. AndroidMainifest.xml
There is a configuration description file for every Android application. Here, Sample declares itself as a service and binds it to the input method. Its intent-filter is directly used by the InputMethod interface, which is also the interface of all input methods.
2. Res directory
Place the resource, that is, the resource file, which contains a lot of things, as follows.
(1) drawable directory, where the icon file is placed.
(2) values directory, which contains strings.xml and xml files for some custom types and values.
Strings.xml
-ime_name defines the name of the input method
-the separator of a word_separators word, that is, a symbol that may be used to indicate the completion of a word input, such as spaces, punctuation, etc.)
-label_xx_key defines the label of the confirmation key for the soft keyboard. As you can see in the later code parsing, the program sets the icon or label of the EnterKey according to the information in the input box. For example, typing on a URL will display a search icon, while when editing a text message, if you write it at the recipient, EnterKey is the Next tag that jumps directly to the body of the message.
Dimens.xml defines the size information of the soft keyboard, including key height (key_height), candidate word font height (candidate_font_height), candidate word vertical gap (candidate_vertical_padding).
Color.xml, which defines the background colors of candidate words, such as candidate_normal, candidate_recommended, candidate_background, and other colors.
(3) layout directory, save the layout configuration file. There is only one configuration file: input.xml, which defines the input view information, including id (android:id= "@ + id/keyboard"), placed at the bottom of the screen (android:layout_alignParentBottom= "true"), horizontal * fill (android:layout_width= "match_parent"), and vertically contains sub-content (android:layout_height= "wrap_content").
(4) xml directory, the files are as follows:
Method.xml, which provides configuration information for search management.
Qwerty.xml, full keyboard layout file for English characters. The definition is intuitive and easy to understand.
Symbols_shift.xml and symbols.xml are full keyboard layout files for punctuation characters.
IV. Source code parsing
(1) Overview
From the InputMethodServiceSample project, we can see that the implementation of an input method requires at least four files: CandidateView, LatinKeyboard, and LatinKeyboardView,SoftKeyboard:
◆ CandidateView is responsible for displaying the candidate area above the soft keyboard.
◆ LatinKeyboard is responsible for parsing and saving keyboard layouts and providing word selection algorithms for use in running programs. Among them, the keyboard layout is stored in the resources as XML files. For example, we press the letters b and a under the Chinese character input method. LatinKeyboard is responsible for turning these two letters into Dad, Ba, Ba, etc., and display them on CandidateView.
◆ LatinKeyboardView is responsible for the display, which is the button we see. Together with CandidateView, it forms InputView, which is what we see as a soft keyboard.
◆ SoftKeyboard inherits InputMethodService, starting an input method, which is actually starting an InputMethodService. When the SoftKeyboard input method is used, the startup starts the SoftKeyboard Service.
(2) LatinKeyboard.java
The soft keyboard class directly inherits the Keyboard class and defines a Keyboard layout in xml format to implement a Latin input keyboard. This is just to create a keyboard object and does not give the means for the specific layout.
To better understand the LatinKeyboard class, here's a brief introduction to the Keyboard class. Keyboard can initialize itself by loading a xml that displays the keyboard layout, and can save the properties of the keys for those keyboards. He has three constructors:
◆ Keyboard (Context context, int xmlLayoutResId), created with context and xml resource id index xml files.
◆ Keyboard (Context context, int xmlLayoutResId, int modeId), this is similar to the above, except that there is an extra modeld.
◆ Keyboard (Context context, int layoutTemplateResId, CharSequence characters, int columns, int horizontalPadding), which is more complex, creates a keyboard with an empty xml layout template, and then fills the template with the specified characters from left to right and from top to bottom.
The source code of this file completely inherits keyboard and initializes it directly with the parent class constructor.
Since you override the createKeyFromXml of the Keyboard class (Resources res, Row parent, int x, int y, XmlResourceParser parser), in order to return a Key object, you might as well simply create a LatinKey object. From this we can see the requirements of object orientation and the use of frameworks.
Next, this file overloads a function of createKeyFromXml, which is a callback function, which is called when the keyboard depicts a key, loads a key from a xml resource file, and places it at the (XQuery y) coordinate. It also determines whether the key is an enter key and saves it. Here, in order to return a Key object, you directly create a LatinKey object of the inner class. From this we can see the requirements of object orientation and the use of frameworks.
In addition, there is another function: setImeOptions, which sets the appropriate label for the enter key of this keyboard based on the current information of the edit box. Different input boxes will result in different enter keys of label or icon. One trick in this function is to use some bit information of imeOption, such as IME_MASK_ACTION, and so on. It is mainly to view the Action information of EditorInfo. Here are:
◆ IME_ACTION_GO: the go action that takes the user to a target of the input box. The confirmation key will not have icon, only label: GO
◆ IME_ACTION_NEXT: the next operation that takes the user to the write input box of the text box. For example, when editing a short message, the content is the next text field of the recipient's mobile phone number box. It's just a NEXT label.
◆ IME_ACTION_SEARCH: search operation. The default action is search. For example, when typing in the URL box, the default is the search operation, which provides an icon like a magnifying glass.
◆ IME-ACTION_SEND: send operation. The default action is to send the current content. For example, when you type in the content box of a short message, it is usually followed by a send operation. It also provides only one Label:SEND.
◆ DEFAULT: by default, there are no special requirements for text boxes, so you just need to set the icon of return.
*, which also defines an inner class-LatinKey, which directly inherits Key to define a single key. Its only overloaded function is isInside (int x, int y), which is used to determine whether a coordinate is within the key. It is overloaded to determine whether the key is a cancel key, and if so, reduce the Y coordinate by 10px, which, according to his explanation, is used to restore the target area of the key that can turn off the keyboard.
(3) LatinKeyboardView.java
Here is a View, which naturally inherits from View, because the keyboard created earlier is just a concept and cannot be instantiated as a UI, so you need to draw with the help of a VIEW class. This class simply inherits the KeyboardView class and then overloads an action method, which is onLongPress.
It will be called when there is a long keystroke event, first determine whether the keystroke is a cancel key, and if so, send an event that the OPTIONS key is pressed to the keyboard by calling the OnKeyboardActionListener object where KeyboardView is placed. It is used to mask the call key and then send an unknown code of the key.
(4) CandidateView.java
CandidateView is a candidate word display view that provides a view of candidate word selection that inherits directly from the View class. When we enter characters, it should be able to display certain prompts according to the characters, such as pinyin homonyms, associative words and so on.
1. Let's take a look at what important variables it defines:
◆ mService: the host class of the candidateView, that is, why the view is served by the input method.
◆ mSuggestions: recommended. For example, when we enter some letters, the input method hopes to make association suggestions according to the input.
◆ mSelectedIndex: the index of the word selected by the user.
◆ mSelectionHighlight: a class that depicts the highlighted area of the selection.
◆ mTypedWordValid: whether the word you typed is legal and correct.
◆ mBgPadding: the background filled area.
◆ mWordWidth: the width of each candidate word.
◆ mWordX: the X coordinate of each candidate word. With these two variables, the candidate key can be accurately drawn on the screen.
◆ mColor*: defines various colors.
◆ mPaint: a drawing class, which will be used later
◆ mVerticalPadding: vertically fills an area.
◆ mTargetScrollX: the Abscissa of the target scroll, that is, where to scroll the target.
◆ mTotalWidth: total width
◆ mGestureDetector: declare a gesture monitor
GestureDetector objects seem rare, so let's take a look at android.view.GestureDetector. This is a class related to action events that can be used to detect a variety of action events, which is called a gesture monitor. Its callback function is GestureDetector.OnGestureListener, which is executed when the action occurs and can only be issued when it is touched. It has no effect with the scroll ball. To use this, you usually first create an object, as shown in the code, and then set GestureDetector.OnGestureListener to write the code to be executed in onTouchEvent (MotionEvent) at the same time.
two。 Constructor, mainly the initialization of some variables.
First initialize mSelectionHighlight, which is a drawable object, and use the setState method of drawable to set the initial state of the drawable. At the same time, add a color.xml file to the res directory to define all the color resources used, and then use R index, these resources can be added to their own R.java content, can be directly referenced. The rest of the content is to initialize the background, the background color of the selected and unselected view, which is defined in the previous color.xml. To obtain in this way:
Resources r = context.getResources ()
The method to get the current resource object.
SetBackgroundColor (r.getColor (R.color.candidate_background))
A gesture detector (gesturedetector) is then initialized, and its Listener overloads a method, onScroll, which is triggered when the gesture detector finds a scroll action. In this function, the main thing is to make the judgment of sliding.
A lot of view methods are used here: getScrollX (); getWidth (); scrollTo (sx, getScrollY ()); invalidate (); we explain as follows:
◆ getScrollX (): gets the Abscissa of the scrolled view
◆ scrollTo (): scroll to target coordinates
◆ getScrollY (): gets the ordinate of the scrolled view
◆ invalidate (): make view redraw
In this case, distanceX is the X-axis distance scrolled since the last call to onscroll. Assuming that the view has not been scrolled before, * scrolls * * and the coordinates are in the display area, sx=getScrollX () + distanceX, then view is in the position of scrollTo. If the sx exceeds the width of the * display, the scrollTo rolls back to the original sx, that is, it does not move. In other words: the system scrolls to create a sense of inertia, when you actually view to the X coordinate point, the system gives you another distanceX, this distanceX is not the distance between the two actions, but should be the distance between the stop point of the last scrolling action and the stop point of this scrolling action, the distance is calculated by the system itself, we don't care, as long as we reach the * boundary, the view will no longer scroll, or scroll in place.
Next:
◆ setHorizontalFadingEdgeEnabled (true); / / sets whether the horizontal edge fades out when the view scrolls horizontally.
◆ setWillNotDraw (false); / / view does not draw itself
◆ setHorizontalScrollBarEnabled (false); / / No horizontal scroll bar is set
◆ setVerticalScrollBarEnabled (false); / / No vertical scroll bar is set
3. SetService sets the host input method.
4. ComputeHorizontalScrollRange, which represents the horizontal scrolling area of the view, returns the overall width of the candidate view.
5. OnMeasure, overloaded from the view class, is called by the parent view during the layout phase. For example, when the parent view needs to be laid out according to the size of its child views, you need to call back this function to see the size of the view. When calling this function, you must call setMeasureDimension internally to save the width and height, or there will be an exception. It is reloaded here for the system to detect the size of the character area to be drawn, because the font may have a size and should be based on the font. It first calculates its expected width, calls resolveSize to see if it can get the width of 50px, and then calculates the desired height, based on the font and the padding of the display prompt area.
6. OnDraw, the main function of view, each view must rewrite this function to draw itself. It provides a canvas, and if it is empty, the parent class is called directly to draw.
The internal logic here is roughly as follows:
Determine whether there is a candidate word, if not, do not need to draw.
Initialize the filled area of the background and get it directly from the background of view.
For each candidate word, get its text, then calculate its width, and then add the gap on both sides.
Determine whether the current word is selected: the position of the touch + the position of the scroll. If it is between the left and right of the current word, the highlighted area is drawn on the canvas, the size of the highlighted area is set to the size of the current word, and the index of the selected word is saved.
Draw the text on the canvas of the candidate word, and it makes a decision to determine which word is recommended. By default, it is the candidate word, but it determines whether the word is legal, if so, the word is the candidate, otherwise the second word is the candidate, and then draw it.
Draw a line to separate the candidate words. The total width mentioned above can be obtained after all the words have been drawn.
To determine whether the target scrolling is current or not, you need to scroll over it.
7. ScrollToTarget, roll to the target area. Get the current value, then add a scrolling distance to see if it exceeds and adjust accordingly, and then scroll to the appropriate coordinates.
8. SetSuggestions, set the candidate word, and then draw it.
9. OnTouchEvent, called when a touch event is generated. First of all, determine whether it is a gesturedetector listening action, if not, proceed to the following processing. Initialize the action, record what happened, and record the coordinates of the touch. Then, classify the responses according to the type of action:
◆ down: no action
◆ move: if you move to the left, you have to manually select the candidate word.
◆ up: candidate words need to be selected manually.
10. TakeSuggestionAt, select the word at coordinate x, which deals with the user tapping the keyboard, that is, selecting the candidate word.
11. RemoveHighlight, remove the highlight.
(5) SoftKeyboard.java
The overall framework of the entire input method, including when to create, when to display the input method, and how to communicate with the text box, and so on. The above files are all for this kind of service. In general, an input method requires an input view, a candidate word view, and a link to the application.
The basic timing diagram is as follows:
The essence of input method in Android is a Service. Assuming that the user has just started Android and the user moves focus * * into the text edit box, Android will notify Service to start initialization work. As a result, there is a series of actions as shown in the picture.
Going back to the source, the onCreate method inherits from the Service class, which has the same meaning as other Service methods. Here, Sample does some non-UI initialization, that is, the initialization of string variable vocabulary delimiters.
Next, execute onInitializeInterface, which is where the UI is initialized, and this method will be called after creation and after configuration changes. Sample initializes the Keyboard here, reads the soft keyboard information from the XML file, and encapsulates it into the Keyboard object.
The third is the onStartInput method, where we are bound to the client to receive all the details about the editing object.
The fourth method to execute is onCreateInputView, which is called by the framework when the area entered by the user is to be displayed, when the input method is displayed, or when the configuration information is changed. In this method, the inputview is initialized: read the layout file information, set onKeyboardActionListener, and initially set keyboard.
The fifth method is onCreateCandidatesView, which is called by the framework when you want to display a view of the candidate words. Similar to onCreateInputView. In this way, the candidateview is initialized.
The sixth method, also known as onStartInputView, is the one in which inputview and the current keyboard are re-associated.
Of the six methods above, the onCreateInputView and onCreateCandidatesView methods are executed only once during initialization, unless the configuration information is changed. So what exactly is a change in configuration information? When you look at InputMethodService's API document, you can see that there is a method, onConfigurationChanged, which, as explained by the document, is mainly responsible for configuration changes. In the example, there is no override method, but in the PinyinIME in the android source package, this method is used so that interested friends can look at the source code of PinyinIME after reading SoftKeyboard Sample.
Some of the other methods in this class are not explained because they are more intuitive. Interested friends can refer to the "self-analysis of softkeyboard in android sdk (4)".
Fifth, input method debugging
By using debug mode breakpoints, it is helpful for us to better understand the timing of the input method and the function and call persistence of each class and its method.
Here we use Eclipse's DDMS perspective for debugging, and refer to "developing and debugging Android applications with Eclipse".
First switch to DDMS mode, where DDMS will link to the running phone or simulator, and can extract all kinds of information on the phone, such as threads, as well as various services running in the background, and so on. Click "Debug selected Process" on the sidebar to implant the debugger into the service.
After switching to debug mode, you will find that the debugger is linked to the simulator, and then you can debug the input method like a normal program.
Through the debug mode, we can find that the input method first executes onCreateInputView- > onCreateCandidatesView, and at this time, the interface of the input method has not been shown at all. When we click the mouse in an input box, the system generates an event that is initially captured by the input method, and then gives control to the input method. In addition, when switching objects, the input method is always thought of as the end of an input, and then carries out a series of reset work. All keyboard and other events are passed to the input method first, so if a keystroke event is not something we can handle, we need to pass it on instead of discarding it, because it may be something else's control.
In the message sending interface, after typing TO someone, click on the content input box, the first call is onFinishInput, that is, the end of the last input, ready for this input. After that, onStartInputView is called to show the interface. The onStartInput is then called to indicate the start of formal input. In this process, to complete according to different input box, select a different keyboard, when you enter a key, the first trigger is the onKey callback, here to determine whether it is the input of ordinary characters, or control characters, such as delete, return, and so on. For example, enter a 'gcharacters here, and then call the function handleCharacter that handles ordinary characters. The strategy here is to type a normal character, increase the Composing, and update the list of candidate words. There is a subtle switch, mPrediction, which determines whether the Composing needs to be saved. When you type in the URL box, for example, you will turn this switch off and type it directly into the text box.
In order to test all the functions, you have to come up with an input method so that you can execute each function, so that you can see the true face of the input method.
Please try it for yourself, which is good for reading and understanding the flow, timing and life cycle of the source code. You can also easily find the bug of your own code.
VI. Invocation of input method
If you want to invoke the input method and receive the string passed from the input method from a View, you can call the widget EditText. However, if you want to make a very cool and personalized input method, you must connect the input method like EditText, as described below:
First, define a class that inherits from BaseInputConnection. As mentioned earlier, the input method submits the selected characters through commitText.
Public class MyBaseInputConnection extends BaseInputConnection {public MyBaseInputConnection (View targetView, boolean fullEditor) {super (targetView, fullEditor);} public static String tx= ""; / / the input method program uses this method to output @ Override public boolean commitText (CharSequence text, int newCursorPosition) {tx= text.toString (); return true;}}.
BaseInputConnection is equivalent to a channel between InputMethodService and View. Whenever InputMethodService produces a result, the commitText method of BaseInputConnection is called to pass the result.
After that, the input method is called out and the custom BaseInputConnection channel is passed to InputMethodService in the following way.
Public class MyView extends XXView. {/ / get InputMethodManager InputMethodManager input = (InputMethodManager) context.getSystemService (Context.INPUT_METHOD_SERVICE); / / define the event handler ResultReceiver receiver = new ResultReceiver (new Handler () {public void handleMessage (Message msg) {}}); / / call this input.showSoftInput (this, 0, mRR) when you want to exhale the input method. ... @ Override / / this method inherits from View. Pass the custom BaseInputConnection channel to InputMethodService public InputConnection onCreateInputConnection (EditorInfo outAttrs) {return new MyBaseInputConnection (this, false);}}
On the low-level interface, you call the input method and receive the output of the input method.
This is how to understand IMF in the Android development shared by the editor. If you happen to have similar doubts, you might as well refer to the above analysis to understand. If you want to know more about it, you are welcome to follow the industry information channel.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.