一:简述

点击文本框EditText,系统会自动弹出软键盘(其本质是一个Dialog),这必然会引起当前Activity主窗口的大小调整
而Android提供了不同的可选模式去调整活动窗口的大小,与之相关的属性为:android:windowSoftInputMode, 当然具体的实现是由系统完成的
可以在清单文件Manifest.xml中的Activity标签内设置
如:android:windowSoftInputMode="stateUnspecified|adjustPan"
该属性可选的值有两部分,一部分为软键盘的状态控制,另一部分是活动主窗口的调整。前一部分本文不做讨论,请读者自行查阅android文档。

一: 压缩模式
android:windowSoftInputMode="adjustResize", 那么不管活动主窗口压缩后文本框EditText是否可见(这将于下面一种模式形成对比),
当前Activity主窗口顶部保持不变,总是被从下向上压缩,压缩的距离等于软键盘的高度
测试代码(Android2.3.3SDK):

  1. public class CustomRelativeLayout extends RelativeLayout{


  2. public CustomRelativeLayout(Context context, AttributeSet attrs) {

  3. super(context, attrs);

  4. }



  5. @Override

  6. protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

  7. Log.i("lanyan", "onMeasure");

  8. super.onMeasure(widthMeasureSpec, heightMeasureSpec);

  9. }


  10. @Override

  11. protected void onLayout(boolean changed, int l, int t, int r, int b) {

  12. Log.i("lanyan", "onLayout");

  13. super.onLayout(changed, l, t, r, b);

  14. }


  15. /**

  16. * 当前活动主窗口大小改变时调用

  17. */

  18. @Override

  19. protected void onSizeChanged(int w, int h, int oldw, int oldh) {

  20. Log.i("lanyan", "onSizeChanged");

  21. super.onSizeChanged(w, h, oldw, oldh);

  22. }


  23. }

复制代码

  1. <com.lanyan.drawable.widget.customrelativelayout xmlns:android="http://schemas.android.com/apk/res/android"

  2. android:layout_width="fill_parent"

  3. android:layout_height="fill_parent"

  4. android:orientation="vertical"

  5. >


  6. <textview android:layout_width="fill_parent"

  7. android:layout_height="20dp" android:background="#9999CC"

  8. android:layout_alignParentTop="true" android:text="============= 我在顶部 =============="

  9. android:textColor="#FFFFFF"/>


  10. <edittext android:layout_width="fill_parent"

  11. android:layout_height="wrap_content"

  12. android:layout_marginTop="220dp" />


  13. <textview android:layout_width="fill_parent"

  14. android:layout_height="20dp" android:background="#9999CC"

  15. android:layout_alignParentBottom="true" android:text="============= 我在底部 =============="

  16. android:textColor="#FFFFFF"/>


复制代码

运行程序,点击文本框,日志顺序如下:
onMeasure
onSizeChanged
onLayout
实际上,当设置为adjustResize后,软键盘弹出时,要对主窗口布局重新进行measure和layout,而在layout时,发现窗口的大小发生的变化,因此调用了onSizeChanged
示意图1:EditText距离底部的距离 < 软键盘高度
2012071500281924.png2012071500283045.png
可以看到, 顶部不变,底部被软键盘顶了上去,文本框被遮住
2,微调xml布局,使得EditText距离底部的距离 > 软键盘高度
2012071500403320.png2012071500405871.png

二: 平移模式
android:windowSoftInputMode="adjustPan",此模式下,Activity主窗口大小始终保持不变,不管是否平移,
总是保证文本框不被软键盘覆盖且输入内容可见
上述代码的日志信息:
onMeasure
onLayout
可以看到,并不会调用onSizeChanged()方法
示意图1, EditText距离底部距离 < 软键盘高度
2012071500443369.png2012071500452269.png
底部TextView并没有被顶上去,而是活动主窗口整体向上平移(包括标题栏),具体平移的距离由系统measure,以便确保文本框可见
2,EditText距离底部的距离 > 软键盘高度

与上面类似,只是窗口并未平移,因为即使软键盘弹出,也不影响文本框是否可见,这种情况下,软键盘等于是"浮动"在Activity上面

三: 自动模式
android:windowSoftInputMode="adjustUnspecified"
系统自动决定是采用平移模式还是压缩模式,决定因素在于内容是否可以滚动。

二:监听软键盘的显示隐藏
可以通过onSizeChanged()方法间接地对软键盘的显示隐藏进行监听(并未精确到软键盘显示隐藏之前/之后这种程度),从而可以在主窗口大小发生变化时,进行自定义的操作,如显示或隐藏某个view

由于View类并未提供类似setOnClickListener(....)这样方便的接口,所以还是要重写根布局,并且加个回调接口即可
此方法仅当Activity为压缩模式是有效,平移模式窗口大小不变,系统不会调用onSizeChanged()方法

  1. public class CustomRelativeLayout extends RelativeLayout{


  2. private KeyboardChangeListener listener;


  3. public CustomRelativeLayout(Context context, AttributeSet attrs) {

  4. super(context, attrs);

  5. }


  6. @Override

  7. protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

  8. Log.i("lanyan", "onMeasure");

  9. super.onMeasure(widthMeasureSpec, heightMeasureSpec);

  10. }


  11. @Override

  12. protected void onLayout(boolean changed, int l, int t, int r, int b) {

  13. Log.i("lanyan", "onLayout");

  14. super.onLayout(changed, l, t, r, b);

  15. }


  16. /**

  17. * 当前活动主窗口大小改变时调用

  18. */

  19. @Override

  20. protected void onSizeChanged(int w, int h, int oldw, int oldh) {

  21. Log.i("lanyan", "onSizeChanged");

  22. super.onSizeChanged(w, h, oldw, oldh);


  23. if (null != listener) {

  24. listener.onKeyboardChange(w, h, oldw, oldh);

  25. }

  26. }


  27. public void setOnKeyboardChangeListener(KeyboardChangeListener listener) {

  28. this.listener = listener;

  29. }


  30. /**

  31. * Activity主窗口大小改变时的回调接口(本示例中,等价于软键盘显示隐藏时的回调接口)

  32. * @author mo

  33. *

  34. */

  35. public interface KeyboardChangeListener {

  36. public void onKeyboardChange(int w, int h, int oldw, int oldh);

  37. }


  38. }

复制代码

  1. public class EditActivity extends Activity{


  2. @Override

  3. protected void onCreate(Bundle savedInstanceState) {

  4. super.onCreate(savedInstanceState);


  5. setContentView(R.layout.edit);

  6. CustomRelativeLayout customRelativeLayout = (CustomRelativeLayout)findViewById(R.id.relativelayout1);

  7. customRelativeLayout.setOnKeyboardChangeListener(new CustomRelativeLayout.KeyboardChangeListener() {


  8. @Override

  9. public void onKeyboardChange(int w, int h, int oldw, int oldh) {


  10. //do your operation


  11. }

  12. });


  13. }


  14. }

复制代码

PS: 上述软键盘的弹出都是点击文本框,系统自动弹出的
也可以通过代码的方式手动控制软键盘的显示与隐藏(Android2.3.3SDK)

  1. tv.setOnClickListener(new OnClickListener() {

  2. @Override

  3. public void onClick(View v) {

  4. InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);

  5. //隐藏软键盘

  6. // imm.hideSoftInputFromWindow(tv.getWindowToken(), 0);

  7. //显示软键盘

  8. // imm.showSoftInputFromInputMethod(tv.getWindowToken(), 0);

  9. //切换软键盘的显示与隐藏

  10. imm.toggleSoftInputFromWindow(tv.getWindowToken(), 0, InputMethodManager.HIDE_NOT_ALWAYS);

  11. //或者

  12. // imm.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS);

  13. }

  14. });


更多相关文章

  1. android window窗口机制
  2. iOS和android解决键盘弹出遮挡控件的处理比较
  3. Android 软键盘弹出隐藏挤压界面等各种问题小结
  4. android 隐藏输入键盘的方法
  5. android获取当前窗口的宽度和高度
  6. Android屏幕方向及键盘状态
  7. Android WindowManager与窗口管理
  8. Android 手动显示和隐藏软键盘

随机推荐

  1. Android动态快捷方式兼容性问题
  2. Android新手轻松学知乎日报开发(三)封装简
  3. Android(安卓)游戏开发之服务器端
  4. 2014年年终总结以及新的规划
  5. View和Layout
  6. Android(安卓)java层和C层的相互调用
  7. TaintDroid下载预编译(五):TaintDroid(Androi
  8. android 系统开发
  9. android 给自己的app编写 用户引导(UserGu
  10. [置顶] Android异步加载数据库和多线程编