This paper analyzes the hidden display method of the soft keyboard of Android programming. Share to everyone for your reference, specific as follows:
Android is a specially designed operating system for touch screens, and when you click on the edit box, the system automatically pops up a soft keyboard for the user to enter.
Then, pop-up soft keyboard will inevitably cause the original layout height of the reduction, then the system should be how to deal with the reduction of the layout? Can we make custom controls in the application? These are the key points to be discussed in this article.
First, the principle of soft keyboard display
What is the nature of the software disk? The soft keyboard is actually a dialog!
Inputmethodservice creates a dialog for our input method and sets certain parameters of the dialog window, such as gravity, to be displayed at the bottom or full screen. When we click on the input box, the system adjusts the active main window to make room for the input method, and then the dialog is displayed at the bottom or full screen.
Second, the active main window adjustment
Android defines an attribute, named Windowsoftinputmode, that allows the program to control how the active main window adjusts. We can set up the activity in Androidmanifet.xml. such as: android:windowsoftinputmode= "Stateunchanged|adjustpan"
The optional value for this property has two parts, one for state control of the soft keyboard and the other for the active main window adjustment. The first part of this article is not discussed, please read the android documentation yourself.
Mode one, compression mode
If the Windowsoftinputmode value is set to Adjustresize, the active main window is always resized to allow space for the soft keyboard.
We tested it through a piece of code, and when we set the attribute, what did the system do when we popped the IME.
Overriding the layout layout:
public class Resizelayout extends linearlayout{private static int count = 0;
Public Resizelayout (context, AttributeSet attrs) {Super (context, attrs); @Override protected void onsizechanged (int w, int h, int oldw, int oldh) {super.onsizechanged (W, H, OLDW, old
h); LOG.E ("onsizechanged" + count++, "=>onresize called!
w= "+w +", h= "+h+", oldw= "+oldw+", oldh= "+OLDH"; @Override protected void OnLayout (Boolean changed, int l, int t, int r, int b) {super.onlayout (changed, L, T,
R, b); LOG.E ("OnLayout" + count++, "=>onlayout called!
L= "+ L +", t= "+ t +", r= "+ R +", b= "+b"; @Override protected void onmeasure (int widthmeasurespec, int heightmeasurespec) {super.onmeasure (widthmeasure
Spec, Heightmeasurespec); LOG.E ("onmeasure" + count++, "=>onmeasure called!
Widthmeasurespec= "+ Widthmeasurespec +", heightmeasurespec= "+ Heightmeasurespec"; }
Our layout is set to:
<com.winuxxan.inputmethodtest.resizelayout
xmlns:android= "Http://schemas.android.com/apk/res/android"
android:id= "@+id/root_layout"
android:layout_width= "fill_parent"
android:layout_height= "Fill_" Parent "
android:orientation=" vertical "
>
<edittext
android:layout_width=" Fill_parent "
android:layout_height= "wrap_content"
/>
<linearlayout
android:id= "@+id/bottom_layout" "
android:layout_width=" fill_parent "
android:layout_height=" fill_parent "
android:orientation=" Vertical "
android:gravity=" Bottom ">s
<textview
android:layout_width=" Fill_parent " android:layout_height= "Wrap_content"
android:text= "@string/hello"
android:background= "#77777777"
/>
</LinearLayout>
</com.winuxxan.inputMethodTest.ResizeLayout>
Androidmanifest.xml Activity Setting Properties: Android:windowsoftinputmode = "Adjustresize"
To run the program, click on the text box to view debugging information:
E/onmeasure 6 (7960): =>onmeasure called! widthmeasurespec=1073742144, Heightmeasurespec = 1073742024
E/onmeasure 7 (7960): =>onmeasure called! widthmeasurespec=1073742144, Heightmeasurespec = 1073742025
E/onsizechanged 8 (7960): =>onsizechanged called! w=320,h=201,oldw=320,oldh=377
E/onlayout 9 (7960): =>onlayout called! L=0, t=0,r=320,b=201
From the debug results we can see that when we clicked the text box, the root layout called onmeasure,onsizechanged and onlayout.
In fact, when the soft keyboard is set to Adjustresize, the main window layout is measure and layout, and when layout, the size of the window is changed, so onsizechanged is invoked.
From the results of the operation we can also see that the original in the bottom of the TextView was top of the input method.
Mode two, translation mode
If the Windowsoftinputmode value is set to Adjustpan, the active main window does not resize the screen to allow space for the soft keyboard. Instead, the contents of the current window will be automatically moved so that the current focus is never overwritten by the keyboard and the user can always see the input part. This is usually not expected to be larger than the resizing, because the user may close the soft keyboard to gain interaction with the overwritten content.
In the example above, we change the properties of the Androidmanifest.xml: Android:windowsoftinputmode = "Adjustpan"
Rerun, and click on the text box to view debugging information:
E/onmeasure 6 (8378): =>onmeasure called! widthmeasurespec=1073742144, heightmeasurespec=1073742200
E/onmeasure 7 (8378): =>onmeasure called! widthmeasurespec=1073742144, heightmeasurespec=1073742201
E/onlayout 8 (8378): =>onlayout called! L=0, t=0,r=320,b=377
We see: The system also measrue and layout, but we found that the layout process onsizechanged did not call, which shows that the input method does not change the original layout before and after the size.
From the results of the operation we can see that the lower TextView is not top to the input method.
In fact, when the input box is not blocked, the pattern does not adjust the layout, but when the input box will be blocked, the window will be translated. That is, the pattern is always to keep the input box visible. The entire window, including the title bar, is moved up to ensure that the text box is visible.
Mode three automatic mode
When a property Windowsoftinputmode is set to adjustuspecified, it is not specified whether the active main window is resized to leave the soft keyboard space, or whether the contents of the window are visible when the current focus is on the screen. The system will automatically select one of these modes that is primarily dependent on whether the contents of the window have any layout view to scroll their content. If you have such a view, the window will resize so that the contents of the scrolling window are visible in a smaller area. This is the default behavior setting for the main window.
In other words, the system automatically determines whether to use the translation mode or compression mode, the determining factor is the content can be scrolled.
Third, listen to the soft keyboard display hidden
Sometimes, using the system's own mechanism to achieve the main window adjustment is not the result we want, we may want the soft keyboard display hidden, manually modify the layout, so that the soft keyboard pop-up more beautiful. Then you need to listen to the soft keyboard display hidden.
directly to the soft keyboard display hidden listening methods I did not find, if you find a way to please tell me. There is also this method for compression mode, the translation mode is not necessarily valid.
We can use the soft keyboard to display and hide, the main window has been redesigned this feature to listen. If we set the mode to compression mode, we can trace the onsizechanged function of the layout, and if it is a translation mode, then the function may not be invoked.
We can override the root layout because the height of the root layout is generally not changed.
Assuming that the layout is linear and the pattern is compressed, we write an example that hides a view when the Input method pops up, and a view is displayed when the input method is hidden.
public class Resizelayout extends linearlayout{
private Onresizelistener mlistener;
Public interface Onresizelistener {
void OnResize (int w, int h, int oldw, int oldh);
public void Setonresizelistener (Onresizelistener l) {
mlistener = l;
}
Public Resizelayout (context, AttributeSet attrs) {
Super (context, attrs);
}
@Override
protected void onsizechanged (int w, int h, int oldw, int oldh) {
super.onsizechanged (W, H, OLDW, OLDH) ;
if (Mlistener!= null) {
mlistener.onresize (W, H, OLDW, OLDH);}}}
In our activity, we invoke the following methods:
public class Inputmethodtestactivity extends activity {private static final int bigger = 1;
private static final int smaller = 2;
private static final int msg_resize = 1;
private static final int height_threadhold = 30;
Class Inputhandler extends Handler {@Override public void Handlemessage (msg) {switch (msg.what) { Case Msg_resize: {if (msg.arg1 = = bigger) {Findviewbyid (r.id.bottom_layout). Setvisibility (view.visible)
;
else {Findviewbyid (r.id.bottom_layout). setvisibility (View.gone);
}} break;
Default:break;
Super.handlemessage (msg);
} private Inputhandler Mhandler = new Inputhandler (); /** called the activity is a.
* * @Override public void onCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate);
Setcontentview (R.layout.main);
Resizelayout layout = (resizelayout) Findviewbyid (r.id.root_layout); Layout. Setonresizelistener (New Resizelayout.onresizelistener () {public void OnResize (int w, int h, int oldw, int oldh) {
int change = bigger;
if (H < OLDH) {change = smaller;
msg = new Message ();
Msg.what = 1;
MSG.ARG1 = change;
Mhandler.sendmessage (msg);
}
});
}
}
It is particularly noteworthy that you cannot change the view you want to change directly in Onresizelistener, because the onsizechanged function is actually running in the view's layout method. If you change the display properties of the view directly in the Onsizechange, you will probably need to call the layout method again to display the correct. However, our approach is called in layout, so there is an error. So we use the handler method in the example.
I hope this article will help you with the Android program.