Android登陆页面仿拉钩平滑动画过度动效

224 阅读3分钟
原文链接: click.aliyun.com

之前记录过一篇实现仿拉钩特效的文章《Android登陆页面仿拉钩动效,你总会需要它!》(可点击查看),那个实现的还是存在一些问题的,根据一些网友的反馈的情况,所以今天有时间又看了一下这个效果。今天带来相对完美一点的demo,关于键盘事件参考了Stack Overflow上以为大神的做法,在此基础上稍微修改了一些bug。

链接:
https://stackoverflow.com/questions/32497840/how-to-hide-ad-banner-when-opened-keyboard-on-android

效果

5e0d784b7f8e840d43485c3613660d5da960d84b

动态效果图

中心思想就是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开发者门户”。