關於Android軟鍵盤彈出的問題
在開發中,我們經常會用到EditText,這就無可避免的會遇到軟鍵盤彈出遮擋佈局的問題,通常情況下我們可以設定AndroidManifist.xml來設定對應的屬性。
1.stateUnspecified:軟鍵盤的狀態並沒有指定,系統將選擇一個合適的狀態或依賴於主題的設定
2.stateUnchanged當這個activity出現時,軟鍵盤將一直保持在上一個activity裡的狀態,無論是隱藏還是顯示
3.stateHidden使用者選擇activity時,軟鍵盤總是被隱藏
4.stateAlwaysHidden:即使Activity主視窗獲取到焦點,軟鍵盤也總是被隱藏的
5.stateVisible:軟鍵盤通常是可見的
6.stateAlwaysVisible:使用者選擇activity時,軟鍵盤總是顯示的狀態
7.adjustUnspecified:預設設定,通常由系統自行決定是隱藏還是顯示
8.adjustResize:該Activity總是調整螢幕的大小以便留出軟鍵盤的空間
9.adjustPan:當前視窗的內容將自動移動以便當前焦點從不被鍵盤覆蓋和使用者能總是看到輸入內容的部分
一般情況下我使用的較多的是adjustPan,自動適應,但是這個屬性經常會把佈局頂上去,這就比較坑爹了,尤其是有時候會把標題欄都抵上去,而且只會剛好露出焦點,部分輸入框是被遮擋的,如下圖:
正常情況下,未彈出的時候
點選輸入框,彈出之後
大寫的醜,使用者體驗非常不好。仔細思考一下,軟鍵盤也就相當於是一個佈局,彈出的時候就相當於在我們的佈局下方加入了一個佈局,上頂相當於是一個滑動的問題,那麼如果在除標題欄以外的地方巢狀一個ScrollView是不是就能避免標題欄被抵上去呢,果然,這麼一試就成了。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v7.widget.Toolbar
android:id="@+id/talk_list_tool_bar"
android:layout_width ="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="@color/blue_titlebar"
android:elevation="4dp"
android:gravity="center"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_gravity="center"
android:ellipsize="end"
android:singleLine="true"
android:text="對話記錄"
android:textColor="@color/white"
android:textSize="@dimen/titleTextSize"
android:textStyle="bold"/>
</android.support.v7.widget.Toolbar>
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:fillViewport="true">
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/bgcolor"
android:orientation="vertical">
<ListView
android:id="@+id/consult_talk_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="@+id/consult_talk_list_bottom_lay"
android:layout_alignParentTop="true"
android:divider="@null"
android:overScrollMode="never"
android:scrollbars="none"
android:transcriptMode="normal"/>
<View
android:layout_width="match_parent"
android:layout_height="0.5dp"
android:layout_below="@+id/consult_talk_list"
android:background="@color/black"/>
<LinearLayout
android:id="@+id/consult_talk_list_bottom_lay"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:orientation="vertical">
<LinearLayout
android:id="@+id/consult_talk_list_lay"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:background="#eee"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingBottom="6dp"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:paddingTop="6dp"
android:visibility="gone">
<ImageView
android:id="@+id/consult_talk_list_item_voice"
android:layout_width="32dp"
android:layout_height="32dp"
android:clickable="true"
android:src="@drawable/voice_icon"/>
<ImageView
android:id="@+id/bar_image_add_btn"
android:layout_width="28dp"
android:layout_height="28dp"
android:clickable="true"
android:scaleType="centerCrop"
android:src="@drawable/ic_plus"
android:visibility="gone"/>
<LinearLayout
android:id="@+id/rl_editbar_bg"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_weight="1"
android:background="@drawable/shape_bg_reply_edittext"
android:gravity="center_vertical"
android:orientation="horizontal">
<EditText
android:id="@+id/consult_talk_list_item_edit"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="#0000"
android:maxLines="3"
android:minHeight="36dp"
android:textColor="@color/text_color"
android:textSize="16sp"/>
</LinearLayout>
<Button
android:id="@+id/consult_talk_list_item_send"
android:layout_width="56dp"
android:layout_height="32dp"
android:background="@drawable/shape_bg_button_reply"
android:text="傳送"
android:textColor="@color/white"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:background="#eee"
android:gravity="center"
android:orientation="horizontal"
android:paddingBottom="6dp"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:paddingTop="6dp">
<TextView
android:id="@+id/consult_talk_list_item_btn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="30dp"
android:layout_marginRight="30dp"
android:background="@drawable/good_button_back"
android:gravity="center"
android:paddingBottom="10dp"
android:paddingTop="10dp"
android:text="點選評價"
android:textColor="@color/text_color"
android:textSize="18sp"
android:visibility="gone"/>
</LinearLayout>
</LinearLayout>
</RelativeLayout>
</ScrollView>
</LinearLayout>
這個時候只也不需要設定成adjustPan了,只設置成stateHidden就行了,預設隱藏軟鍵盤。當輸入框獲取到焦點的時候,聊天記錄的ListView就會上滑而不影響標題欄。當然如果記錄較多的時候我們想讓每次獲取焦點的時候記錄都處於最下方,即ListView每次都滾到最底部,這樣就可以看到最新的訊息,我們可以監聽軟鍵盤的彈出和隱藏事件來完成。
EditText.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
Rect r = new Rect();
//獲取當前介面可視部分的四個座標
GridReflyActivity.this.getWindow().getDecorView().getWindowVisibleDisplayFrame(r);
//獲取螢幕的高度
int screenHeight = GridReflyActivity.this.getWindow().getDecorView().getRootView().getHeight();
//ScreenHeight是螢幕高度,穩定不變的,但是應用的可視區域r會變,如果軟鍵盤彈出,那麼r.bottom就會變小
int heightDifference = screenHeight - r.bottom;
if (heightDifference > 0) {
doSomeThing();
} else {
doSomeThing()
}
}
}
heightDifference > 0時,我們可以設定彈出事件,heightDifference < 0時,我們可以設定隱藏的事件。
現在很多App的登陸頁面中點選登陸框隱藏logo的效果也可以通過這個完成。