Android Input Method

Source: Internet
Author: User

I 've been reading the examples and source code of the Input Method for a lot of time, and it's very dizzy and depressing. Let me calm down and think about the entire code. In fact, most of the Code is processing the drawing interface and event processing. The core code is very small and is encapsulated perfectly by the underlying layer.
First, let's look at the interface of the general input method:

 
There are two parts: The first part is the CandidateView, which is used to display candidate words. Currently, common input methods have this function, such as inputting abc in sogou and google input methods, the input box displays many associated Chinese words. The next part is the soft keyboard. There is nothing to say about it.

The core class in the input method is InputMethodService.
Second, CandidateView and KeyboardView
 
CandidateView is a candidate window. InputMethodService calls the public View onCreateCandidatesView () interface during startup. In this method
After the CandidateView object is returned, InputMethodService will deploy it in the corresponding position.
The CandidateView parent class does not exist in android, so you have to write it from the beginning. The general practice is:
Use the public void setService (InputMethodService listener) method to upload the Service class, and then use public void setSuggestions (List <String> suggestions ...) The method passes the list of candidate words, and CandidateView displays them on the interface. After the user selects the candidate words, use the service method pickSuggestionManually (mSelectedIndex ), pass the serial number of the selected candidate word in the list. So far, CandidateView has completed its sacred mission.
 
In android, KeyboardView has a general class, which can be inherited by displaying a very professional soft keyboard through a simple configuration file. In the source code, most of its code is being drawn and processed, but its essential functions are quite simple. After you press a key on the soft keyboard, it passes the value represented by this key to the InputMethodService class and completes its mission. InputMethodService obtains the View in the public View onCreateInputView () method.
 
InputMethodService is the core of the input method. This class is a Service. Unlike other obscure services, InputMethodService is a Service with a View. There are several important internal interfaces:
InputMethodImpl
InputMethodSessionImpl
InputConnection
InputMethodService interacts with the system and input box through these classes.
The input box obtains information from InputMethodService through InputConnection. When the input method is started, InputConnection is created by the client control and passed to the input method application, which is called by the Input Method Application for information feedback.

The InputMethod interface defines a set of methods used to manipulate input methods. For example, bindInput, hideInput, and startInput. For system security, this type of interface can only be accessed by the system, and the client control cannot directly call this interface. All input method applications require the BIND_INPUT_METHOD permission of the client control as the system's security mechanism. Otherwise, they cannot interact with the input method service.

InputMethodSession is a secondary interface class of InputMethod. It opens function interfaces that can be called directly for client controls. This includes distributing Keyboard Events to the input method application, updating the cursor position, and updating the problem information selected in the editing area. The client control uses IIputMethodSession to perform one-way interaction on the input method application. That is, it can only transmit information to the input method application and cannot obtain information.
 
The above points are copied from the internet. I feel that these points are particularly useful for understanding InputMethodService.
The code is too much to see but cannot see the essence. The most practical of these classes is the InputConnection
Public boolean commitText (CharSequence text, int newCursorPosition ).
Through KeyboardView and CandidateView, The InputMethodService class has obtained the desired content, and then passed the value to the input box through this method.
 
I can't help but feel depressed when I read the source code. I 'd like to write an input method to let it go:
The following figure shows a CandidateView layout:

 
This View does not perform any self-drawing. It uses the existing View of android and a Button on both sides to scroll Multiple candidate words and display the candidate words (TextView) in the middle ), to facilitate CandidateView to inherit the internal class of RelativeLayout and to add sub-controls and controls, the setService and setSuggestions methods are not needed. They are internal classes, but they are used in combination with the above description, think twice or more:
 
Public class helloIme extends InputMethodService {
 
Class CandidateView extends RelativeLayout {
TextView TV; // The candidate word is displayed in the middle.
Button btLeft, btRight; // left and right buttons
HelloIme listener; // helloIme is used to return the subscript of the selected candidate word
List <String> suggestions; // List of candidate words. After KeyboardView is pressed with different keys, related lists are set.
Int mSelectedIndex =-1; // subscript of the current candidate word

Public CandidateView (Context context ){
Super (context );

TV = new TextView (context );
TV. setId (1 );
RelativeLayout. LayoutParams lpCenter = new RelativeLayout. LayoutParams (200, ViewGroup. LayoutParams. WRAP_CONTENT );
LpCenter. addRule (RelativeLayout. CENTER_IN_PARENT );
AddView (TV, lpCenter );
TV. setOnClickListener (new OnClickListener (){
Public void onClick (View v ){
Listener. pickSuggestionManually (mSelectedIndex );
}
});

BtLeft = new Button (context );
BtLeft. setText ("<");
BtLeft. setOnClickListener (new OnClickListener (){
Public void onClick (View arg0 ){
MSelectedIndex = mSelectedIndex> 0? (MSelectedIndex-1): 0;
TV. setText (suggestions. get (mSelectedIndex ));
}
});

RelativeLayout. LayoutParams lpLeft = new RelativeLayout. LayoutParams (60, ViewGroup. LayoutParams. WRAP_CONTENT );
LpLeft. addRule (RelativeLayout. LEFT_OF, 1 );
AddView (btLeft, lpLeft );

BtRight = new Button (context );
BtRight. setText ("> ");
BtRight. setOnClickListener (new OnClickListener (){
Public void onClick (View v ){
MSelectedIndex = mSelectedIndex> = suggestions. size ()-1? Suggestions. size ()-1: mSelectedIndex + 1;
TV. setText (suggestions. get (mSelectedIndex ));
}
});

RelativeLayout. LayoutParams lpRight = new RelativeLayout. LayoutParams (60, ViewGroup. LayoutParams. WRAP_CONTENT );
LpRight. addRule (RelativeLayout. RIGHT_OF, 1 );
AddView (btRight, lpRight );
}

Public void setService (helloIme listener ){
This. listener = listener;
}

Public void setSuggestions (List <String> suggestions ){
MSelectedIndex = 0;
TV. setText (suggestions. get (mSelectedIndex ));
This. suggestions = suggestions;
}
}
The most important line above is the two lines in bold. The layout of the View still consumes a lot of code :(
 
The KeyboardView layout is expected as follows:

If () {}, if () {} else if (){}..., whie () {} is output to the input box during whie. This class is also an internal class inherited from RelativeLayout:
Class KeyboardView extends RelativeLayout {
Public KeyboardView (Context context ){
Super (context );

Button btIf = new Button (context );
BtIf. setText ("if ");
BtIf. setId (1 );
RelativeLayout. LayoutParams lpIf = new RelativeLayout. LayoutParams (100, 50 );
LpIf. addRule (RelativeLayout. CENTER_HORIZONTAL );

BtIf. setOnClickListener (new OnClickListener (){
Public void onClick (View v ){
SetCandidatesViewShown (true); // display CandidateView
HelloIme. this. onKey ("if"); // return the value of the clicked button to InputMethodService.
}
});
AddView (btIf, lpIf );

Button btWhile = new Button (context );
BtWhile. setText ("while ");
RelativeLayout. LayoutParams lpWhile = new RelativeLayout. LayoutParams (100, 50 );
LpWhile. addRule (RelativeLayout. BELOW, 1 );
LpWhile. addRule (RelativeLayout. ALIGN_LEFT, 1 );

BtWhile. setOnClickListener (new OnClickListener (){
Public void onClick (View v ){
SetCandidatesViewShown (true );
HelloIme. this. onKey ("while ");
}
});
AddView (btWhile, lpWhile );
}
}
 
CandidateView is not displayed by default. Therefore, you must call the setCandidatesViewShown () method of InputMethodService.
 
Next, paste the helloIme code:
Public class helloIme extends InputMethodService {
Private List <String> suggestionlist; // current candidate vocabulary
Private Hashtable <String, List <String> data; // Dictionary data
Private KeyboardView mkeyView;
Private CandidateView mCandView;

Public void onInitializeInterface () {// when InputMethodService is started, the system calls this method.
// Initialize Dictionary data
Data = new Hashtable <String, List <String> ();
List <String> list = new ArrayList <String> ();
List. add ("if (){}");
List. add ("if () {} else if (){}");
List. add ("if () {} else {}");
Data. put ("if", list );

List = new ArrayList <String> ();
List. add ("while (){}");
Data. put ("while", list );
}

Public View onCreateInputView (){
MkeyView = new KeyboardView (this );
Return mkeyView;
}

Public View onCreateCandidatesView (){
MCandView = new CandidateView (this );
MCandView. setService (this );
Return mCandView;
}

Public void pickSuggestionManually (int mSelectedIndex ){
GetCurrentInputConnection (). commitText (suggestionlist. get (mSelectedIndex), 0); // output content to the input box
SetCandidatesViewShown (false); // hide CandidatesView
}

Public void onKey (CharSequence text ){
// Set the candidate word list based on the pressed Button
Suggestionlist = data. get (text );
MCandView. setSuggestions (suggestionlist );
}

Class KeyboardView extends RelativeLayout {
//......
}

Class CandidateView extends RelativeLayout {
//......
}
}
 
After writing the code, write the configuration file,
Create a new directory xml under the res directory, and then create a method. xml
<? Xml version = "1.0" encoding = "UTF-8"?>
<! -- The attributes in this XML file provide configuration information -->
<! -- For the Search Manager. -->

<Input-method
Xmlns: android = "http://schemas.android.com/apk/res/android"/>
Set Manifest. xml:
<? Xml version = "1.0" encoding = "UTF-8"?>
<Manifest xmlns: android = "http://schemas.android.com/apk/res/android"
Package = "test. helloIme"
Android: versionCode = "1"
Android: versionName = "1.0" type = "codeph" text = "/codeph">
<Application android: icon = "@ drawable/icon" android: label = "@ string/app_name">
<Service android: name = "helloIme"
Android: permission = "android. permission. BIND_INPUT_METHOD">
<Intent-filter>
<Action android: name = "android. view. InputMethod"/>
</Intent-filter>
<Meta-data android: name = "android. view. im" android: resource = "@ xml/method"/>
</Service>
</Application>
<Uses-sdk android: minSdkVersion = "5"/>

</Manifest>
Run the program directly. eclipse outputs the following Log:
[17:16:48-helloIme] Installing helloIme.apk...
[17:16:50-helloIme] Success!
[17:16:50-helloIme]/helloIme/bin/helloIme.apk installed on device
[17:16:50-helloIme] Done!

Well, the installation is successful! Haha, the revolution has not yet succeeded. You still need to set it on the simulator:
Click settings-> Language & keyboard. A test is displayed in the lower part, and a checkbox is displayed on the right. select it.
Find an application with an input box, which is the easiest way to write a short message. Press the left button to press the input box. A prompt box for selecting input methods will pop up. Click it to view the created input method, on the right side, click single button, oh, my ime, and the beautiful hello input method will be displayed in front of you:

 
 
Android is really powerful.

 


From Change everyday

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.