zoukankan      html  css  js  c++  java
  • 自定义侧滑菜单

    详细内容请看代码,注释很详细很详细:

    1:先看xml文件,就是简单的两个线性布局,一个作为当前界面,一个作为隐藏的侧滑界面。

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal"
        tools:context="com.example.actionbar.SlideMenActivity" >
    
    
        <LinearLayout 
            android:id="@+id/menu"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:background="#ff00ff00"
            android:orientation="vertical"
            >
            
        </LinearLayout>
        <LinearLayout
            android:id="@+id/content"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:background="#ffff0000"
            android:orientation="vertical">
            </LinearLayout>
    
    </LinearLayout>

    2:activity的主要代码:

    public class SlideMenActivity extends Activity implements View.OnTouchListener {
        /**
         * 手指每单位时间滑动200个像素
         */
        private static final int SPPED = 200;
        /**
         * 屏幕宽度
         */
        private int mScreenSidth;
        /**
         * menu的layout
         */
        private LinearLayout mMenuLayout;
        /**
         * content的layout
         */
        private LinearLayout mContentLayout;
        /**
         * menu的layout的Paramters
         */
        private LinearLayout.LayoutParams mMenuParams;
        /**
         * menu完全显示的时候给content的宽度值
         */
        private int mMenuPadding = 80;
        /**
         * menu最多滑到左边缘,值由menu布局的宽度决定,marginLeft到达此值之后,不能在减少
         */
        private int mLeftEdge;
        /**
         * 测速度的对象
         */
        private VelocityTracker mVelocityTracker;
        /**
         * 手指按下的X坐标
         */
        private float mXDown;
        /**
         * 手指移动时候的X坐标
         */
        private float mXMove;
        /**
         * 手指抬起的X坐标
         */
        private float mXUp;
        /**
         * menu是否再显示
         */
        private boolean mIsMenuVisible = false;
        
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_slide_men);
            initViewsAndValues();
            mContentLayout.setOnTouchListener(this);
            
            
        }
        
        /**
         * 初始化menu和content并且设置他们的位置
         */
         @SuppressLint("ServiceCast") 
         private void initViewsAndValues(){
             //得到屏幕的宽
             mScreenSidth = getResources().getDisplayMetrics().widthPixels;
             //找到控件
             mMenuLayout = (LinearLayout) findViewById(R.id.menu);
             mContentLayout = (LinearLayout) findViewById(R.id.content);
             //得到menu的parameter
             mMenuParams = (LinearLayout.LayoutParams) mMenuLayout.getLayoutParams();
            //将menu的宽度设置为屏幕宽度减去mMenuPading
             mMenuParams.width = mScreenSidth - mMenuPadding;
             //左边缘的值复制为menu宽度的负数,这样的话就可以将menu隐藏
             mLeftEdge = -mMenuParams.width;
             //将margin设置为mLeftEdge
             mMenuParams.leftMargin = mLeftEdge;
            //将content显示再屏幕上
             mContentLayout.getLayoutParams().width = mScreenSidth;
             
         }
    
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            createVelocityTracker(event);
            switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                //记录按下的x坐标
                mXDown = event.getRawX();
                break;
            case MotionEvent.ACTION_MOVE:
                mXMove = event.getRawX();
                int distanceX = (int)(mXMove - mXDown);
                if(mIsMenuVisible){
                    mMenuParams.leftMargin = distanceX;
                }else{
                    mMenuParams.leftMargin = distanceX + mLeftEdge;
                }
                
                if(mMenuParams.leftMargin < mLeftEdge){
                    //因为leftEdge是负数,就是menu已经隐藏完毕了,不能再往左隐藏了
                    mMenuParams.leftMargin = mLeftEdge;
                }else if(mMenuParams.leftMargin > 0){
                     //menu显示完全了,不能再往右移动了
                    mMenuParams.leftMargin = 0;
                }
                mMenuLayout.setLayoutParams(mMenuParams);
                break;
            case MotionEvent.ACTION_UP:
                mXUp = event.getRawX();
                if(wantToShowMenu()){
                    if(shouldScrollToMenu()){
                        scrollToMenu();
                    }else{
                        //条件不满足,吧menu隐藏
                        scrollToContent();
                    }
                }else if(wantToShowContent()){
                    if(shouldScrollToContent()){
                        scrollToContent();
                    }else{
                        scrollToMenu();
                    }
                }
                break;
    
            default:
                break;
            }
            
            recycleVelocityTrancker();
            return true;
        }
        
        /**
         * 创建VelocityTracker对象,针对于content的界面的滑动事件
         *
         * @param event
         */
        private void createVelocityTracker(MotionEvent event){
            if( null == mVelocityTracker){
                mVelocityTracker = VelocityTracker.obtain();
            }
            mVelocityTracker.addMovement(event);
        }
        /**
         * 判断手势是不是想要显示Content && menu处于显示状态
         *
         * @return
         */
        private boolean wantToShowContent(){
            return mXUp - mXDown < 0 && mIsMenuVisible;
        }
        /**
         * 是不是要显示menu && menu处于隐藏状态
         *
         * @return
         */
        private boolean wantToShowMenu(){
            return mXUp - mXDown > 0 && !mIsMenuVisible;
        }
        /**
         * 是否应该滑动出menu
         *
         * @return
         */
        private boolean shouldScrollToMenu(){
            return mXUp - mXDown > mScreenSidth/2 || getScrollVelocity() > SPPED;
        }
        /**
         * 是否应该让content全部显示出来
         *
         * @return
         */
        private boolean shouldScrollToContent(){
            return mXUp - mXDown < mScreenSidth/2 || getScrollVelocity() > SPPED;
        }
        /**
         * 得到手指滑动速度,每秒移动多少单位像素
         *
         * @return
         */
        private int getScrollVelocity(){
            mVelocityTracker.computeCurrentVelocity(1000);
            int velocity = (int) mVelocityTracker.getXVelocity();
            return Math.abs(velocity);
        }
        /**
         * 显示出menu
         */
        private void scrollToMenu(){
             new ScrollAsyncTask().execute(30);
        }
        /**
         * 隐藏掉menu
         */
        private void scrollToContent(){
             new  ScrollAsyncTask().execute(-30);
        }
        
        /**
         * 回收VelocityTracker对象。
         */
        private void recycleVelocityTrancker(){
            mVelocityTracker.recycle();
            mVelocityTracker = null;
        }
        
        private class ScrollAsyncTask extends AsyncTask<Integer, Integer, Integer>{
    
            
            @Override
            protected Integer doInBackground(Integer... params) {
                //得到当前的margin
                int leftMargin = mMenuParams.leftMargin;
                //不断更改margin的值
                while(true){
                    leftMargin = leftMargin + params[0];
                    if(leftMargin > 0){
                        leftMargin = 0;
                        break;
                    }
                    if(leftMargin < mLeftEdge){
                        leftMargin = mLeftEdge;
                        break;
                    }
                    publishProgress(leftMargin);
                    sleep();
                }
                if(params[0] > 0){
                    mIsMenuVisible = true;            
                }else{
                    mIsMenuVisible = false;
                }
                return leftMargin;
            }
            
            @Override
            protected void onPostExecute(Integer result) {
                mMenuParams.leftMargin = result;
                mMenuLayout.setLayoutParams(mMenuParams);
            }
            
            @Override
            protected void onProgressUpdate(Integer... values) {
                mMenuParams.leftMargin = values[0];
                mMenuLayout.setLayoutParams(mMenuParams);
            }
            
        }
        
        private void sleep(){
            try {
                Thread.sleep(20);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        
        
    }

    到此全部结束。

    代码改变世界!

  • 相关阅读:
    BZOJ2870 最长道路
    为什么要设置Java环境变量
    JavaMail收发邮件的步骤
    Java 7开发者预览版发布
    J2EE的13种核心技术
    jdk1.5、1.6、1.7新特性详细介绍(整理)
    JAVAEE5 VS JAVAEE6
    TOCMAT的web.xml详解(转贴)
    setAttribute()和getAttribute()
    jsp servlet的区别和联系
  • 原文地址:https://www.cnblogs.com/wei1228565493/p/4687972.html
Copyright © 2011-2022 走看看