Research on the display and hiding problem of Android soft keyboard

Source: Internet
Author: User

in Android, it often interacts with the IME's software keyboard. In the manifest file, the system gives an attribute-windowsoftinputmode to the activity to control how the input method is displayed. This property provides a way for the activity's window to interact with the window of the soft keyboard. The property settings here have two effects:
1. Soft keyboard display and hide. -When the activity interface becomes the focus of the user, or is hidden or displayed.
2. Adjust the main window of the activty. Or move the activity window to make room for the soft keyboard, or when the activity's part of window is covered by the software, moving the contents of the activity so that the user can see the current focus.

You must choose at least one of the following property values to set it, either "state ..." or "adjust ...". You can set multiple values. Set different attribute values to be separated by |. For example:
<activityAndroid:windowsoftinputmode="Statevisible|adjustresize" . . . >
The following is a description of the value of the property.
does not specify the state of the software (show or hide). The system selects the appropriate state according to the settings in the theme. The default setting for this property soft keyboard. does not specify whether to adjust the activity interface. Or resize the Activity window to make room for the soft keyboard or to move the contents of the window so that the current focus on the screen is visible. The system automatically chooses one of the modes, depending on whether the window contains a view that can slide its contents. If you have such a view, the size of the window will be adjusted. In such a hypothetical case, a small slide can be visible using the contents of the window. This property is the primary windowr default setting. TD valign= "Top" style= "width:434.0px; Border-style:solid; border-width:1.0px 1.0px 1.0px 1.0px; Border-color: #808080 #808080 #808080 #808080; padding:2.0px 2.0px 2.0px 2.0px "> is displayed TD valign= "Top" style= "width:434.0px; Border-style:solid; border-width:1.0px 1.0px 1.0px 1.0px; Border-color: #808080 #808080 #808080 #808080; padding:2.0px 2.0px 2.0px 2.0px ">
Value Describe
" stateunspecified "
" stateunchnaged " always keep the state of the last soft keyboard. When activity goes to the front end, whether it's the last time it was shown or hidden, it stays the same.
" Statehidden " When the user enters the target activity, the soft keyboard remains hidden. The activity here is that the user is moving forward into the activity, rather than returning to the target activity by exiting other activity.
" statevisible " only if the conditions are right (when the user advances to the Activity's main window) , the keyboard
" statealawaysvisible " When the user chooses to enter the target activity, the soft keyboard is set to visible. The activity here is the activity that the user goes forward to, not the target activity by exiting other activity
" adjustunspecified "
" adjustresize " activity" The window is always resized to make room for the soft keyboard.
"Adjustpan" The activity's main window is not resized to make room for the soft keyboard. Instead, the contents of the window are automatically moved so that the current focus is not obscured by the soft keyboard, and the user can always see what he has entered. This value is typically used when the user rarely wants to resize the window, because the user may need to turn off the soft keyboard to interact with the rest of the window.

from the description of the above system, the system shows that both the activity and the soft keyboard are treated as window windows to handle two interactions.
many times, we want to be able to hear the software keyboard display and shutdown status, such as the situation,

You have a login interface that is designed like this


You want to log in when it's like this,


and then you try to add value to the activity's Windowsoftinputmode property, and when you add adjustresize, it's like this.


You are not reconciled, you will adjustresize change into Adjustpan, the result is this



There is no way, only by ourselves to monitor the keyboard display or hide to dynamically change the layout. Now the question is how to monitor the dynamic change of the keyboard, the system does not provide a corresponding method, we can be implemented in two ways.
1. Under the Adjustresize property, the window size of the activity changes, and the size of the layout in the window will inevitably change. When the view size changes, it is bound to cause a callback for onsizechanged (int, int, int, int). Therefore, it is possible to customize a layout to monitor the callback of the onsizechanged () function and then handle it accordingly. This method is also the most on-line transmission method.
2. With the Viewtreeoberserver class. Viewtreeoberserver can be used to register a listener that can listen to global changes in the view tree. These changes include, but are not limited to, the entire view layout, drawing the source of the transfer, and changing the touch pattern.

implementation of the first method:
Customize a layout, take relativelayout as an example,

can be in int W, int H, int OLDW, int

Package Com.example.keyboardlistener;import Android.content.context;import Android.util.attributeset;import Android.util.log;import Android.widget.relativelayout;public class KeyboardLayout extends Relativelayout {private OnS    Izechangedlistener Mchangedlistener;    private static final String TAG = "Keyboardlayouttag";        Private Boolean mshowkeyboard = false;        Public KeyboardLayout (context context, AttributeSet attrs, int defstyle) {Super (context, attrs, Defstyle); TODO auto-generated Constructor stub} public keyboardlayout (context context, AttributeSet Attrs) {Super        (context, attrs);        TODO auto-generated Constructor stub} public keyboardlayout (context context) {super (context); TODO auto-generated Constructor stub} @Override protected void onmeasure (int widthmeasurespec, int height  MEASURESPEC) {//TODO auto-generated Method Stub super.onmeasure (Widthmeasurespec, Heightmeasurespec);      LOG.D (TAG, "onmeasure-----------"); } @Override protected void OnLayout (Boolean changed, int l, int t, int r, int b) {//TODO auto-generated met        Hod stub super.onlayout (changed, L, T, R, b);    LOG.D (TAG, "OnLayout-------------------"); } @Override protected void onsizechanged (int w, int h, int oldw, int oldh) {//TODO auto-generated Metho        D stub super.onsizechanged (W, H, OLDW, OLDH);        LOG.D (TAG, "--------------------------------------------------------------");        LOG.D (TAG, "w----" + W + "\ n" + "h-----" + H + "\ n" + "OLDW-----" + OLDW + "\NOLDH----" + OLDH); if (null! = Mchangedlistener && 0! = OLDW && 0! = OLDH) {if (H < OLDH) {MSh            Owkeyboard = true;            } else {mshowkeyboard = false;            } mchangedlistener.onchanged (Mshowkeyboard);        LOG.D (TAG, "mshowkeyboard-----" + mshowkeyboard); }} PUBlic void Setonsizechangedlistener (Onsizechangedlistener listener) {Mchangedlistener = listener;    } interface onsizechangedlistener{void OnChanged (Boolean showkeyboard); }    }

Create a handler in the main activity to update the UI through handler when the monitor hears the layout change.

Package Com.example.keyboardlistener;import Android.app.activity;import Android.os.bundle;import Android.os.handler;import Android.os.message;import Android.util.log;import Android.view.viewtreeobserver.onpredrawlistener;import Android.widget.button;import Com.example.keyboardlistener.keyboardlayout.onsizechangedlistener;public class Mainactivity extends Activity {priv    Ate static final String TAG = "Keyboardlayouttag";    Private KeyboardLayout Mroot;    Private Button Mlogin;        private int mloginbottom;    private static final int keyboard_show = 0X10;    private static final int keyboard_hide = 0X20;        Private Boolean mgetbottom = true; Private Handler Mhandler = new Handler () {@Override public void Handlemessage (Message msg) {//            TODO auto-generated Method Stub super.handlemessage (msg);                Switch (msg.what) {case KEYBOARD_HIDE:mRoot.setPadding (0, 0, 0, 0);            Break CaSe keyboard_show:int mrootbottom = mroot.getbottom ();                LOG.D (TAG, "The Mloginbottom is" + mloginbottom);                Mroot.setpadding (0, mrootbottom-mloginbottom, 0, 0);                            Break            Default:break;        }        }            };        @Override protected void OnCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate);                Setcontentview (R.layout.activity_main);        Getactionbar (). Hide ();        Mroot = (keyboardlayout) Findviewbyid (R.id.root_view);        Mlogin = (Button) Findviewbyid (R.id.login); Mroot.setonsizechangedlistener (New Onsizechangedlistener () {@Override public void Oncha                    Nged (Boolean Showkeyboard) {//TODO auto-generated Method stub if (Showkeyboard) {                    Mhandler.sendmessage (Mhandler.obtainmessage (keyboard_show)); LOG.D (TAG, "show keybOard ");                } else {mhandler.sendmessage (Mhandler.obtainmessage (keyboard_hide));                }            }        }); Mroot.getviewtreeobserver (). Addonpredrawlistener (New Onpredrawlistener () {@Override Pub                    Lic Boolean Onpredraw () {//TODO auto-generated Method stub if (Mgetbottom) {                Mloginbottom = Mlogin.getbottom ();//Gets the location information of the login button.                } Mgetbottom = false;            return true;            }        });  }//@Override//Public boolean Oncreateoptionsmenu (Menu menu) {/////Inflate the menu, this adds items to the  Action Bar If it is present.//getmenuinflater (). Inflate (R.menu.main, menu);//Return true;//}}

implementation of the second method:

Use the Viewtreeobserver class to add the view you want to listen to Ongloballayoutlistener Listener, and then in the Ongloballayout () method of the window changes to determine whether the keyboard is paged out. Here is the code for the section of Viewtreeobserver listening:

Mroot.getviewtreeobserver (). Addongloballayoutlistener (New Ongloballayoutlistener () {                        @Override            public void Ongloballayout () {                int offset = Mroot.getrootview (). GetHeight ()-mroot.getheight ();                Determines whether the keyboard displays                if (offset >) {                    mhandler.sendmessage (mhandler.obtainmessage (Keyboard_show)) based on the offset value of the view;                } else {                    mhandler.sendmessage (mhandler.obtainmessage (Keyboard_hide));}}        );

The concrete implementation of handler is the same as the handler in the above structure.


Reference article: Inputmethod


Example source code


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.