In android, it often interacts with the keyboard of the input method. In the Manifest file, the system gives the activity an Attribute-windowSoftInputMode to control the display mode of the input method. This attribute provides the window interaction mode between the Activity window and the keyboard window. Attribute settings have two impacts:
1. Display and hide the keyboard. -When the Activity interface becomes the user's focus, it is hidden or displayed.
2. Adjust the main window of Activty. You can also reduce the window size of the Activity to make room for the keyboard, or move the content of the Activity when some windows of the Activity are covered by the software so that you can see the current focus.
You must select at least one of the following attribute values, either "state..." or "adjust...". You can set multiple values. Set different attribute values. Separate them with |. For example:
The following describes the attribute values.
Value |
Description |
"StateUnSpecified" |
Do not specify the software status (show or hide ). The system selects the status based on the settings in the topic. Default settings for this attribute. |
"StateUnchnaged" |
Always keep the last soft keyboard. When an Activity enters the frontend, whether it is displayed or hidden last time, it remains unchanged. |
"StateHidden" |
When a user enters the target Activity, the keyboard remains hidden. Here, the user enters the Activity forward, instead of returning to the target Activity after exiting other activities. |
"StateVisible" |
Only when the conditions are appropriate (when the user advances to the main window of the Activity), the keyboard will be displayed |
"StateAlawaysVisible" |
When you select to enter the target Activity, the keyboard is set to visible. The Activity here is the Activity that the user enters, instead of returning to the target Activity because the user exits other activities. |
"AdjustUnspecified" |
Do not specify whether to adjust the Activity interface. You can also adjust the size of the Activity window to make room for the keyboard or move the content of the window to make the current focus visible on the screen. The system automatically selects one of the modes, depending on the view that contains the sliding content of the window. If there is such a view, the window size will be adjusted. In such a case, a very small slide will be visible using the window content. This attribute is the default setting of the main windowr. |
"AdjustResize" |
The window of an Activity is always adjusted to make room for the keyboard. |
"AdjustPan" |
The main window of the Activity is not adjusted to make room for the keyboard. On the contrary, the content of the window will be automatically moved so that the current focus will not be covered by the keyboard, and the user can always see what he entered. This value is generally used when users seldom want to adjust the window size, because users may need to close the keyboard to interact with other parts of the window. |
According to the system description above, the system shows that the Activity and the keyboard are processed as windows when processing two interactions.
Most of the time, we want to be able to monitor the display and closing status of the software keyboard, for example,
You have a login interface designed in this way.
This is what you want to do when logging on,
Then you try to add a value to the activity's windowSoftInputMode attribute. When you add adjustResize, this is the case.
You are unwilling to change the adjustResize to adjustPan. The result is as follows:
There is no way. We only need to monitor the display or hide of the keyboard to dynamically change the layout. The problem is how to monitor the dynamic changes of the keyboard. The system does not provide the corresponding method. We can implement it in two ways.
1. Under the adjustResize attribute, the size of the activity window will change, and the size of layout in the window will also change. When the view Size changes, the onSizeChanged (int, int) callback is triggered. Therefore, you may customize a Layout to monitor the callback of the onSizeChanged () function, and then process it accordingly. This method is also the most widely used method for online uploads.
2. Use the ViewTreeOberserver class. ViewTreeOberserver can be used to register a listener that monitors global changes in the view tree. These changes include but are not limited to the layout of the entire View, the source of the rendering transfer, and the changes in the touch mode.
Implementation of the first method:
Customize a Layout. Take RelativeLayout as an example,
In onSizeChanged (IntW,IntH,IntOldw,IntIn the oldh) method, listen to the changes in the interface size, and then define the callback function in this method. when listening to the keyboard being called up, push the keyboard up for a distance, in this way, the logon key is displayed.
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 onSizeChangedListener 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 heightMeasureSpec) { // 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 method 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 method 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) { mShowKeyboard = 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. When the layout changes, update the UI through Handler.
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 {private 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. wha T) {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); getAct IonBar (). hide (); mRoot = (KeyboardLayout) findViewById (R. id. root_view); mLogin = (Button) findViewById (R. id. login); mRoot. setOnSizeChangedListener (new onSizeChangedListener () {@ Override public void onChanged (boolean showKeyboard) {// TODO Auto-generated method stub if (showKeyboard) {mHandler. sendMessage (mHandler. obtainMessage (KEYBOARD_SHOW); Log. d (TAG, "show keyboard");} else {mHandler. send Message (mHandler. obtainMessage (KEYBOARD_HIDE) ;}}); mRoot. getViewTreeObserver (). addOnPreDrawListener (new OnPreDrawListener () {@ Override public boolean onPreDraw () {// TODO Auto-generated method stub if (mGetBottom) {mLoginBottom = mLogin. getBottom (); // obtain the location information of the logon 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:
The ViewTreeObserver class is used to add an OnGlobalLayoutListener listener to the view you want to listen to, and then determine whether the keyboard is called up based on the window changes in the onGlobalLayout () method. The following code is used to listen to ViewTreeObserver:
MRoot. getViewTreeObserver (). addOnGlobalLayoutListener (new OnGlobalLayoutListener () {@ Override public void onGlobalLayout () {int offset = mRoot. getRootView (). getHeight ()-mRoot. getHeight (); // determines whether the keyboard displays if (offset> 300) {mHandler Based on The View offset value. sendMessage (mHandler. obtainMessage (KEYBOARD_SHOW);} else {mHandler. sendMessage (mHandler. obtainMessage (KEYBOARD_HIDE ));}}});
The actual implementation of Handler is the same as that of Handler in the above structure.
Reference: InputMethod
Example source code