Android手機軟鍵盤遮蓋輸入框之重新佈局詳解

yangxi_001發表於2014-10-09

在開發Android應用程式時,經常會有登入介面,無非是輸入使用者名稱、密碼進行登入。當輸入框獲取焦點時,會彈出軟鍵盤進行輸入,如果輸入框和登入按鈕佈局在整個佈局檔案的中間或靠下,勢必會被軟鍵盤遮擋,讓人十分鬱悶。網路上的解決方法無非也就那麼三種:

第一、將登入框放在佈局檔案的頂端,軟鍵盤不會遮擋;這種方案雖然能解決問題,但相當不靈活;

第二、在佈局檔案中根節點處加入ScrollView控制元件;

第三、這是我今天要講的內容

首先,繼承RelativeLayout,獲取當前螢幕高度,實現onMesure、onSizeChanged方法;

其次,為自定義的Layout新增檢視偏移的監聽器

最後、在Activity當中實現監聽

[java] view plaincopy
  1. public class InputMethodRelativeLayout extends RelativeLayout {  
  2.     private int width;  
  3.       
  4.     private int height;  
  5.       
  6.     private int screenHeight;  
  7.       
  8.     private boolean sizeChanged = false;  
  9.       
  10.     private OnSizeChangedListener onSizeChangedListener;  
  11.       
  12.     public InputMethodRelativeLayout(Context context, AttributeSet attrs,  
  13.             int defStyle) {  
  14.         super(context, attrs, defStyle);  
  15.         Display localDisplay = ((Activity)context).getWindowManager().getDefaultDisplay();  
  16.         screenHeight = localDisplay.getHeight();  
  17.         // TODO Auto-generated constructor stub  
  18.     }  
  19.   
  20.     public InputMethodRelativeLayout(Context context, AttributeSet attrs) {  
  21.         super(context, attrs);  
  22.         // TODO Auto-generated constructor stub  
  23.     }  
  24.   
  25.     public InputMethodRelativeLayout(Context context) {  
  26.         super(context);  
  27.         // TODO Auto-generated constructor stub  
  28.     }  
  29.   
  30.     @Override  
  31.     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {  
  32.         // TODO Auto-generated method stub  
  33.         this.width = widthMeasureSpec;  
  34.         this.height = heightMeasureSpec;  
  35.         super.onMeasure(widthMeasureSpec, heightMeasureSpec);  
  36.     }  
  37.   
  38.     @Override  
  39.     protected void onSizeChanged(int w, int h, int oldw, int oldh) {  
  40.         // TODO Auto-generated method stub  
[java] view plaincopy
  1. //監聽不為空、寬度不變、當前高度與歷史高度不為0  
  2. if(this.onSizeChangedListener != null && w == oldw && h != 0 && oldh != 0){  
[java] view plaincopy
  1.         if(h >= oldh || (Math.abs(h - oldh) <= 1 * this.screenHeight / 4)){  
  2.             sizeChanged = false;  
  3.         }else if(h <= oldh || (Math.abs(h - oldh) <= 1 * this.screenHeight / 4)){  
  4.             sizeChanged = true;  
  5.         }  
  6.         this.onSizeChangedListener.onSizeChange(sizeChanged);  
  7.         measure(this.width - w + getWidth(), this.height - h + getHeight());  
  8.     }  
  9. }  
  10.   
  11. /**  
  12. * @Title: setOnSizeChangedListener  
  13. * @Description: 為當前佈局設定onSizeChanged監聽器  
  14. * @param sizeChangedListener 
  15. * @return void  
  16. */   
  17. public void setOnSizeChangedListener(OnSizeChangedListener sizeChangedListener) {  
  18.     this.onSizeChangedListener = sizeChangedListener;  
  19. }  
  20.   
  21.   
  22. public abstract interface OnSizeChangedListener{  
  23.       
  24.     public abstract void onSizeChange(boolean flag);  
  25. }  

在Activity中實現OnSizeChangedListener,原理是設定該佈局的paddingTop屬性來控制子View的偏移,如下:

[java] view plaincopy
  1. public class OALogin extends BaseActivity implements InputMethodRelativeLayout.OnSizeChangedListener{  
  2.       
  3.     @InjectView(R.id.loginpage)  
  4.     private InputMethodRelativeLayout layout;  
  5.       
  6.     @Inject  
  7.     private InputMethodManager inputMethodManager;  
  8.     private float density;  
  9.     @Override  
  10.     protected void onCreate(Bundle savedInstanceState) {  
  11.         // TODO Auto-generated method stub  
  12.         super.onCreate(savedInstanceState);  
  13.         setContentView(R.layout.login_page);  
  14.         getSupportActionBar().hide();  
  15.         density = getResources().getDisplayMetrics().density;  
  16.         layout.setOnSizeChangedListener(this);  
  17.     }  
  18.   
  19.     @Override  
  20.     public void onSizeChange(boolean flag) {  
  21.         // TODO Auto-generated method stub  
  22.         if(flag){  
  23.             layout.setPadding(0, -15900);  
  24.         }else  
  25.             layout.setPadding(0000);  
  26.     }  
  27.   
  28.     @Override  
  29.     public boolean onTouchEvent(MotionEvent event) {  
  30.         // TODO Auto-generated method stub  
  31.         if(event.getAction() == MotionEvent.ACTION_UP){  
  32.             inputMethodManager.hideSoftInputFromWindow(getWindow().getDecorView().getWindowToken(),0);  
  33.         }  
  34.         return super.onTouchEvent(event);  
  35.     }  


在AndroidManifest.xml中註冊該Activity,需要注意的是:必須為該Activity設定android:windowSoftInputMode="adjustResize"屬性,當windowSoftInputMode為adjustResiz時,Layout才會呼叫protected void onSizeChanged(int w, int h, int oldw, int oldh)這個方法。

俗話說,無圖無真相,直接上圖(藉助了QQ2012的登入介面)

各位體會下吧!

轉載:http://blog.csdn.net/mark0614/article/details/8912165

http://winuxxan.blog.51cto.com/2779763/522810

http://trinea.iteye.com/blog/1486663

相關文章