天天看点

Android软键盘遮挡输入框解决方法

一、问题概述

  在编辑框输入内容时会弹出软键盘,而手机屏幕区域有限往往会遮住输入界面

  输入密码时输入框被系统键盘遮挡了,大大降低了用户操作体验,这就是开发中非常常见的软键盘遮挡的问题,该如何解决?

二、简单解决方案

方法一

  在你的activity中的oncreate中setContentView之前写上这个代码

?

1

getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);

方法二

  在 项目的AndroidManifest.xml文件中界面对应的<activity>里加入

?

1

android:windowSoftInputMode=

"adjustPan"

  这样会让屏幕整体上移。如果加上的 是 android:windowSoftInputMode="adjustPan"这样键盘就不会覆盖屏幕。

关于android:windowSoftInputMode

  activity主窗口与软键盘的交互模式,可以用来避免输入法面板遮挡问题,Android1.5后的一个新特性。

  这个属性能影响两件事情:

    【一】当有焦点产生时,软键盘是隐藏还是显示

    【二】是否减少活动主窗口大小以便腾出空间放软键盘

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

  例如:

?

1

<activity android:windowSoftInputMode=

"stateVisible|adjustResize"

. . . >

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

各值的含义:

  【A】stateUnspecified:软键盘的状态并没有指定,系统将选择一个合适的状态或依赖于主题的设置

  【B】stateUnchanged:当这个activity出现时,软键盘将一直保持在上一个activity里的状态,无论是隐藏还是显示

  【C】stateHidden:用户选择activity时,软键盘总是被隐藏

  【D】stateAlwaysHidden:当该Activity主窗口获取焦点时,软键盘也总是被隐藏的

  【E】stateVisible:软键盘通常是可见的

  【F】stateAlwaysVisible:用户选择activity时,软键盘总是显示的状态

  【G】adjustUnspecified:默认设置,通常由系统自行决定是隐藏还是显示

  【H】adjustResize:该Activity总是调整屏幕的大小以便留出软键盘的空间

  【I】adjustPan:当前窗口的内容将自动移动以便当前焦点从不被键盘覆盖和用户能总是看到输入内容的部分

方法三

  把顶级的layout替换成ScrollView,或者说在顶级的Layout上面再加一层ScrollView。这样就会把软键盘和输入框一起滚动了,软键盘会一直处于底部。

?

1 2 3 4 5 6

<ScrollView xmlns:android=

"http://schemas.android.com/apk/res/android"

android:layout_width=

"fill_parent"

android:layout_height=

"fill_parent"

>

<LinearLayout android:layout_width=

"fill_parent"

android:layout_height=

"fill_parent"

android:orientation=

"vertical"

>

</LinearLayout>

</ScrollView>

但这些方法虽然比较简单,但往往都有一定的局限性不是很灵活,有时达不到预期效果,大家可以试试或许也能解决你的问题,下面就教大家一种具有代码可控性的一种方法:

三、代码可控性方法

1.主界面布局文件

?

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 45 46 47 48 49 50

<com.jereh.overidelinearlayout.LinearLayoutView xmlns:android=

"http://schemas.android.com/apk/res/android"

android:layout_width=

"match_parent"

android:id=

"@+id/login_root_layout"

android:layout_height=

"match_parent"

android:orientation=

"vertical"

>

<!—这里模仿一个登录界面-->

<LinearLayout

android:id=

"@+id/login_layout_logo"

android:layout_width=

"match_parent"

android:layout_height=

"0dp"

android:layout_weight=

"10"

android:background=

"#ff0000"

android:orientation=

"vertical"

>

<ImageView

android:id=

"@+id/textView1"

android:layout_width=

"fill_parent"

android:layout_height=

"fill_parent"

android:src=

"@drawable/login_logo"

android:scaleType=

"fitXY"

/>

</LinearLayout>

<!—输入框和密码框-->

<LinearLayout

android:layout_width=

"match_parent"

android:layout_height=

"0dp"

android:layout_marginTop=

"20dp"

android:layout_weight=

"3"

android:orientation=

"vertical"

>

<EditText

android:id=

"@+id/editText1"

android:layout_width=

"match_parent"

android:layout_height=

"wrap_content"

android:layout_alignLeft=

"@+id/textView1"

android:layout_alignParentBottom=

"true"

android:layout_gravity=

"center_vertical"

android:hint=

"用户名"

android:ems=

"10"

>

<requestFocus />

</EditText>

<EditText

android:id=

"@+id/editText1"

android:layout_width=

"match_parent"

android:layout_height=

"wrap_content"

android:layout_alignLeft=

"@+id/textView1"

android:layout_alignParentBottom=

"true"

android:layout_gravity=

"center_vertical"

android:hint=

"密码"

android:ems=

"10"

>

<requestFocus />

</EditText>

</LinearLayout>

</com.jereh.overidelinearlayout.LinearLayoutView>

  可以看出关键地方在于LinearLayoutView这个自定义组件

2.自定义LinearLayoutView

  该组件可实现根据软键盘的弹出/关闭而隐藏和显示某些区域,这是问题解决最关键部分,主要有两点:

  ① 重写onSizeChanged方法

  该方法是View生命周期的方法,当View尺寸发生变化时调用,如竖屏横屏切换、软键盘弹出。这里当软键盘弹出造成View尺寸改变,就会调用onSizeChanged方法,在该方法实现代码的核心思想是根据尺寸变化,当变大(软键盘弹出),将某些区域隐藏以给编辑界面预留出足够显示空间;当恢复(软键盘关闭),再将隐藏的区域显示出来

?

1 2 3 4 5 6 7 8 9 10 11 12 13 14

protected

void

onSizeChanged(

int

w,

final

int

h,

int

oldw,

final

int

oldh) {

super

.onSizeChanged(w, h, oldw, oldh);

uiHandler.post(

new

Runnable() {

public

void

run() {

if

(oldh - h > SOFTKEYPAD_MIN_HEIGHT){

// 软键盘关闭

keyBordStateListener.stateChange(KEYBORAD_SHOW);

//回调方法显示部分区域

}

else

{

// 软键盘弹出

if

(keyBordStateListener !=

null

){

keyBordStateListener.stateChange(KEYBORAD_HIDE);

// 回调方法隐藏部分区域

}

}

}

});

}

  ②提供KeyBordStateListener 接口采用回调机制调用接口的实现方法。

  代码:

?

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

public

interface

KeyBordStateListener{

public

void

stateChange(

int

state);}

//定义接口

private

KeyBordStateListener keyBordStateListener;

public

void

setKeyBordStateListener(KeyBordStateListener keyBordStateListener) {

this

.keyBordStateListener = keyBordStateListener;

}

LinearLayoutView组件的完整代码:

public

class

LinearLayoutView

extends

LinearLayout{

public

static

final

int

KEYBORAD_HIDE =

;

public

static

final

int

KEYBORAD_SHOW =

1

;

private

static

final

int

SOFTKEYPAD_MIN_HEIGHT =

50

;

private

Handler uiHandler =

new

Handler();

public

LinearLayoutView(Context context) {

super

(context);

}

public

LinearLayoutView(Context context, AttributeSet attrs) {

super

(context, attrs);

}

@Override

protected

void

onSizeChanged(

int

w,

final

int

h,

int

oldw,

final

int

oldh) {

// TODO Auto-generated method stub

super

.onSizeChanged(w, h, oldw, oldh);

uiHandler.post(

new

Runnable() {

@Override

public

void

run() {

if

(oldh - h > SOFTKEYPAD_MIN_HEIGHT){

keyBordStateListener.stateChange(KEYBORAD_SHOW);

}

else

{

if

(keyBordStateListener !=

null

){

keyBordStateListener.stateChange(KEYBORAD_HIDE);}

}

}

});

}

private

KeyBordStateListener keyBordStateListener;

public

void

、setKeyBordStateListener(KeyBordStateListener keyBordStateListener) {

this

.keyBordStateListener = keyBordStateListener;

}

public

interface

KeyBordStateListener{

public

void

stateChange(

int

state);

}

3.主界面MainActivity

?

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

public

class

MainActivity

extends

Activity

implements

KeyBordStateListener {

private

LinearLayoutView resizeLayout;

private

LinearLayout logoLayout;

@Override

protected

void

onCreate(Bundle savedInstanceState) {

super

.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

//获得可根据软键盘的弹出/关闭而隐藏和显示某些区域的LinearLayoutView组件

resizeLayout = (LinearLayoutView) findViewById(R.id.login_root_layout);

//获得要控制隐藏和显示的区域

logoLayout = (LinearLayout) findViewById(R.id.login_layout_logo);

resizeLayout.setKeyBordStateListener(

this

);

//设置回调方法

}

//实现接口中的方法,该方法在resizeLayout的onSizeChanged方法中调用

@Override

public

void

stateChange(

int

state) {

// TODO Auto-generated method stub

switch

(state) {

case

LinearLayoutView.KEYBORAD_HIDE:

logoLayout.setVisibility(View.VISIBLE);

break

;

case

LinearLayoutView.KEYBORAD_SHOW:

logoLayout.setVisibility(View.GONE);

break

;

}

}

原文链接:http://www.cnblogs.com/jerehedu/p/4194125.html