Ⅰ android dialog 遮住輸入框的解決思路
在工作中經常會遇到彈出的dialog有輸入框的情況,屏幕大了還好,屏幕小了之後就特別容易出現輸入框被軟鍵盤遮住的情況,下面就是我在實際想中中遇到的
從上圖可以看出輸入框已經看不到了,遇到這種情況的第一個思路都是在dialog的style中添加
<item name="android:windowSoftInputMode">adjustPan</item>,我也試了下基本上沒用。然後換了個思路,既然軟鍵盤彈出來了,為什麼不能讓dialog向上移動同樣的距離呢。思路有了,下面就是把他實現了。
首先就是要計算軟鍵盤的高度,由於google並沒有給出具體的方法來計算軟鍵盤的高度,這時候我們就只能根據布局的高度變化來計算了。首先需要計算出屏幕的bottom坐標,然後監控布局的變動判斷變動後的bottom和初始的bottom的差值,一般肉眼觀察軟鍵盤的高度差不多是屏幕高度的1/3,所以就假設bottom往上移動了屏幕的1/3的距離就認為軟體盤彈出來了,當然也可以根據其他值來判斷,下面貼出具體方法:
/**
* activity中判斷軟鍵盤是否顯示
* @param activity
* */
fun isKeyboardShowing(activity: Activity): Boolean {
val screenHeight = activity.window!!.decorView.height.toDouble()
//獲取view的可見區域
val rect = Rect()
activity.window!!.decorView.getWindowVisibleDisplayFrame(rect)
return (2.0 /3.0) * screenHeight > rect.bottom.toDouble()
}
接下來我們來計算出軟體盤的高度,經過我在多個測試機上實驗發現初始時bottom就是屏幕的高度,下面是計算鍵盤高度的具體方法
/**
* activity中計算軟鍵盤的高度
* @param activity
* */
fun getKeyboardHeight(activity: Activity): Int {
val displayMetrics = DisplayMetrics()
activity.windowManager.defaultDisplay.getMetrics(displayMetrics)
val screenHeight = displayMetrics.heightPixels
val rect = Rect()
activity.window!!.decorView.getWindowVisibleDisplayFrame(rect)
return screenHeight - rect.bottom
}
有了高度之後一切就好辦了我們只需要在軟鍵盤彈出來的時候把dialog往上移動就行,在移動方式上我選擇了設置LayoutParams的方式,開始時想設置底部margin的,結果發現沒作用,dialog一點不移動,最後只好設置上邊的margin為負值
if (SoftUtils.isKeyboardShowing(context)) {
val lp =mRootView.layoutParams as ViewGroup.MarginLayoutParams
if (lp.topMargin ==0) {
lp.topMargin = -SoftUtils.getKeyboardHeight(context)
if (mRootView.height
lp.height =mRootOriginHeight
}
mRootView.layoutParams = lp
}
}else {
if (mRootOriginHeight ==0) {
mRootOriginHeight =mRootView.height
}
val lp =mRootView.layoutParams as ViewGroup.MarginLayoutParams
if (lp.topMargin <0) {
lp.topMargin =0
mRootView.layoutParams = lp
}
}
其中mRootView是dialog最外層的布局。在這裡面比較重要的一點監測方式,在哪裡監測軟鍵盤的彈出動作,在activity中可以監測onWindowFocusChanged方法,但是如果封裝了dialog的話,dialog中的onWindowFocusChanged並不會起作用,在這里我選擇了使用ViewTreeObserver和監聽,通過給mRootView的ViewTreeObserver添加addOnGlobalLayoutListener來實時判斷,下面是完整的方法
private fun setSpace() {
val treeObserver =mRootView.viewTreeObserver
treeObserver.addOnGlobalLayoutListener{
if (SoftUtils.isKeyboardShowing(context)) {
val lp =mRootView.layoutParams as ViewGroup.MarginLayoutParams
if (lp.topMargin ==0) {
lp.topMargin = -SoftUtils.getKeyboardHeight(context)
if (mRootView.height
lp.height =mRootOriginHeight
}
mRootView.layoutParams = lp
}
}else {
if (mRootOriginHeight ==0) {
mRootOriginHeight =mRootView.height
}
val lp =mRootView.layoutParams as ViewGroup.MarginLayoutParams
if (lp.topMargin <0) {
lp.topMargin =0
mRootView.layoutParams = lp
}
}
}
}
在這里當軟鍵盤彈出的時候重新設置了下dialog的高度,因為有時候軟鍵盤的彈出會使dialog的高度壓縮,所以彈出的時候重新設置下就好了。
這就是我的一個解決思路,當然完全按這個寫的話當輸入框較多時也可能出問題,最上層的輸入框跑屏幕之外去了,這種情況下我們只需要根據輸入框的位置動態的計算dialog需要往上移動的距離就行,不要一直設置為計算出來的軟鍵盤的高度。
下圖是解決之後的UI
Ⅱ android載入自定義dialog,背景總是黑色的.不知道為什麼.求解答
AlertDialog.Builder builder = new AlertDialog.Builder(UserInformationActivity.this,AlertDialog.THEME_HOLO_LIGHT);這種形式的,其中「AlertDialog.THEME_HOLO_LIGHT」設置背景,這個是白色的
把Activity設置成dialog的,修改AndroidManifest.xml中該Activity的theme,如:android:theme="@android:style/Theme.Holo.Light.Dialog.NoActionBar" ,這樣這個Activity會以dialog的形式彈出,並且是白色的
自己寫一個自定義dialog繼承dialog,你dialog的布局文件的最外層layout背景顏色設置成白色的
Ⅲ android 怎樣設置dialog的背景
[html]viewplainprint?
<itemname="android:windowFrame">@null</item>