在android中,常常会和输入法的软件键盘交互。在Manifest文件中,系统给activity的一个属性-windowSoftInputMode来控制输入法的显示方式。

该属性提供了Activity的window与软键盘的window交互的方式。这里的属性设置有双方面的影响:

1.软键盘的显示与隐藏。-当Activity界面成为用户的焦点时,或隐藏或显示。

2。

对Activty的主window窗体进行调整。或者将Activity的window窗体调小以便为软键盘腾出空间,或者当Activity的部分window被软件盖住时,移动Activity的内容以便用户可以看到当前的焦点。



你至少要从下列属性值选取一项对其设置,要么是”state...“,要么是”adjust...“。

你能够设置多个值。设置不同的属性值。要用|进行分开。

比方:

<activityandroid:windowSoftInputMode="stateVisible|adjustResize"
. . . >

以下是对属性的值的描写叙述。

描写叙述
”stateUnSpecified“ 不指定软件的状态(显示或隐藏)。系统会依据主题中的设置来选择对应的状态。 该属性软键盘的默认设置。
”stateUnchnaged“ 总是保持上次软键盘的状态。当Activity进入到最前端时,不论是它上次它是显示或隐藏。保持不变。
”stateHidden“ 当用户进入目标Activity时。软键盘保持隐藏状态。这里的Activity是用户是向前进入Activity,而不是因为退出其他Activity退回到目标Activity。
”stateVisible“ 仅仅有条件合适(当用户前进进入到Activity的主window),就会显示键盘
”stateAlawaysVisible“ 当用户选择进入目标Activity时。软键盘被设置为可见的。这里的Activity是用户向前进入的Activity,而不是因为退出其他Activity而回到目标Activity
"adjustUnspecified" 不指定是否去调整Activity的界面。或者调整Activity窗体的大小以便为软键盘腾出空间或者移动窗体的内容来屏幕上当前的焦点可见。系统会自己主动选择当中一种模式,这依赖于窗体是包括能够滑动其内容的view.如有这种视图,窗体的大小就会被调整。在这种假定的情况下,非常小的滑动就能够使用窗体的内容可见。

该属性是主windowr默认设置。

”adjustResize“ Activity的窗体总是被调整其大小以便为软键盘腾出空间。

”adjustPan“ Activity的主窗体不会被调整其大小以便为软键盘腾出空间。相反,窗体的内容会被自己主动移动以便当前的焦点不会被软键盘遮住,用户能够总是看到他输入的内容。

这个值一般用于用户非常少想调整窗体的大小的情况下。由于用户可能须要关闭软键盘来与窗体的其他部分进行交互。

从上面系统的描写叙述了解了系统在处理两个交互时都显示Activity和软键盘都是看作window窗体来处理的。

非常多的时候,我们都希望可以监听到软件键盘的显示与关闭状态。比方下图的情况,

你有一个登录界面是这样设计的

你希望登录时它是这种,

然后你去尝试给activity的windowSoftInputMode属性加上值,当你加上 adjustResize时。它是这种

你不甘心。你将adjustResize改动成adjustPan,结果是这种

没有办法。仅仅有靠我们自己来监听键盘的显示或隐藏来动态改变布局。如今的问题是怎么监听到键盘的动态改变呢。系统并没有提供对应的方法。我们能够通过两种方法来实现。

1.在adjustResize属性下。activity的窗体大小会发生改变,而窗体中的layout的大小也必定后会发生改变。

当view大小发生改变时,必定会引起onSizeChanged(int, int, int, int)的回调。所以可能自己定义一个Layout。来监測onSizeChanged()函数的回调。然后在当中的作对应的处理。

这种方法也是网上传的最多的方法。

2.借助ViewTreeOberserver类。ViewTreeOberserver能够用来注冊一个监听器。它能监听view树的全局变化。

这些变化包含但不限于,整个View的布局,绘制传递的源头,触摸模式的变化。



第一种方法的实现:

自己定义一个Layout。以RelativeLayout为例,

能够在onSizeChanged(int
w, int h,int
oldw,int oldh) 方法里监听界面大小的变化,然后在该方法里定义回调函数。当监听到键盘被调出时,将键盘向上推一段距离,这样将登录键显示出来。

package com.example.keyboardlistener;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.RelativeLayout; public class KeyboardLayout extends RelativeLayout { private onSizeChangedListener mChangedListener;
private static final String TAG ="KeyboardLayoutTAG";
private boolean mShowKeyboard = false; public KeyboardLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// TODO Auto-generated constructor stub
} public KeyboardLayout(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
} public KeyboardLayout(Context context) {
super(context);
// TODO Auto-generated constructor stub
} @Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// TODO Auto-generated method stub
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
Log.d(TAG, "onMeasure-----------");
} @Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
// TODO Auto-generated method stub
super.onLayout(changed, l, t, r, b);
Log.d(TAG, "onLayout-------------------");
} @Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
// TODO Auto-generated method stub
super.onSizeChanged(w, h, oldw, oldh);
Log.d(TAG, "--------------------------------------------------------------");
Log.d(TAG, "w----" + w + "\n" + "h-----" + h + "\n" + "oldW-----" + oldw + "\noldh----" + oldh);
if (null != mChangedListener && 0 != oldw && 0 != oldh) {
if (h < oldh) {
mShowKeyboard = true;
} else {
mShowKeyboard = false;
}
mChangedListener.onChanged(mShowKeyboard);
Log.d(TAG, "mShowKeyboard----- " + mShowKeyboard);
}
} public void setOnSizeChangedListener(onSizeChangedListener listener) {
mChangedListener = listener;
} interface onSizeChangedListener{ void onChanged(boolean showKeyboard);
} }

在主Activity里创建一个Handler。当监听到布局发生变化时,通过Handler更新UI。

package com.example.keyboardlistener;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.ViewTreeObserver.OnPreDrawListener;
import android.widget.Button; import com.example.keyboardlistener.KeyboardLayout.onSizeChangedListener; public class MainActivity extends Activity { private static final String TAG = "KeyboardLayoutTAG";
private KeyboardLayout mRoot;
private Button mLogin;
private int mLoginBottom;
private static final int KEYBOARD_SHOW = 0X10;
private static final int KEYBOARD_HIDE = 0X20;
private boolean mGetBottom = true; private Handler mHandler = new Handler() { @Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
switch (msg.what) {
case KEYBOARD_HIDE:
mRoot.setPadding(0, 0, 0, 0);
break; case KEYBOARD_SHOW:
int mRootBottom = mRoot.getBottom();
Log.d(TAG, "the mLoginBottom is " + mLoginBottom);
mRoot.setPadding(0, mRootBottom - mLoginBottom, 0, 0);
break; default:
break;
}
} }; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); getActionBar().hide();
mRoot = (KeyboardLayout) findViewById(R.id.root_view);
mLogin = (Button) findViewById(R.id.login);
mRoot.setOnSizeChangedListener(new onSizeChangedListener() { @Override
public void onChanged(boolean showKeyboard) {
// TODO Auto-generated method stub
if (showKeyboard) {
mHandler.sendMessage(mHandler.obtainMessage(KEYBOARD_SHOW));
Log.d(TAG, "show keyboard");
} else {
mHandler.sendMessage(mHandler.obtainMessage(KEYBOARD_HIDE));
}
}
}); mRoot.getViewTreeObserver().addOnPreDrawListener(new OnPreDrawListener() { @Override
public boolean onPreDraw() {
// TODO Auto-generated method stub
if (mGetBottom) {
mLoginBottom = mLogin.getBottom();//获取登录button的位置信息。 }
mGetBottom = false;
return true;
}
}); } // @Override
// public boolean onCreateOptionsMenu(Menu menu) {
// // Inflate the menu; this adds items to the action bar if it is present.
// getMenuInflater().inflate(R.menu.main, menu);
// return true;
// } }

另外一种方法的实现:

借助ViewTreeObserver类对你想监听的view加入OnGlobalLayoutListener监听器。然后在onGlobalLayout()方法里窗体的变化情况来推断键盘是否被调出来了。以下是ViewTreeObserver监听的部分的代码:

mRoot.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {

            @Override
public void onGlobalLayout() {
int offset = mRoot.getRootView().getHeight() - mRoot.getHeight();
//依据视图的偏移值来推断键盘是否显示
if (offset > 300) {
mHandler.sendMessage(mHandler.obtainMessage(KEYBOARD_SHOW));
} else {
mHandler.sendMessage(mHandler.obtainMessage(KEYBOARD_HIDE));
} }
});

当中Handler的详细实现同上述结构中的Handler一样。

參考文章:InputMethod

样例源代码下载地址

android 软键盘的显示与隐藏问题的研究的更多相关文章

  1. Android 软键盘的显示和隐藏,这样操作就对了

    一.前言 如果有需要用到输入的地方,通常会有需要自动弹出或者收起软键盘的需求.开篇明义,本文会讲讲弹出和收起软键盘的一些细节,最终还会从源码进行分析. 想要操作软键盘,需要使用到 InputMetho ...

  2. android软键盘的显示和隐藏

    显示: InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE); imm.toggle ...

  3. EditText获取和失去焦点,软键盘的关闭,和软键盘的显示和隐藏的监听

    软键盘显示和隐藏的监听: 注: mReplayRelativeLayout是EditText的父布局 //监听软键盘是否显示或隐藏 mReplayRelativeLayout.getViewTreeO ...

  4. 日积月累:EditText软键盘的显示和隐藏

    在工作过程中,常常会遇见需要根据自己的需求,控制文本框的键盘显示和隐藏. 通过查阅Android文档,介绍可以通过在清单文件中<activity>元素中添加android:windowSo ...

  5. Android软键盘的隐藏显示、事件监听的代码

    把开发过程中重要的一些内容片段做个珍藏,如下资料是关于Android软键盘的隐藏显示.事件监听的内容,应该是对小伙伴们有所用途. public class ResizeLayout extends L ...

  6. Android之Android软键盘的隐藏显示研究

    转自:http://blog.csdn.net/lilu_leo/article/details/6587578 看了很多这类型的文章,这篇文章最有价值,解决了我的烦恼,必须转. Android是一个 ...

  7. Android手动控制软键盘的开启和关闭,判断软键盘是否显示;

    工具类,拿走就能用: import android.annotation.TargetApi; import android.app.Activity; import android.content. ...

  8. android软键盘弹出隐藏的监听

    通过网上搜索关于软键盘的隐藏弹出的监听,有几种方式,其中最有效的方式是在View的Onlayout()里面做文章 具体代码: 将布局视图自定义,重写onlayout()方法,然后在主Activity里 ...

  9. Android 软键盘弹出时把原来布局顶上去的解决方法

    键盘弹出时,会将布局底部的导航条顶上去. 解决办法: 在mainfest.xml中,在和导航栏相关的activity中加: <activity            android:name=& ...

随机推荐

  1. Fisher 线性判别

    Multiplying both sides of this result by wT and adding w0, and making use of y(x)=wTx+w0 and  y(xΓ)= ...

  2. leetcode矩阵与动态规划相关

    目录 54/59螺旋矩阵 62不同路径 64最小路径和 120三角形最小路径和 695岛屿的最大面积 547朋友圈 718最长重复数组 221最大正方形 121/122/123/714/188买卖股票 ...

  3. [Apple开发者帐户帮助]三、创建证书(5)创建WatchKit服务证书

    WatchKit服务证书允许您使用Apple推送通知(APN)将更新推送到Apple Watch上的复杂功能. 所需角色:帐户持有人或管理员. 在证书,标识符和配置文件中,从左侧的弹出菜单中选择iOS ...

  4. Python 40 数据库-外键约束 、多对一与多对多的处理

    mysql提供了 foreign key,专门用于为表和表之间 建立物理关联 思考 表里存储的是一条条的记录,两个表之间能产生的关系有哪些? 现有 A B两张表 1.多对一         2.一对一 ...

  5. Cent OS 6/7 中通过yum安装软件时提示cannot find a valid baseurl...的解决方法

    目录 1 问题描述 2 解决方法一 (Cent OS 7中有效) 3 解决方法二 (Cent OS 7中无效) 1 问题描述 新申请了虚拟机, 系统版本是Cent OS 7.2. 在安装软件的过程中, ...

  6. python请求服务器时如何隐藏User-Agent

    本文结合上一篇文章“python利用有道翻译实现“语言翻译器”的功能”的实现代码,对其进行加工,实现请求服务器时隐藏User-Agent. python实现隐藏User-Agent的一般做法有两种: ...

  7. MySql c#通用类

    using System; using System.Collections.Generic; using System.Linq; using System.Text;//导命名空间 using S ...

  8. [hihocoder][Offer收割]编程练习赛60

    hohahola #pragma comment(linker, "/STACK:102400000,102400000") #include<stdio.h> #in ...

  9. Android高亮TextView

    HighlightTextView Android文本高亮控件,基于View实现. 特点 文本高亮 单词自动换行 高亮词组保持在同一行显示 截图 Demo Java: public class Mai ...

  10. CDC之fast->slow (1)

    Sampling slower signals into faster clock domains causes fewer potential problems than sampling fast ...