android 键盘遮盖输入框_Android各种键盘挡住输入框解决办法
原標題:Android各種鍵盤擋住輸入框解決辦法
今日科技快訊
C919大型客機首飛成功,讓很多人激動不已。然而近日網上也出現了一些不同的聲音:說這架飛機許多部件都是進口貨,甚至有人說C919中國人只是造了個殼子。對此,業內人士回應稱:即使是波音空客,也不可能生產所有零件。全球采購,是航空制造業的通用做法;把所有部件整合在一起,才是最關鍵的核心技術。
作者簡介
大家早上好,新的一周又開始啦!
本篇來自 瀟瀟鳳兒的投稿,對于鍵盤擋住輸入框,給出了多種方案,希望對大家有所幫助。
瀟瀟鳳兒的博客地址:
http://blog.csdn.net/smileiam
正文
在開發中,經常會遇到鍵盤擋住輸入框的情況,比如登錄界面或注冊界面,彈出的軟鍵盤把登錄或注冊按鈕擋住了,用戶必須把軟鍵盤收起,才能點擊相應按鈕,這樣的用戶體驗非常不好。像微信則直接把登錄按鈕做在輸入框的上面,但有很多情況下,這經常滿足不了需求。同時如果輸入框特別多的情況下,點擊輸入時,當前輸入框沒被擋住,但是當前輸入框下面的輸入框卻無法獲取焦點,必須先把鍵盤收起,再去獲取下面輸入框焦點,這樣用戶體驗也非常不好,那有什么辦法呢?
系統的 adjustResize 和 adjustPan 有什么區別,他們使用時的注意事項,有什么系統要求及蔽端呢?
下面對幾種在開發中常用的方法進行總結:
方法一:windowSoftInputMode:adjustResize和adjustPan
主要實現方法:在 AndroidManifest.xml 對應的Activity里添加 android:windowSoftInputMode=”adjustPan” 或是 android:windowSoftInputMode=”adjustResize”屬性
這兩種屬性的區別,官方的解釋是:
這兩個屬性作用都是為了調整界面使鍵盤不擋住輸入框 ,我這里對這兩種屬性使用場景、優缺點、注意事項進行了全方面總結,不知大家平時使用時是否注意到了。
adjustResize失效情況:activity 設置了全屏屬性指 Theme.Light.NotittleBar.Fullscreen 或者設置了 activity 對應的主題中 android:windowTranslucentStatus 屬性,設置方式為:android:windowTranslucentStatus=true,這時如果對應的頁面上含有輸入框,將會導致點擊輸入框時軟鍵盤彈出后鍵盤覆蓋輸入框,導致輸入框看不見。
fitsSystemWindows=”true”,只有初始的view起作用:如果在布局中不是最外層控件設置 fitsSystemWindows=”true”, 那么設置的那個控件高度會多出一個狀態欄高度。若有多個view設置了,因第一個view已經消耗掉 insect,其他 view 設置了也會被系統忽略。
假設原始界面是一個 LinearLayout 包含若干 EditText,如下圖所示,在分別使用兩種屬性時的表現:
1、adjustPan
整個界面向上平移,使輸入框露出,它不會改變界面的布局;界面整體可用高度還是屏幕高度,這個可以通過下面的截圖看出,如點擊 輸入框6,輸入框會被推到鍵盤上方,但 輸入框1 被頂出去了,如果界面包含標題欄,也會被頂出去。
2、adjustResize
需要界面的高度是可變的,或者說 Activity 主窗口的尺寸是可以調整的,如果不能調整,則不會起作用。
例如:Activity 的xml布局中只有一個 LinearLayout 包含若干EditText,在Activity的 AndroidMainfest.xml 中設置 android:windowSoftInputMode=”adjustResize” 屬性,點擊 輸入框6, 發現軟鍵盤擋住了 輸入框6,并沒有調整,如下圖所示:
但使用這兩種屬性,我們可以總結以下幾點:
1).使用 adjustPan, 如果需要輸入的項比較多時,點擊輸入框,當前輸入項會被頂到軟鍵盤上方,但若當前輸入框下面還有輸入項時,卻需要先收起鍵盤,再點擊相應的輸入項才能輸入。這樣操作太繁瑣了,對于用戶體驗不大好;
2).adjustResize 的使用,需要界面本身可顯示的窗口內容能調整,如果不能,不起作用;
方法二:在界面最外層布局包裹ScrollView
1、只使用ScrollView
在相應界面的xml布局中,最外層添加一個 ScrollView,不在 AndroidMainfest.xml 中設置任何 android:windowSoftInputMode屬性,此時點擊輸入框,輸入框均不會被軟鍵盤檔住。即使當前輸入框下方也有輸入框,在鍵盤顯示的情況下,也可以通過上下滑動界面來輸入,而不用先隱藏鍵盤,點擊下方輸入框,再顯示鍵盤輸入。
我們可以根據 Android Studio 的 Inspect Layout 工具來查看界面真正占用的布局高度,工具在:
通過該工具,我們看到:
界面真正能用的高度=屏幕高度-狀態欄高度-軟鍵盤高度
界面中藍框是真正界面所用的高度:
2、ScrollView + adjustPan
我們再在該類的 AndroidMainfest.xml 中設置 windowSoftInputMode屬性 為 adjustPan:
發現當前輸入框不會被擋住,但是輸入框比較多時,在有鍵盤顯示時,界面上下滑動,但只能滑動部分,且如果輸入框在界面靠下方時,點擊輸入框,標題欄也會被頂出去,如下圖所示:
我們借助 Inspect Layout 工具查看此設置布局可用高度,從下圖可以看出,此時布局可用高度是屏幕的高度,上下滑動也只是此屏的高度,在 輸入框9 以下的輸入框滑不出來,向上滑動,也只能滑到 輸入框1。
3、ScrollView+adjustResize
我們前面說過 adjustResize 的使用必須界面布局高度是可變的,如最外層套個 ScrollView 或是界面可收縮的,才起作用。這里在該類的 AndroidMainfest.xml 中設置windowSoftInputMode屬性 為 adjustResize
發現效果和 1 不設置任何 windowSoftInputMode屬性 類似,其使用高度也是:屏幕高度-狀態欄高度-軟鍵盤高度
我們再來看看 windowSoftInputMode 默認屬性值 stateUnspecified:
可以看出,系統將選擇合適的狀態,也就是在界面最外層包含一層 ScrollView 時,設置默認屬性值 stateUnspecified 其實就是 adjustResize屬性。
但以下兩方面無法滿足需求:
1).當 Activity 設置成全屏 fullscreen 模式時或是使用沉浸式狀態欄時,界面最外層包裹 ScrollView,當輸入框超過一屏,當前輸入框下面的輸入框并不能上下滑動來輸入,情況類似于 ScrollView+adjustPan,只能滑動部分,通過 Inspect Layout 也可以看到,界面可用高度是整個屏幕高度,并不會進行調整高度。即使設置 adjustResize,也不起作用。
2).如果是類似于注冊界面或是登錄界面,鍵盤會擋住輸入框下面的登錄按鈕。
沉浸式狀態欄下
自android系統4.4(API>=19)就開始支持沉浸式狀態欄,當使用 System windows(系統窗口)顯示系統一些屬性和操作區域,如最上方的狀態及沒有實體按鍵的最下方的虛擬導航欄。
android:fitsSystemWindows=“true”會使得屏幕上的可布局空間位于狀態欄下方與導航欄上方。
方法三:當鍵盤彈起時,讓界面整體上移;鍵盤收起,讓界面整體下移
使用場景:針對界面全屏或是沉浸式狀態欄,輸入框不會被鍵盤遮擋。主要用于一些登錄界面,或是需要把界面整體都頂上去的場景。
1、主要實現步驟
(1). 獲取Activity布局xml的最外層控件,如xml文件如下:
先獲取到最外層控件:
RelativeLayoutmain =(RelativeLayout) findViewById(R.id.main);
(2).獲取到最后一個控件,如上面的xml文件,最后一個控件是Button:
Buttonlogin_btn =(Button) findViewById(R.id.login_btn);
(3).給最外層控件和最后一個控件添加監聽事件:
2、實現原理
此方法通過監聽 Activity 最外層布局控件來檢測軟鍵盤是否彈出,然后去手動調用控件的 scrollTo方法 達到調整布局目的。
方法四:監聽Activity頂層View,判斷軟鍵盤是否彈起,對界面重新繪制
此方法的實現來自android中提出的issue 5497
https://code.google.com/p/android/issues/detail?id=5497
使用場景:針對界面全屏或是沉浸式狀態欄,界面包含比較多輸入框,界面即使包裹了一層 ScrollView,在鍵盤顯示時,當前輸入框下面的輸入不能通過上下滑動界面來輸入。
一、實現步驟
1、把 SoftHideKeyBoardUtil類 復制到項目中;
2、在需要使用的Activity的onCreate方法中添加 SoftHideKeyBoardUtil.assistActivity(this) 即可。
二、實現原理
SoftHideKeyBoardUtil類 具體代碼如下:
它的實現原理主要是:
(1).找到 Activity 的最外層布局控件,我們知道所有的 Activity 都是 DecorView,它就是一個 FrameLayout控件,該控件id是系統寫死叫 R.id.content,就是我們 setContentView 時,把相應的 View 放在此 FrameLayout 控件里
FrameLayoutcontent =(FrameLayout) activity.findViewById(android.R.id.content);
所以 content.getChildAt(0) 獲取到的 mChildOfContent,也就是我們用 setContentView 放進去的 View。
(2).給我們的 Activity 的xml布局View設置一個 Listener 監聽:
View.getViewTreeObserver() 可以獲取一個 ViewTreeObserver對象——它是一個觀察者,用以監聽當前 View樹 所發生的變化。這里所注冊的 addOnGlobalLayoutListener,就是會在當前的 View樹 的全局布局(GlobalLayout)發生變化、或者其中的 View 可視狀態有變化時,進行通知回調。『軟鍵盤彈出/隱 』都能監聽到。
(3).獲取當前界面可用高度
如下圖所示:
(4).重設高度, 我們計算出的可用高度,是目前在視覺效果上能看到的界面高度。但當前界面的實際高度是比可用高度要多出一個軟鍵盤的距離的。
通過上面的這種方法,一般布局輸入鍵盤擋住輸入框的問題基本都能解決。即使界面全屏或是沉浸式狀態欄情況。
總結
下面對上面幾種方法進行對比:
方法一:
優點:使用簡單,只需在Activity的AndroidMainfest.xml中設置windowSoftInput屬性即可。
注意點:adjustResize屬性必須要界面大小可以自身改變;
缺點:當輸入框比較多時,當前輸入框下方的輸入框會初鍵盤擋住,須收起鍵盤再進入輸入;使用adjustPan,輸入框較多時,因它是把界面當成一個整體,只會顯示一屏的高度,會把ActionBar頂上去。
方法二:
優點:使用簡單,只需在Activity的最外層布局包裹一個ScrollView即可。
注意點:不可使用adjustPan屬性,否則ScrollView失效;
缺點:對于全屏時,在鍵盤顯示時,無法上下滑動界面達到輸入的目的;
方法三:
優點:可以解決全屏時,鍵盤擋入按鈕問題。
缺點:只要有此需求的Activity均需要獲取到最外層控件和最后一個控件,監測鍵盤是否彈出,再調用控件的scrollTo方法對界面整體上移或是下移。代碼冗余。
方法四:
優點:可以解決全屏時,鍵盤擋入輸入框問題。只需要寫一個全局類,其他有需求的界面直接在onCreate方法里調用此類的全局方法,即可。
缺點:多用了一個類。
綜上所述:
1) 當輸入框比較少時,界面只有一個輸入框時,可以通過方法一設置adjustPan;
2) 如果對于非全屏/非沉浸式狀態欄需求,只需要使用方法二即可;
3) 如果全屏全屏/沉浸式狀態欄界面只有一個類有鍵盤擋入輸入框需求,可使用方法三;
4) 如果大部分界面均使用全屏或沉浸式狀態欄,且有此需求,則選擇方法四更恰當。
更多
每天學習累了,看些搞笑的段子放松一下吧。關注最具娛樂精神的公眾號,每天都有好心情。
如果你有好的技術文章想和大家分享,歡迎向我的公眾號投稿,投稿具體細節請在公眾號主頁點擊“投稿”菜單查看。返回搜狐,查看更多
責任編輯:
總結
以上是生活随笔為你收集整理的android 键盘遮盖输入框_Android各种键盘挡住输入框解决办法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 腾讯官宣武侠喜剧《鹊刀门传奇》:赵本山宋
- 下一篇: linux安装静默安装was7,WAS7