查看原文
一、软键盘显示的原理
软键盘的本质是什么?软键盘其实是一个Dialog!
InputMethodService为我们的输入法创建了一个Dialog,并且将该Dialog的Window的某些参数(如Gravity)进行了设置,使之能够在底部或者全屏显示。当我们点击输入框时,系统对活动主窗口进行调整,从而为输入法腾出相应的空间,然后将该Dialog显示在底部,或者全屏显示。
二、活动主窗口调整
android定义了一个属性,名字为windowSoftInputMode, 用它可以让程序可以控制活动主窗口调整的方式。我们可以在AndroidManifet.xml中对Activity进行设置。如:android:windowSoftInputMode="stateUnchanged|adjustPan"
模式一,压缩模式
windowSoftInputMode的值如果设置为adjustResize,那么该Activity主窗口总是被调整大小以便留出软键盘的空间。
我们通过一段代码来测试一下,当我们设置了该属性后,弹出输入法时,系统做了什么。
重写Layout布局:
public class ResizeLayout extends LinearLayout{
private static int count = 0;
public ResizeLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
Log.e("onSizeChanged " + count++, "=>onResize called! w="+w
+ ",h="+h+",oldw="+oldw+",oldh="+oldh);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
Log.e("onLayout " + count++, "=>OnLayout called! l=" + l + ", t="
+ t + ",r=" + r + ",b="+b);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
Log.e("onMeasure " + count++, "=>onMeasure called! widthMeasureSpec="
+ widthMeasureSpec + ", heightMeasureSpec=" + heightMeasureSpec);
}
}
我们的布局设置为:
<com.winuxxan.inputMethodTest.ResizeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/root_layout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
>
<EditText
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<LinearLayout
android:id="@+id/bottom_layout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:gravity="bottom">s
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
android:background="#77777777"
/>
</LinearLayout>
</com.winuxxan.inputMethodTest.ResizeLayout>
AndroidManifest.xml的Activity设置属性:android:windowSoftInputMode = "adjustResize"
运行程序,点击文本框,查看调试信息:
E/onMeasure 6(7960): =>onMeasure called! widthMeasureSpec=1073742144, heightMeasureSpec = 1073742024
E/onMeasure 7(7960): =>onMeasure called! widthMeasureSpec=1073742144, heightMeasureSpec = 1073742025
E/onSizeChanged 8(7960): =>onSizeChanged called! w=320,h=201,oldw=320,oldh=377
E/onLayout 9(7960): =>OnLayout called! l=0, t=0,r=320,b=201
从调试结果我们可以看出,当我们点击文本框后,根布局调用了onMeasure,onSizeChanged和onLayout。
实际上,当设置为adjustResize后,软键盘弹出时,要对主窗口布局重新进行measure和layout,而在layout时,发现窗口的大小发生的变化,因此调用了onSizeChanged。
从下图的运行结果我们也可以看出,原本在下方的TextView被顶到了输入法的上方
模式二,平移模式
windowSoftInputMode的值如果设置为adjustPan,那么该Activity主窗口并不调整屏幕的大小以便留出软键盘的空间。相反,当前窗口的内容将自动移动以便当前焦点从不被键盘覆盖和用户能总是看到输入内容的部分。这个通常是不期望比调整大小,因为用户可能关闭软键盘以便获得与被覆盖内容的交互操作。
上面的例子中,我们将AndroidManifest.xml的属性进行更改:android: windowSoftInputMode = "adjustPan"
重新运行,并点击文本框,查看调试信息:
E/onMeasure 6(8378): =>onMeasure called! widthMeasureSpec=1073742144, heightMeasureSpec=1073742200
E/onMeasure 7(8378): =>onMeasure called! widthMeasureSpec=1073742144, heightMeasureSpec=1073742201
E/onLayout 8(8378): =>OnLayout called! l=0, t=0,r=320,b=377
我们看到:系统也重新进行了measrue和layout,但是我们发现,layout过程中onSizeChanged并没有调用,这说明输入法弹出前后并没有改变原有布局的大小。
从下图的运行结果我们可以看到,下方的TextView并没有被顶到输入法上方。
事实上,当输入框不会被遮挡时,该模式没有对布局进行调整,然而当输入框将要被遮挡时,窗口就会进行平移。也就是说,该模式始终是保持输入框为可见。如下图,整个窗口,包括标题栏均被上移,以保证文本框可见。
模式三 自动模式
当属性windowSoftInputMode被设置为adjustUspecified时,它不被指定是否该Activity主窗口调整大小以便留出软键盘的空间,或是否窗口上的内容得到屏幕上当前的焦点是可见的。系统将自动选择这些模式中一种主要依赖于是否窗口的内容有任何布局视图能够滚动他们的内容。如果有这样的一个视图,这个窗口将调整大小,这样的假设可以使滚动窗口的内容在一个较小的区域中可见的。这个是主窗口默认的行为设置。
也就是说,系统自动决定是采用平移模式还是压缩模式,决定因素在于内容是否可以滚动。
分享到:
相关推荐
这个"android 输入法键盘弹出与否判断和输入法键盘弹出时将界面滚动到指定位置demo"着重于解决两个关键问题:一是检测输入法键盘是否弹出,二是当键盘弹出时如何自动调整界面布局以确保重要内容可见。 首先,我们要...
Android系统在软键盘弹出或隐藏时会触发Activity的布局过程,我们可以通过监听这个过程来判断软键盘的状态。描述中提到的方法是通过重写`onLayout`方法来实现这一功能。 `onLayout`方法是View类的一个回调方法,它...
在默认情况下,Android布局是静态的,当软键盘弹出时,布局不会自动调整。要改变这一行为,我们通常会采用以下几种方法: 1. **调整Activity的WindowSoftInputMode**: 在AndroidManifest.xml中,找到对应的...
Android 软键盘调整界面问题解决方案 Android 软键盘的问题是 Android 开发中常见的问题之一。软键盘的出现可能会导致界面被顶起或被遮挡,从而影响用户体验。解决这个问题需要了解软键盘的属性和调整方法。 首先...
总之,这个源码示例提供了处理Android软键盘弹出动态改变UI布局的方法,特别是对于IM聊天窗口的设计,具有很高的参考价值。开发者可以通过深入研究这些代码,学习如何在软键盘弹出时优雅地调整布局,提升应用的交互...
总的来说,掌握Android软键盘弹出时的界面控制是优化用户体验的重要一环。理解并合理运用`windowSoftInputMode`属性,可以避免用户界面因软键盘弹出而出现的不理想效果,从而提升应用的整体质量。同时,持续关注和...
当软键盘弹出时,屏幕的可使用高度会减少,因此可以通过比较不同时间点的布局高度来判断软键盘是否弹出。然而,这种方法的缺点是它可能导致界面压缩,而不是控件平移,这可能不符合某些开发者的设计需求。如果需要在...
总之,处理Android软键盘弹出的问题需要结合具体应用场景选择合适的方法。理解窗口属性、布局调整和系统UI状态监听是解决问题的关键。希望上述内容能帮助开发者在面对软键盘问题时,能够游刃有余。
当软键盘弹出时,由于屏幕可用空间减少,根布局的高度会相应减小;而当软键盘收起时,根布局的高度则会恢复。可以通过重写onGlobalLayout()方法并使用ViewTreeObserver来监听布局的变化: ```java rootView....
综上所述,实现禁止软键盘弹出并使用自定义键盘的功能,涉及到了Android布局设计、事件监听、DialogFragment的使用以及输入管理等多个方面。通过合理的设计和编程,我们可以提供更符合应用场景的用户体验。在keydemo...
当软键盘弹起时,屏幕可用的高度会减少,因为一部分空间被键盘占用;而当软键盘收起时,屏幕高度将恢复到原始状态。因此,我们可以通过比较当前布局的高度和屏幕原始高度来判断软键盘的状态。 以下是实现监听软键盘...
有时,当软键盘弹出时,它会遮挡住屏幕底部的按钮,如登录按钮,这给用户带来了不便。本文将详细介绍如何解决这一问题,实现软键盘弹出时页面整体上移,以及点击空白区域收起软键盘的效果,并且将11位手机号格式化为...
1.首先说一下思路: 基本就是结合layout中ScrollView视图和...当有焦点产生时,软键盘是隐藏还是显示 2.是否减少活动主窗口大小以便腾出空间放软键盘 windowSoftInputMode的设置必须是下面列表中的一个值,或一个
在默认情况下,当软键盘弹出时,Android会调整Activity的布局以适应屏幕空间,可能会导致底部的元素被键盘遮挡。这种行为是由系统的WindowManager.LayoutParams.FLAGSoftInputMode属性控制的,它有几种模式如ADJUST_...
在Android应用开发中,经常会遇到一个问题,即当用户在输入框中输入时,弹出的软键盘会遮挡部分屏幕内容,尤其是对于登录或注册等需要填写多项信息的界面,这种情况严重影响了用户体验。为了解决这个问题,Android...
通过重写父布局的测量和布局过程,我们可以控制输入框在软键盘弹出时的行为。例如,可以检测键盘的状态,然后动态改变布局的高度或者输入框的位置。 3. **使用CoordinatorLayout**: 如果你的界面使用了Material ...
当软键盘弹出时,如果没有适当的监听机制,可能会导致用户界面上的内容被键盘部分遮挡,影响用户的操作体验。因此,能够监听软键盘的弹出与隐藏,并在适当的时候调整界面布局或执行其他相关操作显得尤为重要。 ...
当软键盘弹出时,由于屏幕空间被占用,Activity的根布局高度会减少。我们可以监听OnGlobalLayoutListener,对比前后布局的高度变化来判断软键盘的状态。以下是一个简单的示例: ```java final View ...
在Android开发中,"EditText跟随键盘弹出,背景不动"是一个常见的用户界面需求,尤其是在创建输入表单或者聊天应用时。这个现象涉及到Android系统的行为、布局管理器以及自定义视图处理。以下将详细讲解相关的知识点...