1. 程式人生 > >軟鍵盤彈出頂起佈局

軟鍵盤彈出頂起佈局

我這個情況比較單一,可能跟某些需求不一樣,僅供參考;
這裡寫圖片描述

這裡寫圖片描述

這裡寫圖片描述

我的需求是這樣的,底部放一個按鈕,點選的時候,從底部彈出一個佈局,點選佈局中的輸入框的時候軟鍵盤彈起,但是軟鍵盤不能遮擋這個佈局,需要將這個佈局頂上去,就是第三張圖的效果;

但是經過我測試後發現結果是隻能將第一個EditText頂起來,第一個EditText以下的部分還是被遮擋了。

類似需求著急使用的可以直接看使用;

思路:從底部彈出一個佈局,想到的是用自定義佈局,popWindow,還有BottomSheet系列,我選擇了BottomSheetDialog;
但是軟鍵盤的遮擋無情的阻斷了我的路,我開始也是去改變android:windowSoftMode這個屬性,但是不管怎麼用都沒用,在單個Activity中使用,在java程式碼上使用,始終沒效果,然後突然醒悟,我要作用的是dialog,我在Activity中用有什麼用,然後去在dialog的佈局中用這個屬性,怎麼用呢,在style檔案中定義一個style,然後在item中使用這個屬性,最後在佈局中使用這個style,但是,

沒用,

依舊如此

然後去網上找大神們的解決方案,記得之前好像無意中掃過佈局被軟鍵盤頂起的一篇文章,當時還大概的看了一眼,好像是監聽軟鍵盤的彈起,然後測試軟體盤的高度來動態改變被頂起佈局距離底部的高度,聽起來不錯,然後看到別人的一個方案,自定義一個ViewGroup,在onMeasure中去這樣動態的測量就OK,但是關於彈起收縮軟鍵盤這個問題又是一個死衚衕,我以為會有一個回撥方法什麼,結果也需要曲線救國,各種解決方案一大堆,但都多多少少有點缺陷,本來碎片化就嚴重,這樣就更可怕了。

也嘗試過使用ScrollView這樣的解決方案,但是對我無效,也可能是我使用的不對;

看到另一個解決方案,是將輸入框上面的圖片logo進行縮放已達到頂起的效果,但是這個對於我不適用,我沒有那麼大的logo要放置,此處也不需要,我倒是挺想放我的自拍,但是公司研究後一致表示不同意,這個方案也就擱淺了。

再想別的招把,要不捨棄一部分美觀,我將這個佈局按鈕的marginBottom設定大一點,看看效果,效果是有的,但是由於不知道軟鍵盤的高度,所以我乾脆一點,設定頂部Layout的高度為鋪滿,這樣鍵盤始終在下面,就不存在遮擋的問題了,但是這樣也不行,因為BottomSsheetDialog好像只加載出頂部Layout的height為wrap_content的樣子,呈現不了match_parent的樣子,始終就是不能鋪滿;這個方案也不行,那我在Button下面加一個weight=1的View或者Space,嘗試後也不行,難道要將marginBottom寫的賊大?這個就更不靠譜了。

搞事情啊!!!

再想想,還有什麼辦法,當我在這個佈局底部放置一個圖片的時候,無意的先滑動了一下佈局,再彈出軟鍵盤,這樣的操作後,竟然達到了我想要的效果,但是我難道 還要提示使用者你再這個地方要劃一下嗎?顯然不可能,我就想著能不能在彈出來的時候讓他自己先滑動一下,記得以前好像用到過BottomSheet系列,好像有個輔助的模式什麼的東西,找了找,找到了BottomSheetBehavior,哈哈,就是你,然後找到了setPeekHeight這個方法,看別人用的是顯示螢幕高度的0.4,我也試了一下,果然只彈出0.4的高度,而且軟鍵盤彈出的時候他也被頂上去了,但是我要彈出我全部的佈局,那就算一下佈局高度比,然後在我還沒算的時候,想起了之前BottomSheetDialog不能鋪滿的特徵,我如果直接寫鋪滿高度的話,那就應該剛好只顯示我的佈局高度,然後果然如此。

使用簡單:
定義一個xml佈局,然後引用

bottomSheet = new BottomSheetDialog(this);
bottomSheet.setContentView(R.layout.dialog_credit_grant);

用他的show()方法,就OK了;

WindowManager wm = this.getWindowManager();
int height = wm.getDefaultDisplay().getHeight();
View view = bottomSheet.getDelegate().findViewById(android.support.design.R.id.design_bottom_sheet);
BottomSheetBehavior bottomSheetBehavior = BottomSheetBehavior.from(view);
bottomSheetBehavior.setPeekHeight((int) (1.0 * height));

指定它的高度為全屏,這樣就可以了。

當然這還是我暫時能看到的,不知道後續會暴露出什麼問題,等後期如果使用中出了問題,我再反饋一下。

補充:因為專案特殊原因,最終還是沒有用到這個,突然發現有朋友需要,也找不到之前的demo了,就臨時又寫了一個,但是發現效果不是很好(主要是過度不好),採用需慎重,或者再找找有沒有別的方案;

資源下載:BottomSheetTest.rar(系統要求最少要一分。。。,如果您有多餘的積分,可以下載參考一下;如果你沒有積分又需要這個資源,就留下郵箱吧)