Android手机软键盘遮盖输入框之重新布局详解

       在开发Android应用程序时,经常会有登录界面,无非是输入用户名、密码进行登录。当输入框获取焦点时,会弹出软键盘进行输入,如果输入框和登录按钮布局在整个布局文件的中间或靠下,势必会被软键盘遮挡,让人十分郁闷。网络上的解决方法无非也就那么三种:

第一、将登录框放在布局文件的顶端,软键盘不会遮挡;这种方案虽然能解决问题,但相当不灵活;

第二、在布局文件中根节点处加入ScrollView控件;

第三、这是我今天要讲的内容

首先,继承RelativeLayout,获取当前屏幕高度,实现onMesure、onSizeChanged方法;

其次,为自定义的Layout添加视图偏移的监听器

最后、在Activity当中实现监听

代码

[java]  view plain copy
 
  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 plain copy
 
  1. //监听不为空、宽度不变、当前高度与历史高度不为0  
  2. if(this.onSizeChangedListener != null && w == oldw && h != 0 && oldh != 0){  
[java]  view plain copy
 
  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 plain copy
 
  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的登录界面)

各位体会下吧!

猜你喜欢

转载自lishuaishuai.iteye.com/blog/2092663