【移動應(yīng)用開發(fā)技術(shù)】Android項目輸入法軟鍵盤顯示隱藏的監(jiān)聽和控制,InputMethodManager用法研究_第1頁
【移動應(yīng)用開發(fā)技術(shù)】Android項目輸入法軟鍵盤顯示隱藏的監(jiān)聽和控制,InputMethodManager用法研究_第2頁
【移動應(yīng)用開發(fā)技術(shù)】Android項目輸入法軟鍵盤顯示隱藏的監(jiān)聽和控制,InputMethodManager用法研究_第3頁
【移動應(yīng)用開發(fā)技術(shù)】Android項目輸入法軟鍵盤顯示隱藏的監(jiān)聽和控制,InputMethodManager用法研究_第4頁
【移動應(yīng)用開發(fā)技術(shù)】Android項目輸入法軟鍵盤顯示隱藏的監(jiān)聽和控制,InputMethodManager用法研究_第5頁
已閱讀5頁,還剩11頁未讀 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

【移動應(yīng)用開發(fā)技術(shù)】Android項目輸入法軟鍵盤顯示隱藏的監(jiān)聽和控制,InputMethodManager用法研究

在項目開發(fā)中,用到編輯框的地方經(jīng)常涉及到要監(jiān)聽或者控制軟鍵盤的顯示/隱藏狀態(tài)。本以為這是很容易解決的一個小問題,沒想到當初碰到這個問題才明白還得花點小心思才能整好?,F(xiàn)將針對軟鍵盤的顯示/隱藏狀態(tài)的監(jiān)聽/監(jiān)控方法做一些總結(jié),以備后用。一、點擊空白處隱藏軟鍵盤這是具有編輯框焦點的頁面對輸入法軟鍵盤狀態(tài)監(jiān)聽的一般需求和解決方法.首先獲得InputMethodManager:

InputMethodManager

manager

=

(InputMethodManager)

getSystemService(Context.INPUT_METHOD_SERVICE);監(jiān)聽點擊:

/**

*

點擊監(jiān)聽

*/

@Override

public

boolean

onTouchEvent(MotionEvent

event)

{

onHideSoftInput(event);

return

super.onTouchEvent(event);

}

/**

*

點擊空白處,關(guān)閉輸入法軟鍵盤

*/

public

void

onHideSoftInput(MotionEvent

event)

{

if

(event.getAction()

==

MotionEvent.ACTION_DOWN)

{

if

(getCurrentFocus()

!=

null

&&

getCurrentFocus().getWindowToken()

!=

null)

{

manager.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(),

InputMethodManager.HIDE_NOT_ALWAYS);

}

}

}二、popwindow與輸入法軟鍵盤的結(jié)合

先說下自己想實現(xiàn)的效果:點擊頂部按鈕,打開編輯菜單popwindow并自動彈出軟鍵盤;再次點擊頂部按鈕,或者點擊編輯菜單popwindow上面的底部按鈕,關(guān)閉菜單并隱藏軟鍵盤;菜單打開狀態(tài),點擊返回鍵,若菜單已顯示先關(guān)閉軟鍵盤,再點擊則關(guān)閉菜單。

大致效果圖如下:1.重寫根布局,監(jiān)聽根布局高度變化對于這個需求,簡單的用上面第一點的方法是無效的。這里沒法直接通過getCurrentFocus()方法判斷頁面是否獲取焦點來控制,需要通過對popwindow的高度變化進行判斷。同時也試過下面的方法,同樣無效。InputMethodManager

imm

=

(InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);

boolean

isOpen=imm.isActive();//isOpen若返回true,則表示輸入法打開

popwindow的根布局我這里用的是RelativeLayout,RelativeLayout類可以通過重寫onSizeChanged方法來監(jiān)聽布局大小變化。重寫一個RelativeLayout類便實現(xiàn)了對popwindow的高度變化的監(jiān)聽了。代碼如下:/**

*

監(jiān)聽輸入法軟鍵盤顯示狀態(tài)的自定義RelativeLayout

*

*

@author

zeng

*

*/

public

class

ResizeRelativeLayout

extends

RelativeLayout

{

public

ResizeRelativeLayout(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.OnResizeRelative(w,

h,

oldw,

oldh);

}

}

//

監(jiān)聽接口

private

OnResizeRelativeListener

mListener;

public

interface

OnResizeRelativeListener

{

void

OnResizeRelative(int

w,

int

h,

int

oldw,

int

oldh);

}

public

void

setOnResizeRelativeListener(OnResizeRelativeListener

l)

{

mListener

=

l;

}

}2.配置布局文件,初始化UI等,代碼如下:初始化UI代碼:

@Override

protected

void

onCreate(Bundle

savedInstanceState)

{

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

initUI();

}

private

void

initUI()

{

mBtn_open

=

findViewById(R.id.button1);

mBtn_open.setOnClickListener(this);

//

編輯窗口

LayoutInflater

inflater

=

getLayoutInflater();

View

menuLayout

=

inflater.inflate(R.layout.menu_window,

null);

mEditMenuWindow

=

new

PopupWindow(menuLayout,

LayoutParams.MATCH_PARENT,

LayoutParams.WRAP_CONTENT,

true);

mEditMenuWindow.setBackgroundDrawable(getResources().getDrawable(R.color.white));

mEditMenuWindow.setTouchable(true);

mEditMenuWindow.setFocusable(true);

mEditMenuWindow.setAnimationStyle(R.style.MenuAnimation);

mEditMenuWindow.setOutsideTouchable(false);

mEditMenuWindow.update();

//監(jiān)聽菜單消失

mEditMenuWindow.setOnDismissListener(this);

//

菜單控件

mEt_menu

=

(EditText)

menuLayout.findViewById(R.id.menu_edit);

TextView

btn_send

=

(TextView)

menuLayout.findViewById(R.id.menu_send);

btn_send.setOnClickListener(this);

//

監(jiān)聽主布局大小變化,監(jiān)控輸入法軟鍵盤狀態(tài)

listenerKeyBoardState(menuLayout);

}其中menu_window.xml文件代碼如下:<?xml

version="1.0"

encoding="utf-8"?>

<com.example.d_popwindow_inputkeyboard.ResizeRelativeLayout

xmlns:android="/apk/res/android"

android:id="@+id/menu_layout"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:orientation="vertical"

android:padding="8dp"

>

<EditText

android:id="@+id/menu_edit"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:layout_above="@+id/menu_send"

android:layout_marginBottom="8dp"

android:background="#ffffffff"

android:enabled="true"

android:focusable="true"

android:focusableInTouchMode="true"

android:gravity="top|left"

android:inputType="none"

android:padding="8dp"

android:textSize="18sp"

>

<requestFocus

/>

</EditText>

<TextView

android:id="@+id/menu_send"

android:layout_width="fill_parent"

android:layout_height="60dp"

android:layout_alignParentBottom="true"

android:layout_gravity="center"

android:background="#ff0f0f0f"

android:gravity="center"

android:text="發(fā)送"

android:textColor="#ffFF6004"

android:textSize="20sp"

android:textStyle="bold"

/>

</com.example.d_popwindow_inputkeyboard.ResizeRelativeLayout>3.打開或關(guān)閉編輯窗口,同時自動顯示或隱藏輸入法軟鍵盤。

此方法兩者的控制順序:先顯示軟鍵盤,再打開編輯窗口;先關(guān)閉編輯窗口,若軟鍵盤當前已顯示則再隱藏軟鍵盤。代碼如下:

//點擊頂部發(fā)送按鈕,打開/關(guān)閉編輯窗口

private

void

clickTopSend()

{

if

(mEditMenuWindow.isShowing())

{

//先關(guān)閉窗口再隱藏軟鍵盤

mEditMenuWindow.dismiss();

//

隱藏輸入法軟鍵盤

//

hideKeyBoard();

}

else

{

//

窗口顯示前顯示輸入法軟鍵盤

showKeyBoard();

//

顯示輸入窗口

mEditMenuWindow.showAsDropDown(mBtn_open,

0,

0);

}

}

//

窗口顯示前顯示輸入法軟鍵盤

private

void

showKeyBoard()

{

InputMethodManager

inputMgr

=

(InputMethodManager)

getSystemService(Context.INPUT_METHOD_SERVICE);

inputMgr.toggleSoftInput(InputMethodManager.SHOW_FORCED,

0);//

調(diào)用此方法才能自動打開輸入法軟鍵盤

mEditMenuWindow.setSoftInputMode(

WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE

|

WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);

mEditMenuWindow.setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED);

//

在顯示popupwindow之后調(diào)用,否則輸入法會在窗口底層

}

//

隱藏輸入法軟鍵盤

private

void

hideKeyBoard()

{

InputMethodManager

inputMgr

=

(InputMethodManager)

getSystemService(Context.INPUT_METHOD_SERVICE);

inputMgr.toggleSoftInput(InputMethodManager.HIDE_NOT_ALWAYS,

0);//

輸入法軟鍵盤打開時關(guān)閉,關(guān)閉時打開

mEditMenuWindow.setSoftInputMode(

WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN

|

WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);

mEditMenuWindow.setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED);

//

在顯示popupwindow之后調(diào)用,否則輸入法會在窗口底層

//此方法無效

//

if(this.getCurrentFocus().getWindowToken()

!=

null)

//

{

//

((InputMethodManager)

getSystemService(INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(this.getCurrentFocus().getWindowToken(),

//

InputMethodManager.HIDE_NOT_ALWAYS);//

關(guān)閉輸入法軟鍵盤

//

}

}

//點擊底部發(fā)送按鈕,關(guān)閉編輯窗口

private

void

closeButtomSend()

{

mEditMenuWindow.dismiss();

}

//編輯窗口關(guān)閉時,隱藏輸入法軟鍵盤

@Override

public

void

onDismiss()

{

//

如果軟鍵盤打開,隱藏輸入法軟鍵盤

if(mIsKeyboardOpened)

{

hideKeyBoard();

}

}4.判斷軟鍵盤的顯示/隱藏狀態(tài)。

通過對編輯窗口的根布局高度變化來判斷軟鍵盤是否處于顯示狀態(tài),在接口方法OnResizeRelative(intw,inth,intoldw,intoldh)里實現(xiàn)對高度變化的判斷。這里主要判斷以下幾種高度變化場景:(1)布局的當前高度小于上一次的高度,即h<oldh,因為布局被軟鍵盤頂上去了,高度變小了。這種場景同樣適用于點擊按鈕第一次打開窗口時的場景,雖然點擊按鈕時,肉眼看到的是窗口一下就充滿了大半個屏幕,也就是當前h>oldh(oldh=0)。但事實上是,第一次打開窗口時,窗口菜單首先是充滿整個屏幕然后再根據(jù)軟鍵盤高度自動縮進的。以下是點擊【打開/發(fā)送】按鈕后,根布局的高度變化日志:可以看出,首次打開時,窗口高度先是1038,然后自動縮進成544,并非一打開便已計算好填充高度。(2)還有一種特殊情況,就是三星輸入法在軟鍵盤初次打開時,輸入字符后軟鍵盤高度會產(chǎn)生變化,同時造成根布局高度變??;若再清除已輸入的字符,此時軟鍵盤高度變小,根布局高度變大。而這兩種情況下,也就是h<oldh或者

h>oldh時,軟鍵盤都是處于顯示狀態(tài)。針對這種情況,我的解決方法是記錄下初次打開時根布局的初始高度值,由于h<oldh時在第(1)步已經(jīng)進行了判斷了,所以這里只要判斷

h>oldh時的情況。而無論

h>oldh變化多大,只要h不超過初始高度值(且初始高度值不為0),那么便可認為當前軟鍵盤仍是處于打開狀態(tài)。此方法運行后的日志如下:兩種狀況下,軟鍵盤都是顯示狀態(tài)。以下是監(jiān)聽高度變化判斷的代碼:

/**

*

監(jiān)聽主布局大小變化,監(jiān)控輸入法軟鍵盤狀態(tài)

*

@param

menuLayout

*/

private

void

listenerKeyBoardState(View

menuLayout)

{

ResizeRelativeLayout

mMenuLayout

=

(ResizeRelativeLayout)

menuLayout.findViewById(R.id.menu_layout);

mMenuLayout.setOnResizeRelativeListener(new

ResizeRelativeLayout.OnResizeRelativeListener()

{

@Override

public

void

OnResizeRelative(int

w,

int

h,

int

oldw,

int

oldh)

{

mIsKeyboardOpened

=

false;

Log.e("菜單高度",

"h

=

"

+

h

+

",oldh

=

"

+

oldh);

//記錄第一次打開輸入法時的布局高度

if

(h

<

oldh

&&

oldh

>

0

&&

mMenuOpenedHeight

==

0)

{

mMenuOpenedHeight

=

h;

}

//

布局的高度小于之前的高度

if

(h

<

oldh

)

{

mIsKeyboardOpened

=

true;

}

//或者輸入法打開情況下,

輸入字符后再清除(三星輸入法軟鍵盤在輸入后,軟鍵盤高度增加一行,清除輸入后,高度變小,但是軟鍵盤仍是打開狀態(tài))

else

if((h

<=

mMenuOpenedHeight)

&&

(mMenuOpenedHeight

!=

0))

{

mIsKeyboardOpened

=

true;

}

Log.e("是否打開",

"軟鍵盤

=

"

+

mIsKeyboardOpened);

}

});

}最后附上DEMO源碼,詳見附件。三、InputMethodManager的一些相關(guān)方法(未有效使用過,僅作筆記)1.調(diào)用顯示系統(tǒng)默認的輸入法方法一、InputMethodManager

imm

=

(InputMethodManager)

getSystemService(Context.INPUT_METHOD_SERVICE);

imm.showSoftInput(m_receiverView,InputMethodManager.SHOW_FORCED);m_receiverView(接受軟鍵盤輸入的視圖(View)InputMethodManager.SHOW_FORCED(提供當前操作的標記,SHOW_FORCED表示強制顯示)方法二、InputMethodManager

m=(InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);

m.toggleSoftInput(0,

InputMethodManager.HIDE_NOT_ALWAYS);這個InputMethodManager類里面的toggleSoftInput方法的API中的解釋是:This

method

toggles

the

input

method

window

display.

If

the

input

window

is

already

displayed,

it

gets

hidden.

If

not

the

input

window

will

be

displayed.這個方法在界面上切換輸入法的功能,如果輸入法出于現(xiàn)實狀態(tài),就將他隱藏,如果處于隱藏狀態(tài),就顯示輸入法。2.調(diào)用隱藏系統(tǒng)默認的輸入法((InputMethodManager)getSystemService(INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(WidgetSearchActivity.this.getCurrentFocus().getWindowToken(),

InputMethodManager.HIDE_NOT_ALWAYS);(WidgetSearchActivity是當前的Activity)3.獲取輸入法打開的狀態(tài)InputMethodManager

imm

=

(InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);

boolean

isOpen=imm.isActive();isOp

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論