一:简述

点击文本框EditText,系统会自动弹出软键盘(其本质是一个Dialog),这必然会引起当前Activity主窗口的大小调整

而Android提供了不同的可选模式去调整活动窗口的大小,与之相关的属性为:android:windowSoftInputMode, 当然具体的实现是由系统完成的

可以在清单文件Manifest.xml中的Activity标签内设置

如:android:windowSoftInputMode="stateUnspecified|adjustPan"

该属性可选的值有两部分,一部分为软键盘的状态控制,另一部分是活动主窗口的调整。前一部分本文不做讨论,请读者自行查阅android文档。

一: 压缩模式

android:windowSoftInputMode="adjustResize", 那么不管活动主窗口压缩后文本框EditText是否可见(这将于下面一种模式形成对比),

当前Activity主窗口顶部保持不变,总是被从下向上压缩,压缩的距离等于软键盘的高度

测试代码(Android2.3.3SDK):

public class CustomRelativeLayout extends RelativeLayout{ public CustomRelativeLayout(Context context, AttributeSet attrs) { super(context, attrs); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { Log.i("lanyan", "onMeasure"); super.onMeasure(widthMeasureSpec, heightMeasureSpec); } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { Log.i("lanyan", "onLayout"); super.onLayout(changed, l, t, r, b); } /** * 当前活动主窗口大小改变时调用 */ @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { Log.i("lanyan", "onSizeChanged"); super.onSizeChanged(w, h, oldw, oldh); } }

<com.lanyan.drawable.widget.CustomRelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <TextView android:layout_width="fill_parent" android:layout_height="20dp" android:background="#9999CC" android:layout_alignParentTop="true" android:text="============= 我在顶部 ==============" android:textColor="#FFFFFF"/> <EditText android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginTop="220dp" /> <TextView android:layout_width="fill_parent" android:layout_height="20dp" android:background="#9999CC" android:layout_alignParentBottom="true" android:text="============= 我在底部 ==============" android:textColor="#FFFFFF"/>com.lanyan.drawable.widget.CustomRelativeLayout>

运行程序,点击文本框,日志顺序如下:

onMeasure

onSizeChanged

onLayout

实际上,当设置为adjustResize后,软键盘弹出时,要对主窗口布局重新进行measure和layout,而在layout时,发现窗口的大小发生的变化,因此调用了onSizeChanged

示意图1:EditText距离底部的距离 < 软键盘高度

可以看到, 顶部不变,底部被软键盘顶了上去,文本框被遮住

2,微调xml布局,使得EditText距离底部的距离 > 软键盘高度

二: 平移模式

android:windowSoftInputMode="adjustPan",此模式下,Activity主窗口大小始终保持不变,不管是否平移,

总是保证文本框不被软键盘覆盖且输入内容可见

上述代码的日志信息:

onMeasure

onLayout

可以看到,并不会调用onSizeChanged()方法

示意图1, EditText距离底部距离 < 软键盘高度

底部TextView并没有被顶上去,而是活动主窗口整体向上平移(包括标题栏),具体平移的距离由系统measure,以便确保文本框可见

2,EditText距离底部的距离 > 软键盘高度

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

三: 自动模式

android:windowSoftInputMode="adjustUnspecified"

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

二:监听软键盘的显示隐藏

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

由于View类并未提供类似setOnClickListener(....)这样方便的接口,所以还是要重写根布局,并且加个回调接口即可

此方法仅当Activity为压缩模式是有效,平移模式窗口大小不变,系统不会调用onSizeChanged()方法

public class CustomRelativeLayout extends RelativeLayout{ private KeyboardChangeListener listener; public CustomRelativeLayout(Context context, AttributeSet attrs) { super(context, attrs); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { Log.i("lanyan", "onMeasure"); super.onMeasure(widthMeasureSpec, heightMeasureSpec); } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { Log.i("lanyan", "onLayout"); super.onLayout(changed, l, t, r, b); } /** * 当前活动主窗口大小改变时调用 */ @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { Log.i("lanyan", "onSizeChanged"); super.onSizeChanged(w, h, oldw, oldh); if (null != listener) { listener.onKeyboardChange(w, h, oldw, oldh); } } public void setOnKeyboardChangeListener(KeyboardChangeListener listener) { this.listener = listener; } /** * Activity主窗口大小改变时的回调接口(本示例中,等价于软键盘显示隐藏时的回调接口) * @author mo * */ public interface KeyboardChangeListener { public void onKeyboardChange(int w, int h, int oldw, int oldh); } }

public class EditActivity extends Activity{ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.edit); CustomRelativeLayout customRelativeLayout = (CustomRelativeLayout)findViewById(R.id.relativelayout1); customRelativeLayout.setOnKeyboardChangeListener(new CustomRelativeLayout.KeyboardChangeListener() { @Override public void onKeyboardChange(int w, int h, int oldw, int oldh) { //do your operation } }); } }

PS: 上述软键盘的弹出都是点击文本框,系统自动弹出的

也可以通过代码的方式手动控制软键盘的显示与隐藏(Android2.3.3SDK)

tv.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE); //隐藏软键盘// imm.hideSoftInputFromWindow(tv.getWindowToken(), 0); //显示软键盘// imm.showSoftInputFromInputMethod(tv.getWindowToken(), 0); //切换软键盘的显示与隐藏 imm.toggleSoftInputFromWindow(tv.getWindowToken(), 0, InputMethodManager.HIDE_NOT_ALWAYS); //或者// imm.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS); } });

更多相关文章

  1. Android控件编辑时键盘弹起与关闭处理
  2. Android应用程序键盘(Keyboard)消息处理机制分析
  3. Android获取软键盘输入内容
  4. Android应用程序键盘(Keyboard)消息处理机制分析(1)
  5. 键盘弹出以后Activity的布局方式
  6. Android inputType ,软键盘输入类型
  7. Android应用程序键盘(Keyboard)消息处理机制分析(25)
  8. Android EditText 自动获取焦点,并弹出键盘

随机推荐

  1. android listView头部自定义标签形式
  2. android activity进入退出动画自定义
  3. Android P的Socket通信实现之传输图片数
  4. [转]Android的多媒体框架OpenCore(PacketV
  5. emulator找不到AVD解决方式
  6. Android studio怎么创建一个Java类文件
  7. 10个经典的Android开源项目
  8. 学习android的网站
  9. RelativeLayout的一些重要属性
  10. Android实习生 —— 网络请求及数据解析