Android 模仿QQ登录界面解决软键盘遮挡问题
2016-09-21 13:58
726 查看
Android 软件盘弹出可能会遮挡住界面上的某些控件。当 windowSoftInputMode 为 adjustPan 时,一般不会挡住 EditText,但是假如 EditText 下面是一个登录按钮,那么这个按钮就可能被挡住,但有时我们希望用户输完密码可以直接点击登录按钮,而不用把软键盘收起来。这时就需要用到 adjustResize,这种模式能够获取到软键盘的高度,这样我们就能够精确的对界面进行控制。
在阅读本章之前,你应该了解 windowSoftInputMode 的一些属性,特别是 adjustResize,如果还不熟悉,建议先阅读Android 软键盘之 windowSoftInputMode 分析再回过头来继续往下看。
QQ 登录界面很好的解决了软键盘遮挡问题,当然在大屏手机上软键盘并不会挡住登录按钮。今天我们也来模仿一个 QQ 登录界面,最终效果如下:
看代码说话:
如图所示:
MainActivity 代码如下:
布局文件:activity_qq_login.xml
点我下载源码
在阅读本章之前,你应该了解 windowSoftInputMode 的一些属性,特别是 adjustResize,如果还不熟悉,建议先阅读Android 软键盘之 windowSoftInputMode 分析再回过头来继续往下看。
QQ 登录界面很好的解决了软键盘遮挡问题,当然在大屏手机上软键盘并不会挡住登录按钮。今天我们也来模仿一个 QQ 登录界面,最终效果如下:
监听软键盘弹出及收起事件
step1. 指定 windowSoftInputMode=”adjustResize”
在 AndroidManifest.xml 中相应的 Activity 设置 android:windowSoftInputMode=”adjustResize”,也可以在 java 代码中设置。step2. 监听 contentView 宽高(layout) 变化
获取 ViewTreeObserver 并监听 OnGlobalLayoutListener。当然最好把这些代码独立出来放在某个帮助类。一开始我是用View#addOnLayoutChangeListener,同样可以监听软键盘弹出及收起,但是在 onLayoutChange 方法发起一个
requestLayout()有时会出现一些问题。
看代码说话:
public class KeyBoardHelper { private Activity activity; private OnKeyBoardStatusChangeListener onKeyBoardStatusChangeListener; private int screenHeight; // 空白高度 = 屏幕高度 - 当前 Activity 的可见区域的高度 // 当 blankHeight 不为 0 即为软键盘高度。 private int blankHeight = 0; public KeyBoardHelper(Activity activity) { this.activity = activity; screenHeight = activity.getResources().getDisplayMetrics().heightPixels; activity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE); if (activity.getRequestedOrientation() != ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) { activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); } } public void onCreate() { View content = activity.findViewById(android.R.id.content); // content.addOnLayoutChangeListener(listener); 这个方法有时会出现一些问题 content.getViewTreeObserver().addOnGlobalLayoutListener(onGlobalLayoutListener); } public void onDestory() { View content = activity.findViewById(android.R.id.content); content.getViewTreeObserver().removeOnGlobalLayoutListener(onGlobalLayoutListener); } private OnGlobalLayoutListener onGlobalLayoutListener = new OnGlobalLayoutListener() { @Override public void onGlobalLayout() { Rect rect = new Rect(); activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(rect); int newBlankheight = screenHeight - rect.bottom; if (newBlankheight != blankHeight) { if (newBlankheight > blankHeight) { // keyboard pop if (onKeyBoardStatusChangeListener != null) { onKeyBoardStatusChangeListener.OnKeyBoardPop(newBlankheight); } } else { // newBlankheight < blankHeight // keyboard close if (onKeyBoardStatusChangeListener != null) { onKeyBoardStatusChangeListener.OnKeyBoardClose(blankHeight); } } } blankHeight = newBlankheight; } }; public void setOnKeyBoardStatusChangeListener( OnKeyBoardStatusChangeListener onKeyBoardStatusChangeListener) { this.onKeyBoardStatusChangeListener = onKeyBoardStatusChangeListener; } public interface OnKeyBoardStatusChangeListener { void OnKeyBoardPop(int keyBoardheight); void OnKeyBoardClose(int oldKeyBoardheight); } }
实现 QQ 登录界面
有了这个 KeyBoardHelper,那么要实现和 QQ 登录界面一样的效果就不难了。我们甚至不需要任何自定义控件。思路是在软键盘弹出时,把登录按钮以上的布局往上移,只要为其设置一个负值的 topMargin 即可。如图所示:
MainActivity 代码如下:
import android.app.Activity; import android.os.Bundle; import android.view.View; import android.view.ViewGroup; import android.view.ViewGroup.MarginLayoutParams; import com.example.qq.support.KeyBoardHelper; import com.example.qq.support.KeyBoardHelper.OnKeyBoardStatusChangeListener; public class MainActivity extends Activity { private int bottomHeight; private KeyBoardHelper boardHelper; private View layoutBottom; private View layoutContent; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_qq_login); layoutContent = findViewById(R.id.layout_content); layoutBottom = findViewById(R.id.layout_bottom); boardHelper = new KeyBoardHelper(this); boardHelper.onCreate(); boardHelper.setOnKeyBoardStatusChangeListener(onKeyBoardStatusChangeListener); layoutBottom.post(new Runnable() { @Override public void run() { bottomHeight = layoutBottom.getHeight(); } }); } private OnKeyBoardStatusChangeListener onKeyBoardStatusChangeListener = new OnKeyBoardStatusChangeListener() { @Override public void OnKeyBoardPop(int keyBoardheight) { final int height = keyBoardheight; if (bottomHeight > height) { layoutBottom.setVisibility(View.GONE); } else { int offset = bottomHeight - height; final ViewGroup.MarginLayoutParams lp = (MarginLayoutParams) layoutContent .getLayoutParams(); lp.topMargin = offset; layoutContent.setLayoutParams(lp); } } @Override public void OnKeyBoardClose(int oldKeyBoardheight) { if (View.VISIBLE != layoutBottom.getVisibility()) { layoutBottom.setVisibility(View.VISIBLE); } final ViewGroup.MarginLayoutParams lp = (MarginLayoutParams) layoutContent .getLayoutParams(); if (lp.topMargin != 0) { lp.topMargin = 0; layoutContent.setLayoutParams(lp); } } }; @Override protected void onDestroy() { super.onDestroy(); boardHelper.onDestory(); } }
布局文件:activity_qq_login.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/layout_root" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <LinearLayout android:id="@+id/layout_content" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <ImageView android:id="@+id/imageView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:layout_marginTop="68dp" android:focusable="true" android:scaleType="centerInside" android:src="@drawable/qq_ava" android:visibility="visible" /> <LinearLayout android:id="@+id/layout_ed" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="18dp" android:background="#ffffff" android:divider="@drawable/divider" android:focusable="true" android:focusableInTouchMode="true" android:orientation="vertical" android:showDividers="middle" > <EditText android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@null" android:hint="QQ号/手机号/邮箱" android:padding="10dp" android:textColor="#000000" android:textColorHint="#d2d2d2" android:textCursorDrawable="@null" /> <EditText android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@null" android:hint="密码" android:padding="10dp" android:textColor="#000000" android:textColorHint="#d2d2d2" android:textCursorDrawable="@null" /> </LinearLayout> <Button android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginLeft="14dp" android:layout_marginRight="14dp" android:layout_marginTop="14dp" android:background="@drawable/btn_login" android:text="登陆" android:textSize="17sp" /> <RelativeLayout android:id="@+id/layout_bottom" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:id="@+id/tv_cannot_login" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_margin="14dp" android:text="无法登陆?" android:textColor="@color/action_bar_bg" android:textSize="14sp" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_alignParentRight="true" android:layout_margin="14dp" android:text="新用户" android:textColor="@color/action_bar_bg" android:textSize="14sp" /> </RelativeLayout> </LinearLayout> <include android:id="@+id/appbar" android:layout_width="fill_parent" android:layout_height="50dp" layout="@layout/appbar" /> </RelativeLayout>
点我下载源码
相关文章推荐
- Android 模仿QQ登录界面解决软键盘遮挡问题
- Android实现QQ登录界面遇到问题及解决方法
- 解决Android软键盘和表情面板切换界面闪动问题
- [Android初级]关于如何解决软键盘弹出后覆盖界面布局的问题
- Android 解决界面底部弹出dialog被虚拟按键遮挡一部分的问题
- Android优雅的方式解决软键盘遮挡按钮问题
- [转]Android:布局实例之模仿QQ登录界面
- 解决 {"ret":100030,"msg":"this api without user authorization"} android QQ第三发登录成功后获取用户信息失败的问题
- 解决支付宝WEB支付界面模块在Android上自动滑动到登录模块的问题
- Android PopupWindow 与 软键盘 的遮挡问题解决
- qq7.0的视频动态图登录界面实现讲解解决videoview黑屏问题解决图片视频各种手机适配与缩放衔接问题
- Android实现QQ新用户注册界面遇到问题及解决方法
- Android:布局实例之模仿QQ登录界面
- 解决自定义状态栏对软键盘及界面内容遮挡问题
- Android: 解决软键盘弹出覆盖界面问题
- Android 解决在页面底部置输入框,软键盘遮挡部分输入框的问题
- android app从登录界面进入主页,按home键回桌面再进入app,重新弹出登录界面的问题解决
- Android PopupWindow 与 软键盘 的遮挡问题解决
- Android解决被软键盘遮挡的EditText问题
- Android PopupWindow 与 软键盘 的遮挡问题解决