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

简介:

之前记录过一篇实现仿拉钩特效的文章《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 &amp;
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 &amp;&amp; heightDiff > activityRootView.getRootView().getHeight()/4) {
isSoftKeyboardOpened = true;
if ((activityRootView.getContext() instanceof Activity)
&amp;&amp; !isFullScreen((Activity) activityRootView.getContext())){
notifyOnSoftKeyboardOpened(heightDiff-statusBarHeight);
}else {
notifyOnSoftKeyboardOpened(heightDiff);
}

} else if (isSoftKeyboardOpened &amp;&amp; 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开发者门户”。

相关文章
|
3月前
|
存储 Shell Android开发
基于Android P,自定义Android开机动画的方法
本文详细介绍了基于Android P系统自定义开机动画的步骤,包括动画文件结构、脚本编写、ZIP打包方法以及如何将自定义动画集成到AOSP源码中。
62 2
基于Android P,自定义Android开机动画的方法
|
5天前
|
Android开发 UED
Android 中加载 Gif 动画
【10月更文挑战第20天】加载 Gif 动画是 Android 开发中的一项重要技能。通过使用第三方库或自定义实现,可以方便地在应用中展示生动的 Gif 动画。在实际应用中,需要根据具体情况进行合理选择和优化,以确保用户体验和性能的平衡。可以通过不断的实践和探索,进一步掌握在 Android 中加载 Gif 动画的技巧和方法,为开发高质量的 Android 应用提供支持。
|
5月前
|
Android开发 容器
35. 【Android教程】视频页面:ViewPager
35. 【Android教程】视频页面:ViewPager
56 3
|
6月前
|
Android开发
Android WindowFeature小探究,Android客户端Web页面通用性能优化实践
Android WindowFeature小探究,Android客户端Web页面通用性能优化实践
|
6月前
|
Java Android开发 开发者
Android10 修改开发者选项中动画缩放默认值
Android10 修改开发者选项中动画缩放默认值
166 0
|
6月前
|
XML Java Android开发
android的三种动画
android的三种动画
37 0
|
3月前
|
存储 安全 物联网
Android经典实战之跳转到系统设置页面或其他系统应用页面大全
本文首发于公众号“AntDream”,关注获取更多技巧。文章总结了Android开发中跳转至系统设置页面的方法,包括设备信息、Wi-Fi、显示与声音设置等,并涉及应用详情与电池优化页面。通过简单的Intent动作即可实现,需注意权限与版本兼容性。每日进步,尽在“AntDream”。
326 2
|
4月前
|
XML Android开发 数据格式
Android 中如何设置activity的启动动画,让它像dialog一样从底部往上出来
在 Android 中实现 Activity 的对话框式过渡动画:从底部滑入与从顶部滑出。需定义两个 XML 动画文件 `activity_slide_in.xml` 和 `activity_slide_out.xml`,分别控制 Activity 的进入与退出动画。使用 `overridePendingTransition` 方法在启动 (`startActivity`) 或结束 (`finish`) Activity 时应用这些动画。为了使前 Activity 保持静止,可定义 `no_animation.xml` 并在启动新 Activity 时仅设置新 Activity 的进入动画。
81 12
|
3月前
|
监控 安全 API
Android项目架构设计问题之保证线上用户不会进入到本地配置页面如何解决
Android项目架构设计问题之保证线上用户不会进入到本地配置页面如何解决
28 0