在做登錄和註冊頁面的時候,經常會遇到諸如軟鍵盤擋住輸入框的情況,android爲此提供了一系列的的配置參數供選擇,你可以在androidmanufist.xml的對應Activity的windowSoftInputMode屬性中選擇如下4者之一進行配置(紫色字):
<activity android:name=".LoginAc"
android:label="@string/app_name"
android:windowSoftInputMode="stateHidden|adjustResize">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
四個參數意思如下:
SOFT_INPUT_ADJUST_NOTHING: 不調整(輸入法完全直接覆蓋住,未開放此參數)
SOFT_INPUT_ADJUST_PAN: 把整個Layout頂上去露出獲得焦點的EditText,不壓縮多餘空間,見圖1
SOFT_INPUT_ADJUST_RESIZE: 整個Layout重新編排,重新分配多餘空間,見圖2
SOFT_INPUT_ADJUST_UNSPECIFIED: 系統自己根據內容自行選擇上兩種方式的一種執行(默認配置)
這裏的多餘空間指的是控件們通過weight分配機制得到的額外空間。
圖1
圖2
圖3
代碼實現方式爲:
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
但是,這樣的配置方法一般都很難完全滿足需要,有得應用會做得比較好,讓頂上去的Layout能夠通過scrollbar滾動。這種解決方法網上有各種介紹,本人也是第一時間從網上找解決方法參考,但最終發現都並未把原理說清,而且大多數有錯誤,或者有多餘配置,於是,我從android系統中源碼中找參考案例,在Email應用中,找到了我想要的。效果如圖4,5。
圖4
圖5
其對應的Activity是AccountSetupBasics.java,對應的xml文件爲account_setup_basics.xml。
來學習下它的xml寫法:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:fillViewport="true"
android:scrollbarStyle="outsideInset" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical" >
<TextView
android:id="@+id/instructions"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dip"
android:textSize="20sp"
android:text="@string/accounts_welcome"
android:textColor="?android:attr/textColorPrimary" />
<View
android:layout_width="fill_parent"
android:layout_height="0dip"
android:layout_weight="1" />
<EditText
android:id="@+id/account_email"
android:hint="@string/account_setup_basics_email_hint"
android:inputType="textEmailAddress"
android:imeOptions="actionNext"
android:layout_height="wrap_content"
android:layout_width="fill_parent" />
<EditText
android:id="@+id/account_password"
android:hint="@string/account_setup_basics_password_hint"
android:inputType="textPassword"
android:imeOptions="actionDone"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:nextFocusDown="@+id/next" />
<CheckBox
android:id="@+id/account_default"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:text="@string/account_setup_basics_default_label"
android:visibility="gone" />
<View
android:layout_width="fill_parent"
android:layout_height="0dip"
android:layout_weight="1" />
</LinearLayout>
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="54dip"
android:background="@android:drawable/bottom_bar" >
<Button
android:id="@+id/manual_setup"
android:text="@string/account_setup_basics_manual_setup_action"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:minWidth="@dimen/button_minWidth"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true" />
<Button
android:id="@+id/next"
android:text="@string/next_action"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:minWidth="@dimen/button_minWidth"
android:drawableRight="@drawable/button_indicator_next"
android:layout_alignParentRight="true"
android:layout_centerVertical="true" />
</RelativeLayout>
</LinearLayout>
</ScrollView>
1 它完全把ScrollView作爲了一個根Layout,而不是網上好多文章寫的在一個Linearlayout裏面嵌入一個ScrollView(貌似這種是行不通的)。
然後把我們原來的根Layout搬入ScrollView(ScrollView只能有一個子控件),我查了下androidmanifist.xml和代碼,未做任何以上2種方法的配置。
2 它定義了2個0dip的View幫助分配空間(設置其weight吃掉剩餘空間,保證輸入框處於界面中心位置),可以猜測出這裏系統調用的是SOFT_INPUT_ADJUST_RESIZE參數,當所有有實際內容的控件空間總和超出特定範圍時,ScrollView開始發揮作用。
如此,完美的解決我們遇到的問題。
另外,網上有人說想用SOFT_INPUT_ADJUST_RESIZE ,但又不希望背景圖片被壓縮,只要按如上方法把Linearlayout的背景圖片設置好即可。
int | SOFT_INPUT_ADJUST_NOTHING |
Adjustment option for set to have a window not adjust for a shown input method. |
int | SOFT_INPUT_ADJUST_PAN |
Adjustment option for set to have a window pan when an input method is shown, so it doesn't need to deal with resizing but just panned by the framework to ensure the current input focus is visible. |
int | SOFT_INPUT_ADJUST_RESIZE |
Adjustment option for set to allow the window to be resized when an input method is shown, so that its contents are not covered by the input method. |
int | SOFT_INPUT_ADJUST_UNSPECIFIED |
Adjustment option for nothing specified. |