Android滑动菜单特效实现,仿人人客户端侧滑效果,史上最简单的侧滑实现
http://blog.****.net/guolin_blog/article/details/8714621
人人客户端有一个特效还是挺吸引人的,在主界面手指向右滑动,就可以将菜单展示出来,而主界面会被隐藏大部分,但是仍有左侧的一小部分同菜单一起展示。
据说人人客户端的这个特效是从facebook客户端模仿来的,至于facebook是不是又从其它地方模仿来的就不得而知了。好,今天我们就一起来实现这个效果,总之我第一次看到这个特效是在人人客户端看到的,我也就主观性地认为我是在模仿人人客户端的特效了。
虽然现在网上类似这种效果的实现也非常多,可是我发现实现方案大都非常复杂,并不容易理解。但其实这种效果并不难实现,因此我今天给大家带来的也是史上最简单的滑动菜单实现方案。
首先还是讲一下实现原理。在一个Activity的布局中需要有两部分,一个是菜单(menu)的布局,一个是内容(content)的布局。两个布局横向排列,菜单布局在左,内容布局在右。初始化的时候将菜单布局向左偏移,以至于能够完全隐藏,这样内容布局就会完全显示在Activity中。然后通过监听手指滑动事件,来改变菜单布局的左偏移距离,从而控制菜单布局的显示和隐藏。原理图如下:
将菜单布局的左偏移值改成0时,效果图如下:
好,我们开始用代码来实现。首先在Eclipse中新建一个Android项目,项目名就叫做RenRenSlideMenuDemo。然后写一下布局文件,创建或打开layout目录下的activity_main.xml文件,加入如下代码:
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:orientation="horizontal"
- tools:context=".MainActivity" >
- <LinearLayout
- android:id="@+id/menu"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:background="@drawable/menu" >
- </LinearLayout>
- <LinearLayout
- android:id="@+id/content"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:background="@drawable/content" >
- </LinearLayout>
- </LinearLayout>
创建或打开MainActivity,这个类仍然是程序的主Activity,也是这次demo唯一的Activity,在里面加入如下代码:
- public class MainActivity extends Activity implements OnTouchListener {
- /**
- * 滚动显示和隐藏menu时,手指滑动需要达到的速度。
- */
- public static final int SNAP_VELOCITY = 200;
- /**
- * 屏幕宽度值。
- */
- private int screenWidth;
- /**
- * menu最多可以滑动到的左边缘。值由menu布局的宽度来定,marginLeft到达此值之后,不能再减少。
- */
- private int leftEdge;
- /**
- * menu最多可以滑动到的右边缘。值恒为0,即marginLeft到达0之后,不能增加。
- */
- private int rightEdge = 0;
- /**
- * menu完全显示时,留给content的宽度值。
- */
- private int menuPadding = 80;
- /**
- * 主内容的布局。
- */
- private View content;
- /**
- * menu的布局。
- */
- private View menu;
- /**
- * menu布局的参数,通过此参数来更改leftMargin的值。
- */
- private LinearLayout.LayoutParams menuParams;
- /**
- * 记录手指按下时的横坐标。
- */
- private float xDown;
- /**
- * 记录手指移动时的横坐标。
- */
- private float xMove;
- /**
- * 记录手机抬起时的横坐标。
- */
- private float xUp;
- /**
- * menu当前是显示还是隐藏。只有完全显示或隐藏menu时才会更改此值,滑动过程中此值无效。
- */
- private boolean isMenuVisible;
- /**
- * 用于计算手指滑动的速度。
- */
- private VelocityTracker mVelocityTracker;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- initValues();
- content.setOnTouchListener(this);
- }
- /**
- * 初始化一些关键性数据。包括获取屏幕的宽度,给content布局重新设置宽度,给menu布局重新设置宽度和偏移距离等。
- */
- private void initValues() {
- WindowManager window = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
- screenWidth = window.getDefaultDisplay().getWidth();
- content = findViewById(R.id.content);
- menu = findViewById(R.id.menu);
- menuParams = (LinearLayout.LayoutParams) menu.getLayoutParams();
- // 将menu的宽度设置为屏幕宽度减去menuPadding
- menuParams.width = screenWidth - menuPadding;
- // 左边缘的值赋值为menu宽度的负数
- leftEdge = -menuParams.width;
- // menu的leftMargin设置为左边缘的值,这样初始化时menu就变为不可见
- menuParams.leftMargin = leftEdge;
- // 将content的宽度设置为屏幕宽度
- content.getLayoutParams().width = screenWidth;
- }
- @Override
- public boolean onTouch(View v, MotionEvent event) {
- createVelocityTracker(event);
- switch (event.getAction()) {
- case MotionEvent.ACTION_DOWN:
- // 手指按下时,记录按下时的横坐标
- xDown = event.getRawX();
- break;
- case MotionEvent.ACTION_MOVE:
- // 手指移动时,对比按下时的横坐标,计算出移动的距离,来调整menu的leftMargin值,从而显示和隐藏menu
- xMove = event.getRawX();
- int distanceX = (int) (xMove - xDown);