方法一:windowSoftInputMode:adjustResize和adjustPan

主要实现方法:在 AndroidManifest.xml 对应的Activity里添加 android:windowSoftInputMode=”adjustPan” 或是 android:windowSoftInputMode=”adjustResize”属性

活动的主窗口如何与包含屏幕上的软键盘窗口交互。这个属性的设置将会影响两件事情 :

1>     软键盘的状态——是否它是隐藏或显示——当活动 (Activity)成为用户关注的焦点。

2>     活动的主窗口调整——是否减少活动主窗口大小以便腾出空间放软键盘或是否当活动窗口的部分被软键盘覆盖时它的内容的当前焦点是可见的。

它的设置必须是下面列表中的一个值,或一个 ”state…”值加一个 ”adjust…”值的组合。在任一组设置多个值——多个 ”state…”values,例如& mdash有未定义的结果。各个值之间用 |分开。例如 : <activity android:windowSoftInputMode="stateVisible|adjustResize" . . . >

在这设置的值 (除 "stateUnspecified"和 "adjustUnspecified"以外 )将覆盖在主题中设置的值

 

描述

"stateUnspecified"

软键盘的状态 (是否它是隐藏或可见 )没有被指定。系统将选择一个合适的状态或依赖于主题的设置。

这个是为了软件盘行为默认的设置。

"stateUnchanged"

软键盘被保持无论它上次是什么状态,是否可见或隐藏,当主窗口出现在前面时。

"stateHidden"

当用户选择该 Activity时,软键盘被隐藏——也就是,当用户确定导航到该 Activity时,而不是返回到它由于离开另一个 Activity。

"stateAlwaysHidden"

软键盘总是被隐藏的,当该 Activity主窗口获取焦点时。

"stateVisible"

软键盘是可见的,当那个是正常合适的时 (当用户导航到 Activity主窗口时 )。

"stateAlwaysVisible"

当用户选择这个 Activity时,软键盘是可见的——也就是,也就是,当用户确定导航到该 Activity时,而不是返回到它由于离开另一个Activity。

"adjustUnspecified"

它不被指定是否该 Activity主 窗口调整大小以便留出软键盘的空间,或是否窗口上的内容得到屏幕上当前的焦点是可见的。系统将自动选择这些模式中一种主要依赖于是否窗口的内容有任何布局 视图能够滚动他们的内容。如果有这样的一个视图,这个窗口将调整大小,这样的假设可以使滚动窗口的内容在一个较小的区域中可见的。这个是主窗口默认的行为 设置。

"adjustResize"

该 Activity主窗口总是被调整屏幕的大小以便留出软键盘的空间

"adjustPan"

该 Activity主窗口并不调整屏幕的大小以便留出软键盘的空间。相反,当前窗口的内容将自动移动以便当前焦点从不被键盘覆盖和用户能总是看到输入内容的部分。这个通常是不期望比调整大小,因为用户可能关闭软键盘以便获得与被覆盖内容的交互操作。

  • adjustResize失效情况:activity 设置了全屏属性指 Theme.Light.NotittleBar.Fullscreen 或者设置了 activity 对应的主题中 android:windowTranslucentStatus 属性,设置方式为:android:windowTranslucentStatus=true,这时如果对应的页面上含有输入框,将会导致点击输入框时软键盘弹出后键盘覆盖输入框,导致输入框看不见。

  • fitsSystemWindows=”true”,只有初始的view起作用:如果在布局中不是最外层控件设置 fitsSystemWindows=”true”, 那么设置的那个控件高度会多出一个状态栏高度。若有多个view设置了,因第一个view已经消耗掉 insect,其他 view 设置了也会被系统忽略

1、adjustPan

整个界面向上平移,使输入框露出,它不会改变界面的布局;界面整体可用高度还是屏幕高度,这个可以通过下面的截图看出,如点击 输入框6,输入框会被推到键盘上方,但 输入框1 被顶出去了,如果界面包含标题栏,也会被顶出去

2、adjustResize

需要界面的高度是可变的,或者说 Activity 主窗口的尺寸是可以调整的,如果不能调整,则不会起作用。

例如:Activity 的xml布局中只有一个 LinearLayout 包含若干EditText,在Activity的 AndroidMainfest.xml 中设置 android:windowSoftInputMode=”adjustResize” 属性,点击 输入框6, 发现软键盘挡住了 输入框6,并没有调整

但使用这两种属性,我们可以总结以下几点:

1). 使用 adjustPan, 如果需要输入的项比较多时,点击输入框,当前输入项会被顶到软键盘上方,但若当前输入框下面还有输入项时,却需要先收起键盘,再点击相应的输入项才能输入。这样操作太繁琐了,对于用户体验不大好;

2). adjustResize 的使用,需要界面本身可显示的窗口内容能调整,如果不能,不起作用;

方法二:在界面最外层布局包裹ScrollView

1、只使用ScrollView

在相应界面的xml布局中,最外层添加一个 ScrollView,不在 AndroidMainfest.xml 中设置任何 android:windowSoftInputMode属性,此时点击输入框,输入框均不会被软键盘档住。即使当前输入框下方也有输入框,在键盘显示的情况下,也可以通过上下滑动界面来输入,而不用先隐藏键盘,点击下方输入框,再显示键盘输入。

2、ScrollView + adjustPan

我们再在该类的 AndroidMainfest.xml 中设置 windowSoftInputMode属性 为 adjustPan:

发现当前输入框不会被挡住,但是输入框比较多时,在有键盘显示时,界面上下滑动,但只能滑动部分,且如果输入框在界面靠下方时,点击输入框,标题栏也会被顶出去

3、ScrollView+adjustResize

我们前面说过 adjustResize 的使用必须界面布局高度是可变的,如最外层套个 ScrollView 或是界面可收缩的,才起作用。这里在该类的 AndroidMainfest.xml 中设置windowSoftInputMode属性 为 adjustResize

发现效果和 1 不设置任何 windowSoftInputMode属性 类似,其使用高度也是:屏幕高度-状态栏高度-软键盘高度

可以看出,系统将选择合适的状态,也就是在界面最外层包含一层 ScrollView 时,设置默认属性值 stateUnspecified 其实就是 adjustResize属性。

但以下两方面无法满足需求:

1). 当 Activity 设置成全屏 fullscreen 模式时或是使用沉浸式状态栏时,界面最外层包裹  ScrollView,当输入框超过一屏,当前输入框下面的输入框并不能上下滑动来输入,情况类似于 ScrollView+adjustPan,只能滑动部分,通过 Inspect Layout 也可以看到,界面可用高度是整个屏幕高度,并不会进行调整高度。即使设置 adjustResize,也不起作用。

2). 如果是类似于注册界面或是登录界面,键盘会挡住输入框下面的登录按钮。

沉浸式状态栏下

自android系统4.4(API>=19)就开始支持沉浸式状态栏,当使用 System windows(系统窗口)显示系统一些属性和操作区域,如最上方的状态及没有实体按键的最下方的虚拟导航栏。

android:fitsSystemWindows=“true”会使得屏幕上的可布局空间位于状态栏下方与导航栏上方。

方法三:当键盘弹起时,让界面整体上移;键盘收起,让界面整体下移

使用场景:针对界面全屏或是沉浸式状态栏,输入框不会被键盘遮挡。主要用于一些登录界面,或是需要把界面整体都顶上去的场景。

1、主要实现步骤

(1). 获取Activity布局xml的最外层控件,如xml文件如下:

先获取到最外层控件:

RelativeLayout main = (RelativeLayout) findViewById(R.id.main);

(2). 获取到最后一个控件,如上面的xml文件,最后一个控件是Button:

Button login_btn = (Button) findViewById(R.id.login_btn);

(3). 给最外层控件和最后一个控件添加监听事件:

2、实现原理

此方法通过监听 Activity 最外层布局控件来检测软键盘是否弹出,然后去手动调用控件的 scrollTo方法 达到调整布局目的。

方法四:监听Activity顶层View,判断软键盘是否弹起,对界面重新绘制

此方法的实现来自android中提出的issue 5497

https://code.google.com/p/android/issues/detail?id=5497

使用场景:针对界面全屏或是沉浸式状态栏,界面包含比较多输入框,界面即使包裹了一层 ScrollView,在键盘显示时,当前输入框下面的输入不能通过上下滑动界面来输入。

一、实现步骤

1、把 SoftHideKeyBoardUtil类 复制到项目中;

2、在需要使用的Activity的onCreate方法中添加 SoftHideKeyBoardUtil.assistActivity(this) 即可。

二、实现原理

SoftHideKeyBoardUtil类 具体代码如下:

它的实现原理主要是:

(1). 找到 Activity 的最外层布局控件,我们知道所有的 Activity 都是 DecorView,它就是一个 FrameLayout控件,该控件id是系统写死叫 R.id.content,就是我们 setContentView 时,把相应的 View 放在此 FrameLayout 控件里

FrameLayout content = (FrameLayout) activity.findViewById(android.R.id.content);

所以 content.getChildAt(0) 获取到的 mChildOfContent,也就是我们用 setContentView 放进去的 View。

(2). 给我们的 Activity 的xml布局View设置一个 Listener 监听:

View.getViewTreeObserver() 可以获取一个 ViewTreeObserver对象——它是一个观察者,用以监听当前 View树 所发生的变化。这里所注册的 addOnGlobalLayoutListener,就是会在当前的 View树 的全局布局(GlobalLayout)发生变化、或者其中的 View 可视状态有变化时,进行通知回调。『软键盘弹出/隐 』都能监听到。

(3). 获取当前界面可用高度

如下图所示:

(4)重设高度, 我们计算出的可用高度,是目前在视觉效果上能看到的界面高度。但当前界面的实际高度是比可用高度要多出一个软键盘的距离的。

通过上面的这种方法,一般布局输入键盘挡住输入框的问题基本都能解决。即使界面全屏或是沉浸式状态栏情况。

总结

下面对上面几种方法进行对比:

方法一:

  • 优点:使用简单,只需在Activity的AndroidMainfest.xml中设置windowSoftInput属性即可。

  • 注意点:adjustResize属性必须要界面大小可以自身改变;

  • 缺点:当输入框比较多时,当前输入框下方的输入框会初键盘挡住,须收起键盘再进入输入;使用adjustPan,输入框较多时,因它是把界面当成一个整体,只会显示一屏的高度,会把ActionBar顶上去。

方法二:

  • 优点:使用简单,只需在Activity的最外层布局包裹一个ScrollView即可。

  • 注意点:不可使用adjustPan属性,否则ScrollView失效;

  • 缺点:对于全屏时,在键盘显示时,无法上下滑动界面达到输入的目的;

方法三:

  • 优点:可以解决全屏时,键盘挡入按钮问题。

  • 缺点:只要有此需求的Activity均需要获取到最外层控件和最后一个控件,监测键盘是否弹出,再调用控件的scrollTo方法对界面整体上移或是下移。代码冗余。

方法四:

  • 优点:可以解决全屏时,键盘挡入输入框问题。只需要写一个全局类,其他有需求的界面直接在onCreate方法里调用此类的全局方法,即可。

  • 缺点:多用了一个类。

综上所述:

1) 当输入框比较少时,界面只有一个输入框时,可以通过方法一设置adjustPan;

2) 如果对于非全屏/非沉浸式状态栏需求,只需要使用方法二即可;

3) 如果全屏全屏/沉浸式状态栏界面只有一个类有键盘挡入输入框需求,可使用方法三;

4) 如果大部分界面均使用全屏或沉浸式状态栏,且有此需求,则选择方法四更恰当。

Android各种键盘挡住输入框解决办法的更多相关文章

  1. android全屏/沉浸式状态栏下,各种键盘挡住输入框解决办法

    https://blog.csdn.net/smileiam/article/details/69055963

  2. 【转】ios输入框被键盘挡住的解决办法

    做IOS开发时,难免会遇到输入框被键盘遮掩的问题.上网上搜索了很多相关的解决方案,看了很多,但是由衷的觉得太麻烦了. 有的解决方案是将视图上的所有的东西都添加到一个滚动视图对象( UIScrollVi ...

  3. 移动端Android软键盘遮住输入框解决!

    在使用vue的情况下,在输入框中添加 <textarea class="textarea" @click="isAndroid" :maxlength=& ...

  4. uitableview 关于键盘挡住输入框解决方法

    // // AboutKeyBoardEventViewController.m // QueryBussinessInfo // // Created by mac on 16/8/23. // C ...

  5. h5软键盘挡住输入框问题解决(android)

    问题 移动端浏览器中的表单在部分android机型上测试,点击靠下的输入框时会遇到弹出的软键盘挡住输入框问题 ios可自身弹起(ios自身的调整偶尔也会出问题,例如第三方键盘会遮挡,原因是第三方输入法 ...

  6. iOS 解决键盘挡住输入框的问题

    iOS开发中经常会用到输入框UITextField,所以也常会遇到键盘挡住输入框而看不到输入框的内容. 在这里记录一种方法,用UITextField的代理来实现View的上移来解决这个问题. 首先设置 ...

  7. 【转】Android出现“Read-only file system”解决办法

    原文网址:http://www.111cn.net/sj/android/44496.htm 下面介绍一篇Android出现“Read-only file system”解决办法 有碰到这类问题的朋友 ...

  8. 【转】Ubuntu 上编译Android出现cannot find -lstdc++解决办法

    [转]Ubuntu 上编译Android出现cannot find -lstdc++解决办法 在Ubuntu 12.04 x86_64机器上编译Android出现下面错误,是因为找不到32bit的li ...

  9. (转载)Android出现“Read-only file system”解决办法

    下面介绍一篇Android出现“Read-only file system”解决办法 有碰到这类问题的朋友可参考参考.   Android-出现Read-only file system的解决方法 输 ...

随机推荐

  1. python多线程之_thread

    多线程类似于同时执行多个不同程序,多线程运行有如下优点: 使用线程可以把占据长时间的程序中的任务放到后台去处理. 用户界面可以更加吸引人,这样比如用户点击了一个按钮去触发某些事件的处理,可以弹出一个进 ...

  2. Java内存泄漏真实案例

    内存泄漏:当不再需要一个对象时,垃圾收集器会回收它:如果不需要的对象一直在产生而不被收回,就称作“内存泄漏”. 以下为本人在工作中遇到的内存泄漏的案例: 1.对于大量的请求,使用了Executors. ...

  3. django优化--ORM优缺点

    谈Django绕不开ORM ORM : ORM概念,ORM特点,ORM 的优点,ORM 的缺点 orm : 对象关系映射 (Object Relational Mapping) ,用于实现面向对象编程 ...

  4. 文件I/O简述

    什么是I/O 宏观上讲,I/O是信息处理系统(例如计算机)与外部世界(可能是人或其他信息处理系统)之间的通信.输入(Input)是系统接收的信号或数据,输出(Output)是从其发送的信号或数据.另一 ...

  5. 对于国嵌上学期《一跃进入C大门》Mini2440的代码修正

    摸索了几天,加了无数的群,病急乱投医式地问了好多个人,终于改对了代码. 下面先贴出给的范例代码 这是C语言代码,是没有错的. 那么出错的地方就在start.S部分 很明显,MPLLCON地址错误,正确 ...

  6. Java语言基础(3)

    1 算术运算符:+,-,*(乘法),/(除法),%(求余数) 1)只有相同类型的数据才可以进行算术运算,经常使用到自动类型转换和强制类型转换,把参与运算的数据转换为同一个类型,然后再进行算术运算. 案 ...

  7. 忘记mysql或mariadb数据库密码的解决方案

    主机环境 主机系统:

  8. CSS3 选择器——笔记+实战案例(基本选择器、组合选择器、属性选择器、伪类选择器)

    使用CSS3 选择器——笔记 CSS通过选择器控制HTML元素,CSS选择器对网页对象可以实现一对一.一对多或者多对一的匹配. 一.CSS3选择器分类 CSS选择器在CSS2.1选择器的基础上新增了属 ...

  9. spark读取hbase(NewHadoopAPI 例子)

    package cn.piesat.controller import java.text.{DecimalFormat, SimpleDateFormat}import java.utilimpor ...

  10. Python CGI编程Ⅹ

    检索Cookie信息 Cookie信息检索页非常简单,Cookie信息存储在CGI的环境变量HTTP_COOKIE中,存储格式如下: 以下是一个简单的CGI检索cookie信http://www.we ...