Android实现登陆页logo随键盘收放动态伸缩(完美解决键盘弹出遮挡控件的问题)_Android

在最近的两个项目中,项目需求要求我们实现 /*登陆页面的内容能够随着键盘的弹出而被顶上去,避免键盘遮挡住登陆按钮*/ 这样的效果,宝宝心里苦呀,本来半天搞定的事还非得折腾一下,好吧我妥协,毕竟我还是一只非常注重用户体验的猿。

那就做吧,初步定下的方案是输入框和登陆按钮大小不变,在键盘弹出的时候让logo的大小和位置进行改变,从而给键盘腾出位置,当然在键盘收起的时候还要给它还原一下,就像什么都没发生一样,嗯对,就是这样,说了这么多,放张图先感受一下效果吧:

接下来上正餐,布局上比较简单,注意给图片外边套上一个合身的linearlayout就好,因为待会要靠它改变logo的位置,布局代码如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:tools="http://schemas.android.com/tools"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:background="@color/white"
 tools:context=".login.LoginActivity"
 android:orientation="vertical"
 android:id="@+id/ll_login_root">
 <LinearLayout
  android:orientation="vertical"
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:layout_marginTop="90dp"
  android:id="@+id/ll_login_logobg"
  android:layout_marginBottom="50dp">
  <ImageView
   android:layout_width="160dp"
   android:layout_height="160dp"
   android:id="@+id/iv_login_logo"
   android:background="@mipmap/login_logo"
   android:layout_gravity="center_horizontal" />
 </LinearLayout>
 <LinearLayout
  android:orientation="vertical"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:layout_marginLeft="50dp"
  android:layout_marginRight="50dp">
  <LinearLayout
   android:orientation="horizontal"
   android:layout_width="match_parent"
   android:layout_height="50dp">
   <ImageView
    android:layout_width="45dp"
    android:layout_height="45dp"
    android:background="@mipmap/login_phone"
    android:id="@+id/imageView2"
    android:layout_gravity="bottom" />
   <EditText
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:inputType="phone"
    android:ems="10"
    android:id="@+id/et_login_phone"
    android:layout_gravity="center"
    android:hint="请输入手机号"
    android:background="@null"
    android:maxLength="11"/>
  </LinearLayout>
  <LinearLayout
   android:orientation="vertical"
   android:layout_width="match_parent"
   android:layout_height="1dp"
   android:background="@color/text_gray"></LinearLayout>
  <LinearLayout
   android:orientation="horizontal"
   android:layout_width="match_parent"
   android:layout_height="50dp" >
   <ImageView
    android:layout_width="45dp"
    android:layout_height="45dp"
    android:background="@mipmap/login_password"
    android:id="@+id/imageView3"
    android:layout_gravity="bottom" />
   <EditText
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:inputType="phone"
    android:ems="10"
    android:id="@+id/et_login_code"
    android:layout_gravity="center"
    android:layout_weight="1"
    android:hint="请输入验证码"
    android:background="@null"
    android:maxLength="6"/>
   <Button
    android:layout_width="90dp"
    android:layout_height="30dp"
    android:text="获取验证码"
    android:textColor="@color/white"
    android:id="@+id/bt_login_getcode"
    android:background="@mipmap/login_button_blue"
    android:layout_gravity="center_vertical"
    android:textSize="14dp" />
  </LinearLayout>
  <LinearLayout
   android:orientation="vertical"
   android:layout_width="match_parent"
   android:layout_height="1dp"
   android:background="@color/text_gray"
   android:layout_marginBottom="10dp" />
  <LinearLayout
   android:orientation="horizontal"
   android:layout_width="match_parent"
   android:layout_height="20dp"
   android:id="@+id/ll_login_warning"
   android:visibility="gone">
   <ImageView
    android:layout_width="25dp"
    android:layout_height="25dp"
    android:background="@mipmap/login_warning"
    android:id="@+id/imageView"
    android:layout_gravity="center_vertical" />
   <TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textAppearance="?android:attr/textAppearanceMedium"
    android:text="请输入验证码"
    android:id="@+id/tv_login_wraning"
    android:layout_gravity="center_vertical"
    android:textColor="@color/text_red"
    android:textSize="13dp" />
  </LinearLayout>
  <Button
   android:layout_width="match_parent"
   android:layout_height="40dp"
   android:textColor="@color/white"
   android:id="@+id/bt_login_submit"
   android:background="@mipmap/login_button_gray"
   android:text="登 录"
   android:textSize="18dp"
   android:layout_marginTop="10dp" />
 </LinearLayout>
</LinearLayout>

主代码如下,我会把注释添加到代码中,因为是整个模块的代码所以也会有一些其他功能在里边:

package com.millionideas.cm.login;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.millionideas.cm.R;
import com.millionideas.cm.home.HomeActivity;
import com.millionideas.cm.main.BaseActivity;
import com.millionideas.cm.tools.TimeCountUtils;
import org.xutils.view.annotation.ContentView;
import org.xutils.view.annotation.Event;
import org.xutils.view.annotation.ViewInject;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@ContentView(R.layout.activity_login)
public class LoginActivity extends BaseActivity implements View.OnLayoutChangeListener{
//用xUtils进行控件绑定
 @ViewInject(R.id.iv_login_logo)
 ImageView iv_login_logo;
 @ViewInject(R.id.ll_login_logobg)
 LinearLayout ll_login_logobg;
 @ViewInject(R.id.et_login_phone)
 EditText et_login_phone;
 @ViewInject(R.id.et_login_code)
 EditText et_login_code;
 @ViewInject(R.id.ll_login_warning)
 LinearLayout ll_login_warning;
 @ViewInject(R.id.tv_login_wraning)
 TextView tv_login_wraning;
 @ViewInject(R.id.bt_login_getcode)
 Button bt_login_getcode;
 @ViewInject(R.id.bt_login_submit)
 Button bt_login_submit;
 @ViewInject(R.id.ll_login_root)
 LinearLayout activityRootView;//需要操作的布局
 private TimeCountUtils timeCountUtils;
 private Matcher phone_num;
 private Pattern phonenumber;
 private ProgressDialog progressDialog;
 private Handler handler;
 private int screenHeight = 0;//屏幕高度
 private int keyHeight = 0; //软件盘弹起后所占高度
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  screenHeight = this.getWindowManager().getDefaultDisplay().getHeight(); //获取屏幕高度
  keyHeight = screenHeight / 3;//弹起高度为屏幕高度的1/3
  timeCountUtils = new TimeCountUtils(LoginActivity.this, 60000, 1000, bt_login_getcode);//时间工具类用以实现倒计时
  progressDialog=new ProgressDialog(this);//对话框
  handler=new Handler();
  bt_login_submit.setClickable(false);
  et_login_phone.addTextChangedListener(new TextWatcher() {//为edittext添加文本改变监听,根据是否有文本输入更改确认按钮的背景颜色
   @Override
   public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
   }
   @Override
   public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
   }
   @Override
   public void afterTextChanged(Editable editable) {
    if (!et_login_phone.getText().toString().equals("")){
     bt_login_submit.setClickable(true);
     bt_login_submit.setBackgroundResource(R.drawable.login_button);
    }else {
     bt_login_submit.setClickable(false);
     bt_login_submit.setBackgroundResource(R.mipmap.login_button_gray);
    }
   }
  });
 }
 //xUtils的事件处理
 @Event(value = {R.id.bt_login_submit, R.id.bt_login_getcode}, type = View.OnClickListener.class)
 private void onClick(View view) {
  switch (view.getId()) {
   case R.id.bt_login_submit://确认按钮事件
    if (!CheckPhone(et_login_phone).matches()) {//判断手机号格式
     ll_login_warning.setVisibility(View.VISIBLE);
     tv_login_wraning.setText("手机号码格式不正确");
    } else if (!et_login_code.getText().toString().equals("000")) {//验证码判断,为方便测试设置了默认值
     ll_login_warning.setVisibility(View.VISIBLE);
     tv_login_wraning.setText("验证码不正确");
    } else {//条件全部满足,开始登陆
     ll_login_warning.setVisibility(View.GONE);
     progressDialog.setMessage("正在登录…");
     progressDialog.show();//弹出加载对话框
     handler.postDelayed(new Runnable() {//设置一个1s的延时操作模拟登陆的过程
      @Override
      public void run() {//登陆成功关掉对话框,跳转页面,关掉本页
       progressDialog.dismiss();//不能用hide
       Intent intent=new Intent(LoginActivity.this, HomeActivity.class);
       startActivity(intent);
       LoginActivity.this.finish();
      }
     },1000);
    }
    break;
   case R.id.bt_login_getcode:
    if (CheckPhone(et_login_phone).matches()) {//手机号正确则获取验证码,开启倒计时
     ll_login_warning.setVisibility(View.GONE);
     bt_login_getcode.setBackgroundResource(R.mipmap.login_button_gray);
     timeCountUtils.start();
    } else {
     ll_login_warning.setVisibility(View.VISIBLE);
     tv_login_wraning.setText("手机号码格式不正确");
    }
    break;
  }
 }
 public Matcher CheckPhone(EditText editText) {//判断手机号格式
  phonenumber = Pattern
    .compile("^[1][3-8][0-9]{9}$");
  phone_num = phonenumber.matcher(editText.getText()
    .toString());
  return phone_num;
 }
 @Override
 protected void onResume() {
  super.onResume();
  activityRootView.addOnLayoutChangeListener(this);//给需要操作的布局设置监听
 }
 @Override
 public void onLayoutChange(View v, int left, int top, int right,
        int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
  /* old是改变前的左上右下坐标点值,没有old的是改变后的左上右下坐标点值
  现在认为只要控件将Activity向上推的高度超过了1/3屏幕高,就认为软键盘弹起*/
  if (oldBottom != 0 && bottom != 0 && (oldBottom - bottom > keyHeight)) {
   ViewGroup.LayoutParams params = iv_login_logo.getLayoutParams();//获取布局,设置键盘弹起后logo的宽高
   params.height = 300;
   params.width = 300;
   iv_login_logo.setLayoutParams(params);
   LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(ll_login_logobg.getLayoutParams());
   lp.setMargins(0, 90, 0, 50);//设置包含logo的布局的位置
   ll_login_logobg.setLayoutParams(lp);
  } else if (oldBottom != 0 && bottom != 0 && (bottom - oldBottom > keyHeight)) {//键盘收回后,logo恢复原来大小,位置同样回到初始位置
   ViewGroup.LayoutParams params = iv_login_logo.getLayoutParams();
   params.height = 480;
   params.width = 480;
   iv_login_logo.setLayoutParams(params);
   LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(ll_login_logobg.getLayoutParams());
   lp.setMargins(0, 270, 0, 150);
   ll_login_logobg.setLayoutParams(lp);
  }
 }
} 

以上所述是小编给大家介绍的Android实现登陆页logo随键盘收放动态伸缩(完美解决键盘弹出遮挡控件的问题),希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对网站的支持!

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索android
软键盘遮挡
android键盘遮挡控件、andr0id自定义控件、ios 键盘遮挡、h5输入框被键盘遮挡、html5 键盘遮挡输入框,以便于您获取更多的相关知识。

时间: 2024-09-11 22:08:40

Android实现登陆页logo随键盘收放动态伸缩(完美解决键盘弹出遮挡控件的问题)_Android的相关文章

Android解决dialog弹出时无法捕捉Activity的back事件的方法

  本文实例讲述了Android解决dialog弹出时无法捕捉Activity的back事件的方法.分享给大家供大家参考.具体分析如下: 在一些情况下,我们需要捕捉back键事件,然后在捕捉到的事件里写入我们需要进行的处理,通常可以采用下面三种办法捕捉到back事件: 1)重写onKeyDown或者onKeyUp方法 2)重写onBackPressed方法 3)重写dispatchKeyEvent方法 这三种办法有什么区别在这里不进行阐述,有兴趣的朋友可以查阅相关资料. 然而在有dialog弹出

Android实现底部弹出PopupWindow背景逐渐变暗效果_Android

在Android开发中,经常需要通过点击某个按钮弹出对话框或者选择框,通过Dialog或者PopupMenu.PopupWindow都能实现. 这里主要介绍后两者:PopupMenu.PopupWindow的实现. 先看两个效果图上边PopupMenu,下边PopupWindow: PopupMenu PopupWindow 一.PopupMenu实现: PopupMenu实现起来比较简单,主要用来实现根据按钮附近弹出的对话框. 首先定义一个menu文件\res\menu\headmenu.xm

android通过socket通信实现客户端读取服务端的二进制数据,并展示在textview控件上

问题描述 android通过socket通信实现客户端读取服务端的二进制数据,并展示在textview控件上 客户端通过socket通信,完成读取服务端的二进制数据读取,并将数据显示在textview控件上,数据全为整型 解决方案 之前接触一些,但不是我我写的.JNI中C读取,生成Native方法.上层调用 解决方案二: 底层c来封装so文件调用socket API.上面Java调用so 解决方案三: ....java自己有socket啊,ls各位回答的什么意思.... 简单的socket网上教

Android PullToRefreshLayout下拉刷新控件的终结者_Android

       说到下拉刷新控件,网上版本有很多,很多软件也都有下拉刷新功能.有一个叫XListView的,我看别人用过,没看过是咋实现的,看这名字估计是继承自ListView修改的,不过效果看起来挺丑的,也没什么扩展性,太单调了.看了QQ2014的列表下拉刷新,发现挺好看的,我喜欢,贴一下图看一下qq的下拉刷新效果:                                                不错吧?嗯,是的.一看就知道实现方式不一样.咱们今天就来实现一个下拉刷新控件.由于有时

基于Android实现点击某个按钮让菜单选项从按钮周围指定位置弹出_Android

Android Material Design:PopupMenu Android Material Design 引入的PopupMenu类似过去的上下文菜单,但是更灵活. 如图所示: 现在给出实现上图PopupMenu的代码. 本例是一个普通的Button触发弹出PopupMenu. 测试的MainActivity.java : package zhangphil.materialdesign; import android.app.Activity; import android.os.B

Android解决dialog弹出时无法捕捉Activity的back事件的方法_Android

本文实例讲述了Android解决dialog弹出时无法捕捉Activity的back事件的方法.分享给大家供大家参考.具体分析如下: 在一些情况下,我们需要捕捉back键事件,然后在捕捉到的事件里写入我们需要进行的处理,通常可以采用下面三种办法捕捉到back事件: 1)重写onKeyDown或者onKeyUp方法 2)重写onBackPressed方法 3)重写dispatchKeyEvent方法 这三种办法有什么区别在这里不进行阐述,有兴趣的朋友可以查阅相关资料. 然而在有dialog弹出时,

Android 解决dialog弹出时无法捕捉Activity的back事件问题_Android

Android 如何解决dialog弹出时无法捕捉Activity的back事件 在一些情况下,我们需要捕捉back键事件,然后在捕捉到的事件里写入我们需要进行的处理,通常可以采用下面三种办法捕捉到back事件: 1)重写onKeyDown或者onKeyUp方法 2)重写onBackPressed方法 3)重写dispatchKeyEvent方法 这三种办法有什么区别在这里不进行阐述,有兴趣的朋友可以查阅相关资料. 然而在有dialog弹出时,想捕捉back键的事件的话,上述三种办法都无法实现.

《Android应用开发入门经典(第3版)》——第6.2节使用输入控件

6.2 使用输入控件 Android应用开发入门经典(第3版) 在很多应用中,需要向用户收集一些基本信息.在一个布局中最基础的数据输入域是EditText.读者在第 1 章的示例应用中已经使用过了EditText.在设计布局时可以使用TextView作为标签,以清楚地阐明意图或增加指示.使用Button可以启动一个动作. 6.2.1 使用TextView和EditView视图 一个TextView会显示一段用户无法改变的文本.EditText视图用于用户输入.与其他控件一样,可以改变TextVi

详解Android中ViewPager的PagerTabStrip子控件的用法_Android

我们先来看一个小例子: 可以看到,效果实现的也是很棒,比之前自定义的标签指示器更加的流畅.下面,简单介绍一下 PagerTabStrip和它的使用. PagerTabStrip是v4支持包里面的类,是ViewPager专用的类,不能在其他地方使用.在使用的时候,我们只需要在ViewPager的布局里面声明即可.     如下面的代码 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns