仿人人客户端向右滑出式菜单
人人客户端向右滑出式菜单:
试着实现了一个,先上效果图:
下面简单说明一下实现原理:
有两个activity,MainActivity和SettingActivity,实现这个效果两个步骤:
1、点击MainActivity左上角的按钮,MainActivity先切换到SettingActivity,获得MainActivity的布局快照,即一张代表其布局的bitmap
2、SettingActivity采用绝对布局,最上面先是覆盖了一张透明的imageView,接着将这个imageview填充上上一步的布局快照,然后通过位移动画移动这张imageView,给人的感觉就好像是前一个activity在移动。
待改进:加入手势控制。
希望大家提出更好的实现方法。
上代码:有注释
MainActivity.java
- importandroid.app.Activity;
- importandroid.content.Intent;
- importandroid.os.Bundle;
- importandroid.util.Log;
- importandroid.view.GestureDetector;
- importandroid.view.GestureDetector.OnGestureListener;
- importandroid.view.MotionEvent;
- importandroid.view.View;
- importandroid.view.View.OnClickListener;
- importandroid.view.View.OnTouchListener;
- importandroid.widget.Toast;
- publicclassMainActivityextendsActivity{
- @Override
- protectedvoidonCreate(BundlesavedInstanceState){
- super.onCreate(savedInstanceState);
- setContentView(R.layout.sample);
- findViewById(R.id.sample_button).setOnClickListener(
- newOnClickListener(){
- @Override
- publicvoidonClick(Viewv){
- SettingActivity.prepare(MainActivity.this,
- R.id.inner_content);
- startActivity(newIntent(MainActivity.this,
- SettingActivity.class));
- overridePendingTransition(0,0);
- }
- });
- }
- }
- importandroid.app.Activity;
- importandroid.content.Context;
- importandroid.graphics.Bitmap;
- importandroid.graphics.Bitmap.Config;
- importandroid.graphics.Canvas;
- importandroid.os.Bundle;
- importandroid.util.TypedValue;
- importandroid.view.KeyEvent;
- importandroid.view.View;
- importandroid.view.View.OnClickListener;
- importandroid.view.WindowManager;
- importandroid.view.animation.Animation;
- importandroid.view.animation.Animation.AnimationListener;
- importandroid.view.animation.TranslateAnimation;
- importandroid.widget.AdapterView;
- importandroid.widget.AdapterView.OnItemClickListener;
- importandroid.widget.ArrayAdapter;
- importandroid.widget.ImageView;
- importandroid.widget.ListView;
- importandroid.widget.RelativeLayout.LayoutParams;
- publicclassSettingActivityextendsActivity{
- privateImageViewmCover;
- privateListViewmList;
- privateAnimationmStartAnimation;
- privateAnimationmStopAnimation;
- privatestaticfinalintDURATION_MS=400;
- privatestaticBitmapsCoverBitmap=null;
- //2个步骤
- //1.activity-->otheractivity
- //2.anim
- //先切换到另一个activity
- //再获得之前activity屏幕的快照将它作为一个cover覆盖在下一个屏幕的上面,然后通过动画移动这个cover,让人感觉好像是前一个屏幕的移动。
- publicstaticvoidprepare(Activityactivity,intid){
- if(sCoverBitmap!=null){
- sCoverBitmap.recycle();
- }
- //用指定大小生成一张透明的32位位图,并用它构建一张canvas画布
- sCoverBitmap=Bitmap.createBitmap(
- activity.findViewById(id).getWidth(),activity.findViewById(id)
- .getHeight(),Config.ARGB_8888);
- Canvascanvas=newCanvas(sCoverBitmap);
- //将指定的view包括其子view渲染到这种画布上,在这就是上一个activity布局的一个快照,现在这个bitmap上就是上一个activity的快照
- activity.findViewById(id).draw(canvas);
- }
- @Override
- publicvoidonCreate(BundlesavedInstanceState){
- super.onCreate(savedInstanceState);
- //绝对布局最上层覆盖了一个imageview
- setContentView(R.layout.main);
- initAnim();
- mCover=(ImageView)findViewById(R.id.slidedout_cover);
- mCover.setImageBitmap(sCoverBitmap);
- mCover.setOnClickListener(newOnClickListener(){
- @Override
- publicvoidonClick(Viewv){
- close();
- }
- });
- mList=(ListView)findViewById(R.id.list);
- mList.setAdapter(newArrayAdapter<String>(SettingActivity.this,
- android.R.layout.simple_list_item_1,newString[]{"First",
- "Second","Third","Fourth","Fifth","Sixth"}));
- mList.setOnItemClickListener(newOnItemClickListener(){
- @Override
- publicvoidonItemClick(AdapterView<?>arg0,Viewarg1,intarg2,
- longarg3){
- close();
- }
- });
- open();
- }
- publicvoidinitAnim(){
- //采用了绝对布局,绝对布局是view的左上角从(0,0)开始
- @SuppressWarnings("deprecation")
- finalandroid.widget.AbsoluteLayout.LayoutParamslp=newandroid.widget.AbsoluteLayout.LayoutParams(
- LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT,0,0);
- findViewById(R.id.slideout_placeholder).setLayoutParams(lp);
- //屏幕的宽度
- intdisplayWidth=((WindowManager)getSystemService(Context.WINDOW_SERVICE))
- .getDefaultDisplay().getWidth();
- //右边的位移量,60dp转换成px
- intsWidth=(int)TypedValue.applyDimension(
- TypedValue.COMPLEX_UNIT_DIP,60,getResources()
- .getDisplayMetrics());
- //将快照向右移动的偏移量
- finalintshift=displayWidth-sWidth;
- //向右移动的位移动画向右移动shift距离,y方向不变
- mStartAnimation=newTranslateAnimation(TranslateAnimation.ABSOLUTE,
- 0,TranslateAnimation.ABSOLUTE,shift,
- TranslateAnimation.ABSOLUTE,0,TranslateAnimation.ABSOLUTE,0);
- //回退时的位移动画
- mStopAnimation=newTranslateAnimation(TranslateAnimation.ABSOLUTE,0,
- TranslateAnimation.ABSOLUTE,-shift,
- TranslateAnimation.ABSOLUTE,0,TranslateAnimation.ABSOLUTE,0);
- //持续时间
- mStartAnimation.setDuration(DURATION_MS);
- //动画完成时停留在结束位置
- mStartAnimation.setFillAfter(true);
- mStartAnimation.setAnimationListener(newAnimationListener(){
- @Override
- publicvoidonAnimationStart(Animationanimation){
- }
- @Override
- publicvoidonAnimationRepeat(Animationanimation){
- }
- @Override
- publicvoidonAnimationEnd(Animationanimation){
- //动画结束时回调
- //将imageview固定在位移后的位置
- mCover.setAnimation(null);
- @SuppressWarnings("deprecation")
- finalandroid.widget.AbsoluteLayout.LayoutParamslp=newandroid.widget.AbsoluteLayout.LayoutParams(
- LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT,
- shift,0);
- mCover.setLayoutParams(lp);
- }
- });
- mStopAnimation.setDuration(DURATION_MS);
- mStopAnimation.setFillAfter(true);
- mStopAnimation.setAnimationListener(newAnimationListener(){
- @Override
- publicvoidonAnimationStart(Animationanimation){
- }
- @Override
- publicvoidonAnimationRepeat(Animationanimation){
- }
- @Override
- publicvoidonAnimationEnd(Animationanimation){
- finish();
- overridePendingTransition(0,0);
- }
- });
- }
- publicvoidopen(){
- mCover.startAnimation(mStartAnimation);
- }
- publicvoidclose(){
- mCover.startAnimation(mStopAnimation);
- }
- @Override
- publicbooleanonKeyDown(intkeyCode,KeyEventevent){
- //摁返回键时也要触发动画
- if(keyCode==KeyEvent.KEYCODE_BACK){
- close();
- returntrue;
- }
- returnsuper.onKeyDown(keyCode,event);
- }
- }
- <?xmlversion="1.0"encoding="utf-8"?>
- <RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/inner_content"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:background="@android:color/white">
- <LinearLayout
- android:layout_width="fill_parent"
- android:layout_height="45dip"
- android:background="#bb000000"
- android:gravity="center_vertical"
- android:orientation="horizontal">
- <Button
- android:id="@+id/sample_button"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginRight="10dip"
- android:drawableTop="@drawable/menuicon"/>
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="slide-outnavigation"
- android:textColor="#ffffff"
- android:textSize="19sp"/>
- </LinearLayout>
- </RelativeLayout>
- <?xmlversion="1.0"encoding="utf-8"?>
- <AbsoluteLayoutxmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/layout"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent">
- <FrameLayout
- android:id="@+id/slideout_placeholder"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:background="#777777">
- <ListView
- android:id="@+id/list"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:cacheColorHint="#00000000"/>
- </FrameLayout>
- <ImageView
- android:id="@+id/slidedout_cover"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:scaleType="fitXY"/>
- </AbsoluteLayout>