Android滑动菜单实现,仿天天动听侧滑成效

Android滑动菜单实现,仿天天动听侧滑效果

最近在做音乐播放软件,设计UI时,看了几款音乐播放软件,发现天天动听有个特效特别好。也就是点击主界面某个菜单按钮或手指向左滑动时,就可以将内容展现出来,而主界面被隐藏一部分。其效果图如下:

Android滑动菜单实现,仿天天动听侧滑成效

当点击右下角的按钮时,则会:

Android滑动菜单实现,仿天天动听侧滑成效

其实现原理为,在一个Activity的布局中需要有两部分,一个是菜单(menu)的布局,一个是(content)的布局。两个布局横向排列,菜单布局在左,内容布局在右。初始化时菜单布局完全显示在屏幕上,此时内容布局就会在屏幕右侧从而看不见。当点击菜单布局上的按钮时,就会时菜单布局向左偏移,以使得内容布局呈现在屏幕上。

其最终实现的效果如下:

Android滑动菜单实现,仿天天动听侧滑成效

当点击按钮后:

Android滑动菜单实现,仿天天动听侧滑成效


具体实现如下:

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="#b2d235" > 
        <Button
            android:id="@+id/button1" 
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="打开"/> 
    </LinearLayout>  
  
    <LinearLayout  
        android:id="@+id/content"  
        android:layout_width="fill_parent"  
        android:layout_height="fill_parent"  
        android:background="@drawable/right">  
    </LinearLayout>  
  
</LinearLayout>  

MainActivity.java:

package com.ye_yun_lin.mytest;

import android.os.AsyncTask;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.LinearLayout;
import android.app.Activity;
import android.content.Context;

public class MainActivity extends Activity implements OnTouchListener{
	private Button backButton;
	private boolean isMenuVisible;
	public static final int SNAP_VELOCITY = 200;
	private int screenWidth;
	private int leftEdge;
	private int rightEdge = 0;
	private int menuPadding = 180;
	private View content;
	private View menu;
	private LinearLayout.LayoutParams menuParams;
	private LinearLayout.LayoutParams contentParams;
	private float xDown;
	private float xMove;
	private float xUp;
	private VelocityTracker mVelocityTracker;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		initvalues();
		menu.setOnTouchListener(this);
		
		backButton=(Button)findViewById(R.id.button1);
		
		backButton.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				menuParams.leftMargin=leftEdge;
				menu.setLayoutParams(menuParams);
				isMenuVisible=false;
			}
		});
	}
	
	@SuppressWarnings("deprecation")
	private void initvalues(){
		WindowManager window = (WindowManager) getSystemService(Context.WINDOW_SERVICE);  
        screenWidth = window.getDefaultDisplay().getWidth();
        menu=findViewById(R.id.menu);
        content=findViewById(R.id.content);
        menuParams=(LinearLayout.LayoutParams)menu.getLayoutParams();
        contentParams=(LinearLayout.LayoutParams)content.getLayoutParams();
        menuParams.width=screenWidth;
        contentParams.width=menuPadding;
        menuParams.leftMargin=rightEdge;
        leftEdge=-menuPadding;
	}

	@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:
			xMove = event.getRawX();
			int distanceX = (int) (xMove - xDown);
			System.out.println("------->>"+distanceX);
			if (isMenuVisible) {  
                menuParams.leftMargin = distanceX;  
            } else {  
                menuParams.leftMargin = leftEdge + distanceX;  
            }  
            if (menuParams.leftMargin < leftEdge) {  
                menuParams.leftMargin = leftEdge;  
            } else if (menuParams.leftMargin > rightEdge) {  
                menuParams.leftMargin = rightEdge;  
            }  
			menu.setLayoutParams(menuParams);
			break; 
			
		case MotionEvent.ACTION_UP:
			xUp = event.getRawX();
			if (wantToShowMenu()) {  
                if (shouldScrollToMenu()) {  
                    scrollToMenu();  
                } else {  
                    scrollToContent();  
                }  
            } else if (wantToShowContent()) {  
                if (shouldScrollToContent()) {  
                    scrollToContent();  
                } else {  
                    scrollToMenu();  
                }  
            }  
            recycleVelocityTracker();  
            break;  
		}
		return true;
	}
	
	private void createVelocityTracker(MotionEvent event) {  
        if (mVelocityTracker == null) {  
            mVelocityTracker = VelocityTracker.obtain();  
        }  
        mVelocityTracker.addMovement(event);  
    }
	
	private int getScrollVelocity() {  
        mVelocityTracker.computeCurrentVelocity(1000);  
        int velocity = (int) mVelocityTracker.getXVelocity();  
        return Math.abs(velocity);  
    }  
	
	private void recycleVelocityTracker() {  
        mVelocityTracker.recycle();  
        mVelocityTracker = null;  
    } 
	
	private boolean wantToShowContent() {  
        return xUp - xDown < 0;  
    }
	
	private boolean wantToShowMenu() {  
        return xUp - xDown > 0;  
    } 
	
	private boolean shouldScrollToMenu() {  
        return xUp - xDown > menuPadding || getScrollVelocity() > SNAP_VELOCITY;  
    }
	
	private boolean shouldScrollToContent() {  
        return xDown - xUp > menuPadding || getScrollVelocity() > SNAP_VELOCITY;  
    }
	
	private void scrollToMenu() {  
        new ScrollTask().execute(30);  
    }
	
	private void scrollToContent() {  
        new ScrollTask().execute(-30);  
    }
	
	class ScrollTask extends AsyncTask<Integer, Integer, Integer> {  
		  
        @Override  
        protected Integer doInBackground(Integer... speed) {  
            int leftMargin = menuParams.leftMargin;  
            while (true) {  
                leftMargin = leftMargin + speed[0];  
                if (leftMargin > rightEdge) {  
                    leftMargin = rightEdge;  
                    break;  
                }  
                if (leftMargin < leftEdge) {  
                    leftMargin = leftEdge;  
                    break;  
                }  
                publishProgress(leftMargin);  
                sleep(20);
                
            }
            if (speed[0] > 0) {  
                isMenuVisible = true;  
            } else {  
            	isMenuVisible = false;  
            } 
            return leftMargin;  
        }
        
        @Override  
        protected void onProgressUpdate(Integer... leftMargin) {  
            menuParams.leftMargin = leftMargin[0];  
            menu.setLayoutParams(menuParams);  
        }  
  
        @Override  
        protected void onPostExecute(Integer leftMargin) {  
            menuParams.leftMargin = leftMargin;  
            menu.setLayoutParams(menuParams);  
        }  
    }
	
	private void sleep(long millis) {  
        try {  
            Thread.sleep(millis);  
        } catch (InterruptedException e) {  
            e.printStackTrace();  
        }  
    }  
}

最终效果如下:

Android滑动菜单实现,仿天天动听侧滑成效---->Android滑动菜单实现,仿天天动听侧滑成效

Android滑动菜单实现,仿天天动听侧滑成效