Blog / 阅读

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

by admin on 2014-04-09 13:33:19 in ,



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



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



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


其最终实现的效果如下:


当点击按钮后:

具体实现如下:


activity_main.xml:

[java] view plaincopy
<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:


[java] view plaincopy
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的onLayout、layout方法讲解

下一篇:android百度地图开发Demo实例附图和源码

评论

写评论

* 必填.

分享

栏目

赞助商


热门文章

Tag 云