值 | 描述 |
”stateUnSpecified“ | 不指定软件的状态(显示或隐藏)。系统会根据主题中的设置来选择相应的状态。 该属性软键盘的默认设置。 |
”stateUnchnaged“ | 总是保持上次软键盘的状态。当Activity进入到最前端时,不论是它上次它是显示或隐藏,保持不变。 |
”stateHidden“ | 当用户进入目标Activity时,软键盘保持隐藏状态。这里的Activity是用户是向前进入Activity,而不是由于退出其它Activity退回到目标Activity。 |
”stateVisible“ | 只有条件合适(当用户前进进入到Activity的主window),就会显示键盘 |
”stateAlawaysVisible“ | 当用户选择进入目标Activity时,软键盘被设置为可见的。这里的Activity是用户向前进入的Activity,而不是由于退出其它Activity而回到目标Activity |
"adjustUnspecified" | 不指定是否去调整Activity的界面。或者调整Activity窗口的大小以便为软键盘腾出空间或者移动窗口的内容来屏幕上当前的焦点可见。系统会自动选择其中一种模式,这依赖于窗口是包含可以滑动其内容的view.如有这样的视图,窗口的大小就会被调整。在这样的假定的情况下,很小的滑动就可以使用窗口的内容可见。 该属性是主windowr默认设置。 |
”adjustResize“ | Activity的窗口总是被调整其大小以便为软键盘腾出空间。 |
”adjustPan“ | Activity的主窗口不会被调整其大小以便为软键盘腾出空间。相反,窗口的内容会被自动移动以便当前的焦点不会被软键盘遮住,用户可以总是看到他输入的内容。这个值一般用于用户很少想调整窗口的大小的情况下,因为用户可能需要关闭软键盘来与窗口的其它部分进行交互。 |
你有一个登录界面是这样设计的
你希望登录时它是这样的,
你不甘心,你将adjustResize修改成adjustPan,结果是这样的
可以在onSizeChanged(int w, int h,int oldw,int oldh) 方法里监听界面大小的变化,然后在该方法里定义回调函数,当监听到键盘被调出时,将键盘向上推一段距离,这样将登录键显示出来。
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); } }
在主Activity里创建一个Handler,当监听到布局发生变化时,通过Handler更新UI。
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.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 onChanged(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 public boolean onPreDraw() { // TODO Auto-generated method stub if (mGetBottom) { mLoginBottom = mLogin.getBottom();//获取登录按钮的位置信息。 } 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; // } }第二种方法的实现:
借助ViewTreeObserver类对你想监听的view添加OnGlobalLayoutListener监听器,然后在onGlobalLayout()方法里窗口的变化情况来判断键盘是否被调出来了。下面是ViewTreeObserver监听的部分的代码:
mRoot.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() { @Override public void onGlobalLayout() { int offset = mRoot.getRootView().getHeight() - mRoot.getHeight(); //根据视图的偏移值来判断键盘是否显示 if (offset > 300) { mHandler.sendMessage(mHandler.obtainMessage(KEYBOARD_SHOW)); } else { mHandler.sendMessage(mHandler.obtainMessage(KEYBOARD_HIDE)); } } });
其中Handler的具体实现同上述结构中的Handler一样。
参考文章:InputMethod
android 软键盘的显示与隐藏问题的研究,布布扣,bubuko.com
原文:http://blog.csdn.net/a2758963/article/details/25163171