android带头像的登录界面键盘遮挡问题解决新思路

来源:互联网 发布:萧然网络问政 编辑:程序博客网 时间:2024/06/11 14:19

先看效果:
这里写图片描述 这里写图片描述
键盘弹出后总结起来主要是两点:

  1. 输入区域包括登录按钮整体上抬

  2. 原来的头像缩小到右上角

整体上抬

做到这个很简单,仅仅需要在AndroidManifest中对应的Activity的元素中加入windowSoftInputMode属性:

<activity            android:name=".activity.LoginActivity"            android:label="@string/login_button_text"            android:launchMode="singleTask"            android:windowSoftInputMode="stateHidden|stateUnchanged|adjustResize"/>

于是运行后跑起来发现登录界面变成了这样:
这里写图片描述
这显然不是我们想要的,虽然整体上抬了,但是登录按钮却依然被遮盖。输入完毕用户名密码后必须要先关闭输入法才能点击到登录按钮,等于多了一步操作。

那么到这里我们就想到了是否可以拿这个头像做文章?可以看到头像占据了很大的空间,那么是否可以在键盘抬起的时候我们调整头像的大小以及位置呢?答案是可以得,但是首先我们要做的是知道何时键盘打开或者关闭,其次再来改变这个头像。
监控键盘的状态

这个Activity的根布局是一个RelativeLayout (文章最后会给出完整的布局):

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto"    android:id="@+id/login_root"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:background="@drawable/shape_login_bg_start">    ...</RelativeLayout>

由于上面键盘抬起的时候那个checkbox依然可以点击到,所以我们这里做个测试,键盘分别是关闭和打开的时候,点击checkbox来计算下这个根布局RelativeLayout的高度是否在变化,添加的测试代码为:

@Bind(R.id.login_root)RelativeLayout mRoot;。。。pwdCheck.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {            @Override            public void onCheckedChanged(CompoundButton compoundButton, boolean b) {                L.d("root view height : " + mRoot.getHeight());            }        });

依次在键盘隐藏和抬起的时候点击checkbox来查看下log:

11-25 14:27:28.710 5623-5623/com.qianmi.shine D/shine: root view height : 1860
11-25 14:27:31.240 5623-5623/com.qianmi.shine D/shine: root view height : 1033

发现这个RelativeLayout的高度在键盘隐藏和抬起的时候是在变化的,那么它的onSideChange这个函数肯定是一直在被调用的。所以我们可以自己继承一个RelativeLayout,同时复写它的onSizeChange函数,通过高度的变化来判断键盘是否打开,同时暴露出一个接口给Activity实现,让Activity在该接口中根据键盘的状态来改变头像的布局。这个自定义的继承自RelativeLayout的控件如下:

public class ResizeRelativeLayout extends RelativeLayout {    public static final int HIDE = 0;    public static final int SHOW = 1;    private Handler mainHandler = new Handler();    public ResizeRelativeLayout(Context context) {        super(context);        // TODO Auto-generated constructor stub    }    public ResizeRelativeLayout(Context context, AttributeSet attrs) {        super(context, attrs);        // TODO Auto-generated constructor stub    }    @Override    protected void onSizeChanged(int w,final int h, int oldw,final int oldh) {        // TODO Auto-generated method stub        super.onSizeChanged(w, h, oldw, oldh);        mainHandler.post(new Runnable() {            @Override            public void run() {                if (oldh - h > 50){                    keyBordStateListener.onStateChange(SHOW);                }                else {                    if(keyBordStateListener != null){                        keyBordStateListener.onStateChange(HIDE);                    }                }            }        });    }    @Override    protected void onLayout(boolean changed, int l, int t, int r, int b) {        // TODO Auto-generated method stub        super.onLayout(changed, l, t, r, b);    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        // TODO Auto-generated method stub        super.onMeasure(widthMeasureSpec, heightMeasureSpec);    }    private KeyBordStateListener  keyBordStateListener;    public void setKeyBordStateListener(KeyBordStateListener keyBordStateListener) {        this.keyBordStateListener = keyBordStateListener;    }    public interface KeyBordStateListener{        public void onStateChange(int state);    }}

在onSizeChange中判断当前的height如果大于过去的height,即说明键盘是隐藏了;反之就是显示了。

Activity对应的修改如下:

@Bind(R.id.login_root)ResizeRelativeLayout mRoot;@Override    public void onStateChange(int state) {        switch (state) {            case ResizeRelativeLayout.HIDE:                //TODO when keyboard is hide                break;            case ResizeRelativeLayout.SHOW:                //TODO when keyboard is show                break;        }    }mRoot.setKeyBordStateListener(this);

头像的变化

有了键盘状态的监听后,头像变化的处理就变的随性了。为了简单起见,这里我们在根布局的右上角同样放置了一个ImageView,他和原来的头像ImageView显示同样的内容。当键盘弹起的时候显示右上角的头像而隐藏中间的大头像(注意一定要设置为Gone,这样子的话布局在onMeasure的时候才会把原来属于大头像的空间腾出来从而让下方的输入框和登录按钮向上抬起的更多);当键盘隐藏的时候则显示中间大头像而隐藏右上角的头像。

修改onStateChange为:

@Bind(R.id.card_small)CardView cardSmall;@Bind(R.id.card)CardView card;@Override    public void onStateChange(int state) {        switch (state) {            case ResizeRelativeLayout.HIDE:                card.setVisibility(View.VISIBLE);                cardSmall.setVisibility(View.INVISIBLE);                break;            case ResizeRelativeLayout.SHOW:                card.setVisibility(View.GONE);                cardSmall.setVisibility(View.VISIBLE);                break;        }    }

(这里需要注明的是,为了让ImageView带阴影,特意用了一个CardView来包含ImageView,因为CardView自带阴影效果,所以这里即对CardView进行可见性变化,具体见文末的布局完整文件;其次这里为了做出带圆角的ImageView,用了别的人一个控件,RoundedImageView,请参考https://github.com/vinc3m1/RoundedImageView)

如果需要做的带感的话,可以对中间的大头像做如下的属性动画(一定要是属性动画,因为这样才能真正的“移动”而腾出空间)而不用显示另一个右上角的小头像:

  1. ImageView通过scaleX和scaleY来缩小size

  2. ImageView通过translateX和translateY来移动到右上角

附完整的布局文件:

<?xml version="1.0" encoding="utf-8"?><com.qianmi.shine.widget.ResizeRelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto"    android:id="@+id/login_root"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:background="@drawable/shape_login_bg_start">    <android.support.v7.widget.CardView        android:id="@+id/card_small"        android:layout_width="40dp"        android:layout_height="40dp"        android:layout_alignParentRight="true"        android:layout_alignParentTop="true"        android:layout_margin="20dp"        android:visibility="invisible"        app:cardBackgroundColor="@color/transparent"        app:cardCornerRadius="2dp"        app:cardElevation="2dp">        <com.makeramen.roundedimageview.RoundedImageView            android:id="@+id/profile_small"            android:layout_width="match_parent"            android:layout_height="match_parent"            android:background="@drawable/login_btn_photo_l"            android:scaleType="fitCenter"            android:src="@drawable/photo_l"            app:riv_corner_radius="2dp" />    </android.support.v7.widget.CardView>    <LinearLayout        android:layout_width="315dp"        android:layout_height="wrap_content"        android:layout_centerInParent="true"        android:layout_marginLeft="20dp"        android:layout_marginRight="20dp"        android:orientation="vertical">        <android.support.v7.widget.CardView            android:id="@+id/card"            android:layout_width="98dp"            android:layout_height="98dp"            android:layout_gravity="center_horizontal"            android:layout_marginBottom="@dimen/login_input_height"            app:cardBackgroundColor="@color/transparent"            app:cardCornerRadius="2dp"            app:cardElevation="2dp">            <com.makeramen.roundedimageview.RoundedImageView                android:id="@+id/profile"                android:layout_width="match_parent"                android:layout_height="match_parent"                android:background="@drawable/login_btn_photo_l"                android:scaleType="fitCenter"                android:src="@drawable/photo_l"                app:riv_corner_radius="2dp" />        </android.support.v7.widget.CardView>        <EditText            android:id="@+id/et_login_username"            android:layout_width="match_parent"            android:layout_height="@dimen/login_input_height"            android:layout_marginLeft="@dimen/login_margin_left"            android:background="@drawable/shape_solid_transparent"            android:drawableLeft="@drawable/login_icon_company"            android:drawablePadding="@dimen/login_padding"            android:hint="@string/login_input_hint_username"            android:inputType="textPersonName"            android:singleLine="true"            android:textColor="@color/ColorPrimary"            android:textColorHint="@color/text_hint_color"            android:textCursorDrawable="@drawable/common_input_cursor"            android:textSize="@dimen/login_input_text_size" />        <TextView            android:id="@+id/line1"            style="@style/common_login_horizontalLine_matchParent_normal" />        <EditText            android:id="@+id/et_login_employ_name"            android:layout_width="match_parent"            android:layout_height="@dimen/login_input_height"            android:layout_marginLeft="@dimen/login_margin_left"            android:background="@drawable/shape_solid_transparent"            android:drawableLeft="@drawable/login_icon_man"            android:drawablePadding="@dimen/login_padding"            android:hint="@string/login_input_hint_employ"            android:inputType="textPersonName"            android:singleLine="true"            android:textColor="@color/ColorPrimary"            android:textColorHint="@color/text_hint_color"            android:textCursorDrawable="@drawable/common_input_cursor"            android:textSize="@dimen/login_input_text_size" />        <TextView            android:id="@+id/line2"            style="@style/common_login_horizontalLine_matchParent_normal" />        <EditText            android:id="@+id/et_login_pwd"            android:layout_width="match_parent"            android:layout_height="@dimen/login_input_height"            android:layout_marginLeft="@dimen/login_margin_left"            android:background="@drawable/shape_solid_transparent"            android:drawableLeft="@drawable/login_icon_lock"            android:drawablePadding="@dimen/login_padding"            android:hint="@string/login_input_hint_pwd"            android:inputType="textPassword"            android:singleLine="true"            android:textColor="@color/ColorPrimary"            android:textColorHint="@color/text_hint_color"            android:textCursorDrawable="@drawable/common_input_cursor"            android:textSize="@dimen/login_input_text_size" />        <TextView            android:id="@+id/line3"            style="@style/common_login_horizontalLine_matchParent_normal" />        <CheckBox            android:id="@+id/remember_pwd"            style="@style/RememberPasswordCheckBox"            android:layout_marginLeft="@dimen/login_margin_left"            android:text="@string/login_remember_pwd" />        <Button            android:id="@+id/btn_login"            android:layout_width="match_parent"            android:layout_height="46dp"            android:layout_gravity="center_horizontal"            android:layout_marginTop="32dp"            android:background="@drawable/common_green_btn_selector"            android:focusable="true"            android:text="@string/login_button_text"            android:textColor="@color/text_button_login"            android:textSize="@dimen/login_btn_text_size" />    </LinearLayout></com.qianmi.shine.widget.ResizeRelativeLayout>

转载:http://www.cnblogs.com/soaringEveryday/p/4994666.html

这个解决问题的思路与墨迹天气我的界面的效果有相似之处,如下所示:
这里写图片描述

http://blog.csdn.net/jdsjlzx/article/details/50616299

2 0
原创粉丝点击