- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章Android编程之软键盘的隐藏显示实例详解由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
本文实例分析了Android编程之软键盘的隐藏显示方法。分享给大家供大家参考,具体如下:
Android是一个针对触摸屏专门设计的操作系统,当点击编辑框,系统自动为用户弹出软键盘,以便用户进行输入.
那么,弹出软键盘后必然会造成原有布局高度的减少,那么系统应该如何来处理布局的减少?我们能否在应用程序中进行自定义的控制?这些是本文要讨论的重点.
1、软键盘显示的原理 。
软件盘的本质是什么?软键盘其实是一个Dialog! InputMethodService为我们的输入法创建了一个Dialog,并且将该Dialog的Window的某些参数(如Gravity)进行了设置,使之能够在底部或者全屏显示。当我们点击输入框时,系统对活动主窗口进行调整,从而为输入法腾出相应的空间,然后将该Dialog显示在底部,或者全屏显示.
2、活动主窗口调整 。
android定义了一个属性,名字为windowSoftInputMode, 用它可以让程序可以控制活动主窗口调整的方式。我们可以在AndroidManifet.xml中对Activity进行设置。如:android:windowSoftInputMode="stateUnchanged|adjustPan" 。
该属性可选的值有两部分,一部分为软键盘的状态控制,另一部分是活动主窗口的调整。前一部分本文不做讨论,请读者自行查阅android文档.
模式一,压缩模式 。
windowSoftInputMode的值如果设置为adjustResize,那么该Activity主窗口总是被调整大小以便留出软键盘的空间.
我们通过一段代码来测试一下,当我们设置了该属性后,弹出输入法时,系统做了什么.
重写Layout布局:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
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);
}
|
我们的布局设置为:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
<
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主窗口调整大小以便留出软键盘的空间,或是否窗口上的内容得到屏幕上当前的焦点是可见的。系统将自动选择这些模式中一种主要依赖于是否窗口的内容有任何布局视图能够滚动他们的内容。如果有这样的一个视图,这个窗口将调整大小,这样的假设可以使滚动窗口的内容在一个较小的区域中可见的。这个是主窗口默认的行为设置.
也就是说,系统自动决定是采用平移模式还是压缩模式,决定因素在于内容是否可以滚动.
3、侦听软键盘的显示隐藏 。
有时候,借助系统本身的机制来实现主窗口的调整并非我们想要的结果,我们可能希望在软键盘显示隐藏的时候,手动的对布局进行修改,以便使软键盘弹出时更加美观。这时就需要对软键盘的显示隐藏进行侦听.
直接对软键盘的显示隐藏侦听的方法本人没有找到,如果哪位找到的方法请务必告诉本人一声。还有本方法针对压缩模式,平移模式不一定有效.
我们可以借助软键盘显示和隐藏时,对主窗口进行了重新布局这个特性来进行侦听。如果我们设置的模式为压缩模式,那么我们可以对布局的onSizeChanged函数进行跟踪,如果为平移模式,那么该函数可能不会被调用.
我们可以重写根布局,因为根布局的高度一般情况下是不发生变化的.
假设跟布局为线性布局,模式为压缩模式,我们写一个例子,当输入法弹出时隐藏某个view,输入法隐藏时显示某个view.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
public
class
ResizeLayout
extends
LinearLayout{
private
OnResizeListener mListener;
public
interface
OnResizeListener {
void
OnResize(
int
w,
int
h,
int
oldw,
int
oldh);
}
public
void
setOnResizeListener(OnResizeListener l) {
mListener = l;
}
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);
if
(mListener !=
null
) {
mListener.OnResize(w, h, oldw, oldh);
}
}
}
|
在我们的Activity中,通过如下方法调用:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
public
class
InputMethodTestActivity
extends
Activity {
private
static
final
int
BIGGER =
1
;
private
static
final
int
SMALLER =
2
;
private
static
final
int
MSG_RESIZE =
1
;
private
static
final
int
HEIGHT_THREADHOLD =
30
;
class
InputHandler
extends
Handler {
@Override
public
void
handleMessage(Message msg) {
switch
(msg.what) {
case
MSG_RESIZE: {
if
(msg.arg1 == BIGGER) {
findViewById(R.id.bottom_layout).setVisibility(View.VISIBLE);
}
else
{
findViewById(R.id.bottom_layout).setVisibility(View.GONE);
}
}
break
;
default
:
break
;
}
super
.handleMessage(msg);
}
}
private
InputHandler mHandler =
new
InputHandler();
/** Called when the activity is first created. */
@Override
public
void
onCreate(Bundle savedInstanceState) {
super
.onCreate(savedInstanceState);
setContentView(R.layout.main);
ResizeLayout layout = (ResizeLayout) findViewById(R.id.root_layout);
layout.setOnResizeListener(
new
ResizeLayout.OnResizeListener() {
public
void
OnResize(
int
w,
int
h,
int
oldw,
int
oldh) {
int
change = BIGGER;
if
(h < oldh) {
change = SMALLER;
}
Message msg =
new
Message();
msg.what =
1
;
msg.arg1 = change;
mHandler.sendMessage(msg);
}
});
}
}
|
这里特别需要注意的是,不能直接在OnResizeListener中对要改变的View进行更改,因为OnSizeChanged函数实际上是运行在View的layout方法中,如果直接在onSizeChange中改变view的显示属性,那么很可能需要重新调用layout方法才能显示正确。然而我们的方法又是在layout中调用的,因此会出现错误。因此我们在例子中采用了Handler的方法.
希望本文所述对大家Android程序设计有所帮助.
最后此篇关于Android编程之软键盘的隐藏显示实例详解的文章就讲到这里了,如果你想了解更多关于Android编程之软键盘的隐藏显示实例详解的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我正试图找到一个基准来衡量用户愿意等待远程服务响应的时间。在我的例子中,响应是非常有用的,但不是对数据输入的业务关键验证。我想 HCI 领域一定已经在这方面做了一些工作。 如果您知道软实时响应的普遍接
这个问题在这里已经有了答案: What's the difference between SoftReference and WeakReference in Java? (12 个回答) 关闭6年前
社区维基 我不在乎声誉点,我只想要好的答案。请随意将此问题标记为社区 wiki。 上下文 我一直在研究《理性策划者》,并发现了以下观察结果: 逻辑编程非常有趣。 逻辑编程有时是违反直觉的 逻辑编程通常
我已阅读this article关于Java中不同类型的引用(强引用、软引用、弱引用、幻像引用),但我不太理解。 这些引用类型之间有什么区别?每种类型何时使用? 最佳答案 Java 提供了两种不同类型
我需要一个带有弱键或软键的并发 HashMap ,其中等式是 equals 而不是 ==。 对于此类键,Google Collection 默认选择 ==。 有没有办法覆盖这个选择?我应该如何进行?
我读了here使用下面的命令我们可以在 Linux 系统上模拟硬重启: echo 1 > /proc/sys/kernel/sysrq echo b > /proc/sysrq-trigger 但我想
我正在使用软件 I²C实现读取一组 Sensirion SHT21 传感器。我正在尝试找出一种让传感器回答以查看它们是否实际连接到设备的方法。我正在使用 Arduino,这意味着我所有的代码都是 C/
这个问题在这里已经有了答案: How do you determine using stat() whether a file is a symbolic link? (1 个回答) 关闭 9 年前
关闭。这个问题是off-topic .它目前不接受答案。 想改进这个问题吗? Update the question所以它是on-topic用于堆栈溢出。 关闭 10 年前。 Improve thi
我一直在使用 ICS 上的 Wifi Direct API,但有点卡住了。 在 API 中,有一个名为 createGroup 的方法可以在手机上创建一个基于遗留软件的接入点。这很棒并且有效,但我似乎
当我在 ruby 中有一个数组时,我可以在其上运行 delete_if block 。问题是它从我的数组中删除了元素。我想要相同的功能,只是不对原始数组进行更改,而是返回一个删除了对象的新数组。
在 Ubuntu Virtualbox 上运行从 Windows 移植的音频应用程序时,它报告以下内容: Devices found: OpenAL Soft OpenAL Soft 40964 in
下面是我的数据库结构的简化版本(在 MVC 2 中构建一个概念验证站点,使用 Entity Framework 4 作为我的 ORM): [Stores] StoreID (PK) StoreName
我用 ESP8266 创建了一个软 AP,我通过 android 6.0 marshmallow mobile 连接到它。连接后,如果我忽略它并打开浏览器窗口打开我的网络服务器页面或使用自定义构建的应
如何应用 Three.js online editor 中所示的 PCF (SOFT) 阴影类型以 JavaScript 代码的形式发送到你的渲染器? 最佳答案 要使用该类型的阴影,您需要使用相应类型
我知道 Wifi Direct 的工作原理是在其中一台设备中创建软 AP(软件接入点)。我也知道很多 Android 支持 Wifi Direct,但 iPhone 不支持。 我的问题是:是否可以创建
我有一个在 14.04.05 LTS 上运行的 Ubuntu 服务器。 此服务器上还安装了几个 ugins mongodb 应用程序。 MongoDB版本为3.4.2 我正在尝试增加 mongodb
我是一名优秀的程序员,十分优秀!