Android进阶之路 - RecyclerView左划删除(SwipeRecyclerView的简单使用)

阅读之前,请喝口水,慢慢看,主要看加黑加粗字体

如果心静,15分看懂,30分实现,反之遥遥无期

这篇博客是借鉴的yanzhenjie高级猿的代码,同时是在同事的代码中进行抽离出来的,代码可以直接copy,记得不要漏下代码

Effect (如果我们不仅仅需要删除功能,我们可以在item样式里自己随便添加的!)
这里写图片描述

准备工作 - build导入

compile'com.yanzhenjie:recyclerview-swipe:1.0.0'

ItemSlideHelper(这是一个监听手势的help-可直接Copy,无需改变)

package com.example.dow.recyclerdelete;

import android.animation.Animator;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.graphics.Rect;
import android.support.v4.view.GestureDetectorCompat;
import android.support.v4.view.MotionEventCompat;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;

/**
 * 帮助显示左滑菜单
 */
public class ItemSlideHelper implements RecyclerView.OnItemTouchListener, GestureDetector.OnGestureListener {

    private static final String TAG = "ItemSwipeHelper";
    public boolean isUpdate= false;
    private final int DEFAULT_DURATION = 200;
    private View mTargetView;
    private int mActivePointerId;
    private int mTouchSlop;
    private int mMaxVelocity;
    private int mMinVelocity;
    private int mLastX;
    private int mLastY;
    private boolean mIsDragging;
    private Animator mExpandAndCollapseAnim;
    private GestureDetectorCompat mGestureDetector;
    private Callback mCallback;

    public ItemSlideHelper(Context context, Callback callback) {
        this.mCallback = callback;
        
        //手势用于处理fling
        mGestureDetector = new GestureDetectorCompat(context, this);

        ViewConfiguration configuration = ViewConfiguration.get(context);
        mTouchSlop = configuration.getScaledTouchSlop();
        mMaxVelocity = configuration.getScaledMaximumFlingVelocity();
        mMinVelocity = configuration.getScaledMinimumFlingVelocity();
    }

    @Override
    public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
        Log.d(TAG, "onInterceptTouchEvent: " + e.getAction());

        int action =  MotionEventCompat.getActionMasked(e);
        int x = (int) e.getX();
        int y = (int) e.getY();

        //如果RecyclerView滚动状态不是空闲targetView不是空
        if(rv.getScrollState() != RecyclerView.SCROLL_STATE_IDLE){
            if(mTargetView != null){
                //隐藏已经打开
                smoothHorizontalExpandOrCollapse(DEFAULT_DURATION / 2);
                mTargetView = null;
            }
            return false;
        }

        //如果正在运行动画 ,直接拦截什么都不做
        if(mExpandAndCollapseAnim != null && mExpandAndCollapseAnim.isRunning()){
            return true;
        }

        boolean needIntercept =  false;
        switch (action) {
            case MotionEvent.ACTION_DOWN:
                mActivePointerId = MotionEventCompat.getPointerId(e, 0);
                mLastX = (int) e.getX();
                mLastY = (int) e.getY();
                /*
                * 如果之前有一个已经打开的项目,当此次点击事件没有发生在右侧的菜单中则返回TRUE,
                * 如果点击的是右侧菜单那么返回FALSE这样做的原因是因为菜单需要响应Onclick
                * */
                if(mTargetView != null){
                    return !inView(x, y);
                }

                //查找需要显示菜单的view;
                mTargetView = mCallback.findTargetView(x, y);
                break;
            case MotionEvent.ACTION_MOVE:
                int deltaX = (x - mLastX);
                int deltaY = (y - mLastY);
                if(Math.abs(deltaY) > Math.abs(deltaX))
                    return false;

                //如果移动距离达到要求,则拦截
                needIntercept = mIsDragging = mTargetView != null && Math.abs(deltaX) >= mTouchSlop;
                break;
            case MotionEvent.ACTION_CANCEL:
            case MotionEvent.ACTION_UP:
                /*
                * 走这是因为没有发生过拦截事件
                * */
                if(isExpanded()){
                    if (inView(x, y)) {
                      // 如果走这那行这个ACTION_UP的事件会发生在右侧的菜单中
                        Log.d(TAG, "click item");
                        isUpdate= true;
                    }else{
                        //拦截事件,防止targetView执行onClick事件
                        needIntercept = true;
                    }
                    //折叠菜单
                    smoothHorizontalExpandOrCollapse(DEFAULT_DURATION / 2);
                }
                mTargetView = null;
                break;
        }
        return  needIntercept ;
    }

    private boolean isExpanded() {
        return mTargetView != null &&  mTargetView.getScrollX() == getHorizontalRange();
    }

    private boolean isCollapsed() {
        return mTargetView != null && mTargetView.getScrollX() == 0;
    }

    /*
    * 根据targetView的scrollX计算出targetView的偏移,这样能够知道这个point
    * 是在右侧的菜单中
    * */
    private boolean inView(int x, int y) {
        if (mTargetView == null)
            return false;

        int scrollX = mTargetView.getScrollX();
        int left = mTargetView.getWidth() - scrollX;
        int top = mTargetView.getTop();
        int right = left + getHorizontalRange() ;
        int bottom = mTargetView.getBottom();
        Rect rect = new Rect(left, top, right, bottom);
        return rect.contains(x, y);
    }

    @Override
    public void onTouchEvent(RecyclerView rv, MotionEvent e) {
        Log.d(TAG, "onTouchEvent: " + e.getAction());

        if(mExpandAndCollapseAnim != null && mExpandAndCollapseAnim.isRunning() || mTargetView == null)
            return;

        //如果要响应fling事件设置将mIsDragging设为false
        if (mGestureDetector.onTouchEvent(e)) {
            mIsDragging = false;
            return;
        }

        int x = (int) e.getX();
        int y = (int) e.getY();
        int action =  MotionEventCompat.getActionMasked(e);
        switch (action) {
            case MotionEvent.ACTION_DOWN:
                //RecyclerView 不会转发这个Down事件

                break;
            case MotionEvent.ACTION_MOVE:
                int deltaX = (int) (mLastX - e.getX());
                if(mIsDragging) {
                    horizontalDrag(deltaX);
                }
                mLastX = x;
                break;

            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
                 if(mIsDragging){
                    if(!smoothHorizontalExpandOrCollapse(0) && isCollapsed())
                        mTargetView = null;

                    mIsDragging = false;
                 }
                break;
        }
    }

    @Override
    public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {

    }
    /**
     *
     * 根据touch事件来滚动View的scrollX
     *
     * @param delta
     */
    private void horizontalDrag(int delta) {
        int scrollX = mTargetView.getScrollX();
        int scrollY = mTargetView.getScrollY();
        if ((scrollX + delta) <= 0) {
            mTargetView.scrollTo(0, scrollY);
            return;
        }

        int horRange = getHorizontalRange();
        scrollX += delta;
        if (Math.abs(scrollX) < horRange) {
            mTargetView.scrollTo(scrollX, scrollY);
        } else {
            mTargetView.scrollTo(horRange, scrollY);
        }
    }


    /**
     * 根据当前scrollX的位置判断是展开还是折叠
     *
     * @param velocityX
     *  如果不等于0那么这是一次fling事件,否则是一次ACTION_UP或者ACTION_CANCEL
     */
    private boolean smoothHorizontalExpandOrCollapse(float velocityX) {
        int scrollX = mTargetView.getScrollX();
        int scrollRange = getHorizontalRange();
        if (mExpandAndCollapseAnim != null)
            return false;

        int to = 0;
        int duration = DEFAULT_DURATION;

        if (velocityX == 0) {
            //如果已经展一半,平滑展开
            if (scrollX > scrollRange / 2) {
                to = scrollRange;
            }
        } else {
            if (velocityX > 0)
                to = 0;
            else
                to = scrollRange;
            duration = (int) ((1.f - Math.abs(velocityX) / mMaxVelocity) * DEFAULT_DURATION);
        }

        if(to == scrollX)
            return false;

        mExpandAndCollapseAnim = ObjectAnimator.ofInt(mTargetView, "scrollX", to);
        mExpandAndCollapseAnim.setDuration(duration);
        mExpandAndCollapseAnim.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {
            }
            
            @Override
            public void onAnimationEnd(Animator animation) {
                mExpandAndCollapseAnim = null;

                if(isUpdate) {

                    mCallback.updateItem();
                }
                isUpdate= false;
                if (isCollapsed()) {
                    mTargetView = null;
                }
                Log.d(TAG, "onAnimationEnd");
            }

            @Override
            public void onAnimationCancel(Animator animation) {
                //onAnimationEnd(animation);
                mExpandAndCollapseAnim = null;
                Log.d(TAG, "onAnimationCancel");
            }

            @Override
            public void onAnimationRepeat(Animator animation) {
            }
        });
        mExpandAndCollapseAnim.start();
        return true;
    }

    public  int getHorizontalRange(   ) {
        RecyclerView.ViewHolder viewHolder = mCallback.getChildViewHolder(mTargetView);
        return mCallback.getHorizontalRange(viewHolder);
    }

    @Override
    public boolean onDown(MotionEvent e) {
        return false;
    }

    @Override
    public void onShowPress(MotionEvent e) {

    }

    @Override
    public boolean onSingleTapUp(MotionEvent e) {
        return false;
    }

    @Override
    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
        return false;
    }

    @Override
    public void onLongPress(MotionEvent e) {

    }

    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {

        if(Math.abs(velocityX) > mMinVelocity && Math.abs(velocityX) < mMaxVelocity) {
            if(!smoothHorizontalExpandOrCollapse(velocityX) ) {
                if(isCollapsed())
                    mTargetView = null;
                return true;
            }
        }
        return false;
    }

    public interface Callback {

        int getHorizontalRange(RecyclerView.ViewHolder holder);
        RecyclerView.ViewHolder getChildViewHolder(View childView);
        View findTargetView(float x, float y);
        void updateItem();
    }
}

DividerItemDecoration(添加的间隔线条-可直接Copy,无需改变)

package com.example.dow.recyclerdelete;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;

/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
public class DividerItemDecoration extends RecyclerView.ItemDecoration {
 
    private static final int[] ATTRS = new int[]{
            android.R.attr.listDivider
    };
 
    public static final int HORIZONTAL_LIST = LinearLayoutManager.HORIZONTAL;
 
    public static final int VERTICAL_LIST = LinearLayoutManager.VERTICAL;
 
    private Drawable mDivider;
 
    private int mOrientation;
 
    public DividerItemDecoration(Context context, int orientation) {
        final TypedArray a = context.obtainStyledAttributes(ATTRS);
        mDivider = a.getDrawable(0);
        a.recycle();
        setOrientation(orientation);
    }
 
    public void setOrientation(int orientation) {
        if (orientation != HORIZONTAL_LIST && orientation != VERTICAL_LIST) {
            throw new IllegalArgumentException("invalid orientation");
        }
        mOrientation = orientation;
    }
 
    @Override
    public void onDraw(Canvas c, RecyclerView parent) {
        if (mOrientation == VERTICAL_LIST) {
            drawVertical(c, parent);
        } else {
            drawHorizontal(c, parent);
        }
    }
 
    public void drawVertical(Canvas c, RecyclerView parent) {
        final int left = parent.getPaddingLeft();
        final int right = parent.getWidth() - parent.getPaddingRight();
 
        final int childCount = parent.getChildCount();
        for (int i = 0; i < childCount; i++) {
            final View child = parent.getChildAt(i);
            final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
                    .getLayoutParams();
            final int top = child.getBottom() + params.bottomMargin;
            final int bottom = top + mDivider.getIntrinsicHeight();
            mDivider.setBounds(left, top, right, bottom);
            mDivider.draw(c);
        }
    }
 
    public void drawHorizontal(Canvas c, RecyclerView parent) {
        final int top = parent.getPaddingTop();
        final int bottom = parent.getHeight() - parent.getPaddingBottom();
 
        final int childCount = parent.getChildCount();
        for (int i = 0; i < childCount; i++) {
            final View child = parent.getChildAt(i);
            final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
                    .getLayoutParams();
            final int left = child.getRight() + params.rightMargin;
            final int right = left + mDivider.getIntrinsicHeight();
            mDivider.setBounds(left, top, right, bottom);
            mDivider.draw(c);
        }
    }
 
    @Override
    public void getItemOffsets(Rect outRect, int itemPosition, RecyclerView parent) {
        if (mOrientation == VERTICAL_LIST) {
            outRect.set(0, 0, 0, mDivider.getIntrinsicHeight());
        } else {
            outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0);
        }
    }
}

MyViewHolder

item我们复用的layout-这里我们需要根据实际情况设置对应的item的id

package com.example.dow.recyclerdelete;

import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.TextView;

/**
 * ViewHolder复用的layout id
 */
public class MyViewHolder extends RecyclerView.ViewHolder {

    public TextView textView,del;


    public MyViewHolder(View itemView) {
        super(itemView);
        textView = (TextView) itemView.findViewById(R.id.tv_text);
        del = (TextView) itemView.findViewById(R.id.tv_delete);
    }
}

RecyclerAdapter(这个要想实现自己的效果,必须修改!)

注意

  • 其一:onCreateViewHolder中item的layout
  • 其二:onBindViewHolder中的数据设置

代码如下:

package com.example.dow.recyclerdelete;

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.Toast;
import java.util.List;

public class RecyclerAdapter<T> extends RecyclerView.Adapter implements ItemSlideHelper.Callback {
    private List<T> mData;
    private Context mContext;

    private RecyclerView mRecyclerView;

    public RecyclerAdapter(List<T> mData, Context context) {
        this.mData = mData;
        this.mContext = context;
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.gx_list_item, parent, false);
        MyViewHolder holder = new MyViewHolder(view);
        setListener(parent, holder, viewType);
        return holder;
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {
        MyViewHolder viewHolder = (MyViewHolder) holder;
        viewHolder.textView.setText(mData.get(position).toString());
        viewHolder.textView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(mContext, "textView-onClick->>>" + mData.get(position).toString(), Toast.LENGTH_LONG).show();

            }
        });

        /*viewHolder.del.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                mData.remove(position);
                RecyclerAdapter.this.remove(position);
                //RecyclerAdapter.this.notifyDataSetChanged();
                //Toast.makeText(mContext, "del-onClick->>>" + mData.get(position).toString(), Toast.LENGTH_LONG).show();

            }
        });*/
    }

    @Override
    public int getItemCount() {
        return mData.size();
    }

    public void remove(int pos) {
        this.notifyItemRemoved(pos);
    }

    protected void setListener(final ViewGroup parent, final MyViewHolder viewHolder, int viewType) {
        viewHolder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mOnItemClickListener != null) {
                    int position = viewHolder.getAdapterPosition();
                    mOnItemClickListener.onItemClick(v, viewHolder, mData.get(position), position);
                }
            }
        });

        viewHolder.del.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mOnItemClickListener != null) {
                    int position = viewHolder.getAdapterPosition();
                    mOnItemClickListener.delView(v, viewHolder, mData.get(position), position);
                }
            }
        });

        viewHolder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                if (mOnItemClickListener != null) {
                    int position = viewHolder.getAdapterPosition();
                    return mOnItemClickListener.onItemLongClick(v, viewHolder, mData.get(position), position);
                }
                return false;
            }
        });
    }

    public OnItemClickListener<T> mOnItemClickListener;

    @Override
    public void onAttachedToRecyclerView(RecyclerView recyclerView) {
        super.onAttachedToRecyclerView(recyclerView);

        mRecyclerView = recyclerView;
        mRecyclerView.addOnItemTouchListener(new ItemSlideHelper(mRecyclerView.getContext(), this));
    }

    @Override
    public int getHorizontalRange(RecyclerView.ViewHolder holder) {

        if(holder.itemView instanceof LinearLayout){
            ViewGroup viewGroup = (ViewGroup) holder.itemView;
            if(viewGroup.getChildCount() == 2){
                return viewGroup.getChildAt(1).getLayoutParams().width;
            }
        }
        return 0;
    }

    @Override
    public RecyclerView.ViewHolder getChildViewHolder(View childView) {
        return mRecyclerView.getChildViewHolder(childView);
    }

    @Override
    public View findTargetView(float x, float y) {
        return mRecyclerView.findChildViewUnder(x, y);
    }

    @Override
    public void updateItem() {
        Log.e("666666","7777777777777");
        this.notifyDataSetChanged();
    }

    public interface OnItemClickListener<T> {
        void onItemClick(View view, RecyclerView.ViewHolder holder, T o, int position);
        boolean onItemLongClick(View view, RecyclerView.ViewHolder holder, T o, int position);
        void delView(View view, RecyclerView.ViewHolder holder, T o, int position);
    }

    public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
        this.mOnItemClickListener = onItemClickListener;
    }
}

MainActivity

这里必须要修改,因为我们有自己的item样式,还有对应的Bean-其中动画用的是默认动画,间隔线条用的是DividerItemDecoration

package com.example.dow.recyclerdelete;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {
    private RecyclerAdapter adapter;
    private RecyclerView recyclerView;
    private List<String> list = new ArrayList<>();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        recyclerView = (RecyclerView) findViewById(R.id.id_rv);
        initData();
        adapter = new RecyclerAdapter<String>(list, this);
//        recyclerView.setLayoutManager(new GridLayoutManager(this, 2, GridLayoutManager.VERTICAL, false));
        recyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
        recyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL_LIST));

        recyclerView.setItemAnimator(new DefaultItemAnimator());
        recyclerView.setAdapter(adapter);



        adapter.setOnItemClickListener(new RecyclerAdapter.OnItemClickListener() {
            @Override
            public void onItemClick(View view, RecyclerView.ViewHolder holder, Object o, int position) {
                Toast.makeText(MainActivity.this, "onItemClick-->>>"+list.get(position), Toast.LENGTH_LONG).show();
            }

            @Override
            public boolean onItemLongClick(View view, RecyclerView.ViewHolder holder, Object o, int position) {
                Toast.makeText(MainActivity.this, "onItemLongClick-->>>"+list.get(position), Toast.LENGTH_LONG).show();
                return true;//!!!!!!!!!!!!
            }

            @Override
            public void delView(View view, RecyclerView.ViewHolder holder, Object o, int position) {
                list.remove(position);
                //adapter.remove(position);
                //adapter.notifyDataSetChanged();
            }
        });
    }

    private void initData() {
        for (int i = 1; i < 20; i++) {
            list.add("第 " + i + " 项数据");
        }
    }
}

activity_main

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.dow.recyclerdelete.MainActivity">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/id_rv"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</RelativeLayout>

gx_list_item Xml(以后写自己的item)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:orientation="horizontal"
    android:layout_height="50dp">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="10dp"
        >
        <TextView
            android:id="@+id/tv_text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
    </RelativeLayout>

    <LinearLayout
        android:layout_width="60dp"
        android:orientation="horizontal"
        android:layout_height="match_parent">
        <TextView
            android:id="@+id/tv_delete"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:text="删除"
            android:background="@android:color/holo_red_light"
            android:gravity="center"
            android:textColor="@android:color/white"
            />
    </LinearLayout>
</LinearLayout>
  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
setOnDragListener 通常用于监听 View 的拖动事件,而左划右划属于手势事件,可以通过 GestureDetector 来监听。下面是一个示例代码: ```java public class MyView extends View { private GestureDetector mGestureDetector; public MyView(Context context, AttributeSet attrs) { super(context, attrs); mGestureDetector = new GestureDetector(context, new MyGestureListener()); } @Override public boolean onTouchEvent(MotionEvent event) { return mGestureDetector.onTouchEvent(event); } private class MyGestureListener extends GestureDetector.SimpleOnGestureListener { private static final int SWIPE_THRESHOLD = 100; private static final int SWIPE_VELOCITY_THRESHOLD = 100; @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { boolean result = false; try { float diffY = e2.getY() - e1.getY(); float diffX = e2.getX() - e1.getX(); if (Math.abs(diffX) > Math.abs(diffY)) { if (Math.abs(diffX) > SWIPE_THRESHOLD && Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) { if (diffX > 0) { onSwipeRight(); } else { onSwipeLeft(); } result = true; } } } catch (Exception exception) { exception.printStackTrace(); } return result; } } public void onSwipeRight() { // 处理右划事件 } public void onSwipeLeft() { // 处理左划事件 } } ``` 在这个示例代码中,MyView 继承自 View,重写 onTouchEvent 方法,在该方法中将触摸事件交给 GestureDetector 处理。在 GestureDetector 的回调函数中,判断手势是否为左右滑动,如果是,则调用 MyView 中的 onSwipeLeft 或 onSwipeRight 方法进行处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

远方那座山

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值