整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

Android 软键盘控制方法、以及开发中遇到的一些问题

Android 提供了 windowSoftInputMode 属性来控制输入法软键盘窗口和 Activity 主窗口的交互,分为 窗口尺寸调整系列 和 输入法软键盘显示控制系列。

窗口尺寸调整系列:

该系列参数用来控制当软键盘弹起时,Activity 主窗口的调整策略,因为如果不调整主窗口,很可能会导致当前输入的控件被软键盘遮挡。

adjustPan:

Activity的主窗口并不会重新调整大小来为输入法腾出空间,而是窗口的内容会自动上下晃动来保证当前获得焦点的控件不会被键盘遮挡住,然后用户可以看见自己输入的内容。相比于 adjustResize 模式而言,它并不是很令人满意,因为用户必须关闭输入法来和被输入法遮挡住的控件进行交互。

adjustResize:

Activity的主窗口会重新调整大小来为输入法腾出空间。

adjustUnspecified:

当前模式并不会明确指定 Activity 使用adjustPan 或者 adjustResize ,系统会自动选择一个模式,选择结果是,如果当前 Activity 的 Window 中,有可以滚动自身内容的控件,比如 ScrollView,那么选择结果就是 adjustResize,因为它认为滚动可以使 Window 中的内容即使在一个很小的区域中也可以被看见。Activity 的默认模式就是这个模式。

adjustNoting:

Activity 的 Window 没有任何变化。

两种模式下,屏幕 - 主窗口 - 主窗口内容 - 软键盘 的关系如下:

具体效果如下:

没有滚动内容,adjustPan:

没有滚动内容,adjustResize:

没有滚动内容,adjustUnspecified == adjustPan

有滚动内容(ScrollView),adjustPan

有滚动内容(ScrollView),adjustResize

有滚动内容(ScrollView),adjustUnspecified == adjustResize

输入法软键盘显示控制系列:

该系列参数用来控制当一个包含 Window 的事物(Activity、Dialog等)展示在屏幕最前端时,软键盘的显示或者隐藏策略。

stateUnspecified:

系统根据当前具体情况,选择相应的模式。

stateUnchanged:

软键盘保持它的上一个状态(上一个Activity 或者 Dialog 在屏幕最前端时,软键盘的状态),不做变化,不管上一个状态是显示还是隐藏。

stateHidden:

当用户主动进入当前界面时,软键盘隐藏。离开上一个 界面,返回当前界面,不能算作 “主动进入”。被动进入时,保持上一个状态。

stateAlwaysHidden:

只要是用户进入该界面,就隐藏软键盘,不管是主动进入(新启动该界面),还是被动进入(离开上一个界面,返回到当前界面)。

stateVisible:

当用户主动进入当前界面时,显示软键盘。离开上一个 界面,返回当前界面,不能算作 “主动进入”。被动进入时,保持上一个状态。

stateAlwaysVisible:

只要是用户进入该界面,就显示软键盘,不管是主动进入(新启动该界面),还是被动进入(离开上一个界面,返回到当前界面)。

关于某些华为手机的一个Bug

今天遇到一个Bug,是这样的,在某些华为手机上面,除了第一次点击输入框,adjustPan 参数会生效(软键盘可以正常弹起输入框),后面从第二次开始,怎么点击,adjustPan 参数都无效。

布局模型大致如下:

[html] view plain copy print?

  1. <RelativeLayout

  2. xmlns:android="http://schemas.android.com/apk/res/android"

  3. xmlns:tools="http://schemas.android.com/tools"

  4. android:id="@+id/activity_main"

  5. android:layout_width="match_parent"

  6. android:layout_height="match_parent"

  7. tools:context="cn.hjf.inputtest.MainActivity">

  8. <ScrollView

  9. android:layout_width="match_parent"

  10. android:layout_height="match_parent">

  11. <LinearLayout

  12. android:layout_width="match_parent"

  13. android:layout_height="match_parent"

  14. android:orientation="vertical">

  15. <View

  16. android:layout_width="match_parent"

  17. android:layout_height="400dp"

  18. android:background="#2b532b"/>

  19. <EditText

  20. android:layout_width="90dp"

  21. android:layout_height="wrap_content"

  22. android:layout_gravity="center_vertical"

  23. android:background="@null"

  24. android:gravity="center"

  25. android:inputType="numberDecimal"

  26. android:maxLength="8"

  27. android:minWidth="60dp"

  28. android:padding="5dp"

  29. android:text="0.00"/>

  30. </LinearLayout>

  31. </ScrollView>

  32. </RelativeLayout>

  33. <RelativeLayout

    效果是这样的:

    经过漫长时间的排除(很辛苦),终于找到了Bug的触发临界点,就是下面这两句话:

    [html] view plain copy print?

    1. android:gravity="center"

    2. android:inputType="numberDecimal"

    android:gravity="center"

    又经过了漫长时间的验证,得出一个结论:在某些华为机型上面,在这种布局模型下,EditText 中如果设置了 inputType 参数(不为 none),那么,在 gravity 取值为某些值得时候,会导致该问题的发生。大致情况如下:

    红色表示失效,绿色表示有效(可以正常工作)。当这两个参数不指定的时候,可以工作,因为这两个属性默认值的组合是可以工作的,上图中的蓝色块。(备注:没有完全匹配所有情况,如有相似情况,可以按需匹配,查看结果)

    在源码中可以找到这两个属性的默认值:

    attrs.xml

    [html] view plain copy print?

    1. <!-- Default EditText style. -->

    2. <attr name="editTextStyle" format="reference" />

    <!-- Default EditText style. -->

    themes.xml

    [html] view plain copy print?

    1. <item name="editTextStyle">@style/Widget.EditText</item>

    <item name="editTextStyle">@style/Widget.EditText</item>

    styles.xml

    [html] view plain copy print?

    1. <style name="Widget.EditText">

    2. <item name="focusable">true</item>

    3. <item name="focusableInTouchMode">true</item>

    4. <item name="clickable">true</item>

    5. <item name="background">?attr/editTextBackground</item>

    6. <item name="textAppearance">?attr/textAppearanceMediumInverse</item>

    7. <item name="textColor">?attr/editTextColor</item>

    8. <item name="gravity">center_vertical</item>

    9. <item name="breakStrategy">simple</item>

    10. <item name="hyphenationFrequency">normal</item>

    11. </style>

    <style name="Widget.EditText">

    attrs.xml

    [html] view plain copy print?

    1. <!-- The type of data being placed in a text field, used to help an

    2. input method decide how to let the user enter text. The constants

    3. here correspond to those defined by

    4. {@link android.text.InputType}. Generally you can select

    5. a single value, though some can be combined together as

    6. indicated. Setting this attribute to anything besides

    7. <var>none</var> also implies that the text is editable. -->

    8. <attr name="inputType">

    9. <!-- There is no content type. The text is not editable. -->

    10. <flag name="none" value="0x00000000" />

    11. ..........

    <!-- The type of data being placed in a text field, used to help an

    [java] view plain copy print?

    1. /**

    2. * Special content type for when no explicit type has been specified.

    3. * This should be interpreted to mean that the target input connection

    4. * is not rich, it can not process and show things like candidate text nor

    5. * retrieve the current text, so the input method will need to run in a

    6. * limited "generate key events" mode, if it supports it. Note that some

    7. * input methods may not support it, for example a voice-based input

    8. * method will likely not be able to generate key events even if this

    9. * flag is set.

    10. */

    11. public static final int TYPE_NULL = 0x00000000;

    /**

    一个需求

    遇到一个需求,大致模型为:有一个界面,里面有一个 输入框 和 两个按钮,分别控制输入框中数字的加减,如下图所示:

    每次输入框数字变化,不管是手动输入还是按钮控制,都会出发刷新工作,刷新时会弹出一个对话框。

    然后需求是这样的,当手动输入的时候,这时触发刷新时,输入法是显示的,但是对话框显示然后消失后,输入法就被隐藏了。当用按钮控制的时候,是没问题的,因为整个过程,输入法都是隐藏的。所以需求就是,在对话框显示然后消失后,输入法能保持出发刷新时的状态。

    解决问题:当把当前 Activity 设置为 stateUnchanged 的时候,并没有达到理想的效果,因为dialog所在的window,没有设置该属性,所以需要把dialog的window也设置为stateUnchanged,方法为:

    [java] view plain copy print?

    1. getWindow().setSoftInputMode()

天这篇文章我们主要来看一下表单的控件都有哪些,如何使用表单标签,与用户交互。

(1)网站怎样与用户进行交互?

答案是使用HTML表单(form)。表单是可以把浏览者输入的数据传送到服务器端,这样服务器端程序就可以处理表单传过来的数据。

使用语法:<form method="传送方式" action="服务器文件"></form>

详细讲解:

1、<form> :<form>标签是成对出现的,以<form>开始,以</form>结束。

2、action :浏览者输入的数据被传送到的地方,比如一个PHP页面(save.php),后台可以通过这个文件来接收前端传过去的数据资料并进行分析处理。

3、method : 数据传送的方式(get/post),get多用于获取数据,post多用于提交数据(关于这一块大家可以简单了解一下即可,后期我们会在网站制作的时候进行讲解)。

注意:所有表单控件(文本框、文本域、按钮、单选框、复选框等)都必须放在 <form></form> 标签之间(否则用户输入的信息可提交不到服务器上哦!)。

(2)表单控件介绍

1)文本输入框、密码输入框

当用户要在表单中键入字母、数字等内容时,就会用到文本输入框。文本框和密码框只有type类型的区别,其它的写法是一样的。

使用语法:

文本输入框:<input type="text" name="文本名称" value="文本内容" placeholder="文本提示信息" />

密码输入框:<input type="password" name="密码名称" value="密码信息" placeholder="密码提示信息" />

详细讲解:

1、type:当type="text"时,输入框为文本输入框,输入的文字是可以看见的;当type="password"时, 输入框为密码输入框,输入的文字内容是无法看见的。

2、name:为文本框/密码框命名,以备后台程序使用。

3、value:为文本输入框输入的内容。

4、placeholder:当我们的value内容为空的时候显示,用于提示输入框输入信息格式;

使用练习:我们创建一个表单,表单里边包含用户名和密码输入框。具体的代码如下图所示:

在网页中的显示效果如下所示:

2)多行文本输入框

上边文本输入框用于输入单行的文本内容,当用户需要在表单中输入大段文字时,需要用到文本输入域。

使用语法:<textarea rows="行数" cols="列数" placeholder="多行文本提示信息" >文本</textarea>

详细讲解:

1、<textarea>标签是成对出现的,以<textarea>开始,以</textarea>结束。

2、cols:用于控制多行输入域的列数,rows :用于控制多行输入域的行数。

3、placeholder:当我们的textarea内容为空的时候显示,用于提示输入框输入信息格式;

使用练习:我们创建一个新的表单,表单里边包含用户名和密码输入框和用户个人简介多行输入框。具体的代码如下图所示:

我们再网页中的显示效果就如下图所示:

好了,本篇文章就先给大家介绍这两个表单控件的语法以及使用,下篇文章我们将介绍下拉框、选择框、多选框的语法及使用,记得要多加练习才是王道。

每日金句:把每一件简单的事做好就是不简单;把每一件平凡的事做好就是不平凡。喜欢我的文章的小伙伴记得关注一下哦,每天将为你更新最新知识。

:想了解input和label请参看我写的文【207】点我进入【207】

一、button。

<button>是按钮标签,<input type="button" />也是按钮标签,它们之间的区别就是button更加强大,它除了可以包含文本之外,还可以包含格式化的文本和图像,这就是它的强大所在,下面展示它的图片按钮功能,当然我画的按钮很丑,别介意。

图1

图2

这里随便讲讲button标签的四个常用属性。

  1. disabled禁用按钮
  2. name指定按钮名称
  3. type按钮类型,属性值有button,reset,submit三个
  4. value按钮的初始值

图3

图4

图5

二、select。

select是列表和下拉菜单,select不能一个人战斗,它需要option的配合。

图6

图7

disable是禁用的意思。

图8

图9

optgroup可以对option进行分组。

图10

图11

selected初始被选中的项,开始时默认选中菠萝。

图12

图13