仿QQ空间登录,解决键盘挡住输入框的问题

   我们在开发Android应用中,登录和注册界面是少不了的,往往在做登录注册的时候如果给界面加一个LOGO,就有可能把用户名和密码框放在手机屏幕的中间或底部,这样当软键盘弹出的时候,就有可能挡住输入框(往往用户输完用户名和密码还要按返回键盘才能登录),这样用户体验是不好的,我曾今也为这种事情很头疼。首先说一下我原来想到过的解决办法:
      一、原来想到过的解决办法:
    (1)、把登录和输入框让美工做在顶部,不要用LOGO图片类似于淘宝客户端(如下图):这样键盘弹出就不会影响到输入框,但是这样始终不是解决问题的方法(我原来常常让美工设计登录不要设计登录LOGO,呵呵比较自私)

(2)、在布局根结点中加入ScrollView结点,这样当看不见输入框的时候手动滚一下就可以看到,这种方法也可行
(3)、自己给View做一个平移动画,然后处理键盘弹出和消失view的移动,这种设计比较麻烦,而且当View移动了以后要重新计算View的坐标位置,否则拿不到控件的监听事件(表面上看View是移动了,可是移动的只是图片,View上面控件的事件还在原来的位置,比较郁闷)。
(4)、重写RelativeLayout获取当前屏幕高度,实现onMesure、onSizeChanged方法来实现。废话不多说,我们今天采用第(4)种比较正规的方法来实现QQ空间登录页,先上图,无图无真相:以下分别是键盘没有弹出,和键盘弹出时登录情形(以下是我仿写的,布局用的就是QQ空间的布局)
  

二、实现代码(1)、重写RelatvieLayout(自定义View),实现onMesure、onSizeChanged方法。
  1. package com.jun.qqzomelogin;

  2. import android.app.Activity;
  3. import android.content.Context;
  4. import android.util.AttributeSet;
  5. import android.view.Display;
  6. import android.widget.RelativeLayout;
  7. /**
  8. *
  9. * @author junjun
  10. * 自定义布局解决键盘弹出挡住输入框的问题
  11. */
  12. public class InputMethodRelativeLayout extends RelativeLayout {
  13.         private int width;
  14.         protected OnSizeChangedListenner onSizeChangedListenner;
  15.         private boolean sizeChanged  = false; //变化的标志
  16.         private int height;
  17.         private int screenWidth; //屏幕宽度
  18.         private int screenHeight; //屏幕高度

  19.         public InputMethodRelativeLayout(Context paramContext,
  20.                         AttributeSet paramAttributeSet) {
  21.                 super(paramContext, paramAttributeSet);
  22.                 Display localDisplay = ((Activity) paramContext).getWindowManager()
  23.                                 .getDefaultDisplay();
  24.                 this.screenWidth = localDisplay.getWidth() ;
  25.                 this.screenHeight = localDisplay.getHeight();
  26.         }

  27.         public InputMethodRelativeLayout(Context paramContext,
  28.                         AttributeSet paramAttributeSet, int paramInt) {
  29.                 super(paramContext, paramAttributeSet, paramInt);
  30.         }

  31.         @Override
  32.         protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
  33.                 this.width = widthMeasureSpec;
  34.                 this.height = heightMeasureSpec;
  35.                 super.onMeasure(widthMeasureSpec, heightMeasureSpec);
  36.         }
  37.         
  38.         @Override
  39.         public void onSizeChanged(int w, int h, int oldw,
  40.                         int oldh) {
  41.                 //监听不为空、宽度不变、当前高度与历史高度不为0
  42.                 if ((this.onSizeChangedListenner!= null) && (w == oldw) && (oldw != 0)
  43.                                 && (oldh != 0)) {
  44.                         if ((h >= oldh)
  45.                                         || (Math.abs(h - oldh) <= 1 * this.screenHeight / 4)) {
  46.                                 if ((h <= oldh)
  47.                                                 || (Math.abs(h - oldh) <= 1 * this.screenHeight / 4))
  48.                                         return;
  49.                                 this.sizeChanged  = false;
  50.                         } else {
  51.                                 this.sizeChanged  = true;
  52.                         }
  53.                         this.onSizeChangedListenner.onSizeChange(this.sizeChanged ,oldh, h);
  54.                         measure(this.width - w + getWidth(), this.height
  55.                                         - h + getHeight());
  56.                 }
  57.         }
  58.         /**
  59.          * 设置监听事件
  60.          * @param paramonSizeChangedListenner
  61.          */
  62.         public void setOnSizeChangedListenner(
  63.                         InputMethodRelativeLayout.OnSizeChangedListenner paramonSizeChangedListenner) {
  64.                 this.onSizeChangedListenner = paramonSizeChangedListenner;
  65.         }
  66.         /**
  67.          * 大小改变的内部接口
  68.          * @author junjun
  69.          *
  70.          */
  71.         public abstract interface OnSizeChangedListenner {
  72.                 public abstract void onSizeChange(boolean paramBoolean, int w,int h);
  73.         }
  74. }
复制代码
然后把以上布局引入到自己的xml布局中。如QQ空间的登录布局activity_main.xml
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <com.jun.qqzomelogin.InputMethodRelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3.     android:id="@id/loginpage"
  4.     android:layout_width="fill_parent"
  5.     android:layout_height="fill_parent"
  6.     android:background="@drawable/qz_bitmap_login" >

  7.     <LinearLayout
  8.         android:id="@id/login_container"
  9.         android:layout_width="fill_parent"
  10.         android:layout_height="wrap_content"
  11.         android:gravity="center"
  12.         android:orientation="vertical"
  13.         android:paddingLeft="15.0dip"
  14.         android:paddingRight="15.0dip" >
  15.                 <!-- 大logo -->
  16.         <LinearLayout
  17.             android:id="@id/login_logo_layout_v"
  18.             android:layout_width="wrap_content"
  19.             android:layout_height="wrap_content"
  20.             android:layout_marginBottom="34.0dip"
  21.             android:layout_marginTop="43.0dip"
  22.             android:orientation="vertical" >

  23.             <ImageView
  24.                 android:id="@id/login_logoimg"
  25.                 android:layout_width="125.0dip"
  26.                 android:layout_height="125.0dip"
  27.                 android:adjustViewBounds="true"
  28.                 android:gravity="center"
  29.                 android:src="@drawable/logo_login" />

  30.             <ImageView
  31.                 android:layout_width="125.0dip"
  32.                 android:layout_height="35.0dip"
  33.                 android:layout_marginTop="10.0dip"
  34.                 android:adjustViewBounds="true"
  35.                 android:gravity="center"
  36.                 android:src="@drawable/qz_icon_logo_word_login" />
  37.         </LinearLayout>
  38.                 <!-- 小LOGO -->
  39.         <LinearLayout
  40.             android:id="@id/login_logo_layout_h"
  41.             android:layout_width="fill_parent"
  42.             android:layout_height="wrap_content"
  43.             android:layout_marginBottom="11.0dip"
  44.             android:layout_marginTop="16.0dip"
  45.             android:gravity="left|center"
  46.             android:orientation="horizontal"
  47.             android:visibility="gone" >

  48.             <ImageView
  49.                 android:layout_width="42.0dip"
  50.                 android:layout_height="42.0dip"
  51.                 android:adjustViewBounds="true"
  52.                 android:gravity="center"
  53.                 android:src="@drawable/logo_login" />

  54.             <ImageView
  55.                 android:layout_width="93.0dip"
  56.                 android:layout_height="30.0dip"
  57.                 android:layout_marginLeft="5.0dip"
  58.                 android:adjustViewBounds="true"
  59.                 android:src="@drawable/qz_icon_logo_word_login" />
  60.         </LinearLayout>

  61.         <FrameLayout
  62.             android:layout_width="fill_parent"
  63.             android:layout_height="45.0dip" >

  64.             <EditText
  65.                 android:id="@id/qqId"
  66.                 android:layout_width="fill_parent"
  67.                 android:layout_height="fill_parent"
  68.                 android:background="@drawable/qz_bg_container_cell_top_normal"
  69.                 android:hint="QQ号/手机号/邮箱"
  70.                 android:inputType="textEmailAddress"
  71.                 android:maxLength="50"
  72.                 android:paddingLeft="15.0dip"
  73.                 android:paddingRight="80.0dip"
  74.                 android:singleLine="true"
  75.                 android:text=""
  76.                 android:textColor="#ff000000"
  77.                 android:textColorHint="#ffbbbbbb"
  78.                 android:textSize="16.0dip" />

  79.             <ImageView
  80.                 android:id="@id/uin_close"
  81.                 android:layout_width="30.0dip"
  82.                 android:layout_height="45.0dip"
  83.                 android:layout_gravity="right|center"
  84.                 android:layout_marginRight="40.0dip"
  85.                 android:background="@android:color/transparent"
  86.                 android:clickable="true"
  87.                 android:scaleType="center"
  88.                 android:src="@drawable/qz_icon_close"
  89.                 android:visibility="invisible" />

  90.             <ImageView
  91.                 android:id="@id/selectId"
  92.                 android:layout_width="40.0dip"
  93.                 android:layout_height="45.0dip"
  94.                 android:layout_gravity="right|center"
  95.                 android:background="@android:color/transparent"
  96.                 android:clickable="true"
  97.                 android:paddingLeft="5.0dip"
  98.                 android:paddingRight="15.0dip"
  99.                 android:scaleType="center"
  100.                 android:src="@drawable/qz_icon_navbar_drop_down" />
  101.         </FrameLayout>

  102.         <FrameLayout
  103.             android:layout_width="fill_parent"
  104.             android:layout_height="45.0dip" >

  105.             <EditText
  106.                 android:id="@id/passWord"
  107.                 android:layout_width="fill_parent"
  108.                 android:layout_height="45.0dip"
  109.                 android:background="@drawable/qz_bg_container_cell_bottom_normal"
  110.                 android:hint="密码"
  111.                 android:inputType="textPassword"
  112.                 android:maxLength="16"
  113.                 android:paddingLeft="15.0dip"
  114.                 android:paddingRight="15.0dip"
  115.                 android:singleLine="true"
  116.                 android:textColor="#ff000000"
  117.                 android:textColorHint="#ffbbbbbb"
  118.                 android:textSize="16.0dip" />

  119.             <ImageView
  120.                 android:id="@id/psw_close"
  121.                 android:layout_width="30.0dip"
  122.                 android:layout_height="45.0dip"
  123.                 android:layout_gravity="right|center"
  124.                 android:layout_marginRight="15.0dip"
  125.                 android:background="@android:color/transparent"
  126.                 android:clickable="true"
  127.                 android:scaleType="center"
  128.                 android:src="@drawable/qz_icon_close"
  129.                 android:visibility="invisible" />
  130.         </FrameLayout>

  131.         <Button
  132.             android:id="@id/login_btn"
  133.             android:layout_width="fill_parent"
  134.             android:layout_height="45.0dip"
  135.             android:layout_marginTop="12.0dip"
  136.             android:background="@drawable/qz_selector_login"
  137.             android:text="登 录"
  138.             android:textColor="#ffffffff"
  139.             android:textSize="20.0dip" />
  140.     </LinearLayout>

  141.     <ImageButton
  142.         android:id="@id/lineimg"
  143.         android:layout_width="fill_parent"
  144.         android:layout_height="1.0px"
  145.         android:layout_above="@id/reg_and_forget_password_layout"
  146.         android:background="#ffcfcfcf" />

  147.     <LinearLayout
  148.         android:id="@id/reg_and_forget_password_layout"
  149.         android:layout_width="fill_parent"
  150.         android:layout_height="49.0dip"
  151.         android:layout_alignParentBottom="true"
  152.         android:layout_alignParentRight="true"
  153.         android:orientation="horizontal" >

  154.         <Button
  155.             android:id="@id/forget_password_tv"
  156.             android:layout_width="0.0dip"
  157.             android:layout_height="fill_parent"
  158.             android:layout_weight="1.0"
  159.             android:autoLink="all"
  160.             android:background="@drawable/qz_selector_gray"
  161.             android:gravity="center"
  162.             android:text="找回密码"
  163.             android:textColor="#ff666666"
  164.             android:textSize="14.0dip" />

  165.         <ImageButton
  166.             android:layout_width="1.0px"
  167.             android:layout_height="fill_parent"
  168.             android:background="#ffcfcfcf" />

  169.         <Button
  170.             android:id="@id/reg_tv"
  171.             android:layout_width="0.0dip"
  172.             android:layout_height="fill_parent"
  173.             android:layout_weight="1.0"
  174.             android:autoLink="all"
  175.             android:background="@drawable/qz_selector_gray"
  176.             android:gravity="center"
  177.             android:text="新注册"
  178.             android:textColor="#ff666666"
  179.             android:textSize="14.0dip" />
  180.     </LinearLayout>

  181. </com.jun.qqzomelogin.InputMethodRelativeLayout>
复制代码
(2)、在Activity中实现OnSizeChangedListener,原理是设置该布局的paddingTop属性来控制子View的偏移。
  1. package com.jun.qqzomelogin;

  2. import android.app.Activity;
  3. import android.os.Bundle;
  4. import android.view.View;
  5. import android.widget.LinearLayout;
  6. import com.jun.qqzomelogin.InputMethodRelativeLayout.OnSizeChangedListenner;

  7. /**
  8. *
  9. * @author junjun
  10. *
  11. */
  12. public class MainActivity extends Activity implements OnSizeChangedListenner{

  13.         private InputMethodRelativeLayout layout;  
  14.     private LinearLayout boot ;
  15.     private LinearLayout login_logo_layout_h ;
  16.     private LinearLayout login_logo_layout_v ;

  17.         @Override
  18.         protected void onCreate(Bundle savedInstanceState) {
  19.                 super.onCreate(savedInstanceState);
  20.                 setContentView(R.layout.activity_main);
  21.                 //取得InputMethodRelativeLayout组件
  22.                 layout = (InputMethodRelativeLayout) this.findViewById(R.id.loginpage) ;
  23.                 //设置监听事件
  24.         layout.setOnSizeChangedListenner(this) ;
  25.         //取得大LOGO布局
  26.         login_logo_layout_v = (LinearLayout) this.findViewById(R.id.login_logo_layout_v) ;
  27.         //取得小LOGO布局
  28.         login_logo_layout_h = (LinearLayout) this.findViewById(R.id.login_logo_layout_h) ;
  29.         
  30.         //取得找回密码和新注册布局
  31.         boot = (LinearLayout) this.findViewById(R.id.reg_and_forget_password_layout) ;
  32.       
  33.         }

  34.         /**
  35.          * 在Activity中实现OnSizeChangedListener,原理是设置该布局的paddingTop属性来控制子View的偏移
  36.          */
  37.         @Override
  38.         public void onSizeChange(boolean flag,int w ,int h) {  
  39.         if(flag){//键盘弹出时
  40.             layout.setPadding(0, -10, 0, 0);   
  41.             boot.setVisibility(View.GONE) ;
  42.             login_logo_layout_v.setVisibility(View.GONE) ;
  43.             login_logo_layout_h.setVisibility(View.VISIBLE) ;
  44.         }else{ //键盘隐藏时
  45.             layout.setPadding(0, 0, 0, 0);
  46.             boot.setVisibility(View.VISIBLE) ;
  47.             login_logo_layout_v.setVisibility(View.VISIBLE) ;
  48.             login_logo_layout_h.setVisibility(View.GONE) ;
  49.         }
  50.     }
  51. }
复制代码
注意:在AndroidManifest.xml中注册该Activity,需要注意的是:必须为该Activity设置android:windowSoftInputMode="adjustResize"属性,当windowSoftInputMode为adjustResiz时,Layout才会调用protected void onSizeChanged(int w, int h, int oldw, int oldh)这个方法,而且不能是全屏。
 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值