Android軟鍵盤(pán)遮擋的四種完美解決方案
一、問(wèn)題概述
在編輯框輸入內(nèi)容時(shí)會(huì)彈出軟鍵盤(pán),而手機(jī)屏幕區(qū)域有限往往會(huì)遮住輸入界面,我們先看一下問(wèn)題效果圖:

輸入用戶名和密碼時(shí),系統(tǒng)會(huì)彈出鍵盤(pán),造成系統(tǒng)鍵盤(pán)會(huì)擋住文本框的問(wèn)題,如圖所示:

輸入密碼時(shí)輸入框被系統(tǒng)鍵盤(pán)遮擋了,大大降低了用戶操作體驗(yàn),這就是開(kāi)發(fā)中非常常見(jiàn)的軟鍵盤(pán)遮擋的問(wèn)題,該如何解決?
二、簡(jiǎn)單解決方案
方法一
在你的activity中的oncreate中setContentView之前寫(xiě)上這個(gè)代碼
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
方法二
在 項(xiàng)目的AndroidManifest.xml文件中界面對(duì)應(yīng)的<activity>里加入
android:windowSoftInputMode="stateVisible|adjustResize"
這樣會(huì)讓屏幕整體上移。如果加上的 是 android:windowSoftInputMode="adjustPan"這樣鍵盤(pán)就會(huì)覆蓋屏幕。
關(guān)于android:windowSoftInputMode
activity主窗口與軟鍵盤(pán)的交互模式,可以用來(lái)避免輸入法面板遮擋問(wèn)題,Android1.5后的一個(gè)新特性。
這個(gè)屬性能影響兩件事情:
【一】當(dāng)有焦點(diǎn)產(chǎn)生時(shí),軟鍵盤(pán)是隱藏還是顯示
【二】是否減少活動(dòng)主窗口大小以便騰出空間放軟鍵盤(pán)
它的設(shè)置必須是下面列表中的一個(gè)值,或一個(gè)”state…”值加一個(gè)”adjust…”值的組合。在任一組設(shè)置多個(gè)值——多個(gè)”state…”values,例如&mdash有未定義的結(jié)果。各個(gè)值之間用|分開(kāi)。
例如:
<activity android:windowSoftInputMode="stateVisible|adjustResize". . . >
在這設(shè)置的值(除"stateUnspecified"和"adjustUnspecified"以外)將覆蓋在主題中設(shè)置的值
各值的含義:
【A】stateUnspecified:軟鍵盤(pán)的狀態(tài)并沒(méi)有指定,系統(tǒng)將選擇一個(gè)合適的狀態(tài)或依賴于主題的設(shè)置
【B】stateUnchanged:當(dāng)這個(gè)activity出現(xiàn)時(shí),軟鍵盤(pán)將一直保持在上一個(gè)activity里的狀態(tài),無(wú)論是隱藏還是顯示
【C】stateHidden:用戶選擇activity時(shí),軟鍵盤(pán)總是被隱藏
【D】stateAlwaysHidden:當(dāng)該Activity主窗口獲取焦點(diǎn)時(shí),軟鍵盤(pán)也總是被隱藏的
【E】stateVisible:軟鍵盤(pán)通常是可見(jiàn)的
【F】stateAlwaysVisible:用戶選擇activity時(shí),軟鍵盤(pán)總是顯示的狀態(tài)
【G】adjustUnspecified:默認(rèn)設(shè)置,通常由系統(tǒng)自行決定是隱藏還是顯示
【H】adjustResize:該Activity總是調(diào)整屏幕的大小以便留出軟鍵盤(pán)的空間
【I】adjustPan:當(dāng)前窗口的內(nèi)容將自動(dòng)移動(dòng)以便當(dāng)前焦點(diǎn)從不被鍵盤(pán)覆蓋和用戶能總是看到輸入內(nèi)容的部分
方法三
把頂級(jí)的layout替換成ScrollView,或者說(shuō)在頂級(jí)的Layout上面再加一層ScrollView。這樣就會(huì)把軟鍵盤(pán)和輸入框一起滾動(dòng)了,軟鍵盤(pán)會(huì)一直處于底部。
<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>
但這些方法雖然比較簡(jiǎn)單,但往往都有一定的局限性不是很靈活,有時(shí)達(dá)不到預(yù)期效果,大家可以試試或許也能解決你的問(wèn)題,下面就教大家一種具有代碼可控性的一種方法:
三、代碼可控性方法
1.主界面布局文件
<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"> <!—這里模仿一個(gè)登錄界面--> <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>
可以看出關(guān)鍵地方在于LinearLayoutView這個(gè)自定義組件
2.自定義LinearLayoutView
該組件可實(shí)現(xiàn)根據(jù)軟鍵盤(pán)的彈出/關(guān)閉而隱藏和顯示某些區(qū)域,這是問(wèn)題解決最關(guān)鍵部分,主要有兩點(diǎn):
?、?重寫(xiě)onSizeChanged方法
該方法是View生命周期的方法,當(dāng)View尺寸發(fā)生變化時(shí)調(diào)用,如豎屏橫屏切換、軟鍵盤(pán)彈出。這里當(dāng)軟鍵盤(pán)彈出造成View尺寸改變,就會(huì)調(diào)用onSizeChanged方法,在該方法實(shí)現(xiàn)代碼的核心思想是根據(jù)尺寸變化,當(dāng)變大(軟鍵盤(pán)彈出),將某些區(qū)域隱藏以給編輯界面預(yù)留出足夠顯示空間;當(dāng)恢復(fù)(軟鍵盤(pán)關(guān)閉),再將隱藏的區(qū)域顯示出來(lái)
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){ // 軟鍵盤(pán)關(guān)閉
keyBordStateListener.stateChange(KEYBORAD_SHOW);//回調(diào)方法顯示部分區(qū)域
}else { // 軟鍵盤(pán)彈出
if(keyBordStateListener != null){
keyBordStateListener.stateChange(KEYBORAD_HIDE);// 回調(diào)方法隱藏部分區(qū)域
}
}
}
});
}
?、谔峁㎏eyBordStateListener 接口采用回調(diào)機(jī)制調(diào)用接口的實(shí)現(xiàn)方法。
代碼:
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
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);
//獲得可根據(jù)軟鍵盤(pán)的彈出/關(guān)閉而隱藏和顯示某些區(qū)域的LinearLayoutView組件
resizeLayout = (LinearLayoutView) findViewById(R.id.login_root_layout);
//獲得要控制隱藏和顯示的區(qū)域
logoLayout = (LinearLayout) findViewById(R.id.login_layout_logo);
resizeLayout.setKeyBordStateListener(this);//設(shè)置回調(diào)方法
}
//實(shí)現(xiàn)接口中的方法,該方法在resizeLayout的onSizeChanged方法中調(diào)用
@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;
}
}
四、實(shí)現(xiàn)效果
鍵盤(pán)彈出:

鍵盤(pán)關(guān)閉:

以上所述是小編給大家介紹的Android軟鍵盤(pán)遮擋的四種完美解決方案,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
相關(guān)文章
Android ReboundScrollView仿IOS拖拽回彈效果
這篇文章主要為大家詳細(xì)介紹了Android ReboundScrollView仿IOS拖拽回彈效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-11-11
Android開(kāi)發(fā)Dart?Constructors構(gòu)造函數(shù)使用技巧整理
這篇文章主要為大家介紹了Android開(kāi)發(fā)Dart?Constructors構(gòu)造函數(shù)使用技巧整理,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-05-05
ScrollView嵌套ListView滑動(dòng)沖突的解決方法
這篇文章主要介紹了ScrollView嵌套ListView滑動(dòng)沖突的解決方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-11-11
Ubuntu中為Android實(shí)現(xiàn)Application Frameworks層增加硬件訪問(wèn)服務(wù)
本文主要介紹Android實(shí)現(xiàn) Application Frameworks層增加硬件訪問(wèn)服務(wù),這里對(duì)實(shí)現(xiàn)增加硬件訪問(wèn)服務(wù)的功能做出了詳細(xì)的工作流程,并提供示例代碼,有需要的小伙伴參考下2016-08-08
基于Android如何實(shí)現(xiàn)將數(shù)據(jù)庫(kù)保存到SD卡
有時(shí)候?yàn)榱诵枰?,?huì)將數(shù)據(jù)庫(kù)保存到外部存儲(chǔ)或者SD卡中(對(duì)于這種情況可以通過(guò)加密數(shù)據(jù)來(lái)避免數(shù)據(jù)被破解),本文給大家分享Android如何實(shí)現(xiàn)將數(shù)據(jù)庫(kù)保存到SD卡,對(duì)android數(shù)據(jù)庫(kù)sd卡相關(guān)知識(shí)感興趣的朋友一起學(xué)習(xí)吧2015-12-12
Android 多種dialog的實(shí)現(xiàn)方法(推薦)
下面小編就為大家分享一篇Android 多種dialog的實(shí)現(xiàn)方法(推薦),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-01-01
使用RecyclerView實(shí)現(xiàn)瀑布流高度自適應(yīng)
這篇文章主要為大家詳細(xì)介紹了使用RecyclerView實(shí)現(xiàn)瀑布流高度自適應(yīng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-09-09

