之前记录过一篇实现仿拉钩特效的文章《Android登陆页面仿拉钩动效,你总会需要它!》(可点击查看),那个实现的还是存在一些问题的,根据一些网友的反馈的情况,所以今天有时间又看了一下这个效果。今天带来相对完美一点的demo,关于键盘事件参考了Stack Overflow上以为大神的做法,在此基础上稍微修改了一些bug。
链接:
https://stackoverflow.com/questions/32497840/how-to-hide-ad-banner-when-opened-keyboard-on-android
效果
中心思想就是activity根布局监听布局变化,实现ViewTreeObserver.OnGlobalLayoutListener接口,根据根布局高度变化超过高度的1/4就是认为键盘弹起来了。链接上的人是默认高度变化超过100就认为键盘弹起,并且此处获取的键盘的高度没有减去状态栏的高度,我改进了一下,当非全屏的时候获取的键盘高度减去状态栏的高度。
修改后的代码如下:
import android.app.Activity;
import android.graphics.Rect;
import android.view.View;
import android.view.ViewTreeObserver;
import android.view.WindowManager;
import java.util.LinkedList;
import java.util.List;
public class KeyboardWatcher implements ViewTreeObserver.OnGlobalLayoutListener {
public interface SoftKeyboardStateListener {
void onSoftKeyboardOpened(int keyboardHeightInPx);
void onSoftKeyboardClosed();
}
private final List<SoftKeyboardStateListener> listeners = new LinkedList<SoftKeyboardStateListener>();
private final View activityRootView;
private int lastSoftKeyboardHeightInPx;
private boolean isSoftKeyboardOpened;
private int statusBarHeight = -1;
public KeyboardWatcher(View activityRootView) {
this(activityRootView, false);
}
public boolean isFullScreen(Activity activity) {
return (activity.getWindow().getAttributes().flags &
WindowManager.LayoutParams.FLAG_FULLSCREEN)==WindowManager.LayoutParams.FLAG_FULLSCREEN;
}
public KeyboardWatcher(View activityRootView, boolean isSoftKeyboardOpened) {
this.activityRootView = activityRootView;
this.isSoftKeyboardOpened = isSoftKeyboardOpened;
activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(this);
//获取status_bar_height资源的ID
int resourceId = activityRootView.getContext().getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
//根据资源ID获取响应的尺寸值
statusBarHeight = activityRootView.getContext().getResources().getDimensionPixelSize(resourceId);
}
}
@Override
public void onGlobalLayout() {
final Rect r = new Rect();
//r will be populated with the coordinates of your view that area still visible.
activityRootView.getWindowVisibleDisplayFrame(r);
final int heightDiff = activityRootView.getRootView().getHeight() - (r.bottom - r.top);
if (!isSoftKeyboardOpened && heightDiff > activityRootView.getRootView().getHeight()/4) {
isSoftKeyboardOpened = true;
if ((activityRootView.getContext() instanceof Activity)
&& !isFullScreen((Activity) activityRootView.getContext())){
notifyOnSoftKeyboardOpened(heightDiff-statusBarHeight);
}else {
notifyOnSoftKeyboardOpened(heightDiff);
}
} else if (isSoftKeyboardOpened && heightDiff < activityRootView.getRootView().getHeight()/4) {
isSoftKeyboardOpened = false;
notifyOnSoftKeyboardClosed();
}
}
public void setIsSoftKeyboardOpened(boolean isSoftKeyboardOpened) {
this.isSoftKeyboardOpened = isSoftKeyboardOpened;
}
public boolean isSoftKeyboardOpened() {
return isSoftKeyboardOpened;
}
/**
* Default value is zero {@code 0}.
*
* @return last saved keyboard height in px
*/
public int getLastSoftKeyboardHeightInPx() {
return lastSoftKeyboardHeightInPx;
}
public void addSoftKeyboardStateListener(SoftKeyboardStateListener listener) {
listeners.add(listener);
}
public void removeSoftKeyboardStateListener(SoftKeyboardStateListener listener) {
listeners.remove(listener);
}
private void notifyOnSoftKeyboardOpened(int keyboardHeightInPx) {
this.lastSoftKeyboardHeightInPx = keyboardHeightInPx;
for (SoftKeyboardStateListener listener : listeners) {
if (listener != null) {
listener.onSoftKeyboardOpened(keyboardHeightInPx);
}
}
}
private void notifyOnSoftKeyboardClosed() {
for (SoftKeyboardStateListener listener : listeners) {
if (listener != null) {
listener.onSoftKeyboardClosed();
}
}
}
}
下面开始写登陆页面的布局,也没啥难的,就我这个方案注意几点就行:
1.把需要往上移动的布局放在一个容器里面;
2.容器的高度计算好,给出定值;
3.登录页面设置键盘模式为:android:windowSoftInputMode="adjustResize"
4.在KeyboardWatcher.SoftKeyboardStateListener的回调接口里面处理要处理的事,也就是平移动画之类的,看着玩耍吧!
void onSoftKeyboardOpened(int keyboardHeightInPx);
void onSoftKeyboardClosed();
回顾
这个跟上次相比还有一个点就是关于显示和隐藏密码的问题:
1.发现之前项目的显示和隐藏密码是动态设置EditText的inputType来实现的,效果不太好,有点键盘抖动的赶脚。所以用了EditText的setTransformationMethod方法来实现,想过看了就知道,棒棒的~
2.封装了TextView的上下左右Drawable,可以实现动态在布局文件设置大小及资源,省的在Act or Frg去设置了:
<com.wzh.study.login.suggest.DrawableTextView
android:id="@+id/logo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_gravity="center"
android:layout_marginTop="100dp"
android:drawablePadding="10dp"
android:gravity="center_vertical"
android:text="欢迎登陆"
android:textSize="18sp"
android:textStyle="bold"
app:drawableHeight="40dp"
app:drawableWidth="120dp"
app:leftDrawable="@drawable/google" />
drawablePadding属性照样使用,只是设置上下左右图片的属性用自定义的吧,代码很简单,不在贴了。
原文发布时间为:2018-10-31
本文作者:wenzhihao123
本文来自云栖社区合作伙伴“安卓巴士Android开发者门户”,了解相关信息可以关注“安卓巴士Android开发者门户”。