仿人人客户端向右滑出式菜单

人人客户端向右滑出式菜单:

仿人人客户端向右滑出式菜单

试着实现了一个,先上效果图:

仿人人客户端向右滑出式菜单

下面简单说明一下实现原理:

有两个activity,MainActivity和SettingActivity,实现这个效果两个步骤:

1、点击MainActivity左上角的按钮,MainActivity先切换到SettingActivity,获得MainActivity的布局快照,即一张代表其布局的bitmap

2、SettingActivity采用绝对布局,最上面先是覆盖了一张透明的imageView,接着将这个imageview填充上上一步的布局快照,然后通过位移动画移动这张imageView,给人的感觉就好像是前一个activity在移动。

待改进:加入手势控制。

希望大家提出更好的实现方法。

上代码:有注释

MainActivity.java

  1. importandroid.app.Activity;
  2. importandroid.content.Intent;
  3. importandroid.os.Bundle;
  4. importandroid.util.Log;
  5. importandroid.view.GestureDetector;
  6. importandroid.view.GestureDetector.OnGestureListener;
  7. importandroid.view.MotionEvent;
  8. importandroid.view.View;
  9. importandroid.view.View.OnClickListener;
  10. importandroid.view.View.OnTouchListener;
  11. importandroid.widget.Toast;
  12. publicclassMainActivityextendsActivity{
  13. @Override
  14. protectedvoidonCreate(BundlesavedInstanceState){
  15. super.onCreate(savedInstanceState);
  16. setContentView(R.layout.sample);
  17. findViewById(R.id.sample_button).setOnClickListener(
  18. newOnClickListener(){
  19. @Override
  20. publicvoidonClick(Viewv){
  21. SettingActivity.prepare(MainActivity.this,
  22. R.id.inner_content);
  23. startActivity(newIntent(MainActivity.this,
  24. SettingActivity.class));
  25. overridePendingTransition(0,0);
  26. }
  27. });
  28. }
  29. }
SettingActivity.java

  1. importandroid.app.Activity;
  2. importandroid.content.Context;
  3. importandroid.graphics.Bitmap;
  4. importandroid.graphics.Bitmap.Config;
  5. importandroid.graphics.Canvas;
  6. importandroid.os.Bundle;
  7. importandroid.util.TypedValue;
  8. importandroid.view.KeyEvent;
  9. importandroid.view.View;
  10. importandroid.view.View.OnClickListener;
  11. importandroid.view.WindowManager;
  12. importandroid.view.animation.Animation;
  13. importandroid.view.animation.Animation.AnimationListener;
  14. importandroid.view.animation.TranslateAnimation;
  15. importandroid.widget.AdapterView;
  16. importandroid.widget.AdapterView.OnItemClickListener;
  17. importandroid.widget.ArrayAdapter;
  18. importandroid.widget.ImageView;
  19. importandroid.widget.ListView;
  20. importandroid.widget.RelativeLayout.LayoutParams;
  21. publicclassSettingActivityextendsActivity{
  22. privateImageViewmCover;
  23. privateListViewmList;
  24. privateAnimationmStartAnimation;
  25. privateAnimationmStopAnimation;
  26. privatestaticfinalintDURATION_MS=400;
  27. privatestaticBitmapsCoverBitmap=null;
  28. //2个步骤
  29. //1.activity-->otheractivity
  30. //2.anim
  31. //先切换到另一个activity
  32. //再获得之前activity屏幕的快照将它作为一个cover覆盖在下一个屏幕的上面,然后通过动画移动这个cover,让人感觉好像是前一个屏幕的移动。
  33. publicstaticvoidprepare(Activityactivity,intid){
  34. if(sCoverBitmap!=null){
  35. sCoverBitmap.recycle();
  36. }
  37. //用指定大小生成一张透明的32位位图,并用它构建一张canvas画布
  38. sCoverBitmap=Bitmap.createBitmap(
  39. activity.findViewById(id).getWidth(),activity.findViewById(id)
  40. .getHeight(),Config.ARGB_8888);
  41. Canvascanvas=newCanvas(sCoverBitmap);
  42. //将指定的view包括其子view渲染到这种画布上,在这就是上一个activity布局的一个快照,现在这个bitmap上就是上一个activity的快照
  43. activity.findViewById(id).draw(canvas);
  44. }
  45. @Override
  46. publicvoidonCreate(BundlesavedInstanceState){
  47. super.onCreate(savedInstanceState);
  48. //绝对布局最上层覆盖了一个imageview
  49. setContentView(R.layout.main);
  50. initAnim();
  51. mCover=(ImageView)findViewById(R.id.slidedout_cover);
  52. mCover.setImageBitmap(sCoverBitmap);
  53. mCover.setOnClickListener(newOnClickListener(){
  54. @Override
  55. publicvoidonClick(Viewv){
  56. close();
  57. }
  58. });
  59. mList=(ListView)findViewById(R.id.list);
  60. mList.setAdapter(newArrayAdapter<String>(SettingActivity.this,
  61. android.R.layout.simple_list_item_1,newString[]{"First",
  62. "Second","Third","Fourth","Fifth","Sixth"}));
  63. mList.setOnItemClickListener(newOnItemClickListener(){
  64. @Override
  65. publicvoidonItemClick(AdapterView<?>arg0,Viewarg1,intarg2,
  66. longarg3){
  67. close();
  68. }
  69. });
  70. open();
  71. }
  72. publicvoidinitAnim(){
  73. //采用了绝对布局,绝对布局是view的左上角从(0,0)开始
  74. @SuppressWarnings("deprecation")
  75. finalandroid.widget.AbsoluteLayout.LayoutParamslp=newandroid.widget.AbsoluteLayout.LayoutParams(
  76. LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT,0,0);
  77. findViewById(R.id.slideout_placeholder).setLayoutParams(lp);
  78. //屏幕的宽度
  79. intdisplayWidth=((WindowManager)getSystemService(Context.WINDOW_SERVICE))
  80. .getDefaultDisplay().getWidth();
  81. //右边的位移量,60dp转换成px
  82. intsWidth=(int)TypedValue.applyDimension(
  83. TypedValue.COMPLEX_UNIT_DIP,60,getResources()
  84. .getDisplayMetrics());
  85. //将快照向右移动的偏移量
  86. finalintshift=displayWidth-sWidth;
  87. //向右移动的位移动画向右移动shift距离,y方向不变
  88. mStartAnimation=newTranslateAnimation(TranslateAnimation.ABSOLUTE,
  89. 0,TranslateAnimation.ABSOLUTE,shift,
  90. TranslateAnimation.ABSOLUTE,0,TranslateAnimation.ABSOLUTE,0);
  91. //回退时的位移动画
  92. mStopAnimation=newTranslateAnimation(TranslateAnimation.ABSOLUTE,0,
  93. TranslateAnimation.ABSOLUTE,-shift,
  94. TranslateAnimation.ABSOLUTE,0,TranslateAnimation.ABSOLUTE,0);
  95. //持续时间
  96. mStartAnimation.setDuration(DURATION_MS);
  97. //动画完成时停留在结束位置
  98. mStartAnimation.setFillAfter(true);
  99. mStartAnimation.setAnimationListener(newAnimationListener(){
  100. @Override
  101. publicvoidonAnimationStart(Animationanimation){
  102. }
  103. @Override
  104. publicvoidonAnimationRepeat(Animationanimation){
  105. }
  106. @Override
  107. publicvoidonAnimationEnd(Animationanimation){
  108. //动画结束时回调
  109. //将imageview固定在位移后的位置
  110. mCover.setAnimation(null);
  111. @SuppressWarnings("deprecation")
  112. finalandroid.widget.AbsoluteLayout.LayoutParamslp=newandroid.widget.AbsoluteLayout.LayoutParams(
  113. LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT,
  114. shift,0);
  115. mCover.setLayoutParams(lp);
  116. }
  117. });
  118. mStopAnimation.setDuration(DURATION_MS);
  119. mStopAnimation.setFillAfter(true);
  120. mStopAnimation.setAnimationListener(newAnimationListener(){
  121. @Override
  122. publicvoidonAnimationStart(Animationanimation){
  123. }
  124. @Override
  125. publicvoidonAnimationRepeat(Animationanimation){
  126. }
  127. @Override
  128. publicvoidonAnimationEnd(Animationanimation){
  129. finish();
  130. overridePendingTransition(0,0);
  131. }
  132. });
  133. }
  134. publicvoidopen(){
  135. mCover.startAnimation(mStartAnimation);
  136. }
  137. publicvoidclose(){
  138. mCover.startAnimation(mStopAnimation);
  139. }
  140. @Override
  141. publicbooleanonKeyDown(intkeyCode,KeyEventevent){
  142. //摁返回键时也要触发动画
  143. if(keyCode==KeyEvent.KEYCODE_BACK){
  144. close();
  145. returntrue;
  146. }
  147. returnsuper.onKeyDown(keyCode,event);
  148. }
  149. }
sample.xml

  1. <?xmlversion="1.0"encoding="utf-8"?>
  2. <RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"
  3. android:id="@+id/inner_content"
  4. android:layout_width="fill_parent"
  5. android:layout_height="fill_parent"
  6. android:background="@android:color/white">
  7. <LinearLayout
  8. android:layout_width="fill_parent"
  9. android:layout_height="45dip"
  10. android:background="#bb000000"
  11. android:gravity="center_vertical"
  12. android:orientation="horizontal">
  13. <Button
  14. android:id="@+id/sample_button"
  15. android:layout_width="wrap_content"
  16. android:layout_height="wrap_content"
  17. android:layout_marginRight="10dip"
  18. android:drawableTop="@drawable/menuicon"/>
  19. <TextView
  20. android:layout_width="wrap_content"
  21. android:layout_height="wrap_content"
  22. android:text="slide-outnavigation"
  23. android:textColor="#ffffff"
  24. android:textSize="19sp"/>
  25. </LinearLayout>
  26. </RelativeLayout>
main.xml

  1. <?xmlversion="1.0"encoding="utf-8"?>
  2. <AbsoluteLayoutxmlns:android="http://schemas.android.com/apk/res/android"
  3. android:id="@+id/layout"
  4. android:layout_width="fill_parent"
  5. android:layout_height="fill_parent">
  6. <FrameLayout
  7. android:id="@+id/slideout_placeholder"
  8. android:layout_width="fill_parent"
  9. android:layout_height="fill_parent"
  10. android:background="#777777">
  11. <ListView
  12. android:id="@+id/list"
  13. android:layout_width="fill_parent"
  14. android:layout_height="fill_parent"
  15. android:cacheColorHint="#00000000"/>
  16. </FrameLayout>
  17. <ImageView
  18. android:id="@+id/slidedout_cover"
  19. android:layout_width="fill_parent"
  20. android:layout_height="fill_parent"
  21. android:scaleType="fitXY"/>
  22. </AbsoluteLayout>