android之SlideMenu双向滑动

开始动手之前先来讲一下实现原理,在一个Activity的布局中需要有三部分,一个是左侧菜单的布局,一个是右侧菜单的布局,一个是内容布局。左侧菜单居屏幕左边缘对齐,右侧菜单居屏幕右边缘对齐,然后内容布局占满整个屏幕,并压在了左侧菜单和右侧菜单的上面。当用户手指向右滑动时,将右侧菜单隐藏,左侧菜单显示,然后通过偏移内容布局的位置,就可以让左侧菜单展现出来。同样的道理,当用户手指向左滑动时,将左侧菜单隐藏,右侧菜单显示,也是通过偏移内容布局的位置,就可以让右侧菜单展现出来。

1.新建Android项目,然后新建一个DoubleSlideMenu继承自RelativeLayout,核心类代码:

public class DoubleMenu extends RelativeLayout implements OnTouchListener {
    //滚动和隐藏菜单布局时手指所需要的速度
    private static final int SNAP_VELOCITY=200;
    //未进行任何滑动
    private static final int DO_NOTHING=0;
    //左侧滑动菜单的显示
    private static final int SHOW_LEFT_MENU=1;
    //右侧菜单显示
    private static final int SHOW_RIGHT_MENU=2;
    //左侧菜单隐藏
    private static final int HIDE_LEFT_MENU=3;
    //右侧菜单隐藏
    private static final int HIDE_RIGHT_MENU=4;

    //记录滑动的状态
    private int slideState;
    //滑动菜单最小的距离
    private int touchSlop;
    //屏幕宽
    private int screenWidth;
    //按下的横坐标
    private float xDown;
    //按下的纵坐标
    private float yDown;
    //移动的横坐标
    private float xMove;
    //移动的纵坐标
    private float yMove;
    //弹起的横坐标
    private float xUp;

    //标志左侧菜单是否显示
    private boolean isLeftMenuVisible;
    //标志右侧菜单是否显示
    private boolean isRightMenuVisible;
    //左侧菜单布局
    private View leftMenuLayout;
    //右侧菜单布局
    private View rightMenuLayout;
    //左侧菜单布局参数
    private MarginLayoutParams leftMenuLayoutParams;
    //右侧菜单布局参数
    private MarginLayoutParams rightMenuLayoutParams;
    //内容页面布局
    private View contentLayout;
    //内容页面布局参数
    private RelativeLayout.LayoutParams contentLayoutParams;
    //标志菜单是否正在滑动
    private boolean isSliding;
    //用于监听滑动事件的View
    private View mBindView;
    //手指的速度
    private VelocityTracker mVelocityTracker;

    public DoubleMenu(Context context, AttributeSet attrs) {
        super(context, attrs);
        WindowManager wm=(WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        screenWidth=wm.getDefaultDisplay().getWidth();
        touchSlop=ViewConfiguration.get(context).getScaledTouchSlop();  //触发滚动菜单事件的最小距离
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);
        if(changed){
            //获取左侧菜单
            leftMenuLayout=getChildAt(0);
            leftMenuLayoutParams=(MarginLayoutParams) leftMenuLayout.getLayoutParams();
            //获取右侧菜单
            rightMenuLayout=getChildAt(1);
            rightMenuLayoutParams=(MarginLayoutParams) rightMenuLayout.getLayoutParams();
            //获取内容页面
            contentLayout=getChildAt(2);
            contentLayoutParams=(RelativeLayout.LayoutParams) contentLayout.getLayoutParams();
            contentLayoutParams.width=screenWidth;
            contentLayout.setLayoutParams(contentLayoutParams);
        }
    }
    //绑定监听滑动的View
    public void setScrollEvent(View bindView){
        mBindView=bindView;
        mBindView.setOnTouchListener(this);
    }

    //判断左侧布局是否显示
    public boolean isLeftMenuVisible(){
        return isLeftMenuVisible;
    }
    //判断右侧布局是否显示
    public boolean isRightMenuVisible(){
        return isRightMenuVisible;
    }

    //显示左侧菜单时初始化
    public void initShowLeftState(){
        contentLayoutParams.rightMargin=0;
        contentLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT, 0);
        contentLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
        contentLayout.setLayoutParams(contentLayoutParams);
        leftMenuLayout.setVisibility(View.VISIBLE);
        rightMenuLayout.setVisibility(View.GONE);
    }
    //显示右侧菜单时初始化
    public void initShowRightState(){
        contentLayoutParams.leftMargin=0;
        contentLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, 0);
        contentLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
        contentLayout.setLayoutParams(contentLayoutParams);
        rightMenuLayout.setVisibility(View.VISIBLE);
        leftMenuLayout.setVisibility(View.GONE);
    }

    //根据手指移动的方向,判断用户滑动意图
    private void checkSlideState(int moveDistanceX,int moveDistanceY){
        if(isLeftMenuVisible){  //如果左侧菜单已经正在显示,判断是否需要关闭
            if(!isSliding&&Math.abs(moveDistanceX)>touchSlop&&moveDistanceX<0){
                isSliding = true;
                slideState=HIDE_LEFT_MENU;
            }
        }
        else if(isRightMenuVisible){
            if(!isSliding&&Math.abs(moveDistanceX)>touchSlop&&moveDistanceX>0){
                isSliding = true;
                slideState=HIDE_RIGHT_MENU;
            }
        }
        else{
            if(!isSliding&&Math.abs(moveDistanceX)>touchSlop&&moveDistanceX>0&&Math.abs(moveDistanceY)<touchSlop){
                isSliding = true;
                slideState=SHOW_LEFT_MENU;
                initShowLeftState();
            }
            else if(!isSliding&&Math.abs(moveDistanceX)>touchSlop&&moveDistanceX<0&&Math.abs(moveDistanceY)<touchSlop){
                isSliding=true;
                slideState=SHOW_RIGHT_MENU;
                initShowRightState();
            }
        }
    }

    //在滑动中,检查左侧菜单的边界值
    private void checkLeftMenuBorder(){
        if(contentLayoutParams.rightMargin>0){
            contentLayoutParams.rightMargin=0;  //隐藏左侧菜单的时刻
        }
        else if(contentLayoutParams.rightMargin<-leftMenuLayoutParams.width){
            contentLayoutParams.rightMargin=-leftMenuLayoutParams.width;  //显示左侧菜单的时刻
        }
    }
    //在滑动过程中检查右侧菜单的边界值
    private void checkRightMenuBorder(){
        if(contentLayoutParams.leftMargin>0){
            contentLayoutParams.leftMargin=0;
        }
        else if(contentLayoutParams.leftMargin<-rightMenuLayoutParams.width){
            contentLayoutParams.leftMargin=-rightMenuLayoutParams.width;
        }
    }

    /**
     * 创建VelocityTracker对象,并将触摸事件加入到VelocityTracker当中。
     *
     * @param event
     *            右侧布局监听控件的滑动事件
     */
    private void createVelocityTracker(MotionEvent event) {
        if (mVelocityTracker == null) {
            mVelocityTracker = VelocityTracker.obtain();
        }
        mVelocityTracker.addMovement(event);
    }
    /**
     * 获取手指在绑定布局上的滑动速度。
     *
     * @return 滑动速度,以每秒钟移动了多少像素值为单位。
     */
    private int getScrollVelocity() {
        mVelocityTracker.computeCurrentVelocity(1000);
        int velocity = (int) mVelocityTracker.getXVelocity();
        return Math.abs(velocity);
    }
    /**
     * 回收VelocityTracker对象。
     */
    private void recycleVelocityTracker() {
        mVelocityTracker.recycle();
        mVelocityTracker = null;
    }

    //判断是否应该将左侧菜单显示出来
    private boolean shouldScrollToLeftMenu(){
        return xUp-xDown>leftMenuLayoutParams.width/2||getScrollVelocity()>SNAP_VELOCITY;
    }
    //判断是否应将右侧菜单显示
    private boolean shouldScrollToRightMenu(){
        return xDown-xUp>rightMenuLayoutParams.width/2||getScrollVelocity()>SNAP_VELOCITY;
    }
    //判断是否应从左侧转到内容页面
    private boolean shouldScrollToContentFromLeft(){
        return xDown-xUp>leftMenuLayoutParams.width/2||getScrollVelocity()>SNAP_VELOCITY;
    }
    //判断是否应从右侧转到内容页面
    private boolean shouldScrollToContentFromRight(){
        return xUp-xDown>rightMenuLayoutParams.width/2|getScrollVelocity()>SNAP_VELOCITY;
    }

    //让获得焦点的控件在滑动过程中失去焦点
    private void unFocusBindView(){
        if(mBindView!=null){
            mBindView.setPressed(false);
            mBindView.setFocusable(false);
            mBindView.setFocusableInTouchMode(false);
        }
    }

    class LeftMenuScrollTask extends AsyncTask<Integer, Integer, Integer>{
        @Override
        protected Integer doInBackground(Integer... speed) {
            int rightMargin=contentLayoutParams.rightMargin;
            while(true){
                rightMargin=rightMargin+speed[0];
                if(rightMargin>0){  //隐藏
                    rightMargin=0;
                    break;
                }
                if(rightMargin<-leftMenuLayoutParams.width){
                    rightMargin=-leftMenuLayoutParams.width;
                    break;
                }
                publishProgress(rightMargin);
                sleep(15);
            }
            if(speed[0]>0){
                isLeftMenuVisible=false;
            }
            else{
                isLeftMenuVisible=true;
            }
            isSliding=false;
            return rightMargin;
        }
        @Override
        protected void onProgressUpdate(Integer... values) {
            contentLayoutParams.rightMargin=values[0];
            contentLayout.setLayoutParams(contentLayoutParams);
            unFocusBindView();
        }
        @Override
        protected void onPostExecute(Integer result) {
            contentLayoutParams.rightMargin=result;
            contentLayout.setLayoutParams(contentLayoutParams);
        }
    }

    class RightMenuScrollTask extends AsyncTask<Integer, Integer, Integer>{
        @Override
        protected Integer doInBackground(Integer... speed) {
            int leftMargin=contentLayoutParams.leftMargin;
            while(true){
                leftMargin=leftMargin+speed[0];
                if(leftMargin>0){
                    leftMargin=0;
                    break;
                }
                if(leftMargin<-rightMenuLayoutParams.width){
                    leftMargin=-rightMenuLayoutParams.width;
                    break;
                }
                publishProgress(leftMargin);
                sleep(20);
            }
            if(speed[0]>0){
                isRightMenuVisible=false;
            }
            else{
                isRightMenuVisible=true;
            }
            isSliding=false;
            return leftMargin;
        }
        @Override
        protected void onProgressUpdate(Integer... values) {
            contentLayoutParams.leftMargin=values[0];
            contentLayout.setLayoutParams(contentLayoutParams);
            unFocusBindView();
        }
        @Override
        protected void onPostExecute(Integer result) {
            contentLayoutParams.leftMargin=result;
            contentLayout.setLayoutParams(contentLayoutParams);
        }
    }
    private void sleep(long millis) {
        try {
            Thread.sleep(millis);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    //将界面滚到左侧菜单
    public void scrollToLeftMenu(){
        new LeftMenuScrollTask().execute(-30);
    }
    //将界面滚动到右侧菜单
    public void scrollToRightMenu(){
        new RightMenuScrollTask().execute(-30);
    }
    //将界面从左侧滚到内容
    public void scrollToContentFromLeft(){
        new LeftMenuScrollTask().execute(30);
    }
    //将界面从右侧滚到内容
    public void scrollToContentFromRight(){
        new RightMenuScrollTask().execute(30);
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        createVelocityTracker(event);
        switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            xDown=event.getRawX();
            yDown=event.getRawY();
            slideState=DO_NOTHING;
            break;
        case MotionEvent.ACTION_MOVE:{
            xMove=event.getRawX();
            yMove=event.getRawY();
            int moveDistanceX=(int)(xMove-xDown);
            int moveDistanceY=(int)(yMove-yDown);
            checkSlideState(moveDistanceX, moveDistanceY);
            switch (slideState) {
            case SHOW_LEFT_MENU:
                contentLayoutParams.rightMargin=-moveDistanceX;
                checkLeftMenuBorder();
                contentLayout.setLayoutParams(contentLayoutParams);
                break;
            case HIDE_LEFT_MENU:
                contentLayoutParams.rightMargin=-leftMenuLayoutParams.width-moveDistanceX;
                checkLeftMenuBorder();
                contentLayout.setLayoutParams(contentLayoutParams);
                break;
            case SHOW_RIGHT_MENU:
                contentLayoutParams.leftMargin=moveDistanceX;
                checkRightMenuBorder();
                contentLayout.setLayoutParams(contentLayoutParams);
                break;
            case HIDE_RIGHT_MENU:
                contentLayoutParams.leftMargin=-rightMenuLayoutParams.width+moveDistanceX;
                checkRightMenuBorder();
                contentLayout.setLayoutParams(contentLayoutParams);
                break;
              }
            break;
            }
        case MotionEvent.ACTION_UP:
            xUp=event.getRawX();
            int upDistanceX=(int)(xUp-xDown);
            if(isSliding){
                switch (slideState) {
                case SHOW_LEFT_MENU:
                    if(shouldScrollToLeftMenu()){
                        scrollToLeftMenu();
                    }
                    else{
                        scrollToContentFromLeft();
                    }
                    break;
                case HIDE_LEFT_MENU:
                    if(shouldScrollToContentFromLeft()){
                        scrollToContentFromLeft();
                    }
                    else{
                        scrollToLeftMenu();
                    }
                    break;
                case SHOW_RIGHT_MENU:
                    if(shouldScrollToRightMenu()){
                        scrollToRightMenu();
                    }
                    else{
                        scrollToContentFromRight();
                    }
                    break;
                case HIDE_RIGHT_MENU:
                    if(shouldScrollToContentFromRight()){
                        scrollToContentFromRight();
                    }
                    else{
                        scrollToRightMenu();
                    }
                default:
                    break;
                }
            }
            else if(upDistanceX<touchSlop&&isLeftMenuVisible){
                scrollToContentFromLeft();
            }
            else if(upDistanceX<touchSlop&&isRightMenuVisible){
                scrollToContentFromRight();
            }
            recycleVelocityTracker();
            break;
        }

        if(v.isClickable()){   //这里要求控件必须是clickable的.
            if(isSliding){
                unFocusBindView();  //正在滑动时取消控件焦点
                return true;
            }
            if(isLeftMenuVisible||isRightMenuVisible){
                return true;//当左菜单或右菜单显示时,取消触摸事件
            }
            return false;
        }
        return true;
    }
}

首先在onLayout()方法中分别获取到左侧菜单、右侧菜单和内容布局的参数,并将内容布局的宽度重定义成屏幕的宽度,这样就可以保证内容布局既能覆盖住下面的菜单布局,还能偏移出屏幕。然后在onTouch()方法中监听触屏事件,以判断用户手势的意图。这里事先定义好了几种滑动状态,DO_NOTHING表示没有进行任何滑动,SHOW_LEFT_MENU表示用户想要滑出左侧菜单,SHOW_RIGHT_MENU表示用户想要滑出右侧菜单,HIDE_LEFT_MENU表示用户想要隐藏左侧菜单,HIDE_RIGHT_MENU表示用户想要隐藏右侧菜单,在checkSlideState()方法中判断出用户到底是想进行哪一种滑动操作,并给slideState变量赋值,然后根据slideState的值决定如何偏移内容布局。接着当用户手指离开屏幕时,会根据当前的滑动距离,决定后续的滚动方向,通过LeftMenuScrollTask和RightMenuScrollTask来完成完整的滑动过程。另外在滑动的过程,内容布局上的事件会被屏蔽掉,主要是通过一系列的return操作实现的.

2.打开activity_main.xml

<com.example.doubleslidemenu.DoubleMenu 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:id="@+id/double_slideMenu"
    tools:context=".MainActivity" >
    <RelativeLayout
        android:layout_width="270dp"
        android:layout_height="fill_parent"
        android:id="@+id/left_menu"
        android:layout_alignParentLeft="true"
        android:background="#00ccff"
        android:visibility="invisible"
        >
                <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:text="This is left menu"
            android:textColor="#000000"
            android:textSize="28sp" />
    </RelativeLayout>

        <RelativeLayout
        android:id="@+id/right_menu"
        android:layout_width="270dip"
        android:layout_height="fill_parent"
        android:layout_alignParentRight="true"
        android:background="#00ffcc"
        android:visibility="invisible" >
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:text="This is right menu"
            android:textColor="#000000"
            android:textSize="28sp" />
    </RelativeLayout>
     <LinearLayout
        android:id="@+id/content"
        android:layout_width="320dip"
        android:layout_height="fill_parent"
        android:orientation="vertical"
        android:background="#e9e9e9" >
        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            >
            <Button
                android:id="@+id/show_left_button"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentLeft="true"
                android:text="show left"
                />
            <Button
                android:id="@+id/show_right_button"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentRight="true"
                android:text="show right"
                />
        </RelativeLayout>
        <ListView
            android:id="@+id/contentList"
            android:layout_width="fill_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:scrollbars="none"
            android:cacheColorHint="#00000000" >
        </ListView>
    </LinearLayout>
</com.example.doubleslidemenu.DoubleMenu>

3.打开MainActivity.java

public class MainActivity extends Activity {
    /**
     * 双向滑动菜单布局
     */
    private DoubleMenu bidirSldingLayout;
    /**
     * 在内容布局上显示的ListView
     */
    private ListView contentList;
    /**
     * ListView的适配器
     */
    private ArrayAdapter<String> contentListAdapter;
    /**
     * 用于填充contentListAdapter的数据源。
     */
    private String[] contentItems = { "Content Item 1", "Content Item 2", "Content Item 3",
            "Content Item 4", "Content Item 5", "Content Item 6", "Content Item 7",
            "Content Item 8", "Content Item 9", "Content Item 10", "Content Item 11",
            "Content Item 12", "Content Item 13", "Content Item 14", "Content Item 15",
            "Content Item 16" };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        bidirSldingLayout = (DoubleMenu) findViewById(R.id.double_slideMenu);
        Button showLeftButton = (Button) findViewById(R.id.show_left_button);
        Button showRightButton = (Button) findViewById(R.id.show_right_button);
        contentList = (ListView) findViewById(R.id.contentList);
        contentListAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,
                contentItems);
        contentList.setAdapter(contentListAdapter);
        bidirSldingLayout.setScrollEvent(contentList);
        showLeftButton.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                if (bidirSldingLayout.isLeftMenuVisible()) {
                    bidirSldingLayout.scrollToContentFromLeft();
                } else {
                    bidirSldingLayout.initShowLeftState();
                    bidirSldingLayout.scrollToLeftMenu();
                }
            }
        });
        showRightButton.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                if (bidirSldingLayout.isRightMenuVisible()) {
                    bidirSldingLayout.scrollToContentFromRight();
                } else {
                    bidirSldingLayout.initShowRightState();
                    bidirSldingLayout.scrollToRightMenu();
                }
            }
        });
    }
}

至此,可以双向滑动的SlideMenu就完成了.

时间: 2024-10-14 14:18:38

android之SlideMenu双向滑动的相关文章

Android上下菜单双向滑动实现

这是研究了网上大神双向左右滑动后实现的上下双向滑动特效,有兴趣的朋友可以看下面代码,注释很详细,原理就是根据手指滑动的方向,来将上下两个布局进行显示与隐藏.主要用了onTouch方法,获取滑动的距离进行偏移. import android.content.Context; import android.os.AsyncTask; import android.util.AttributeSet; import android.view.MotionEvent; import android.vi

Android双向滑动菜单完全解析,教你如何一分钟实现双向滑动特效

转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/9671609 记得在很早之前,我写了一篇关于Android滑动菜单的文章,其中有一个朋友在评论中留言,希望我可以帮他将这个滑动菜单改成双向滑动的方式.当时也没想花太多时间,简单修改了一下就发给了他,结果没想到后来却有一大批的朋友都来问我要这份双向滑动菜单的代码.由于这份代码写得很不用心,我发了部分朋友之后实在不忍心继续发下去了,于是决定专门写一篇文章来介绍更好的Android双向滑

【转】Android双向滑动菜单完全解析,教你如何一分钟实现双向滑动特效

转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/9671609 记得在很早之前,我写了一篇关于Android滑动菜单的文章,其中有一个朋友在评论中留言,希望我可以帮他将这个滑动菜单改成双向滑动的方式.当时也没想花太多时间,简单修改了一下就发给了他,结果没想到后来却有一大批的朋友都来问我要这份双向滑动菜单的代码.由于这份代码写得很不用心,我发了部分朋友之后实在不忍心继续发下去了,于是决定专门写一篇文章来介绍更好的Android双向滑

22.Android 十分方便的滑动标签页

22.Android 十分方便的滑动标签页 Android 十分方便的滑动标签页 前言 EasySlidingTabs属性 EasySlidingTabs布局 FragmentPagerAdapter EasySlidingTabs设置Tab背景 Github传送门 效果图 前言 其实滑动标签页是很常见的,网上搜也是一大堆.但是好用.简单.少bug.可扩展的库实在不多.很多想在做滑动标签页的时候也是经常想到各种不靠谱的库,虽然不难,但是容易坑自己. 原三星底层App大神JiangEcho提供技术

仿优酷Android客户端图片左右滑动(自动滑动)

最终效果: 页面布局main.xml: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent

Android监听ScrollView滑动到顶端和底部

MainActivity如下: package cn.testscrollview; import android.os.Bundle; import android.view.MotionEvent; import android.view.View; import android.view.View.OnTouchListener; import android.widget.ScrollView; import android.app.Activity; /** * Demo描述: * 监

高仿优酷Android客户端图片左右滑动(自动切换)

本例是用ViewPager去做的实现,支持自动滑动和手动滑动,不仅优酷网,实际上有很多商城和门户网站都有类似的实现: 具体思路: 1. 工程中需要添加android-support-v4.jar,才能使用ViewPager控件. 2. 图片的自动切换: 可使用Timer或者ScheduledExecutorService,这个有多重方式可以实现. 同时要切换底部的dots(园点) 3.Handler+Message机制更新UI,这个相信大家都很熟练,不再描述 4. 实现的一些细节:注意本例中的优

Android重写ViewPager修改滑动灵敏度

使用ViewPager作为一个页面进行切换,里面可以存放很多View,但有时在操作View时不小心滑动一下就有可能跳到下一页,这并不是我们想要的,这里就需要重写ViewPager修改它的滑动条件 效果图 程序目录结构 BTViewPager.java package com.example.viewpagerdemo; import android.content.Context; import android.support.v4.view.ViewPager; import android.

Android三种左右滑动效果 手势识别

Android三种左右滑动效果 手势识别(转) 手势识别 1.onCreate中添加GestureDetector mGestureDetector; //监听手势事件 mGestureDetector = new GestureDetector(this, onGestureListener); 2.//实现处理事件 OnGestureListener onGestureListener = new OnGestureListener() { //添加未实现的方法 }; 3.重写onTouch