




版權(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. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 按揭房屋買賣合同協(xié)議書
- 三農(nóng)莊休閑旅游經(jīng)營手冊
- 企業(yè)多元化業(yè)務(wù)拓展下的倉儲管理系統(tǒng)創(chuàng)新方案
- 高地溫隧道施工方案
- 景觀棧橋施工方案
- 濕地橋梁樁基施工方案
- 車牌識別系統(tǒng)道閘施工方案
- 建筑工程臨時用工協(xié)議書-@-1
- 鍋爐管束防腐施工方案
- 仲愷高新區(qū)瀝林英光小學改擴建二期項目環(huán)評報告表
- TZRIA 002-2024 工業(yè)巡檢四足機器人技術(shù)條件
- 小學科學二年級下冊教案(全冊)
- 2025安徽振含控股集團有限公司招聘8人筆試參考題庫附帶答案詳解
- 2025年內(nèi)蒙古機電職業(yè)技術(shù)學院單招職業(yè)技能測試題庫及答案一套
- 河道洪水應(yīng)急響應(yīng)預案
- 《欣賞與設(shè)計》(教案)2024-2025學年數(shù)學六年級下冊 北師大版
- 2025年中國煙氣檢測儀器行業(yè)市場運行態(tài)勢、進出口貿(mào)易及發(fā)展趨勢預測報告
- 減免保證金申請書
- 五年級下冊語文第三單元遨游漢字王國單元整體教學設(shè)計
- 銀行信貸部門廉政風險點及防控措施
- 高一上學期統(tǒng)編版(2019)必修中外歷史綱要上翻書大賽課件
評論
0/150
提交評論