寫在前面:在項目開發當中有時會碰到許多奇奇怪怪的問題,這次是碰上了彈出輸入法對界面造成影響的問題。
一、出現問題
先來看看出現問題的場景:
這個界面整體是由若干個EditText輸入框和兩個置於底端按鈕組成。我之前已在AndroidManifest.xml 配置文件中設置了Activity的Window屬性adjustPan(更多關於Window屬性的知識可以看下這篇博客:http://blog.csdn.net/twoicewoo/article/details/7384398),這解決了EditText下方的控件被彈出的輸入法頂上去造成界面壓縮的問題。但是,還有一個問題仍沒有解決,那就是當我讓EditText獲得焦點時,處於屏幕底端的兩個按鈕會被輸入法頂上去的問題。就像這樣:
我的底部按鈕佈局是這樣寫的:
<LinearLayout
android:id="@+id/divBottom"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_alignParentBottom="true"
android:background="@color/back_transparent"
android:orientation="horizontal">
<Button
android:layout_width="match_parent"
android:layout_height="35dp"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
android:layout_weight="1"
android:layout_marginLeft="20dp"
android:layout_marginRight="15dp"
android:background="@color/orange"
android:text="保存模板"
android:textSize="16dp"
android:textColor="@color/white"/>
<Button
android:layout_width="match_parent"
android:layout_height="35dp"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
android:layout_weight="1"
android:layout_marginLeft="15dp"
android:layout_marginRight="20dp"
android:background="@color/orange"
android:text="預覽"
android:textSize="16dp"
android:textColor="@color/white"/>
</LinearLayout>
可以看到,我爲底部鑲嵌了兩個Button控件的LinearLayout 設置了android:layout_alignParentBottom=”true” 這個屬性,使它可以懸浮在ScrollView 上並一直處於屏幕底端。在嘗試了多種設置配置文件和控件屬性的方法都無法解決這個問題後,我想到了在代碼中去動態設置LinearLayout 組件的marginTop 值的方法。
二、解決問題
解決的思路是這樣,要讓這個LinearLayout 組件(最外層是RelativeLayout佈局)一直處於屏幕底端,且不被輸入法頂上去,那就讓這個組件和屏幕頂端保持一個不變的距離就好了。也就是保持android:layout_marginTop 的值不變。由於考慮到Android手機有多種分辨率,我們要去代碼中進行動態設置這個值。具體這個值的算法是這樣的:屏幕的高度 減去底部導航條的高度(如果有虛擬鍵) 再減去我們底部LinearLayout 組件一半的高度,最後得到的值就是我們需要的。
有了思路,解決問題就簡單,網上能找到許多關於動態設置margin 值的資料,我在這裏就不贅述了。直接上代碼:
divBottom = (LinearLayout) findViewById(R.id.divBottom);
RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) divBottom.getLayoutParams();
lp.setMargins(0, ScreenUtils.getScreenH(this)-ScreenUtils.getNavigationBarHeight(this)-DpOrPx.dip2px(this,25),0,0);
其中ScreenUtils.getScreenH(this)是獲取屏幕高度的,ScreenUtils.getNavigationBarHeight(this) 是獲取底部導航條高度的,單位都是px:
public static int getScreenH(Context context){
if (screenH == 0){
initScreen(context);
}
return screenH;
}
public static int getNavigationBarHeight(Context context) {
Resources resources = context.getResources();
int resourceId = resources.getIdentifier("navigation_bar_height","dimen", "android");
int height = resources.getDimensionPixelSize(resourceId);
Log.v("dbw", "Navi height:" + height);
return height;
}
private static void initScreen(Context context){
DisplayMetrics metric = context.getResources().getDisplayMetrics();
screenW = metric.widthPixels;
screenH = metric.heightPixels;
screenDensity = metric.density;
}
DpOrPx.dip2px(this,25) 是將LinearLayout 組件高度50dp的一半轉成px單位:
public static int dip2px(Context context, float dpValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dpValue * scale + 0.5f);
}
這些方法在網上都能非常輕易地找到,有興趣,想更深地瞭解裏面具體參數的含義的童鞋可以自己去找找,我就不在這詳細講了。
最後貼一張解決了問題的截圖進行收尾吧(:з」∠),如果各位有啥疑問或者意見,非常歡迎來指導和交流~~