Android軟鍵盤遮擋的四種解決方案


目錄:

一、問題概述

二、簡單解決方案

三、代碼可控性方法

  1、主頁面布局文件

  2、自定義LinearLayoutView

  3、主界面MainActivity

四、實現效果

一、問題概述

  在編輯框輸入內容時會彈出軟鍵盤,而手機屏幕區域有限往往會遮住輸入界面,我們先看一下問題效果圖:

                                       

  輸入用戶名和密碼時,系統會彈出鍵盤,造成系統鍵盤會擋住文本框的問題,如圖所示:

                                        

  輸入密碼時輸入框被系統鍵盤遮擋了,大大降低了用戶操作體驗,這就是開發中非常常見的軟鍵盤遮擋的問題,該如何解決?

二、簡單解決方案

  方法一

  在你的activity中的oncreate中setContentView之前寫上這個代碼

getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);

  方法二

   在 項目的AndroidManifest.xml文件中界面對應的<activity>里加入

android:windowSoftInputMode="stateVisible|adjustResize" 

  這樣會讓屏幕整體上移。如果加上的 是 android:windowSoftInputMode="adjustPan"這樣鍵盤就會覆蓋屏幕。

關於android:windowSoftInputMode

  activity主窗口與軟鍵盤的交互模式,可以用來避免輸入法面板遮擋問題,Android1.5后的一個新特性。

  這個屬性能影響兩件事情:

    【一】當有焦點產生時,軟鍵盤是隱藏還是顯示

    【二】是否減少活動主窗口大小以便騰出空間放軟鍵盤

   它的設置必須是下面列表中的一個值,或一個”state…”值加一個”adjust…”值的組合。在任一組設置多個值——多個”state…”values,例如&mdash有未定義的結果。各個值之間用|分開。

  例如:

<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。這樣就會把軟鍵盤和輸入框一起滾動了,軟鍵盤會一直處於底部。

 <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.主界面布局文件

<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方法,在該方法實現代碼的核心思想是根據尺寸變化,當變大(軟鍵盤彈出),將某些區域隱藏以給編輯界面預留出足夠顯示空間;當恢復(軟鍵盤關閉),再將隱藏的區域顯示出來

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  接口采用回調機制調用接口的實現方法。

  代碼: 

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);
        //獲得可根據軟鍵盤的彈出/關閉而隱藏和顯示某些區域的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/ 
本文版權歸煙台傑瑞教育科技有限公司和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利。
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM