当前位置: 代码迷 >> Android >> Android手机软键盘掩饰输入框之重新布局详解
  详细解决方案

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

热度:38   发布时间:2016-04-28 04:46:06.0
Android手机软键盘遮盖输入框之重新布局详解

?????? 在开发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. [email protected]:?setOnSizeChangedListener??
  13. [email protected]:?为当前布局设置onSizeChanged监听器??
  14. [email protected]?
  15. [email protected]?
  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,?-159,?0,?0);??
  24. ????????}else??
  25. ????????????layout.setPadding(0,?0,?0,?0);??
  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的登录界面)

各位体会下吧!

  相关解决方案