本文来自http://blog.csdn.net/chenshaoyang0011转载请申明文章出处!

文中如有纰漏之处,望不吝指教~~~欢迎讨论,共同学习~~~

进入AllApps界面是通过点击Hotseat中的allAppsButton触发事件,通过前面的分析,已经知道在setupViews()方法中,就为button设置好了onTouchListener:

[java] view plain copy
  1. privatevoidsetupViews(){
  2. ......
  3. //Gettheallappsbutton
  4. mAllAppsButton=findViewById(R.id.all_apps_button);
  5. if(mAllAppsButton!=null){
  6. mAllAppsButton.setOnTouchListener(newView.OnTouchListener(){
  7. @Override
  8. publicbooleanonTouch(Viewv,MotionEventevent){
  9. //(MotionEvent.ACTION_POINTER_1_DOWN&MotionEvent.ACTION_MASK)
  10. //(MotionEvent.ACTION_POINTER_2_DOWN&MotionEvent.ACTION_MASK)
  11. //(MotionEvent.ACTION_POINTER_3_DOWN&MotionEvent.ACTION_MASK)
  12. //==MotionEvent.ACTION_DOWN
  13. if((event.getAction()&MotionEvent.ACTION_MASK)==MotionEvent.ACTION_DOWN){
  14. onTouchDownAllAppsButton(v);
  15. }
  16. returnfalse;
  17. }
  18. });
  19. }
  20. ......
  21. }

这里简单说明下,为什么在判断事件的时候不直接使用event.getAction()==MotionEvent.ACTION_DOWN,而是采用(event.getAction()&MotionEvent.ACTION_MASK)==MotionEvent.ACTION_DOWN呢?查看文档,我们可以发现ACTION_MASK的值为0x000000ff,二进制的值为11111111ACTION_DOWN的值为0x00000000,二进制为00000000。在真实的设备中通常支持多点触控,但根据直观的判断,多指按下和单指按下都属于按下AndroidACTION_MASK恰恰是为了解决这个问题而存在的因为(MotionEvent.ACTION_POINTER_1_DOWN&MotionEvent.ACTION_MASK)==MotionEvent.ACTION_DOWN,(MotionEvent.ACTION_POINTER_2_DOWN&MotionEvent.ACTION_MASK)==MotionEvent.ACTION_DOWN,(MotionEvent.ACTION_POINTER_3_DOWN&MotionEvent.ACTION_MASK)==MotionEvent.ACTION_DOWN。这就是为什么要先再判断的原因了。ACTION_DOWN被触发后,onTouchDownAllAppsButton()被调用。


[java] view plain copy
  1. publicvoidonTouchDownAllAppsButton(Viewv){
  2. //Providethesamehapticfeedbackthatthesystemoffersforvirtualkeys.
  3. v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);
  4. }
在onTouchDownAllAppsButton()中为ACTION_DOWN事件提供了触感反馈(振动反馈)。

接着,顺着启动的过程,进入到了Hotseat.resetLayout()方法中

[java] view plain copy
  1. voidresetLayout(){
  2. ......
  3. allAppsButton.setOnClickListener(newView.OnClickListener(){
  4. @Override
  5. publicvoidonClick(android.view.Viewv){
  6. if(mLauncher!=null){
  7. mLauncher.onClickAllAppsButton(v);
  8. }
  9. }
  10. });
  11. ......
  12. }
这里为allAppsButton设置了OnClickListener,当allAppsButton被点击后,会调用Launcher.onClickAllAppsButton()方法。 [java] view plain copy
  1. /**
  2. *Eventhandlerforthe"grid"buttonthatappearsonthehomescreen,which
  3. *entersallappsmode.
  4. *
  5. *@paramvTheviewthatwasclicked.
  6. */
  7. publicvoidonClickAllAppsButton(Viewv){
  8. showAllApps(true);
  9. }
接着进入showAllApps()方法。 [java] view plain copy
  1. voidshowAllApps(booleananimated){
  2. if(mState!=State.WORKSPACE)return;
  3. //显示apps_customize也就是AllApps页面,切换时有缩放和渐显的动画
  4. cameraZoomOut(State.APPS_CUSTOMIZE,animated,false);
  5. mAppsCustomizeTabHost.requestFocus();
  6. //Hidethesearchbarandhotseat
  7. //将searchBar隐藏起来
  8. mSearchDropTargetBar.hideSearchBar(animated);
  9. //Changethestate*after*we'vecalledallthetransitioncode
  10. //将状态mState从WORKSPACE切换到APPS_CUSTOMIZE
  11. mState=State.APPS_CUSTOMIZE;
  12. //Pausetheauto-advanceofwidgetsuntilweareoutofAllApps
  13. //停止对AppWidget的自动更新
  14. mUserPresent=false;
  15. updateRunning();
  16. //将桌面上打开的文件夹关闭
  17. closeFolder();
  18. //Sendanaccessibilityeventtoannouncethecontextchange
  19. getWindow().getDecorView().sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED);
  20. }

进入方法后可以看到,最主要的功能是在cameraZoomOut()方法中,以动画的方式来显示AllApps页。接着隐藏了SearchDropTargetBarHotseat。为了节省资源,关闭了AppWidget的自动更新。下面进入cameraZoomOut()

[java] view plain copy
  1. /**
  2. *Zoomthecameraoutfromtheworkspacetoreveal'toView'.
  3. *Assumesthattheviewtoshowisanchoredateithertheverytoporverybottom
  4. *ofthescreen.
  5. *@paramtoStateThestatetozoomoutto.MustbeAPPS_CUSTOMIZE.
  6. */
  7. privatevoidcameraZoomOut(StatetoState,booleananimated,finalbooleanspringLoaded){
  8. ......
  9. //设置缩放时的轴心
  10. setPivotsForZoom(toView,toState,scale);
  11. //ShrinkworkspacesawayifgoingtoAppsCustomizefromworkspace
  12. //缩小workspaces然后让它消失。
  13. mWorkspace.changeState(Workspace.State.SMALL,animated);
  14. if(animated){
  15. //如果需要动画,就是用scaleAnim来实现缩放的动画效果
  16. finalValueAnimatorscaleAnim=ValueAnimator.ofFloat(0f,1f).setDuration(duration);
  17. scaleAnim.setInterpolator(newWorkspace.ZoomOutInterpolator());
  18. scaleAnim.addUpdateListener(newLauncherAnimatorUpdateListener(){
  19. publicvoidonAnimationUpdate(floata,floatb){
  20. ((View)toView.getParent()).invalidate();
  21. toView.fastInvalidate();
  22. toView.setFastScaleX(a*scale+b*1f);
  23. toView.setFastScaleY(a*scale+b*1f);
  24. }
  25. });
  26. toView.setVisibility(View.VISIBLE);
  27. toView.setFastAlpha(0f);
  28. //使用alphaAnim来实现渐显的动画效果
  29. ValueAnimatoralphaAnim=ValueAnimator.ofFloat(0f,1f).setDuration(fadeDuration);
  30. alphaAnim.setInterpolator(newDecelerateInterpolator(1.5f));
  31. alphaAnim.addUpdateListener(newLauncherAnimatorUpdateListener(){
  32. publicvoidonAnimationUpdate(floata,floatb){
  33. //don'tneedtoinvalidatebecausewedosoabove
  34. toView.setFastAlpha(a*0f+b*1f);
  35. }
  36. });
  37. alphaAnim.setStartDelay(startDelay);
  38. alphaAnim.start();
  39. if(toViewinstanceofLauncherTransitionable){
  40. //切换开始时,调用AppsCustomizeTabHost.onLauncherTransitionStart()方法
  41. ((LauncherTransitionable)toView).onLauncherTransitionStart(instance,scaleAnim,
  42. false);
  43. }
  44. scaleAnim.addListener(newAnimatorListenerAdapter(){
  45. booleananimationCancelled=false;
  46. @Override
  47. publicvoidonAnimationStart(Animatoranimation){
  48. updateWallpaperVisibility(true);
  49. //Preparetheposition
  50. toView.setTranslationX(0.0f);
  51. toView.setTranslationY(0.0f);
  52. toView.setVisibility(View.VISIBLE);
  53. toView.bringToFront();
  54. }
  55. @Override
  56. publicvoidonAnimationEnd(Animatoranimation){
  57. //Ifwedon'tsetthefinalscalevalueshere,ifthisanimationiscancelled
  58. //itwillhavethewrongscalevalueandsubsequentcameraPananimationswill
  59. //notfixthat
  60. toView.setScaleX(1.0f);
  61. toView.setScaleY(1.0f);
  62. if(toViewinstanceofLauncherTransitionable){
  63. //当切换过程完成时,调用AppsCustomizeTabHost.onLauncherTransitionEnd()方法
  64. ((LauncherTransitionable)toView).onLauncherTransitionEnd(instance,
  65. scaleAnim,false);
  66. }
  67. ......
  68. }
  69. @Override
  70. publicvoidonAnimationCancel(Animatoranimation){
  71. animationCancelled=true;
  72. }
  73. });
  74. //toViewshouldappearrightattheendoftheworkspaceshrinkanimation
  75. if(mStateAnimation!=null)mStateAnimation.cancel();
  76. mStateAnimation=newAnimatorSet();
  77. mStateAnimation.play(scaleAnim).after(startDelay);
  78. mStateAnimation.start();
  79. }else{
  80. //不需要动画效果
  81. ......
  82. }

这里演示了使用ValueAnimator来实现动画效果的方式。动画结束之后,页面的切换就完成了。

更多相关文章

  1. android 下 数据持久化
  2. android调用python脚本
  3. Android(安卓)值动画一(ObjectAnimator)
  4. 浏览Butter Knife源码收获
  5. 关于android消息处理的个人理解
  6. android webView调用js函数的几种方法
  7. Android应用开发提高系列——Android动态加载(下)——加载已安装AP
  8. Android中关联源码的方法
  9. android onMeasure 实现

随机推荐

  1. 谷歌Android手机应用开发环境的搭建 转载
  2. Android开发指南-框架主题-内容提供器
  3. Android(安卓)深入解析光传感器
  4. Android(安卓)实用工具Hierarchy Viewer
  5. [Android(安卓)NDK]Android(安卓)JNI开发
  6. Android中的GPS应用开发入门教程
  7. Android基础 : Android(安卓)Service
  8. Handler和Message的使用之三
  9. Android客户端应用享用传统Web服务
  10. 【Android】进入应用和切换界面时闪屏的