遇到這麼個需求,先看圖:
其實是乙個軟體的登入介面,初始是第乙個圖的樣子,當軟鍵盤彈出後變為第二個圖的樣子,因為登入介面有使用者名稱、密碼、登入按鈕,不這樣的話軟鍵盤彈出後會遮住登入按鈕(其實之前的實現放到了scrollview裡面,監聽軟鍵盤彈出後滾動到底部,軟鍵盤隱藏後滾動到頂部,也是可以的)。
最簡單的方法就是多加幾個冗餘的view,根據軟鍵盤的狀態隱藏不需要的view,顯示需要的view,但這樣感覺太挫了,然後就想起了前兩年研究的relativelayout布局,relativelayout中子控制項的布局都是相對位置,只需要在軟鍵盤彈出隱藏時改變應用的位置規則就行了。
先來看一下布局檔案
<軟鍵盤的彈出隱藏用ongloballayoutlistener監聽實現,對activity應用android:windowsoftinputmode="statehidden|adjustresize",這樣開始時軟鍵盤不顯示,當軟鍵盤彈出時布局被resize。relativelayout
xmlns:android
=""xmlns:tools
=""android:id
="@+id/root"
android:layout_width
="match_parent"
android:layout_height
="match_parent"
android:padding
="20dp"
tools:context
="$.$"
>
<
relativelayout
android:id
="@+id/container"
android:layout_width
="match_parent"
android:layout_height
="wrap_content"
android:layout_alignparenttop
="true"
>
<
imageview
android:id
="@+id/logo"
android:layout_width
="150dp"
android:layout_height
="150dp"
android:layout_centerhorizontal
="true"
android:scaletype
="centercrop"
android:src
="@drawable/ic_launcher"
tools:ignore
="contentdescription"
/>
<
textview
android:id
="@+id/label"
android:layout_width
="wrap_content"
android:layout_height
="wrap_content"
android:layout_below
="@id/logo"
android:layout_centerhorizontal
="true"
android:layout_marginleft
="10dp"
android:layout_margintop
="10dp"
android:text
="@string/hello_world"
android:textsize
="20sp"
/>
relativelayout
>
<
edittext
android:id
="@+id/input"
android:layout_width
="match_parent"
android:layout_height
="wrap_content"
android:layout_below
="@id/container"
android:layout_margin
="16dp"
android:hint
="input sth."
tools:ignore
="hardcodedtext"
/>
relativelayout
>
接下來是**,所有的**都在這裡了
public當activity啟動時也會進行layout,此時用rootbottom記錄了初始時最外層布局底部的位置,此後當軟鍵盤彈出時,布局被壓縮,再次獲取同乙個view底部的位置,如果比rootbottom**明軟鍵盤彈出了,如果大於或等於rootbottom說明軟鍵盤隱藏了。class mainactivity extends
activity
//adjustresize,軟鍵盤彈出後高度會變小
if (r.bottom
} else }}
});}
}
所有的**都在上面,也有詳細注釋,有兩點需要注意一下:
activity啟動時會進行layout,此時會呼叫ongloballayout,而且一般會呼叫兩次,這樣第二次時會進入else語句,要注意過濾
軟鍵盤彈出或隱藏時進入ongloballayout,此時根據需要縮放logo的大小,並改變logo和label的位置,這些操作會引起再次ongloballayout,需要將之後的ongloballayout過濾掉,不然就無限迴圈了。
可以看到上面**中的過濾條件,以else語句中的為例,activity啟動時會進入else,此時logo是水平居中狀態,會跳過else裡面的if語句,這樣就處理掉了第一種情況。
當因為軟鍵盤收起進入else時,logo已經因為if語句塊變為了顯示在左上角,所以會進入else中的if語句,重新改變logo為水平居中,由於修改了logo的大小和位置,會導致再次進入ongloballayout,仍是進入else,但此時已經設定logo為水平居中了,不會再次進入else中的if語句,這樣通過乙個條件判斷就處理了上面提到的兩點注意事項。
關於addrule
relativelayout中每乙個子控制項所應用的規則都是通過陣列儲存的,如下所示:
public以某一規則的索引為下標,值就是規則對應的anchor,如果是相對於另乙個子控制項,值就是另乙個子控制項的id,如果是相對于父控制項,值就是`true`,即-1,如果沒有應用某一規則值就是0,可以看到,removerule就是把相應位置的值改為了0:static
final
int true = -1;
public
void addrule(int
verb)
public
void addrule(int verb, int
anchor)
publicremoverule是api 17才加的方法,為了在api 17前也能使用,可以使用它的等價方法,像上面的例子中的一樣,使用addrule(verb, 0)。void removerule(int
verb)
Android動態改變布局
遇到這麼個需求,先看圖 其實是乙個軟體的登入介面,初始是第乙個圖的樣子,當軟鍵盤彈出後變為第二個圖的樣子,因為登入介面有使用者名稱 密碼 登入按鈕,不這樣的話軟鍵盤彈出後會遮住登入按鈕 其實之前的實現放到了scrollview裡面,監聽軟鍵盤彈出後滾動到底部,軟鍵盤隱藏後滾動到頂部,也是可以的 最簡...
Android動態改變布局
遇到這麼個需求,先看圖 其實是乙個軟體的登入介面,初始是第乙個圖的樣子,當軟鍵盤彈出後變為第二個圖的樣子,因為登入介面有使用者名稱 密碼 登入按鈕,不這樣的話軟鍵盤彈出後會遮住登入按鈕 其實之前的實現放到了scrollview裡面,監聽軟鍵盤彈出後滾動到底部,軟鍵盤隱藏後滾動到頂部,也是可以的 最簡...
Android 動態布局
android 動態布局 絕對布局 absolutelayout abslayout new absolutelayout this setcontentview abslayout button btn1 new button this btn1.settext this is a button ...