一、問題概述
在編輯框輸入內容時會彈出軟鍵盤,而手機屏幕區域有限往往會遮住輸入界面
輸入密碼時輸入框被系統鍵盤遮擋了,大大降低了用戶操作體驗,這就是開發中非常常見的軟鍵盤遮擋的問題,該如何解決?
二、簡單解決方案
方法一
在你的activity中的oncreate中setContentView之前寫上這個代碼
1
|
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN); |
方法二
在 項目的AndroidManifest.xml文件中界面對應的<activity>里加入
1
|
android:windowSoftInputMode= "adjustPan" |
這樣會讓屏幕整體上移。如果加上的 是 android:windowSoftInputMode="adjustPan"這樣鍵盤就不會覆蓋屏幕。
關於android:windowSoftInputMode
activity主窗口與軟鍵盤的交互模式,可以用來避免輸入法面板遮擋問題,Android1.5後的一個新特性。
這個屬性能影響兩件事情:
【一】當有焦點產生時,軟鍵盤是隱藏還是顯示
【二】是否減少活動主窗口大小以便騰出空間放軟鍵盤
它的設置必須是下面列表中的一個值,或一個”state…”值加一個”adjust…”值的組合。在任一組設置多個值——多個”state…”values,例如&mdash有未定義的結果。各個值之間用|分開。
例如:
1
|
<activity android:windowSoftInputMode= "stateVisible|adjustResize" . . . > |
在這設置的值(除"stateUnspecified"和"adjustUnspecified"以外)將覆蓋在主題中設置的值
各值的含義:
【A】stateUnspecified:軟鍵盤的狀態並沒有指定,系統將選擇一個合適的狀態或依賴於主題的設置
【B】stateUnchanged:當這個activity出現時,軟鍵盤將一直保持在上一個activity裏的狀態,無論是隱藏還是顯示
【C】stateHidden:用戶選擇activity時,軟鍵盤總是被隱藏
【D】stateAlwaysHidden:當該Activity主窗口獲取焦點時,軟鍵盤也總是被隱藏的
【E】stateVisible:軟鍵盤通常是可見的
【F】stateAlwaysVisible:用戶選擇activity時,軟鍵盤總是顯示的狀態
【G】adjustUnspecified:默認設置,通常由系統自行決定是隱藏還是顯示
【H】adjustResize:該Activity總是調整屏幕的大小以便留出軟鍵盤的空間
【I】adjustPan:當前窗口的內容將自動移動以便當前焦點從不被鍵盤覆蓋和用戶能總是看到輸入內容的部分
方法三
把頂級的layout替換成ScrollView,或者說在頂級的Layout上面再加一層ScrollView。這樣就會把軟鍵盤和輸入框一起滾動了,軟鍵盤會一直處於底部。
1
2
3
4
5
6
|
<ScrollView xmlns:android= "http://schemas.android.com/apk/res/android" android:layout_width= "fill_parent" android:layout_height= "fill_parent" > <LinearLayout android:layout_width= "fill_parent" android:layout_height= "fill_parent" android:orientation= "vertical" > </LinearLayout> </ScrollView> |
但這些方法雖然比較簡單,但往往都有一定的侷限性不是很靈活,有時達不到預期效果,大家可以試試或許也能解決你的問題,下面就教大家一種具有代碼可控性的一種方法:
三、代碼可控性方法
1.主界面佈局文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
|
<com.jereh.overidelinearlayout.LinearLayoutView xmlns:android= "http://schemas.android.com/apk/res/android" android:layout_width= "match_parent" android:id= "@+id/login_root_layout" android:layout_height= "match_parent" android:orientation= "vertical" > <!—這裏模仿一個登錄界面--> <LinearLayout android:id= "@+id/login_layout_logo" android:layout_width= "match_parent" android:layout_height= "0dp" android:layout_weight= "10" android:background= "#ff0000" android:orientation= "vertical" > <ImageView android:id= "@+id/textView1" android:layout_width= "fill_parent" android:layout_height= "fill_parent" android:src= "@drawable/login_logo" android:scaleType= "fitXY" /> </LinearLayout> <!—輸入框和密碼框--> <LinearLayout android:layout_width= "match_parent" android:layout_height= "0dp" android:layout_marginTop= "20dp" android:layout_weight= "3" android:orientation= "vertical" > <EditText android:id= "@+id/editText1" android:layout_width= "match_parent" android:layout_height= "wrap_content" android:layout_alignLeft= "@+id/textView1" android:layout_alignParentBottom= "true" android:layout_gravity= "center_vertical" android:hint= "用戶名" android:ems= "10" > <requestFocus /> </EditText> <EditText android:id= "@+id/editText1" android:layout_width= "match_parent" android:layout_height= "wrap_content" android:layout_alignLeft= "@+id/textView1" android:layout_alignParentBottom= "true" android:layout_gravity= "center_vertical" android:hint= "密碼" android:ems= "10" > <requestFocus /> </EditText> </LinearLayout> </com.jereh.overidelinearlayout.LinearLayoutView> |
可以看出關鍵地方在於LinearLayoutView這個自定義組件
2.自定義LinearLayoutView
該組件可實現根據軟鍵盤的彈出/關閉而隱藏和顯示某些區域,這是問題解決最關鍵部分,主要有兩點:
① 重寫onSizeChanged方法
該方法是View生命週期的方法,當View尺寸發生變化時調用,如豎屏橫屏切換、軟鍵盤彈出。這裏當軟鍵盤彈出造成View尺寸改變,就會調用onSizeChanged方法,在該方法實現代碼的核心思想是根據尺寸變化,當變大(軟鍵盤彈出),將某些區域隱藏以給編輯界面預留出足夠顯示空間;當恢復(軟鍵盤關閉),再將隱藏的區域顯示出來
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
protected void
onSizeChanged( int w, final
int h, int oldw, final
int oldh) { super .onSizeChanged(w, h, oldw, oldh); uiHandler.post( new Runnable() { public
void run() { if
(oldh - h > SOFTKEYPAD_MIN_HEIGHT){ // 軟鍵盤關閉 keyBordStateListener.stateChange(KEYBORAD_SHOW); //回調方法顯示部分區域 } else {
// 軟鍵盤彈出 if (keyBordStateListener != null ){ keyBordStateListener.stateChange(KEYBORAD_HIDE); // 回調方法隱藏部分區域 } } } }); } |
②提供KeyBordStateListener 接口採用回調機制調用接口的實現方法。
代碼:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
public
interface KeyBordStateListener{ public void
stateChange( int state);} //定義接口 private
KeyBordStateListener keyBordStateListener; public
void setKeyBordStateListener(KeyBordStateListener keyBordStateListener) { this .keyBordStateListener = keyBordStateListener; } LinearLayoutView組件的完整代碼: public
class LinearLayoutView extends LinearLayout{ public
static final
int KEYBORAD_HIDE = 0 ; public
static final
int KEYBORAD_SHOW = 1 ; private
static final
int SOFTKEYPAD_MIN_HEIGHT = 50 ; private Handler uiHandler =
new Handler(); public
LinearLayoutView(Context context) { super (context); } public
LinearLayoutView(Context context, AttributeSet attrs) { super (context, attrs); } @Override protected void
onSizeChanged( int w, final
int h, int oldw, final
int oldh) { // TODO Auto-generated method stub super .onSizeChanged(w, h, oldw, oldh); uiHandler.post( new Runnable() { @Override public
void run() { if
(oldh - h > SOFTKEYPAD_MIN_HEIGHT){ keyBordStateListener.stateChange(KEYBORAD_SHOW); } else {
if (keyBordStateListener != null ){ keyBordStateListener.stateChange(KEYBORAD_HIDE);} } } }); } private KeyBordStateListener keyBordStateListener; public
void 、setKeyBordStateListener(KeyBordStateListener keyBordStateListener) { this .keyBordStateListener = keyBordStateListener; } public
interface KeyBordStateListener{ public
void stateChange( int state); } |
3.主界面MainActivity
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
public
class MainActivity extends Activity
implements KeyBordStateListener { private
LinearLayoutView resizeLayout; private
LinearLayout logoLayout; @Override protected void
onCreate(Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.activity_main); //獲得可根據軟鍵盤的彈出/關閉而隱藏和顯示某些區域的LinearLayoutView組件 resizeLayout = (LinearLayoutView) findViewById(R.id.login_root_layout); //獲得要控制隱藏和顯示的區域 logoLayout = (LinearLayout) findViewById(R.id.login_layout_logo); resizeLayout.setKeyBordStateListener( this ); //設置回調方法 } //實現接口中的方法,該方法在resizeLayout的onSizeChanged方法中調用 @Override public
void stateChange( int state) { // TODO Auto-generated method stub switch
(state) { case
LinearLayoutView.KEYBORAD_HIDE: logoLayout.setVisibility(View.VISIBLE); break ; case
LinearLayoutView.KEYBORAD_SHOW: logoLayout.setVisibility(View.GONE); break ; } } |
原文鏈接:http://www.cnblogs.com/jerehedu/p/4194125.html