中国领先的IT技术网站
|
|

Android登陆页面仿拉钩动效,你总会需要它!

看到这个标题是不是JH一紧,你可能会说我就没遇到过,但是现在没遇到不代表就遇不到,毕竟设计也是变幻莫测,只有你想不到的,没有你不能实现的,说的这么吊,到底是啥效果?没错就是一个小小的登录页面,大家都有拉勾app吧,看拉勾的登录页做的很是平滑动画,而且带动画效果,所以就有了类似拉勾登录效果。

作者:wenzhihao123来源:安卓巴士Android开发者门户|2017-04-07 17:00

Android登陆页面仿拉钩动效

哈哈,看到这个标题是不是JH一紧,你可能会说我就没遇到过,但是现在没遇到不代表就遇不到,毕竟设计也是变幻莫测,只有你想不到的,没有你不能实现的,说的这么吊,到底是啥效果?没错就是一个小小的登录页面,大家都有拉勾app吧,看拉勾的登录页做的很是平滑动画,而且带动画效果,所以就有了类似拉勾登录效果,如图:

虽然是个简单的页面,但是涵盖的东西不算少啊,很纳闷为何谷歌一直不提供简单,方便,准确的键盘监听事件?惆怅啊,所以我们只能自己从侧面监听键盘事件了,我们可以监听最外层布局的变化来判断键盘是不是弹起了。闲话不多说,上车吧。

布局文件,大家都能看懂吧。

我们要想监听键盘事件,首先我们想得到的是键盘弹起的时候我们可以去搞点事情,键盘搜起的时候我们再去搞点事情,知道这些还不够,我们还要知道键盘弹起了多少,以及需要平移多少的距离。我们都知道我们的一个页面弹起键盘的时候这个页面的根布局会回调他的监听方法:addOnLayoutChangeListener( );当键盘弹起的时候,我们的布局是变化了,因此会执行这个回调方法,但是前提是必须设置我们的Activity的windowSoftInputMode属性为adjustResize。

我们想让布局整体平移的距离也就是弹起时候处于最底部的view距离顶部的高度减去我们键盘的高度。现在认为只要控件将Activity向上推的高度超过了1/3屏幕高,就认为软键盘弹起

  1.  scrollView.addOnLayoutChangeListener(new ViewGroup.OnLayoutChangeListener() { 
  2.             @Override 
  3.             public void onLayoutChange(View v, int leftint topint rightint bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { 
  4.               /* old是改变前的左上右下坐标点值,没有old的是改变后的左上右下坐标点值 
  5.               现在认为只要控件将Activity向上推的高度超过了1/3屏幕高,就认为软键盘弹起*/ 
  6.                 if (oldBottom != 0 && bottom != 0 && (oldBottom - bottom > keyHeight)) { 
  7.                     Log.e("wenzhihao""up------>"+(oldBottom - bottom)); 
  8.                     int dist = btn_login.getBottom() - bottom; 
  9.                     if (dist>0){ 
  10.                         ObjectAnimator mAnimatorTranslateY = ObjectAnimator.ofFloat(content, "translationY", 0.0f, -dist); 
  11.                         mAnimatorTranslateY.setDuration(300); 
  12.                         mAnimatorTranslateY.setInterpolator(new LinearInterpolator()); 
  13.                         mAnimatorTranslateY.start(); 
  14.                         zoomIn(logo, dist); 
  15.                     } 
  16.                     service.setVisibility(View.INVISIBLE); 
  17.  
  18.                 } else if (oldBottom != 0 && bottom != 0 && (bottom - oldBottom > keyHeight)) { 
  19.                     Log.e("wenzhihao""down------>"+(bottom - oldBottom)); 
  20.                     if ((btn_login.getBottom() - oldBottom)>0){ 
  21.                         ObjectAnimator mAnimatorTranslateY = ObjectAnimator.ofFloat(content, "translationY", content.getTranslationY(), 0); 
  22.                         mAnimatorTranslateY.setDuration(300); 
  23.                         mAnimatorTranslateY.setInterpolator(new LinearInterpolator()); 
  24.                         mAnimatorTranslateY.start(); 
  25.                         //键盘收回后,logo恢复原来大小,位置同样回到初始位置 
  26.                         zoomOut(logo); 
  27.                     } 
  28.                     service.setVisibility(View.VISIBLE); 
  29.                 } 
  30.             } 
  31.         }); 
  32. /n_login是登录按钮   

这样我们发现是可以实现效果了,但是我想全屏显示,懵比了,发现全屏的时候不回调这个方法了,怎么办?又是查资料一看原来这个也是一个bug,但是有解决方案,AndroidBug5497Workaround。也是谷歌提供的?直接拷贝过来,会发现其实他的作用就是让Activity最外层的根布局,当有布局变化时去响应这个变化mChildOfContent.getViewTreeObserver().addOnGlobalLayoutListener();

  1. package com.wzh.study.login; 
  2.  
  3.  
  4. import android.app.Activity; 
  5.  
  6. import android.graphics.Rect; 
  7.  
  8. import android.view.View
  9.  
  10. import android.view.ViewTreeObserver; 
  11.  
  12. import android.widget.FrameLayout; 
  13.  
  14.  
  15. public class AndroidBug5497Workaround { 
  16.  
  17.  
  18.     // For more information, see https://code.google.com/p/android/issues/detail?id=5497 
  19.  
  20.     // To use this class, simply invoke assistActivity() on an Activity that already has its content view set
  21.  
  22.  
  23.     public static void assistActivity (Activity activity) { 
  24.  
  25.         new AndroidBug5497Workaround(activity); 
  26.  
  27.     } 
  28.  
  29.  
  30.     private View mChildOfContent; 
  31.  
  32.     private int usableHeightPrevious; 
  33.  
  34.     private FrameLayout.LayoutParams frameLayoutParams; 
  35.  
  36.  
  37.     private AndroidBug5497Workaround(Activity activity) { 
  38.  
  39.         FrameLayout content = (FrameLayout) activity.findViewById(android.R.id.content); 
  40.  
  41.         mChildOfContent = content.getChildAt(0); 
  42.  
  43.         mChildOfContent.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { 
  44.  
  45.             public void onGlobalLayout() { 
  46.  
  47.                 possiblyResizeChildOfContent(); 
  48.  
  49.             } 
  50.  
  51.         }); 
  52.  
  53.         frameLayoutParams = (FrameLayout.LayoutParams) mChildOfContent.getLayoutParams(); 
  54.  
  55.     } 
  56.  
  57.  
  58.     private void possiblyResizeChildOfContent() { 
  59.  
  60.         int usableHeightNow = computeUsableHeight(); 
  61.  
  62.         if (usableHeightNow != usableHeightPrevious) { 
  63.  
  64.             int usableHeightSansKeyboard = mChildOfContent.getRootView().getHeight(); 
  65.  
  66.             int heightDifference = usableHeightSansKeyboard - usableHeightNow; 
  67.  
  68.             if (heightDifference > (usableHeightSansKeyboard/4)) { 
  69.  
  70.                 // keyboard probably just became visible 
  71.  
  72.                 frameLayoutParams.height = usableHeightSansKeyboard - heightDifference; 
  73.  
  74.             } else { 
  75.  
  76.                 // keyboard probably just became hidden 
  77.  
  78.                 frameLayoutParams.height = usableHeightSansKeyboard; 
  79.  
  80.             } 
  81.  
  82.             mChildOfContent.requestLayout(); 
  83.  
  84.             usableHeightPrevious = usableHeightNow; 
  85.  
  86.         } 
  87.  
  88.     } 
  89.  
  90.  
  91.     private int computeUsableHeight() { 
  92.  
  93.         Rect r = new Rect(); 
  94.  
  95.         mChildOfContent.getWindowVisibleDisplayFrame(r); 
  96.  
  97.         return (r.bottom - r.top); 
  98.  
  99.     } 
  100.  
  101.  
  102.  

使用方式,如果我们设置了全屏,就去加载它,不设置不管:

  1. if(isFullScreen(this)){ 
  2.  
  3.             AndroidBug5497Workaround.assistActivity(this); 
  4.  
  5.  
  6. ... 
  7.  
  8. public boolean isFullScreen(Activity activity) { 
  9.  
  10.     return (activity.getWindow().getAttributes().flags & 
  11.  
  12.             WindowManager.LayoutParams.FLAG_FULLSCREEN)==WindowManager.LayoutParams.FLAG_FULLSCREEN; 
  13.  
  14.  

接下来就看具体动画事件了,键盘弹起来的时候整体向上平移,LOGO缩小,键盘收起的时候整体下移,并且LOGO恢复原来大小。这里用到的都是属性动画,只有属性动画我们才可以实现真正平移效果。

我看网上很多人使用addOnLayoutChangeListener()去监听键盘事件,但是这个方法回调的太频繁,比如本例特效,输入框后面有文字时候显示清除的图标,如果用这个方法那么也会执行一次,可能会影响你的动画,当然你也可以去记录第一次的高度让他不会走逻辑,但是我觉得也不是很靠谱,虽然我这个方法也不是很棒 ๑乛◡乛๑~。

最后贴上源码:

如果有什么问题欢迎指出,我将给出例子地址,包含另一种实现方式就是用scrollview滑动到最底部的方式来实现平移效果~

【编辑推荐】

  1. Android应用安全风险与防范
  2. 惊天秘密!从Thread开始,揭露Android线程通讯的诡计和主线程的阴谋
  3. Android之RootTools框架简单使用
  4. Android O开发者预览版终于推出啦!官方介绍新特性
  5. 一个能让你了解所有函数调用顺序的Android库
【责任编辑:枯木 TEL:(010)68476606】

点赞 0
分享:
大家都在看
猜你喜欢

热门职位+更多

读 书 +更多

网管员必读—网络应用(第2版)

本书虽然是《网管员必读—网络应用》的改版,但它绝不是简单的修改,而是完完全全的重写,内容更实用、更专业。全书共9章,13个大小方案,...

订阅51CTO邮刊

点击这里查看样刊

订阅51CTO邮刊
× 大数据高端培训 仅限10人