码迷,mamicode.com
首页 > 其他好文 > 详细

解决键盘挡住输入框的问题

时间:2015-04-10 19:29:05      阅读:259      评论:0      收藏:0      [点我收藏+]

标签:

我们在开发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方法。
 
package com.jun.qqzomelogin;

import android.app.Activity;
import android.content.Context;
import android.util.AttributeSet;
import android.view.Display;
import android.widget.RelativeLayout;
/**
 * 
 * @author junjun
 * 自定义布局解决键盘弹出挡住输入框的问题
 */
public class InputMethodRelativeLayout extends RelativeLayout {
        private int width;
        protected OnSizeChangedListenner onSizeChangedListenner;
        private boolean sizeChanged  = false; //变化的标志
        private int height;
        private int screenWidth; //屏幕宽度
        private int screenHeight; //屏幕高度

        public InputMethodRelativeLayout(Context paramContext,
                        AttributeSet paramAttributeSet) {
                super(paramContext, paramAttributeSet);
                Display localDisplay = ((Activity) paramContext).getWindowManager()
                                .getDefaultDisplay();
                this.screenWidth = localDisplay.getWidth() ;
                this.screenHeight = localDisplay.getHeight();
        }

        public InputMethodRelativeLayout(Context paramContext,
                        AttributeSet paramAttributeSet, int paramInt) {
                super(paramContext, paramAttributeSet, paramInt);
        }

        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
                this.width = widthMeasureSpec;
                this.height = heightMeasureSpec;
                super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        }
        
        @Override
        public void onSizeChanged(int w, int h, int oldw,
                        int oldh) {
                //监听不为空、宽度不变、当前高度与历史高度不为0 
                if ((this.onSizeChangedListenner!= null) && (w == oldw) && (oldw != 0)
                                && (oldh != 0)) {
                        if ((h >= oldh)
                                        || (Math.abs(h - oldh) <= 1 * this.screenHeight / 4)) {
                                if ((h <= oldh)
                                                || (Math.abs(h - oldh) <= 1 * this.screenHeight / 4))
                                        return;
                                this.sizeChanged  = false;
                        } else {
                                this.sizeChanged  = true;
                        }
                        this.onSizeChangedListenner.onSizeChange(this.sizeChanged ,oldh, h);
                        measure(this.width - w + getWidth(), this.height
                                        - h + getHeight());
                }
        }
        /**
         * 设置监听事件
         * @param paramonSizeChangedListenner
         */
        public void setOnSizeChangedListenner(
                        InputMethodRelativeLayout.OnSizeChangedListenner paramonSizeChangedListenner) {
                this.onSizeChangedListenner = paramonSizeChangedListenner;
        }
        /**
         * 大小改变的内部接口
         * @author junjun
         *
         */
        public abstract interface OnSizeChangedListenner {
                public abstract void onSizeChange(boolean paramBoolean, int w,int h);
        }
}

然后把以上布局引入到自己的xml布局中。如QQ空间的登录布局activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<com.jun.qqzomelogin.InputMethodRelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@id/loginpage"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="@drawable/qz_bitmap_login" >

    <LinearLayout
        android:id="@id/login_container"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:orientation="vertical"
        android:paddingLeft="15.0dip"
        android:paddingRight="15.0dip" >
                <!-- 大logo -->
        <LinearLayout
            android:id="@id/login_logo_layout_v"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="34.0dip"
            android:layout_marginTop="43.0dip"
            android:orientation="vertical" >

            <ImageView
                android:id="@id/login_logoimg"
                android:layout_width="125.0dip"
                android:layout_height="125.0dip"
                android:adjustViewBounds="true"
                android:gravity="center"
                android:src="@drawable/logo_login" />

            <ImageView
                android:layout_width="125.0dip"
                android:layout_height="35.0dip"
                android:layout_marginTop="10.0dip"
                android:adjustViewBounds="true"
                android:gravity="center"
                android:src="@drawable/qz_icon_logo_word_login" />
        </LinearLayout>
                <!-- 小LOGO -->
        <LinearLayout
            android:id="@id/login_logo_layout_h"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_marginBottom="11.0dip"
            android:layout_marginTop="16.0dip"
            android:gravity="left|center"
            android:orientation="horizontal"
            android:visibility="gone" >

            <ImageView
                android:layout_width="42.0dip"
                android:layout_height="42.0dip"
                android:adjustViewBounds="true"
                android:gravity="center"
                android:src="@drawable/logo_login" />

            <ImageView
                android:layout_width="93.0dip"
                android:layout_height="30.0dip"
                android:layout_marginLeft="5.0dip"
                android:adjustViewBounds="true"
                android:src="@drawable/qz_icon_logo_word_login" />
        </LinearLayout>

        <FrameLayout
            android:layout_width="fill_parent"
            android:layout_height="45.0dip" >

            <EditText
                android:id="@id/qqId"
                android:layout_width="fill_parent"
                android:layout_height="fill_parent"
                android:background="@drawable/qz_bg_container_cell_top_normal"
                android:hint="QQ号/手机号/邮箱"
                android:inputType="textEmailAddress"
                android:maxLength="50"
                android:paddingLeft="15.0dip"
                android:paddingRight="80.0dip"
                android:singleLine="true"
                android:text=""
                android:textColor="#ff000000"
                android:textColorHint="#ffbbbbbb"
                android:textSize="16.0dip" />

            <ImageView
                android:id="@id/uin_close"
                android:layout_width="30.0dip"
                android:layout_height="45.0dip"
                android:layout_gravity="right|center"
                android:layout_marginRight="40.0dip"
                android:background="@android:color/transparent"
                android:clickable="true"
                android:scaleType="center"
                android:src="@drawable/qz_icon_close"
                android:visibility="invisible" />

            <ImageView
                android:id="@id/selectId"
                android:layout_width="40.0dip"
                android:layout_height="45.0dip"
                android:layout_gravity="right|center"
                android:background="@android:color/transparent"
                android:clickable="true"
                android:paddingLeft="5.0dip"
                android:paddingRight="15.0dip"
                android:scaleType="center"
                android:src="@drawable/qz_icon_navbar_drop_down" />
        </FrameLayout>

        <FrameLayout
            android:layout_width="fill_parent"
            android:layout_height="45.0dip" >

            <EditText
                android:id="@id/passWord"
                android:layout_width="fill_parent"
                android:layout_height="45.0dip"
                android:background="@drawable/qz_bg_container_cell_bottom_normal"
                android:hint="密码"
                android:inputType="textPassword"
                android:maxLength="16"
                android:paddingLeft="15.0dip"
                android:paddingRight="15.0dip"
                android:singleLine="true"
                android:textColor="#ff000000"
                android:textColorHint="#ffbbbbbb"
                android:textSize="16.0dip" />

            <ImageView
                android:id="@id/psw_close"
                android:layout_width="30.0dip"
                android:layout_height="45.0dip"
                android:layout_gravity="right|center"
                android:layout_marginRight="15.0dip"
                android:background="@android:color/transparent"
                android:clickable="true"
                android:scaleType="center"
                android:src="@drawable/qz_icon_close"
                android:visibility="invisible" />
        </FrameLayout>

        <Button
            android:id="@id/login_btn"
            android:layout_width="fill_parent"
            android:layout_height="45.0dip"
            android:layout_marginTop="12.0dip"
            android:background="@drawable/qz_selector_login"
            android:text="登 录"
            android:textColor="#ffffffff"
            android:textSize="20.0dip" />
    </LinearLayout>

    <ImageButton
        android:id="@id/lineimg"
        android:layout_width="fill_parent"
        android:layout_height="1.0px"
        android:layout_above="@id/reg_and_forget_password_layout"
        android:background="#ffcfcfcf" />

    <LinearLayout
        android:id="@id/reg_and_forget_password_layout"
        android:layout_width="fill_parent"
        android:layout_height="49.0dip"
        android:layout_alignParentBottom="true"
        android:layout_alignParentRight="true"
        android:orientation="horizontal" >

        <Button
            android:id="@id/forget_password_tv"
            android:layout_width="0.0dip"
            android:layout_height="fill_parent"
            android:layout_weight="1.0"
            android:autoLink="all"
            android:background="@drawable/qz_selector_gray"
            android:gravity="center"
            android:text="找回密码"
            android:textColor="#ff666666"
            android:textSize="14.0dip" />

        <ImageButton
            android:layout_width="1.0px"
            android:layout_height="fill_parent"
            android:background="#ffcfcfcf" />

        <Button
            android:id="@id/reg_tv"
            android:layout_width="0.0dip"
            android:layout_height="fill_parent"
            android:layout_weight="1.0"
            android:autoLink="all"
            android:background="@drawable/qz_selector_gray"
            android:gravity="center"
            android:text="新注册"
            android:textColor="#ff666666"
            android:textSize="14.0dip" />
    </LinearLayout>

</com.jun.qqzomelogin.InputMethodRelativeLayout>

(2)、在Activity中实现OnSizeChangedListener,原理是设置该布局的paddingTop属性来控制子View的偏移

package com.jun.qqzomelogin;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.LinearLayout;
import com.jun.qqzomelogin.InputMethodRelativeLayout.OnSizeChangedListenner;

/**
 * 
 * @author junjun
 *
 */
public class MainActivity extends Activity implements OnSizeChangedListenner{

        private InputMethodRelativeLayout layout;  
    private LinearLayout boot ;
    private LinearLayout login_logo_layout_h ;
    private LinearLayout login_logo_layout_v ;

        @Override
        protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_main);
                //取得InputMethodRelativeLayout组件
                layout = (InputMethodRelativeLayout) this.findViewById(R.id.loginpage) ;
                //设置监听事件
        layout.setOnSizeChangedListenner(this) ;
        //取得大LOGO布局
        login_logo_layout_v = (LinearLayout) this.findViewById(R.id.login_logo_layout_v) ;
        //取得小LOGO布局
        login_logo_layout_h = (LinearLayout) this.findViewById(R.id.login_logo_layout_h) ;
        
        //取得找回密码和新注册布局
        boot = (LinearLayout) this.findViewById(R.id.reg_and_forget_password_layout) ;
       
        }

        /**
         * 在Activity中实现OnSizeChangedListener,原理是设置该布局的paddingTop属性来控制子View的偏移
         */
        @Override
        public void onSizeChange(boolean flag,int w ,int h) {  
        if(flag){//键盘弹出时
            layout.setPadding(0, -10, 0, 0);   
            boot.setVisibility(View.GONE) ;
            login_logo_layout_v.setVisibility(View.GONE) ;
            login_logo_layout_h.setVisibility(View.VISIBLE) ;
        }else{ //键盘隐藏时
            layout.setPadding(0, 0, 0, 0); 
            boot.setVisibility(View.VISIBLE) ;
            login_logo_layout_v.setVisibility(View.VISIBLE) ;
            login_logo_layout_h.setVisibility(View.GONE) ;
        }
    } 
}

在AndroidManifest.xml中注册该Activity,需要注意的是:必须为该Activity设置 android:windowSoftInputMode="adjustResize"属性,当windowSoftInputMode为 adjustResiz时,Layout才会调用protected void onSizeChanged(int w, int h, int oldw, int oldh)这个方法,而且不能是全屏。好了就到这里,希望对你有帮助。

解决键盘挡住输入框的问题

标签:

原文地址:http://www.cnblogs.com/feng-de-wei-xiao/p/4415341.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!