zoukankan      html  css  js  c++  java
  • 它们的定义android滑动菜单

    在这里实现了两个滑动菜单效果,的拖放内容的第一部分,菜单拖出像这样的效果感觉,另一种是拖动内容。后面的内容固定菜单。我感觉有层次感的效果,如下面



    第一种效果的代码实现例如以下:

    package com.tenghu.customsideslip.menu.view;
    
    import android.content.Context;
    import android.os.AsyncTask;
    import android.util.AttributeSet;
    import android.util.DisplayMetrics;
    import android.view.MotionEvent;
    import android.view.VelocityTracker;
    import android.view.View;
    import android.view.WindowManager;
    import android.widget.LinearLayout;
    
    /**
     * Created by Arvin_Li on 2014/11/19.
     */
    public class ScrollSideslipMenu extends LinearLayout{
    
        private static final int SNAP_VELOCITY=200;//速度阈值
        private View mMenu;//菜单布局
        private View mContent;//内容布局
    
        private int screenWidth;//屏幕宽度
        private int menuWidth;//菜单宽度
    
        private int leftEdge;//左边界
        private int rightEdge=0;//右边界。值恒为0
    
        private float xUp;//手指抬起时记录横坐标
        private float xDown;//手指按下时记录横坐标
        private float xMove;//手指移动时记录横坐标
    
        private int toRightPaddingWidth=50;//菜单全然显示时,留给内容的宽度
        private LayoutParams menuParams;//菜单布局參数
    
        private boolean once=false;//初始化数据仅仅载入一次
        private boolean isShowMenu;//是否显示菜单
    
        private VelocityTracker velocityTracker;//速度跟踪器
    
        public ScrollSideslipMenu(Context context) {
            super(context);
            initWindowWidth(context);
        }
    
        public ScrollSideslipMenu(Context context, AttributeSet attrs) {
            super(context, attrs);
            initWindowWidth(context);
        }
    
        /**
         * 初始化获取屏幕宽度
         */
        private void initWindowWidth(Context context){
            WindowManager windowManager= (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
            DisplayMetrics displayMetrics=new DisplayMetrics();
            windowManager.getDefaultDisplay().getMetrics(displayMetrics);
            //获取屏幕宽度
            screenWidth=displayMetrics.widthPixels;
        }
    
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            if(!once){
                mMenu=this.getChildAt(0);//获取菜单布局
                mContent=this.getChildAt(1);//获取内容布局
                menuParams= (LayoutParams) mMenu.getLayoutParams();//获取菜单布局參数
                menuWidth=menuParams.width=screenWidth-toRightPaddingWidth;//设置菜单宽度
                mContent.getLayoutParams().width=screenWidth;//设置内容宽度
                leftEdge=-menuWidth;//左边界
                menuParams.leftMargin=leftEdge;//默认菜单不显示
                once=true;
            }
        }
    
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            createVelocityTracker(event);
            switch (event.getAction()){
                //按下
                case MotionEvent.ACTION_DOWN:
                    xDown=event.getRawX();//记录按下时的横坐标
                    break;
                //移动
                case MotionEvent.ACTION_MOVE:
                    //记录移动时的横坐标
                    xMove=event.getRawX();
                    //计算移动时与按下时的距离
                    int moveDistanceX= (int) (xMove-xDown);
                    if(isShowMenu){
                        menuParams.leftMargin=moveDistanceX;
                    }else{
                        menuParams.leftMargin=leftEdge+moveDistanceX;
                    }
    
                    if(menuParams.leftMargin<leftEdge){
                        menuParams.leftMargin=leftEdge;
                    }
    
                    if(menuParams.leftMargin>rightEdge){
                        menuParams.leftMargin=rightEdge;
                    }
    
                    mMenu.setLayoutParams(menuParams);//设置參数
                    break;
                //抬起
                case MotionEvent.ACTION_UP:
                    //记录抬起时的横坐标
                    xUp=event.getRawX();
                    //计算抬起时与按下时的距离
                    int upDistanceX= (int) (xUp-xDown);
                    if(upDistanceX>0&&!isShowMenu){
                        if(upDistanceX>menuWidth/2||getScrollVelocity()>SNAP_VELOCITY){
                            scrollToMenu();
    
                        }else{
                            scrollToContent();
                        }
                    }else if(upDistanceX<0&&isShowMenu){
                        if(Math.abs(upDistanceX)>menuWidth/2||getScrollVelocity()>SNAP_VELOCITY){
                            scrollToContent();
                        }else{
                            scrollToMenu();
                        }
                    }
                    mMenu.setLayoutParams(menuParams);
                    break;
            }
            return true;
        }
    
        /**
         * 滚动内容部分
         */
        private void scrollToContent(){
            new ScrollTask().execute(-30);
        }
    
        /**
         * 滚动菜单部分
         */
        private void scrollToMenu(){
            new ScrollTask().execute(30);
        }
    
        /**
         * 创建速度阈值
         */
        private void createVelocityTracker(MotionEvent event){
            if(null==velocityTracker){
                velocityTracker=VelocityTracker.obtain();
            }
            velocityTracker.addMovement(event);
        }
    
        /**
         * 获取滚动时的速度
         * @return
         */
        private int getScrollVelocity(){
            velocityTracker.computeCurrentVelocity(1000);
            int velocity= (int) velocityTracker.getXVelocity();//获取横向速度
            return Math.abs(velocity);
        }
    
        /**
         * 创建一个异步滚动任务
         */
        class ScrollTask extends AsyncTask<Integer,Integer,Integer>{
    
            @Override
            protected Integer doInBackground(Integer... params) {
                int leftMargin=menuParams.leftMargin;
                while(true){
                    leftMargin=leftMargin+params[0];
                    if(leftMargin<leftEdge){
                        leftMargin=leftEdge;
                        break;
                    }
                    if(leftMargin>rightEdge){
                        leftMargin=rightEdge;
                        break;
                    }
                    publishProgress(leftMargin);
                    sleep(20);
                }
    
                if(params[0]>0){
                    isShowMenu=true;
                }else{
                    isShowMenu=false;
                }
                return leftMargin;
    
            }
    
            /**
             * 运行结束
             * @param integer
             */
            @Override
            protected void onPostExecute(Integer integer) {
                menuParams.leftMargin=integer;
                mMenu.setLayoutParams(menuParams);
            }
    
            /**
             * 运行doInBackground中的publishProgress调用该方法
             * @param values
             */
            @Override
            protected void onProgressUpdate(Integer... values) {
                menuParams.leftMargin=values[0];
                mMenu.setLayoutParams(menuParams);
            }
        }
    
        /**
         * 当前线程睡眠多少毫秒
         * @param millis
         */
        private void sleep(long millis){
            try {
                Thread.sleep(millis);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    

    布局文件:

    <?xml version="1.0" encoding="utf-8"?

    > <com.tenghu.customsideslip.menu.view.ScrollSideslipMenu xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal" android:background="@drawable/bg_01"> <!--引用菜单布局文件--> <include layout="@layout/left_menu"/> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/bg_02"></LinearLayout> </com.tenghu.customsideslip.menu.view.ScrollSideslipMenu>


    另外一种效果实现:

    package com.tenghu.customsideslip.menu.view;
    
    import android.content.Context;
    import android.os.AsyncTask;
    import android.util.AttributeSet;
    import android.util.DisplayMetrics;
    import android.view.MotionEvent;
    import android.view.VelocityTracker;
    import android.view.View;
    import android.view.WindowManager;
    import android.widget.RelativeLayout;
    
    /**
     * Created by Arvin_Li on 2014/11/19.
     */
    public class CustomSideslipMenu extends RelativeLayout {
        private static final int SNAP_VELOCITY=200;//手势滑动的速度
        //屏幕宽度
        private int mScreenWidth;
        //菜单布局
        private View mMenu;
        //主体内容部分
        private View mContent;
        //声明菜单宽度
        private int menuWidth;
        //菜单全然显示时。留给内容部分的宽度
        private int toRightPaddingWidth=50;
        //主体内容布局參数
        private LayoutParams contentParams;
        //主体内容滑动到左边缘,由菜单宽度来决定
        private int leftEdge;
        //菜单显示时。主体内容到右边界,值恒为0
        private int rightEdge=0;
        private VelocityTracker velocityTracker;//声明速度跟踪器
        private float xDown;//记录手指按下的横坐标
        private float xUp;//记录手指抬起时的横坐标
        private float xMove;//记录手指移动时的横坐标
        private boolean once=false;//仅仅运行一次
        private boolean isShowMenu=true;//是否显示菜单
        public CustomSideslipMenu(Context context) {
            super(context);
            init(context);
        }
    
        public CustomSideslipMenu(Context context, AttributeSet attrs) {
            super(context, attrs);
            init(context);
        }
    
        /**
         * 初始化
         */
        private void init(Context context){
            //获取窗体管理类
            WindowManager windowManager= (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
            //创建DisplayMetrics
            DisplayMetrics displayMetrics=new DisplayMetrics();
            windowManager.getDefaultDisplay().getMetrics(displayMetrics);
            //获取屏幕宽度
            mScreenWidth=displayMetrics.widthPixels;
        }
    
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            if(!once){
                //获取菜单布局
                mMenu=this.getChildAt(0);
                //获取主体内容布局
                mContent=this.getChildAt(1);
                contentParams= (LayoutParams) mContent.getLayoutParams();//获取主体菜单參数
                //菜单宽度
                menuWidth=mMenu.getLayoutParams().width=mScreenWidth-toRightPaddingWidth;
                //设置主体内容的宽度
                mContent.getLayoutParams().width=mScreenWidth;
                leftEdge=menuWidth;//设置左边界
                once=true;
            }
        }
    
        @Override
        public boolean onTouchEvent(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);
                    if(isShowMenu){
                        contentParams.leftMargin=distanceX;
                        contentParams.rightMargin=-distanceX;
                    }else{
                        contentParams.leftMargin=leftEdge+distanceX;
                    }
    
                    if(contentParams.leftMargin>leftEdge){
                        contentParams.leftMargin=leftEdge;
                        contentParams.rightMargin=-leftEdge;
                    }
    
                    if(contentParams.leftMargin<rightEdge){
                        contentParams.leftMargin=rightEdge;
                        contentParams.rightMargin=rightEdge;
                    }
                    mContent.setLayoutParams(contentParams);//測试參数
                    break;
                //手指抬起
                case MotionEvent.ACTION_UP:
                    xUp=event.getRawX();//手指抬起时横坐标
                    //计算抬起时与按下时的距离
                    int upDistanceX=(int) (xDown-xUp);
                    if(upDistanceX>0&&!isShowMenu){
                            if(upDistanceX>menuWidth/2||getScrollVelocity()>SNAP_VELOCITY){
                                scrollToMenu();
                            }else{
                                scrollToContent();
                            }
                    }else if(upDistanceX<0&&isShowMenu){
                        if(Math.abs(upDistanceX)>menuWidth/2||getScrollVelocity()>SNAP_VELOCITY){
                            scrollToContent();
                        }else{
                            scrollToMenu();
                        }
                        //手指抬起时销毁
                        recycleVelocityTracker();
                    }
                    break;
            }
            return true;
        }
    
        /**
         * 滚动菜单
         */
        private void scrollToMenu(){
            new ScrollTask().execute(-30);
        }
    
        /**
         * 滚动内容
         */
        private void scrollToContent(){
            new ScrollTask().execute(30);
        }
    
        /**
         * 获取速度
         * @return
         */
        private int getScrollVelocity(){
            velocityTracker.computeCurrentVelocity(1000);
            int velocity= (int) velocityTracker.getXVelocity();
            return Math.abs(velocity);
        }
    
        /**
         * 销毁速度跟踪器
         */
        private void recycleVelocityTracker(){
            if (null != velocityTracker) {
                velocityTracker.recycle();
                velocityTracker = null;
            }
        }
    
    
        /**
         * 创建速度跟踪器
         */
        private void createVelocityTracker(MotionEvent event){
            if(null==velocityTracker){
                velocityTracker=velocityTracker.obtain();
            }
            velocityTracker.addMovement(event);
        }
    
        /**
         * 创建异步滚动任务类
         */
        class ScrollTask extends AsyncTask<Integer,Integer,Integer>{
    
            @Override
            protected Integer doInBackground(Integer... params) {
                int leftMargin=contentParams.leftMargin;
                while(true){
                    leftMargin=leftMargin+params[0];
                    if(leftMargin>leftEdge){
                        leftMargin=leftEdge;
                        break;
                    }
    
                    if(leftMargin<rightEdge){
                        leftMargin=rightEdge;
                        break;
                    }
                    if(params[0]<0){
                        isShowMenu=true;
                       // leftMargin=rightEdge;
                    }else{
                        isShowMenu=false;
                    }
                    publishProgress(leftMargin);
                    sleep(20);
                }
                return leftMargin;
            }
    
            @Override
            protected void onProgressUpdate(Integer... values) {
                contentParams.leftMargin=values[0];
               contentParams.rightMargin=-values[0];
                mContent.setLayoutParams(contentParams);
            }
    
            @Override
            protected void onPostExecute(Integer integer) {
                contentParams.leftMargin=integer;
               contentParams.rightMargin=-integer;
                mContent.setLayoutParams(contentParams);
            }
        }
    
        /**
         * 当前线程睡眠多少毫秒
         * @param millis
         */
        private void sleep(long millis){
            try {
                Thread.sleep(millis);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    

    布局文件:

    <com.tenghu.customsideslip.menu.view.CustomSideslipMenu 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:background="@drawable/bg_01"
        tools:context=".MainActivity">
    
        <include layout="@layout/left_menu" />
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">
    
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:background="@drawable/bg_02"
                android:orientation="vertical">
                <Button
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:onClick="testScrollMenu"
                    android:text="測试另外一种側滑菜单"/>
            </LinearLayout>
        </LinearLayout>
    </com.tenghu.customsideslip.menu.view.CustomSideslipMenu>
    

    菜单布局文件:

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center_vertical">
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginLeft="30dp"
            android:orientation="vertical">
    
            <RelativeLayout
                android:layout_width="wrap_content"
                android:layout_height="50dp"
                android:layout_marginBottom="10dp">
    
                <ImageView
                    android:id="@+id/iv_img_01"
                    android:layout_width="50dp"
                    android:layout_height="match_parent"
                    android:src="@drawable/app_01" />
    
                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:layout_marginLeft="10dp"
                    android:layout_toRightOf="@id/iv_img_01"
                    android:gravity="center_vertical"
                    android:text="第一个Item" />
            </RelativeLayout>
    
            <RelativeLayout
                android:layout_width="wrap_content"
                android:layout_height="50dp"
                android:layout_marginBottom="10dp">
    
                <ImageView
                    android:id="@+id/iv_img_02"
                    android:layout_width="50dp"
                    android:layout_height="match_parent"
                    android:src="@drawable/app_02" />
    
                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:layout_marginLeft="10dp"
                    android:layout_toRightOf="@id/iv_img_02"
                    android:gravity="center_vertical"
                    android:text="第二个Item" />
            </RelativeLayout>
    
            <RelativeLayout
                android:layout_width="wrap_content"
                android:layout_height="50dp"
                android:layout_marginBottom="10dp">
    
                <ImageView
                    android:id="@+id/iv_img_03"
                    android:layout_width="50dp"
                    android:layout_height="match_parent"
                    android:src="@drawable/app_03" />
    
                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:layout_marginLeft="10dp"
                    android:layout_toRightOf="@id/iv_img_03"
                    android:gravity="center_vertical"
                    android:text="第三个Item" />
            </RelativeLayout>
    
            <RelativeLayout
                android:layout_width="wrap_content"
                android:layout_height="50dp"
                android:layout_marginBottom="10dp">
    
                <ImageView
                    android:id="@+id/iv_img_04"
                    android:layout_width="50dp"
                    android:layout_height="match_parent"
                    android:src="@drawable/app_04" />
    
                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:layout_marginLeft="10dp"
                    android:layout_toRightOf="@id/iv_img_04"
                    android:gravity="center_vertical"
                    android:text="第四个Item" />
            </RelativeLayout>
    
            <RelativeLayout
                android:layout_width="wrap_content"
                android:layout_height="50dp"
                android:layout_marginBottom="10dp">
    
                <ImageView
                    android:id="@+id/iv_img_05"
                    android:layout_width="50dp"
                    android:layout_height="match_parent"
                    android:src="@drawable/app_05" />
    
                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:layout_marginLeft="10dp"
                    android:layout_toRightOf="@id/iv_img_05"
                    android:gravity="center_vertical"
                    android:text="第五个Item" />
            </RelativeLayout>
    
        </LinearLayout>
    </RelativeLayout>
    

    这里的菜单,能够是用ListView来布局,做測试就没有那样做了。所有代码所有在这里了。能够看出。两种效果仅仅是继承了不通的布局,感觉另外一种效果在设置背景时有点问题,就是在这里
    <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">
    
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:background="@drawable/bg_02"
                android:orientation="vertical">
                <Button
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:onClick="testScrollMenu"
                    android:text="測试另外一种側滑菜单"/>
            </LinearLayout>
        </LinearLayout>
    假设将背景设置到第一层的LinearLayout上,那么自己定义側滑菜单那里设置背景就显示不出来,设置到第二层就能够,我不知道是怎么回事肿。假设我们掌握发现,麻烦告诉小弟。

    版权声明:本文博客原创文章。博客,未经同意,不得转载。

  • 相关阅读:
    《AI for Game Developers》第七章 A*路径寻找算法 (二)(skiplow翻译)
    芯片科普学习笔记
    sprboot 配置logback 日志输出
    springboot+mybatis 配置双数据源(mysql,oracle,sqlserver,db2)
    vue 封装axios请求
    *arg参数
    pytest mac安装了pytest,但是输入pytest却提示命令不存在
    构建Java Web开发环境
    在CentOS上编译安装PostgreSQL
    在Ubuntu 14.04上使用Eclipse开发和调试PosgreSQL9.3.4
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/4674704.html
Copyright © 2011-2022 走看看